Source code of Windows XP (NT5)
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.

332 lines
9.5 KiB

  1. /*++
  2. *
  3. * Component: hidserv.exe
  4. * File: hidserv.c
  5. * Purpose: main entry and NT service routines.
  6. *
  7. * Copyright (C) Microsoft Corporation 1997,1998. All rights reserved.
  8. *
  9. * WGJ
  10. --*/
  11. #include <windows.h>
  12. #include <shlwapi.h>
  13. #include <tchar.h>
  14. CHAR HidservServiceName[] = "HidServ";
  15. CHAR HidservDisplayName[] = "HID Input Service";
  16. void
  17. StartHidserv(
  18. void
  19. )
  20. /*++
  21. Routine Description:
  22. Cal the SCM to start the NT service.
  23. --*/
  24. {
  25. SC_HANDLE hSCM;
  26. SC_HANDLE hService;
  27. SERVICE_STATUS curStatus;
  28. BOOL Ret;
  29. // Open the SCM on this machine.
  30. hSCM = OpenSCManager( NULL,
  31. NULL,
  32. SC_MANAGER_CONNECT);
  33. if (hSCM) {
  34. // Open this service for START access
  35. hService = OpenService( hSCM,
  36. HidservServiceName,
  37. SERVICE_START);
  38. if(hService) {
  39. // Start this service.
  40. Ret = StartService( hService,
  41. 0,
  42. NULL);
  43. // Close the service and the SCM
  44. CloseServiceHandle(hService);
  45. }
  46. CloseServiceHandle(hSCM);
  47. }
  48. }
  49. void
  50. StopHidserv(
  51. void
  52. )
  53. /*++
  54. Routine Description:
  55. Cal the SCM to stop the NT service.
  56. --*/
  57. {
  58. SC_HANDLE hSCM;
  59. SC_HANDLE hService;
  60. SERVICE_STATUS Status;
  61. BOOL Ret;
  62. // Open the SCM on this machine.
  63. hSCM = OpenSCManager( NULL,
  64. NULL,
  65. SC_MANAGER_CONNECT);
  66. if (hSCM) {
  67. // Open this service for DELETE access
  68. hService = OpenService( hSCM,
  69. HidservServiceName,
  70. SERVICE_STOP);
  71. if(hService) {
  72. // Stop this service.
  73. Ret = ControlService( hService,
  74. SERVICE_CONTROL_STOP,
  75. &Status);
  76. CloseServiceHandle(hService);
  77. }
  78. CloseServiceHandle(hSCM);
  79. }
  80. }
  81. void
  82. InstallHidserv(
  83. void
  84. )
  85. /*++
  86. Routine Description:
  87. Install the NT service to Auto-start with no dependencies.
  88. --*/
  89. {
  90. SC_HANDLE hService;
  91. SC_HANDLE hSCM;
  92. TCHAR szModulePathname[] = "%SystemRoot%\\system32\\svchost.exe -k netsvcs";
  93. TCHAR szParameterKeyName[] = "System\\CurrentControlSet\\Services\\HidServ\\Parameters";
  94. TCHAR szServiceValName[] = "ServiceDll";
  95. TCHAR szServiceName[] = "HidServ";
  96. TCHAR szGroupName[] = "shsvc";
  97. TCHAR szSvcHostRegKey[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost";
  98. TCHAR szValue[] = TEXT("%SystemRoot%\\System32\\hidserv.dll");
  99. // Open the SCM on this machine.
  100. hSCM = OpenSCManager( NULL,
  101. NULL,
  102. SC_MANAGER_CREATE_SERVICE);
  103. if (hSCM) {
  104. // The service should exist, so this should fail
  105. hService = CreateService( hSCM,
  106. HidservServiceName,
  107. HidservDisplayName,
  108. SERVICE_ALL_ACCESS,
  109. SERVICE_WIN32_SHARE_PROCESS,
  110. SERVICE_AUTO_START,
  111. SERVICE_ERROR_NORMAL,
  112. szModulePathname,
  113. NULL, NULL, NULL,
  114. NULL, NULL);
  115. // If for some reason the service had been removed, manually set registry values
  116. if(hService) {
  117. HKEY hKey;
  118. LONG status;
  119. status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  120. szParameterKeyName,
  121. 0,
  122. NULL,
  123. 0,
  124. KEY_ALL_ACCESS,
  125. NULL,
  126. &hKey,
  127. NULL);
  128. if(status == ERROR_SUCCESS) {
  129. status = RegSetValueEx(hKey,
  130. szServiceValName,
  131. 0,
  132. REG_EXPAND_SZ,
  133. szValue,
  134. _tcslen(szValue));
  135. RegCloseKey(hKey);
  136. }
  137. status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  138. szSvcHostRegKey,
  139. 0,
  140. KEY_ALL_ACCESS,
  141. &hKey);
  142. if(status == ERROR_SUCCESS) {
  143. DWORD dwSize = 0;
  144. TCHAR* szData;
  145. status = RegQueryValueEx(hKey,
  146. szGroupName,
  147. 0,
  148. NULL,
  149. NULL,
  150. &dwSize);
  151. if(status == ERROR_SUCCESS) {
  152. dwSize += (_tcslen(szServiceName)+2) * sizeof(TCHAR);
  153. szData = (TCHAR*) malloc (dwSize);
  154. if(szData) {
  155. RegQueryValueEx(hKey,
  156. szGroupName,
  157. 0,
  158. NULL,
  159. (LPBYTE) szData,
  160. &dwSize);
  161. if(_tcsstr(szData, szServiceName) == NULL) {
  162. szData = _tcscat(szData, TEXT(" "));
  163. szData = _tcscat(szData, szServiceName);
  164. RegSetValueEx(hKey,
  165. szGroupName,
  166. 0,
  167. REG_MULTI_SZ,
  168. (LPBYTE) szData,
  169. _tcslen(szData));
  170. }
  171. free(szData);
  172. }
  173. }
  174. RegCloseKey(hKey);
  175. }
  176. CloseServiceHandle(hService);
  177. } else {
  178. // Service exists, set to autostart
  179. hService = OpenService(hSCM,
  180. HidservServiceName,
  181. SERVICE_ALL_ACCESS);
  182. if (hService) {
  183. QUERY_SERVICE_CONFIG config;
  184. DWORD junk;
  185. HKEY hKey;
  186. LONG status;
  187. if (ChangeServiceConfig(hService,
  188. SERVICE_NO_CHANGE,
  189. SERVICE_AUTO_START,
  190. SERVICE_NO_CHANGE,
  191. NULL, NULL, NULL,
  192. NULL, NULL, NULL,
  193. HidservDisplayName)) {
  194. // Wait until we're configured correctly.
  195. while (QueryServiceConfig(hService,
  196. &config,
  197. sizeof(config),
  198. &junk)) {
  199. if (config.dwStartType == SERVICE_AUTO_START) {
  200. break;
  201. }
  202. }
  203. }
  204. CloseServiceHandle(hService);
  205. }
  206. }
  207. CloseServiceHandle(hSCM);
  208. }
  209. // Go ahead and start the service for no-reboot install.
  210. StartHidserv();
  211. }
  212. void
  213. RemoveHidserv(
  214. void
  215. )
  216. /*++
  217. Routine Description:
  218. Remove the NT service from the registry database.
  219. --*/
  220. {
  221. SC_HANDLE hSCM;
  222. SC_HANDLE hService;
  223. // Stop the service first
  224. StopHidserv();
  225. // Open the SCM on this machine.
  226. hSCM = OpenSCManager( NULL,
  227. NULL,
  228. SC_MANAGER_CONNECT);
  229. if (hSCM) {
  230. // Open this service for DELETE access
  231. hService = OpenService( hSCM,
  232. HidservServiceName,
  233. DELETE);
  234. if(hService) {
  235. // Remove this service from the SCM's database.
  236. DeleteService(hService);
  237. CloseServiceHandle(hService);
  238. }
  239. CloseServiceHandle(hSCM);
  240. }
  241. }
  242. void
  243. CALLBACK
  244. HidservInstaller(
  245. HWND hwnd,
  246. HINSTANCE hInstance,
  247. LPSTR szCmdLine,
  248. int iCmdShow
  249. )
  250. /*++
  251. Routine Description:
  252. HidServ starts as an NT Service (started by the SCM) unless
  253. a command line param is passed in. Command line params may be
  254. used to start HidServ as a free-standing app, or to control
  255. the NT service.
  256. If compiled non-unicode, we bypass all the NT stuff.
  257. --*/
  258. {
  259. if(!szCmdLine){
  260. return;
  261. }else{
  262. if ((szCmdLine[0] == '-') || (szCmdLine[0] == '/')) {
  263. // Command line switch
  264. if (StrCmpI(&szCmdLine[1], "install") == 0) {
  265. InstallHidserv();
  266. } else if (StrCmpI(&szCmdLine[1], "remove") == 0) {
  267. RemoveHidserv();
  268. } else if (StrCmpI(&szCmdLine[1], "stop") == 0) {
  269. StopHidserv();
  270. } else {
  271. StartHidserv();
  272. }
  273. }
  274. }
  275. }