You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
7.3 KiB
255 lines
7.3 KiB
/*++
|
|
*
|
|
* Component: hidserv.dll
|
|
* File: hidserv.c
|
|
* Purpose: main entry and NT service routines.
|
|
*
|
|
* Copyright (C) Microsoft Corporation 1997,1998. All rights reserved.
|
|
*
|
|
* WGJ
|
|
--*/
|
|
|
|
#include "hidserv.h"
|
|
|
|
TCHAR HidservDisplayName[] = TEXT("HID Input Service");
|
|
|
|
|
|
VOID
|
|
InitializeGlobals()
|
|
/*++
|
|
Routine Description:
|
|
Since .dll might be unloaded/loaded into the same process, so must reinitialize global vars
|
|
--*/
|
|
{
|
|
PnpEnabled = FALSE;
|
|
hNotifyArrival = 0;
|
|
INITIAL_WAIT = 500;
|
|
REPEAT_INTERVAL = 150;
|
|
hInstance = 0;
|
|
hWndHidServ = 0;
|
|
cThreadRef = 0;
|
|
hMutexOOC = 0;
|
|
hService = 0;
|
|
}
|
|
|
|
|
|
void
|
|
StartHidserv(
|
|
void
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Cal the SCM to start the NT service.
|
|
--*/
|
|
{
|
|
SC_HANDLE hSCM;
|
|
SC_HANDLE hService;
|
|
BOOL Ret;
|
|
|
|
INFO(("Start HidServ Service."));
|
|
|
|
// Open the SCM on this machine.
|
|
hSCM = OpenSCManager( NULL,
|
|
NULL,
|
|
SC_MANAGER_CONNECT);
|
|
|
|
if (hSCM) {
|
|
// Open this service for DELETE access
|
|
hService = OpenService( hSCM,
|
|
HidservServiceName,
|
|
SERVICE_START);
|
|
|
|
if (hService) {
|
|
// Start this service.
|
|
Ret = StartService( hService,
|
|
0,
|
|
NULL);
|
|
|
|
// Close the service and the SCM
|
|
CloseServiceHandle(hService);
|
|
}
|
|
|
|
CloseServiceHandle(hSCM);
|
|
}
|
|
}
|
|
|
|
void
|
|
InstallHidserv(
|
|
HWND hwnd,
|
|
HINSTANCE hInstance,
|
|
LPSTR szCmdLine,
|
|
int iCmdShow
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Install the NT service to Auto-start with no dependencies.
|
|
--*/
|
|
{
|
|
SC_HANDLE hService;
|
|
SC_HANDLE hSCM;
|
|
|
|
// Open the SCM on this machine.
|
|
hSCM = OpenSCManager( NULL,
|
|
NULL,
|
|
SC_MANAGER_CREATE_SERVICE);
|
|
|
|
if (hSCM) {
|
|
|
|
// Service exists, set to autostart
|
|
|
|
hService = OpenService(hSCM,
|
|
HidservServiceName,
|
|
SERVICE_ALL_ACCESS);
|
|
if (hService) {
|
|
QUERY_SERVICE_CONFIG config;
|
|
DWORD junk;
|
|
HKEY hKey;
|
|
LONG status;
|
|
|
|
if (ChangeServiceConfig(hService,
|
|
SERVICE_NO_CHANGE,
|
|
SERVICE_AUTO_START,
|
|
SERVICE_NO_CHANGE,
|
|
NULL, NULL, NULL,
|
|
NULL, NULL, NULL,
|
|
HidservDisplayName)) {
|
|
// Wait until we're configured correctly.
|
|
while (QueryServiceConfig(hService,
|
|
&config,
|
|
sizeof(config),
|
|
&junk)) {
|
|
if (config.dwStartType == SERVICE_AUTO_START) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
CloseServiceHandle(hService);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// Go ahead and start the service for no-reboot install.
|
|
StartHidserv();
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
ServiceHandlerEx(
|
|
DWORD fdwControl, // requested control code
|
|
DWORD dwEventType, // event type
|
|
LPVOID lpEventData, // event data
|
|
LPVOID lpContext // user-defined context data
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Handle the service handler requests as required by the app.
|
|
This should virtually always be an async PostMessage. Do not
|
|
block this thread.
|
|
--*/
|
|
{
|
|
PWTSSESSION_NOTIFICATION sessionNotification;
|
|
|
|
switch (fdwControl) {
|
|
case SERVICE_CONTROL_INTERROGATE:
|
|
INFO(("ServiceHandler Request SERVICE_CONTROL_INTERROGATE (%x)", fdwControl));
|
|
SetServiceStatus(hService, &ServiceStatus);
|
|
return NO_ERROR;
|
|
case SERVICE_CONTROL_CONTINUE:
|
|
INFO(("ServiceHandler Request SERVICE_CONTROL_CONTINUE (%x)", fdwControl));
|
|
//SET_SERVICE_STATE(SERVICE_START_PENDING);
|
|
//PostMessage(hWndMmHid, WM_MMHID_START, 0, 0);
|
|
return NO_ERROR;
|
|
case SERVICE_CONTROL_PAUSE:
|
|
INFO(("ServiceHandler Request SERVICE_CONTROL_PAUSE (%x)", fdwControl));
|
|
//SET_SERVICE_STATE(SERVICE_PAUSE_PENDING);
|
|
//PostMessage(hWndMmHid, WM_MMHID_STOP, 0, 0);
|
|
return NO_ERROR;
|
|
case SERVICE_CONTROL_STOP:
|
|
INFO(("ServiceHandler Request SERVICE_CONTROL_STOP (%x)", fdwControl));
|
|
SET_SERVICE_STATE(SERVICE_STOP_PENDING);
|
|
PostMessage(hWndHidServ, WM_CLOSE, 0, 0);
|
|
return NO_ERROR;
|
|
case SERVICE_CONTROL_SHUTDOWN:
|
|
INFO(("ServiceHandler Request SERVICE_CONTROL_SHUTDOWN (%x)", fdwControl));
|
|
SET_SERVICE_STATE(SERVICE_STOP_PENDING);
|
|
PostMessage(hWndHidServ, WM_CLOSE, 0, 0);
|
|
return NO_ERROR;
|
|
case SERVICE_CONTROL_SESSIONCHANGE:
|
|
INFO(("ServiceHandler Request SERVICE_CONTROL_SESSIONCHANGE (%x)", fdwControl));
|
|
sessionNotification = (PWTSSESSION_NOTIFICATION)lpEventData;
|
|
PostMessage(hWndHidServ, WM_WTSSESSION_CHANGE, dwEventType, (LPARAM)sessionNotification->dwSessionId);
|
|
return NO_ERROR;
|
|
default:
|
|
WARN(("Unhandled ServiceHandler code, (%x)", fdwControl));
|
|
}
|
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
VOID
|
|
WINAPI
|
|
ServiceMain(
|
|
DWORD dwArgc,
|
|
LPWSTR * lpszArgv
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
The main thread for the Hid service.
|
|
--*/
|
|
{
|
|
HANDLE initDoneEvent;
|
|
HANDLE threadHandle;
|
|
|
|
InitializeGlobals();
|
|
|
|
initDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
|
|
if (!initDoneEvent) {
|
|
goto ServiceMainError;
|
|
}
|
|
|
|
ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
|
|
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
|
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE;
|
|
ServiceStatus.dwWin32ExitCode = NO_ERROR;
|
|
ServiceStatus.dwServiceSpecificExitCode = NO_ERROR;
|
|
ServiceStatus.dwCheckPoint = 0;
|
|
ServiceStatus.dwWaitHint = 0;
|
|
|
|
hService =
|
|
RegisterServiceCtrlHandlerEx(HidservServiceName,
|
|
ServiceHandlerEx,
|
|
NULL);
|
|
|
|
if (!hService) {
|
|
goto ServiceMainError;
|
|
}
|
|
|
|
SET_SERVICE_STATE(SERVICE_START_PENDING);
|
|
|
|
threadHandle = CreateThread(NULL, // pointer to thread security attributes
|
|
0, // initial thread stack size, in bytes (0 = default)
|
|
HidServMain, // pointer to thread function
|
|
initDoneEvent, // argument for new thread
|
|
0, // creation flags
|
|
&MessagePumpThreadId); // pointer to returned thread identifier
|
|
|
|
if (!threadHandle) {
|
|
goto ServiceMainError;
|
|
}
|
|
|
|
WaitForSingleObject(initDoneEvent, INFINITE);
|
|
|
|
CloseHandle(threadHandle);
|
|
|
|
ServiceMainError:
|
|
|
|
if (initDoneEvent) {
|
|
CloseHandle(initDoneEvent);
|
|
}
|
|
}
|
|
|
|
|
|
|