Leaked source code of windows server 2003
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.

418 lines
10 KiB

  1. #ifndef WIN32_LEAN_AND_MEAN
  2. #define WIN32_LEAN_AND_MEAN
  3. #endif
  4. #include <windows.h>
  5. #include <tchar.h>
  6. #include <regstr.h>
  7. // this will change when the .h is moved to a public location
  8. #include "comp.h"
  9. HINSTANCE hInstance;
  10. PCOMPAIBILITYCALLBACK CompatCallback;
  11. LPVOID CompatContext;
  12. #define szServicesPath REGSTR_PATH_SERVICES TEXT("\\")
  13. #define szDeviceMap TEXT("HARDWARE\\DEVICEMAP")
  14. typedef struct _INPUT_DRIVER_DATA {
  15. LPTSTR Service;
  16. BOOL DisableReplacements;
  17. LPTSTR DeviceMapSubKey;
  18. } INPUT_DRIVER_DATA;
  19. INPUT_DRIVER_DATA DriverData[] = {
  20. { TEXT("sermouse"), FALSE, NULL },
  21. { TEXT("i8042prt"), TRUE, TEXT("KeyboardPort") },
  22. { TEXT("mouclass"), TRUE, TEXT("PointerClass") },
  23. { TEXT("kbdclass"), TRUE, TEXT("KeyboardClass") },
  24. };
  25. #define NUM_DRIVER_DATA (sizeof(DriverData) / sizeof(INPUT_DRIVER_DATA))
  26. LPENUM_SERVICE_STATUS
  27. AllocEnumServiceStatus(SC_HANDLE hSCManager, LPDWORD Count)
  28. {
  29. LPENUM_SERVICE_STATUS ess;
  30. DWORD size;
  31. DWORD resume;
  32. EnumServicesStatus(hSCManager,
  33. SERVICE_DRIVER,
  34. SERVICE_ACTIVE,
  35. NULL,
  36. 0,
  37. &size,
  38. Count,
  39. &resume);
  40. if (size == 0) {
  41. return NULL;
  42. }
  43. ess = (LPENUM_SERVICE_STATUS) LocalAlloc(LPTR, size);
  44. if (!ess) {
  45. return NULL;
  46. }
  47. EnumServicesStatus(hSCManager,
  48. SERVICE_DRIVER,
  49. SERVICE_ACTIVE,
  50. ess,
  51. size,
  52. &size,
  53. Count,
  54. &resume);
  55. return ess;
  56. }
  57. LPQUERY_SERVICE_CONFIG
  58. GetServiceConfig(SC_HANDLE hService)
  59. {
  60. LPQUERY_SERVICE_CONFIG pConfig;
  61. DWORD configSize;
  62. QueryServiceConfig(hService, NULL, 0, &configSize);
  63. pConfig = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, configSize);
  64. if (pConfig == NULL) {
  65. return NULL;
  66. }
  67. if (!QueryServiceConfig(hService, pConfig, configSize, &configSize)) {
  68. LocalFree(pConfig);
  69. pConfig = NULL;
  70. }
  71. return pConfig;
  72. }
  73. BOOL
  74. ValidImagePath(LPTSTR Service, LPTSTR ImagePath, LPTSTR *ImageName)
  75. {
  76. LPTSTR pszDriver, pszDriverEnd, pszDriverBegin;
  77. if (!ImagePath) {
  78. return FALSE;
  79. }
  80. if (lstrlen(ImagePath) == 0) {
  81. return TRUE;
  82. }
  83. if (_tcschr(ImagePath, TEXT('\\')) == 0) {
  84. return FALSE;
  85. }
  86. pszDriver = ImagePath;
  87. pszDriverEnd = pszDriver + lstrlen(pszDriver);
  88. while(pszDriverEnd != pszDriver &&
  89. *pszDriverEnd != TEXT('.')) {
  90. pszDriverEnd--;
  91. }
  92. // pszDriverEnd points to either the beginning of the string or '.'
  93. pszDriverBegin = pszDriverEnd;
  94. while(pszDriverBegin != pszDriver &&
  95. *pszDriverBegin != TEXT('\\')) {
  96. pszDriverBegin--;
  97. }
  98. pszDriverBegin++;
  99. //
  100. // If pszDriver and pszDriverEnd are different, we now
  101. // have the driver name.
  102. //
  103. if (pszDriverBegin > pszDriver &&
  104. pszDriverEnd > pszDriverBegin) {
  105. LONG len, res;
  106. LPTSTR image;
  107. len = ((LONG) (pszDriverEnd - pszDriverBegin)) + 1;
  108. image = (LPTSTR) LocalAlloc(LPTR, len * sizeof(TCHAR));
  109. if (!image) {
  110. return FALSE;
  111. }
  112. // want to copy up to, but not including, the ','
  113. lstrcpyn(image, pszDriverBegin, len);
  114. res = lstrcmpi(image, Service);
  115. if (ImageName != NULL) {
  116. *ImageName = image;
  117. }
  118. else {
  119. LocalFree(image);
  120. }
  121. return res == 0;
  122. }
  123. else {
  124. return FALSE;
  125. }
  126. }
  127. VOID
  128. SetServiceStartValue(LPTSTR Service, DWORD StartValue)
  129. {
  130. COMPATIBILITY_ENTRY ce;
  131. TCHAR szStart[] = TEXT("Start");
  132. LPTSTR regPath;
  133. DWORD len;
  134. len = lstrlen(Service) + lstrlen(szServicesPath) + 1;
  135. len *= sizeof(TCHAR);
  136. regPath = (LPTSTR) LocalAlloc(LPTR, len);
  137. if (!regPath) {
  138. return;
  139. }
  140. lstrcpy(regPath, szServicesPath);
  141. lstrcat(regPath, Service);
  142. ZeroMemory(&ce, sizeof(COMPATIBILITY_ENTRY));
  143. // Description and TextName are need even though this is hidden
  144. ce.Description = Service;
  145. ce.TextName = Service;
  146. ce.RegKeyName = regPath;
  147. ce.RegValName = szStart;
  148. ce.RegValDataSize = sizeof(DWORD);
  149. ce.RegValData = (LPVOID) &StartValue;
  150. ce.Flags |= COMPFLAG_HIDE;
  151. CompatCallback(&ce, CompatContext);
  152. LocalFree(regPath);
  153. }
  154. VOID
  155. SetServiceImagePath(LPTSTR Service)
  156. {
  157. COMPATIBILITY_ENTRY ce;
  158. TCHAR szImagePath[] = TEXT("ImagePath");
  159. TCHAR szPath[] = TEXT("System32\\Drivers\\");
  160. LPTSTR imagePath, regPath;
  161. DWORD len;
  162. len = lstrlen(Service) + lstrlen(szServicesPath) + 1;
  163. len *= sizeof(TCHAR);
  164. regPath = (LPTSTR) LocalAlloc(LPTR, len);
  165. if (!regPath) {
  166. return;
  167. }
  168. len = lstrlen(szPath) + lstrlen(Service) + lstrlen(TEXT(".sys")) + 1;
  169. len *= sizeof(TCHAR);
  170. imagePath = (LPTSTR) LocalAlloc(LPTR, len);
  171. if (!imagePath) {
  172. LocalFree(regPath);
  173. return;
  174. }
  175. lstrcpy(regPath, szServicesPath);
  176. lstrcat(regPath, Service);
  177. lstrcpy(imagePath, szPath);
  178. lstrcat(imagePath, Service);
  179. lstrcat(imagePath, TEXT(".sys"));
  180. ZeroMemory(&ce, sizeof(COMPATIBILITY_ENTRY));
  181. // Description and TextName are need even though this is hidden
  182. ce.Description = Service;
  183. ce.TextName = Service;
  184. ce.RegKeyName = regPath;
  185. ce.RegValName = szImagePath;
  186. ce.RegValDataSize = len;
  187. ce.RegValData = (LPVOID) imagePath;
  188. ce.Flags |= COMPFLAG_HIDE;
  189. CompatCallback(&ce, CompatContext);
  190. LocalFree(regPath);
  191. LocalFree(imagePath);
  192. }
  193. SC_HANDLE
  194. CheckService(SC_HANDLE hSCManager, LPTSTR Service, BOOL *Disabled)
  195. {
  196. SC_HANDLE hService;
  197. LPQUERY_SERVICE_CONFIG pConfig;
  198. hService = OpenService(hSCManager, Service, SERVICE_QUERY_CONFIG);
  199. if (hService) {
  200. pConfig = GetServiceConfig(hService);
  201. if (pConfig) {
  202. if (pConfig->dwStartType == SERVICE_DISABLED &&
  203. pConfig->lpBinaryPathName &&
  204. lstrlen(pConfig->lpBinaryPathName) == 0) {
  205. //
  206. // The service has been preinstalled in the registry, but never
  207. // installed on the machine (indicated byno image path,
  208. // disabled). Setting its start value to demand start will not
  209. // cause any conflicts at all in the PNP world of input drivers.
  210. //
  211. SetServiceStartValue(Service, SERVICE_DEMAND_START);
  212. }
  213. else {
  214. if (pConfig->dwStartType != SERVICE_SYSTEM_START &&
  215. pConfig->dwStartType != SERVICE_DEMAND_START) {
  216. if (Disabled) {
  217. *Disabled = TRUE;
  218. }
  219. SetServiceStartValue(Service, SERVICE_DEMAND_START);
  220. }
  221. if (!ValidImagePath(Service, pConfig->lpBinaryPathName, NULL)) {
  222. SetServiceImagePath(Service);
  223. }
  224. }
  225. LocalFree(pConfig);
  226. pConfig = NULL;
  227. }
  228. }
  229. return hService;
  230. }
  231. BOOL
  232. KnownInputDriver(LPTSTR Service)
  233. {
  234. int i = 0;
  235. for ( ; i < NUM_DRIVER_DATA; i++) {
  236. if (lstrcmpi(Service, DriverData[i].Service) == 0) {
  237. return TRUE;
  238. }
  239. }
  240. return FALSE;
  241. }
  242. VOID
  243. EnumAndDisableFromDeviceMap(SC_HANDLE hSCManager, LPTSTR Key)
  244. {
  245. HKEY hMap, hSubKey;
  246. DWORD dwIndex = 0, dwType, err, dwValueNameSize, dwDataSize;
  247. TCHAR szValueName[255], szData[255];
  248. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  249. szDeviceMap,
  250. 0,
  251. KEY_READ,
  252. &hMap) != ERROR_SUCCESS) {
  253. return;
  254. }
  255. if (RegOpenKeyEx(hMap, Key, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) {
  256. RegCloseKey(hMap);
  257. return;
  258. }
  259. RegCloseKey(hMap);
  260. do {
  261. dwValueNameSize = sizeof(szValueName) / sizeof(TCHAR);
  262. dwDataSize = sizeof(szData);
  263. err = RegEnumValue(hSubKey,
  264. dwIndex++,
  265. szValueName,
  266. &dwValueNameSize,
  267. 0,
  268. &dwType,
  269. (LPBYTE) szData,
  270. &dwDataSize);
  271. if (err == ERROR_SUCCESS) {
  272. LPTSTR service = _tcsrchr(szData, TEXT('\\'));
  273. if (service) {
  274. service++;
  275. if (!KnownInputDriver(service)) {
  276. SetServiceStartValue(service, SERVICE_DISABLED);
  277. }
  278. }
  279. }
  280. } while (err == ERROR_SUCCESS);
  281. RegCloseKey(hSubKey);
  282. }
  283. BOOL
  284. InputUpgradeCheck(PCOMPAIBILITYCALLBACK CompatibilityCallback, LPVOID Context)
  285. {
  286. SC_HANDLE hSCManager, hService;
  287. BOOL disabled;
  288. int i;
  289. LPENUM_SERVICE_STATUS ess = NULL;
  290. DWORD count, resume;
  291. CompatCallback = CompatibilityCallback;
  292. CompatContext = Context;
  293. hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  294. if (hSCManager == NULL) {
  295. return TRUE;
  296. }
  297. for (i = 0; i < NUM_DRIVER_DATA; i++) {
  298. disabled = FALSE;
  299. hService = CheckService(hSCManager, DriverData[i].Service, &disabled);
  300. if (hService) {
  301. if (disabled && DriverData[i].DisableReplacements) {
  302. // search and destroy
  303. EnumAndDisableFromDeviceMap(hSCManager,
  304. DriverData[i].DeviceMapSubKey);
  305. }
  306. CloseServiceHandle(hService);
  307. }
  308. }
  309. CloseServiceHandle(hSCManager);
  310. return TRUE;
  311. }
  312. BOOL APIENTRY
  313. DllMain(HINSTANCE hDll,
  314. DWORD dwReason,
  315. LPVOID lpReserved)
  316. {
  317. switch (dwReason) {
  318. case DLL_PROCESS_ATTACH:
  319. hInstance = hDll;
  320. break;
  321. case DLL_PROCESS_DETACH:
  322. break;
  323. case DLL_THREAD_DETACH:
  324. break;
  325. case DLL_THREAD_ATTACH:
  326. break;
  327. default:
  328. break;
  329. }
  330. return TRUE;
  331. }