B
bhoomilc
Guest
Hi All,
I'm trying to develop USB detect windows service for my custom use in one of the project.
The behavior of detect insert/remove device works perfect with good sense.
The only weired behaviour I have seen is the Log messages is printed twice for device insert/remove.
here is the code for the same,
#include <stdio.h>
#include <windows.h>
#include <dbt.h>
#include <initguid.h>
#include <usbiodef.h>
#define SERVICE_NAME L"USBDetectService"
#define SLEEP_TIME 5000
SERVICE_STATUS Status;
SERVICE_STATUS_HANDLE hStatus;
HDEVNOTIFY hDeviceNotify;
FILE* Log;
void ServiceMain();
DWORD ControlHandler(DWORD, DWORD, LPVOID, LPVOID);
void main()
{
Log = fopen("C:\\SampleUSBEventService.log", "w");
fprintf(Log, "Logging started...\n");
fprintf(Log, "Service executable started...\n");
SERVICE_TABLE_ENTRY ServiceTable[1];
ServiceTable[0].lpServiceName = SERVICE_NAME;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
fprintf(Log, "Invoking StartServiceCtrlDispatcher...\n");
StartServiceCtrlDispatcher(ServiceTable);
fprintf(Log, "Logging finished!\n");
fclose(Log);
}
void ServiceMain()
{
fprintf(Log, "Entering ServiceMain function...\n");
Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
Status.dwCurrentState = SERVICE_START_PENDING;
Status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
Status.dwWin32ExitCode = 0;
Status.dwServiceSpecificExitCode = 0;
Status.dwCheckPoint = 0;
Status.dwWaitHint = 0;
hStatus =
RegisterServiceCtrlHandlerEx(SERVICE_NAME,
(LPHANDLER_FUNCTION_EX)ControlHandler,
0);
fprintf(Log, "RegisterServiceCtrlHandlerEx returned %p\n", hStatus);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
fprintf(Log, "Error : RegisterServiceCtrlHandlerEx returned %d\n", GetLastError());; // Error
SetServiceStatus(hStatus, &Status);
// Some initialization
fprintf(Log, "Registering device notification...\n");
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
hDeviceNotify = NULL;
// static const GUID GuidDevInterfaceDisk =
// { 0x53F56307, 0xB6BF, 0x11D0,
// { 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B } };
static const GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72,
0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
//static const GUID guidForModemDevices = { 0x2c7089aa, 0x2e0e, 0x11d1,
//{ 0xb1, 0x14, 0x00, 0xc0, 0x4f, 0xc2, 0xaa, 0xe4 } };
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
//NotificationFilter.dbcc_classguid = WceusbshGUID;
hDeviceNotify =
RegisterDeviceNotification((HANDLE)hStatus,
&NotificationFilter,
DEVICE_NOTIFY_SERVICE_HANDLE |
DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
fprintf(Log, "RegisterDeviceNotification returned %p\n", hDeviceNotify);
if (hDeviceNotify == NULL)
fprintf(Log, "Error : RegisterDeviceNotification returned %d\n", GetLastError());; // Error
Status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &Status);
fprintf(Log, "Running...\n");
while (Status.dwCurrentState == SERVICE_RUNNING)
{
Sleep(SLEEP_TIME);
}
}
DWORD ControlHandler(DWORD dwControl, DWORD dwEventType,
LPVOID lpEventData, LPVOID lpContext)
{
fprintf(Log, "ControlHandler call with %d:%d\n", dwControl, dwEventType);
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
UnregisterDeviceNotification(hDeviceNotify);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
return NO_ERROR;
case SERVICE_CONTROL_SHUTDOWN:
UnregisterDeviceNotification(hDeviceNotify);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
return NO_ERROR;
//case SERVICE_CONTROL_PAUSE:
// fprintf(Log, "SERVICE_CONTROL_PAUSE! ");
// Status.dwCurrentState = SERVICE_PAUSED;
// SetServiceStatus(hStatus, &Status);
// return NO_ERROR;
//case SERVICE_CONTROL_CONTINUE:
// Status.dwCurrentState = SERVICE_RUNNING;
// fprintf(Log, "SERVICE_CONTROL_CONTINUE! ");
// SetServiceStatus(hStatus, &Status);
// return NO_ERROR;
case SERVICE_CONTROL_DEVICEEVENT:
fprintf(Log, "SERVICE_CONTROL_DEVICEEVENT! ");
switch (dwEventType)
{
case DBT_DEVICEARRIVAL:
// Handle
fprintf(Log, "DBT_DEVICEARRIVAL\n");
break;
case DBT_DEVICEREMOVECOMPLETE:
fprintf(Log, "DBT_DEVICEREMOVECOMPLETE\n");
// Handle
break;
}
break;
default:
fprintf(Log, "Unknown dwControl: %d\n", dwControl);
SetServiceStatus(hStatus, &Status);
break;
}
return NO_ERROR;
}
/////////////////////////////////////////LOG-FILE view/////////////////////////////
Logging started...
Service executable started...
Invoking StartServiceCtrlDispatcher...
Entering ServiceMain function...
RegisterServiceCtrlHandlerEx returned 00E371E0
Registering device notification...
RegisterDeviceNotification returned 00E25F00
Running...
ControlHandler call with 11:32768
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEARRIVAL
ControlHandler call with 11:32768
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEARRIVAL
ControlHandler call with 11:32772
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEREMOVECOMPLETE
ControlHandler call with 11:32772
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEREMOVECOMPLETE
ControlHandler call with 1:0
Logging finished!
///////////////////////////////////////////////////////////////////////////////////////////////
why the ControlHandler callback execute twice?
thanks in advance.
BhoomilC
Continue reading...
I'm trying to develop USB detect windows service for my custom use in one of the project.
The behavior of detect insert/remove device works perfect with good sense.
The only weired behaviour I have seen is the Log messages is printed twice for device insert/remove.
here is the code for the same,
#include <stdio.h>
#include <windows.h>
#include <dbt.h>
#include <initguid.h>
#include <usbiodef.h>
#define SERVICE_NAME L"USBDetectService"
#define SLEEP_TIME 5000
SERVICE_STATUS Status;
SERVICE_STATUS_HANDLE hStatus;
HDEVNOTIFY hDeviceNotify;
FILE* Log;
void ServiceMain();
DWORD ControlHandler(DWORD, DWORD, LPVOID, LPVOID);
void main()
{
Log = fopen("C:\\SampleUSBEventService.log", "w");
fprintf(Log, "Logging started...\n");
fprintf(Log, "Service executable started...\n");
SERVICE_TABLE_ENTRY ServiceTable[1];
ServiceTable[0].lpServiceName = SERVICE_NAME;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
fprintf(Log, "Invoking StartServiceCtrlDispatcher...\n");
StartServiceCtrlDispatcher(ServiceTable);
fprintf(Log, "Logging finished!\n");
fclose(Log);
}
void ServiceMain()
{
fprintf(Log, "Entering ServiceMain function...\n");
Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
Status.dwCurrentState = SERVICE_START_PENDING;
Status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
Status.dwWin32ExitCode = 0;
Status.dwServiceSpecificExitCode = 0;
Status.dwCheckPoint = 0;
Status.dwWaitHint = 0;
hStatus =
RegisterServiceCtrlHandlerEx(SERVICE_NAME,
(LPHANDLER_FUNCTION_EX)ControlHandler,
0);
fprintf(Log, "RegisterServiceCtrlHandlerEx returned %p\n", hStatus);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
fprintf(Log, "Error : RegisterServiceCtrlHandlerEx returned %d\n", GetLastError());; // Error
SetServiceStatus(hStatus, &Status);
// Some initialization
fprintf(Log, "Registering device notification...\n");
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
hDeviceNotify = NULL;
// static const GUID GuidDevInterfaceDisk =
// { 0x53F56307, 0xB6BF, 0x11D0,
// { 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B } };
static const GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72,
0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
//static const GUID guidForModemDevices = { 0x2c7089aa, 0x2e0e, 0x11d1,
//{ 0xb1, 0x14, 0x00, 0xc0, 0x4f, 0xc2, 0xaa, 0xe4 } };
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
//NotificationFilter.dbcc_classguid = WceusbshGUID;
hDeviceNotify =
RegisterDeviceNotification((HANDLE)hStatus,
&NotificationFilter,
DEVICE_NOTIFY_SERVICE_HANDLE |
DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
fprintf(Log, "RegisterDeviceNotification returned %p\n", hDeviceNotify);
if (hDeviceNotify == NULL)
fprintf(Log, "Error : RegisterDeviceNotification returned %d\n", GetLastError());; // Error
Status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &Status);
fprintf(Log, "Running...\n");
while (Status.dwCurrentState == SERVICE_RUNNING)
{
Sleep(SLEEP_TIME);
}
}
DWORD ControlHandler(DWORD dwControl, DWORD dwEventType,
LPVOID lpEventData, LPVOID lpContext)
{
fprintf(Log, "ControlHandler call with %d:%d\n", dwControl, dwEventType);
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
UnregisterDeviceNotification(hDeviceNotify);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
return NO_ERROR;
case SERVICE_CONTROL_SHUTDOWN:
UnregisterDeviceNotification(hDeviceNotify);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
return NO_ERROR;
//case SERVICE_CONTROL_PAUSE:
// fprintf(Log, "SERVICE_CONTROL_PAUSE! ");
// Status.dwCurrentState = SERVICE_PAUSED;
// SetServiceStatus(hStatus, &Status);
// return NO_ERROR;
//case SERVICE_CONTROL_CONTINUE:
// Status.dwCurrentState = SERVICE_RUNNING;
// fprintf(Log, "SERVICE_CONTROL_CONTINUE! ");
// SetServiceStatus(hStatus, &Status);
// return NO_ERROR;
case SERVICE_CONTROL_DEVICEEVENT:
fprintf(Log, "SERVICE_CONTROL_DEVICEEVENT! ");
switch (dwEventType)
{
case DBT_DEVICEARRIVAL:
// Handle
fprintf(Log, "DBT_DEVICEARRIVAL\n");
break;
case DBT_DEVICEREMOVECOMPLETE:
fprintf(Log, "DBT_DEVICEREMOVECOMPLETE\n");
// Handle
break;
}
break;
default:
fprintf(Log, "Unknown dwControl: %d\n", dwControl);
SetServiceStatus(hStatus, &Status);
break;
}
return NO_ERROR;
}
/////////////////////////////////////////LOG-FILE view/////////////////////////////
Logging started...
Service executable started...
Invoking StartServiceCtrlDispatcher...
Entering ServiceMain function...
RegisterServiceCtrlHandlerEx returned 00E371E0
Registering device notification...
RegisterDeviceNotification returned 00E25F00
Running...
ControlHandler call with 11:32768
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEARRIVAL
ControlHandler call with 11:32768
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEARRIVAL
ControlHandler call with 11:32772
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEREMOVECOMPLETE
ControlHandler call with 11:32772
SERVICE_CONTROL_DEVICEEVENT! DBT_DEVICEREMOVECOMPLETE
ControlHandler call with 1:0
Logging finished!
///////////////////////////////////////////////////////////////////////////////////////////////
why the ControlHandler callback execute twice?
thanks in advance.
BhoomilC
Continue reading...