Всем привет :) я пишу сервис и пытаюсь подписать его на сообщения о подключении-отключении флешек.
Код не работает, до функции диспетчеризации дело не доходит. Полный код программы вот, ниже :)
Я сначала подумал, что дело в ServiceStatus.dwControlsAccepted, у меня равно SERVICE_ACCEPT_STOP и SERVICE_ACCEPT_SHUTDOWN, но в MSDN про это мутно как-то написано, а в заголовочном winsvc.h ничего на "принимать сообщения про устройства" похожего нет.
C
#define UNICODE
#define WINVER 0x501
#include <stdio.h>
#include <windows.h>
#include <dbt.h>
#define SERVICE_NAME L"MediaSpy Service"
#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:\\mss.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)
; // 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 } };
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// NotificationFilter.dbcc_classguid = GuidDevInterfaceDisk;
hDeviceNotify =
RegisterDeviceNotification( (HANDLE)hStatus,
&NotificationFilter,
DEVICE_NOTIFY_SERVICE_HANDLE |
DEVICE_NOTIFY_ALL_INTERFACE_CLASSES );
fprintf(Log, "RegisterDeviceNotification returned %p\n", hDeviceNotify);
if(hDeviceNotify == NULL)
; // 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_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;
}
default:
fprintf(Log, "Unknown dwControl: %d\n", dwControl);
SetServiceStatus(hStatus, &Status);
break;
}
return NO_ERROR;
}
У меня неправильно написан фрагмент с регистрацией функции-обработчика. Надо:
C
hStatus = RegisterServiceCtrlHandlerEx( SERVICE_NAME, (LPHANDLER_FUNCTION_EX)ControlHandler, 0 );
А сигнатура функции такая:
C
DWORD ControlHandler(DWORD, DWORD, LPVOID, LPVOID);
Но это всё равно не работает :)