您的位置:首页 > 其它

如何在Windows服务程序中添加U盘插拔的消息

2014-06-18 16:46 316 查看
研究了下这个问题,主要要在一般的windows服务程序中修改两个地方:

一、调用RegisterServiceCtrlHandlerEx

VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv )
{
// Register
the handler function for the service.

gSvcStatusHandle =
RegisterServiceCtrlHandlerEx(
SVCNAME,

SvcCtrlHandler,
NULL);

if( !gSvcStatusHandle )
{

printf("Failed to register service control handler");

return;
}

// These SERVICE_STATUS members remain as set
here.

gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

gSvcStatus.dwServiceSpecificExitCode = 0;

// Report initial
status to the SCM.

ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR,
3000 );

// Perform service-specific initialization and
work.

HDEVNOTIFY hDevNotify;

if(!DoRegisterDeviceInterface(GUID_DEVINTERFACE_VOLUME, &hDevNotify))

{
printf("DoRegisterDeviceInterface failed\n");

ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
return;

}

SvcInit( dwArgc, lpszArgv );

UnregisterDeviceNotification(hDevNotify);
}

二、注册设备响应接口

/*
Routine Description:
Registers for notification of changes
in the device interfaces for
the specified interface class GUID.

Parameters:
InterfaceClassGuid - The interface class GUID for the
device
interfaces.

hDevNotify - Receives the device
notification handle. On failure,
this value is NULL.

Return
Value:
If the function succeeds, the return value is TRUE.
If the
function fails, the return value is FALSE.
*/

BOOL DoRegisterDeviceInterface(
GUID InterfaceClassGuid,

HDEVNOTIFY *hDevNotify
)

{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );

NotificationFilter.dbcc_size =

sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype
= DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid =
InterfaceClassGuid;

*hDevNotify =
RegisterDeviceNotification(
gSvcStatusHandle,

&NotificationFilter,

DEVICE_NOTIFY_SERVICE_HANDLE
);

if(!*hDevNotify)

{
printf("RegisterDeviceNotification failed: %d\n",

GetLastError());
return FALSE;

}

return TRUE;
}

三、处理U盘插拔消息

DWORD WINAPI SvcCtrlHandler(DWORD dwCtrl, DWORD dwEventType, LPVOID
lpEventData, LPVOID lpContext)
{
// Handle the requested control code.

switch(dwCtrl)
{
case SERVICE_CONTROL_STOP:

ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);

// Signal
the service to stop.

SetEvent(ghSvcStopEvent);

return NO_ERROR;

case SERVICE_CONTROL_DEVICEEVENT:
if
(DBT_DEVICEARRIVAL == dwEventType)
{
FILE *fp;

DEV_BROADCAST_HDR * pHdr = (DEV_BROADCAST_HDR
*)lpEventData;
PDEV_BROADCAST_DEVICEINTERFACE pDevInf;

PDEV_BROADCAST_HANDLE pDevHnd;
PDEV_BROADCAST_OEM
pDevOem;
PDEV_BROADCAST_PORT pDevPort;

PDEV_BROADCAST_VOLUME pDevVolume;

switch(
pHdr->dbch_devicetype )
{
case
DBT_DEVTYP_DEVICEINTERFACE:
pDevInf =
(PDEV_BROADCAST_DEVICEINTERFACE)pHdr;

fp =
fopen("C:\\log.txt", "a+");
if (fp)

{
_ftprintf(fp, _T("%s\n"),
pDevInf->dbcc_name);
fclose(fp);

}
break;
case DBT_DEVTYP_HANDLE:

pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr;
break;

case DBT_DEVTYP_OEM:
pDevOem =
(PDEV_BROADCAST_OEM)pHdr;
break;
case
DBT_DEVTYP_PORT:
pDevPort = (PDEV_BROADCAST_PORT)pHdr;

break;
case DBT_DEVTYP_VOLUME:

pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
break;

}
}
break;

case
SERVICE_CONTROL_INTERROGATE:
// Fall through to send current
status.
break;

default:
break;
}

ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);

return NO_ERROR;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐