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.

1856 lines
53 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. clasprop.c
  5. Abstract:
  6. Routines for the following 'built-in' class property page providers:
  7. LegacyDriver
  8. Author:
  9. Lonny McMichael 15-May-1997
  10. --*/
  11. #include "setupp.h"
  12. #pragma hdrstop
  13. #include <help.h>
  14. #include <strsafe.h>
  15. //
  16. // Help Ids for legacy driver property page
  17. //
  18. #define idh_devmgr_driver_hidden_servicename 2480
  19. #define idh_devmgr_driver_hidden_displayname 2481
  20. #define idh_devmgr_driver_hidden_status 2482
  21. #define idh_devmgr_driver_hidden_startbut 2483
  22. #define idh_devmgr_driver_hidden_stopbut 2484
  23. #define idh_devmgr_driver_hidden_startup 2485
  24. #define idh_devmgr_devdrv_details 400400
  25. #define idh_devmgr_driver_copyright 106130
  26. #define idh_devmgr_driver_driver_files 106100
  27. #define idh_devmgr_driver_provider 106110
  28. #define idh_devmgr_driver_file_version 106120
  29. const DWORD LegacyDriver_HelpIDs[]=
  30. {
  31. IDC_STATIC_SERVICE_NAME, idh_devmgr_driver_hidden_servicename,
  32. IDC_EDIT_SERVICE_NAME, idh_devmgr_driver_hidden_servicename,
  33. IDC_STATIC_DISPLAY_NAME, idh_devmgr_driver_hidden_displayname,
  34. IDC_EDIT_DISPLAY_NAME, idh_devmgr_driver_hidden_displayname,
  35. IDC_STATIC_CURRENT_STATUS_STATIC, idh_devmgr_driver_hidden_status,
  36. IDC_STATIC_CURRENT_STATUS, idh_devmgr_driver_hidden_status,
  37. IDC_BUTTON_START, idh_devmgr_driver_hidden_startbut,
  38. IDC_BUTTON_STOP, idh_devmgr_driver_hidden_stopbut,
  39. IDC_COMBO_STARTUP_TYPE, idh_devmgr_driver_hidden_startup,
  40. IDC_LEGACY_DETAILS, idh_devmgr_devdrv_details,
  41. IDC_PROP_LEGACY_ICON, NO_HELP,
  42. IDC_PROP_LEGACY_DESC, NO_HELP,
  43. IDC_GROUP_CURRENT_STATUS, NO_HELP,
  44. IDC_GROUP_STARTUP_TYPE, NO_HELP,
  45. 0, 0
  46. };
  47. const DWORD DriverFiles_HelpIDs[]=
  48. {
  49. IDC_DRIVERFILES_ICON, NO_HELP,
  50. IDC_DRIVERFILES_DESC, NO_HELP,
  51. IDC_DRIVERFILES_FILES, NO_HELP,
  52. IDC_DRIVERFILES_FILELIST, idh_devmgr_driver_driver_files,
  53. IDC_DRIVERFILES_TITLE_PROVIDER, idh_devmgr_driver_provider,
  54. IDC_DRIVERFILES_PROVIDER, idh_devmgr_driver_provider,
  55. IDC_DRIVERFILES_TITLE_COPYRIGHT,idh_devmgr_driver_copyright,
  56. IDC_DRIVERFILES_COPYRIGHT, idh_devmgr_driver_copyright,
  57. IDC_DRIVERFILES_TITLE_VERSION, idh_devmgr_driver_file_version,
  58. IDC_DRIVERFILES_VERSION, idh_devmgr_driver_file_version,
  59. 0, 0
  60. };
  61. #define SERVICE_BUFFER_SIZE 4096
  62. #define MAX_SECONDS_UNTIL_TIMEOUT 30
  63. #define SERVICE_WAIT_TIME 500
  64. #define WAIT_TIME_SLOT 1
  65. #define TRIES_COUNT 5
  66. #define START_LEGACY_DEVICE 0
  67. #define STOP_LEGACY_DEVICE 1
  68. //
  69. // The only reason we have the DiskPropPageProvider and TapePropPageProvider
  70. // APIs are so that the classes can get their icon out of syssetup.dll.
  71. //
  72. BOOL
  73. DiskPropPageProvider(
  74. IN PSP_PROPSHEETPAGE_REQUEST PropPageRequest,
  75. IN LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
  76. IN LPARAM lParam
  77. )
  78. {
  79. //
  80. // No property pages to add for now
  81. //
  82. UNREFERENCED_PARAMETER(PropPageRequest);
  83. UNREFERENCED_PARAMETER(lpfnAddPropSheetPageProc);
  84. UNREFERENCED_PARAMETER(lParam);
  85. return TRUE;
  86. }
  87. BOOL
  88. TapePropPageProvider(
  89. IN PSP_PROPSHEETPAGE_REQUEST PropPageRequest,
  90. IN LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
  91. IN LPARAM lParam
  92. )
  93. {
  94. //
  95. // No property pages to add for now
  96. //
  97. UNREFERENCED_PARAMETER(PropPageRequest);
  98. UNREFERENCED_PARAMETER(lpfnAddPropSheetPageProc);
  99. UNREFERENCED_PARAMETER(lParam);
  100. return TRUE;
  101. }
  102. ///////////////////////////////////////////////////////////////////////////////
  103. //
  104. // Driver Files popup dialog
  105. //
  106. ///////////////////////////////////////////////////////////////////////////////
  107. typedef struct _DRIVERFILES_INFO {
  108. HDEVINFO DeviceInfoSet;
  109. PSP_DEVINFO_DATA DeviceInfoData;
  110. } DRIVERFILES_INFO, * PDRIVERFILES_INFO;
  111. const TCHAR* tszStringFileInfo = TEXT("StringFileInfo\\%04X%04X\\");
  112. const TCHAR* tszFileVersion = TEXT("FileVersion");
  113. const TCHAR* tszLegalCopyright = TEXT("LegalCopyright");
  114. const TCHAR* tszCompanyName = TEXT("CompanyName");
  115. const TCHAR* tszTranslation = TEXT("VarFileInfo\\Translation");
  116. const TCHAR* tszStringFileInfoDefault = TEXT("StringFileInfo\\040904B0\\");
  117. BOOL
  118. GetVersionInfo(
  119. IN PTSTR FullPathName,
  120. OUT PTSTR Provider,
  121. IN ULONG CchProviderSize,
  122. OUT PTSTR Copyright,
  123. IN ULONG CchCopyrightSize,
  124. OUT PTSTR Version,
  125. IN ULONG CchVersionSize
  126. )
  127. {
  128. DWORD Size, dwHandle;
  129. TCHAR str[MAX_PATH];
  130. TCHAR strStringFileInfo[MAX_PATH];
  131. PVOID pVerInfo;
  132. Size = GetFileVersionInfoSize((LPTSTR)(LPCTSTR)FullPathName, &dwHandle);
  133. if (!Size) {
  134. return FALSE;
  135. }
  136. if ((pVerInfo = malloc(Size)) != NULL) {
  137. if (GetFileVersionInfo((LPTSTR)(LPCTSTR)FullPathName, dwHandle, Size, pVerInfo)) {
  138. //
  139. // get VarFileInfo\Translation
  140. //
  141. PVOID pBuffer;
  142. UINT Len;
  143. if (!VerQueryValue(pVerInfo, (LPTSTR)tszTranslation, &pBuffer, &Len)) {
  144. StringCchCopy(strStringFileInfo,
  145. SIZECHARS(strStringFileInfo),
  146. tszStringFileInfoDefault);
  147. } else {
  148. StringCchPrintf(strStringFileInfo,
  149. SIZECHARS(strStringFileInfo),
  150. tszStringFileInfo, *((WORD*)pBuffer), *(((WORD*)pBuffer) + 1));
  151. }
  152. if (SUCCEEDED(StringCchCopy(str, SIZECHARS(str), strStringFileInfo)) &&
  153. SUCCEEDED(StringCchCat(str, SIZECHARS(str), tszFileVersion)) &&
  154. VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len)) {
  155. StringCchCopy(Version, CchVersionSize, (LPTSTR)pBuffer);
  156. if (SUCCEEDED(StringCchCopy(str, SIZECHARS(str), strStringFileInfo)) &&
  157. SUCCEEDED(StringCchCat(str, SIZECHARS(str), tszLegalCopyright)) &&
  158. VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len)) {
  159. StringCchCopy(Copyright, CchCopyrightSize, (LPTSTR)pBuffer);
  160. if (SUCCEEDED(StringCchCopy(str, SIZECHARS(str), strStringFileInfo)) &&
  161. SUCCEEDED(StringCchCat(str, SIZECHARS(str), tszCompanyName)) &&
  162. VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len)) {
  163. StringCchCopy(Provider, CchProviderSize, (LPTSTR)pBuffer);
  164. }
  165. }
  166. }
  167. }
  168. free(pVerInfo);
  169. }
  170. return TRUE;
  171. }
  172. BOOL
  173. pDriverFilesGetServiceFilePath(
  174. HDEVINFO DeviceInfoSet,
  175. PSP_DEVINFO_DATA DeviceInfoData,
  176. PTSTR ServiceFilePath,
  177. ULONG CchServiceFileSize
  178. )
  179. {
  180. BOOL bReturn = FALSE;
  181. TCHAR ServiceName[MAX_PATH];
  182. SC_HANDLE hSCManager = NULL;
  183. SC_HANDLE hSCService = NULL;
  184. LPQUERY_SERVICE_CONFIG lpqscBuf = NULL;
  185. DWORD dwBytesNeeded, Size;
  186. BOOL bComposePathNameFromServiceName = TRUE;
  187. ServiceFilePath[0] = TEXT('\0');
  188. if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
  189. DeviceInfoData,
  190. SPDRP_SERVICE,
  191. NULL,
  192. (PBYTE)ServiceName,
  193. sizeof(ServiceName),
  194. NULL)) {
  195. try {
  196. //
  197. // Open the Service Control Manager
  198. //
  199. if ((hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ)) != NULL) {
  200. //
  201. // Try to open the service's handle
  202. //
  203. if ((hSCService = OpenService(hSCManager, ServiceName, GENERIC_READ)) != NULL) {
  204. //
  205. // Now, attempt to get the configuration
  206. //
  207. if ((!QueryServiceConfig(hSCService, NULL, 0, &dwBytesNeeded)) &&
  208. (ERROR_INSUFFICIENT_BUFFER == GetLastError())) {
  209. if ((lpqscBuf = (LPQUERY_SERVICE_CONFIG)malloc(dwBytesNeeded)) != NULL) {
  210. if ((QueryServiceConfig(hSCService, lpqscBuf, dwBytesNeeded, &Size)) &&
  211. (lpqscBuf->lpBinaryPathName[0] != TEXT('\0'))) {
  212. if (GetFileAttributes(lpqscBuf->lpBinaryPathName) != 0xFFFFFFFF) {
  213. bReturn = TRUE;
  214. StringCchCopy(ServiceFilePath, CchServiceFileSize, lpqscBuf->lpBinaryPathName);
  215. bComposePathNameFromServiceName = FALSE;
  216. }
  217. }
  218. free(lpqscBuf);
  219. }
  220. }
  221. CloseServiceHandle(hSCService);
  222. }
  223. CloseServiceHandle(hSCManager);
  224. }
  225. //
  226. // If we could not get the path name from the service then we will attempt
  227. // to find it ourselves
  228. //
  229. if (bComposePathNameFromServiceName) {
  230. TCHAR FullPathName[MAX_PATH];
  231. if (GetSystemDirectory(FullPathName, SIZECHARS(FullPathName)) &&
  232. SUCCEEDED(StringCchCat(FullPathName, SIZECHARS(FullPathName), TEXT("\\drivers\\"))) &&
  233. SUCCEEDED(StringCchCat(FullPathName, SIZECHARS(FullPathName), ServiceName)) &&
  234. SUCCEEDED(StringCchCat(FullPathName, SIZECHARS(FullPathName), TEXT(".sys")))) {
  235. if (GetFileAttributes(FullPathName) != 0xFFFFFFFF) {
  236. bReturn = TRUE;
  237. StringCchCopy(ServiceFilePath, CchServiceFileSize, FullPathName);
  238. }
  239. }
  240. }
  241. } except (EXCEPTION_EXECUTE_HANDLER) {
  242. ;
  243. }
  244. }
  245. return(bReturn);
  246. }
  247. void
  248. DriverFiles_ShowFileDetail(
  249. HWND hDlg
  250. )
  251. {
  252. TCHAR DriverFile[MAX_PATH];
  253. TCHAR Provider[MAX_PATH];
  254. TCHAR Copyright[MAX_PATH];
  255. TCHAR Version[MAX_PATH];
  256. DWORD_PTR Index;
  257. if ((Index = SendMessage(GetDlgItem(hDlg, IDC_DRIVERFILES_FILELIST), LB_GETCURSEL, 0, 0)) != LB_ERR) {
  258. SendMessage(GetDlgItem(hDlg, IDC_DRIVERFILES_FILELIST), LB_GETTEXT, Index, (LPARAM)DriverFile);
  259. Provider[0] = TEXT('\0');
  260. Copyright[0] = TEXT('\0');
  261. Version[0] = TEXT('\0');
  262. GetVersionInfo(DriverFile,
  263. Provider,
  264. SIZECHARS(Provider),
  265. Copyright,
  266. SIZECHARS(Copyright),
  267. Version,
  268. SIZECHARS(Version));
  269. if (Provider[0] != TEXT('\0')) {
  270. SetDlgItemText(hDlg, IDC_DRIVERFILES_PROVIDER, Provider);
  271. }
  272. if (Version[0] != TEXT('\0')) {
  273. SetDlgItemText(hDlg, IDC_DRIVERFILES_VERSION, Version);
  274. }
  275. if (Copyright[0] != TEXT('\0')) {
  276. SetDlgItemText(hDlg, IDC_DRIVERFILES_COPYRIGHT, Copyright);
  277. }
  278. }
  279. }
  280. BOOL
  281. DriverFiles_OnInitDialog(
  282. HWND hDlg,
  283. HWND FocusHwnd,
  284. LPARAM lParam
  285. )
  286. {
  287. PDRIVERFILES_INFO dfi = (PDRIVERFILES_INFO) GetWindowLongPtr(hDlg, DWLP_USER);
  288. HICON ClassIcon;
  289. HICON OldIcon;
  290. TCHAR DeviceDescription[MAX_DEVICE_ID_LEN];
  291. TCHAR DriverName[MAX_PATH];
  292. UNREFERENCED_PARAMETER(FocusHwnd);
  293. dfi = (PDRIVERFILES_INFO)lParam;
  294. SetWindowLongPtr(hDlg, DWLP_USER, (ULONG_PTR)dfi);
  295. //
  296. // Draw the interface: first the icon
  297. //
  298. if (SetupDiLoadClassIcon(&dfi->DeviceInfoData->ClassGuid, &ClassIcon, NULL)) {
  299. OldIcon = (HICON)SendDlgItemMessage(hDlg,
  300. IDC_DRIVERFILES_ICON,
  301. STM_SETICON,
  302. (WPARAM)ClassIcon,
  303. 0);
  304. if (OldIcon) {
  305. DestroyIcon(OldIcon);
  306. }
  307. }
  308. //
  309. // Then the device name
  310. //
  311. if (SetupDiGetDeviceRegistryProperty(dfi->DeviceInfoSet,
  312. dfi->DeviceInfoData,
  313. SPDRP_DEVICEDESC,
  314. NULL,
  315. (PBYTE)DeviceDescription,
  316. MAX_DEVICE_ID_LEN,
  317. NULL)) {
  318. SetDlgItemText(hDlg, IDC_DRIVERFILES_DESC, DeviceDescription);
  319. }
  320. if ((pDriverFilesGetServiceFilePath(dfi->DeviceInfoSet, dfi->DeviceInfoData, DriverName, SIZECHARS(DriverName))) &&
  321. (DriverName[0] != TEXT('\0'))) {
  322. SendMessage(GetDlgItem(hDlg, IDC_DRIVERFILES_FILELIST), LB_ADDSTRING, 0, (LPARAM)DriverName);
  323. }
  324. SendMessage(GetDlgItem(hDlg, IDC_DRIVERFILES_FILELIST), LB_SETCURSEL, 0, 0);
  325. DriverFiles_ShowFileDetail(hDlg);
  326. return TRUE;
  327. }
  328. BOOL
  329. DriverFiles_OnContextMenu(
  330. HWND HwndControl,
  331. WORD Xpos,
  332. WORD Ypos
  333. )
  334. {
  335. UNREFERENCED_PARAMETER(Xpos);
  336. UNREFERENCED_PARAMETER(Ypos);
  337. WinHelp(HwndControl,
  338. L"devmgr.hlp",
  339. HELP_CONTEXTMENU,
  340. (ULONG_PTR) DriverFiles_HelpIDs);
  341. return FALSE;
  342. }
  343. void
  344. DriverFiles_OnHelp(
  345. HWND ParentHwnd,
  346. LPHELPINFO HelpInfo
  347. )
  348. {
  349. UNREFERENCED_PARAMETER(ParentHwnd);
  350. if (HelpInfo->iContextType == HELPINFO_WINDOW) {
  351. WinHelp((HWND) HelpInfo->hItemHandle,
  352. L"devmgr.hlp",
  353. HELP_WM_HELP,
  354. (ULONG_PTR) DriverFiles_HelpIDs);
  355. }
  356. }
  357. void
  358. DriverFiles_OnCommand(
  359. HWND hDlg,
  360. int ControlId,
  361. HWND ControlHwnd,
  362. UINT NotifyCode
  363. )
  364. {
  365. UNREFERENCED_PARAMETER(ControlHwnd);
  366. UNREFERENCED_PARAMETER(NotifyCode);
  367. switch (ControlId) {
  368. case IDOK:
  369. case IDCANCEL:
  370. EndDialog(hDlg, 0);
  371. break;
  372. case IDC_DRIVERFILES_FILELIST:
  373. if (ControlId == LBN_SELCHANGE) {
  374. DriverFiles_ShowFileDetail(hDlg);
  375. }
  376. break;
  377. }
  378. }
  379. INT_PTR
  380. APIENTRY
  381. DriverFiles_DlgProc(
  382. IN HWND hDlg,
  383. IN UINT uMessage,
  384. IN WPARAM wParam,
  385. IN LPARAM lParam
  386. )
  387. {
  388. switch(uMessage) {
  389. case WM_INITDIALOG:
  390. return DriverFiles_OnInitDialog(hDlg, (HWND)wParam, lParam);
  391. case WM_COMMAND:
  392. DriverFiles_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam));
  393. break;
  394. case WM_CLOSE:
  395. EndDialog(hDlg, 0);
  396. break;
  397. case WM_CONTEXTMENU:
  398. return DriverFiles_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  399. case WM_HELP:
  400. DriverFiles_OnHelp(hDlg, (LPHELPINFO) lParam);
  401. break;
  402. }
  403. return FALSE;
  404. }
  405. ///////////////////////////////////////////////////////////////////////////////
  406. //
  407. // Legacy Devices property page provider
  408. //
  409. ///////////////////////////////////////////////////////////////////////////////
  410. typedef struct _LEGACY_PAGE_INFO {
  411. HDEVINFO DeviceInfoSet;
  412. PSP_DEVINFO_DATA DeviceInfoData;
  413. SC_HANDLE hSCManager; // Handle to the SC Manager
  414. SC_HANDLE hService; // The handle to the service
  415. DWORD dwStartType; // The start type
  416. SERVICE_STATUS ServiceStatus; // Tells us if the service is started
  417. TCHAR ServiceName[MAX_DEVICE_ID_LEN];
  418. TCHAR DisplayName[MAX_PATH];
  419. DWORD NumDependentServices;
  420. LPENUM_SERVICE_STATUS pDependentServiceList;
  421. } LEGACY_PAGE_INFO, * PLEGACY_PAGE_INFO;
  422. BOOL
  423. DependentServices_OnInitDialog(
  424. HWND hDlg,
  425. HWND FocusHwnd,
  426. LPARAM lParam
  427. )
  428. {
  429. PLEGACY_PAGE_INFO lpi;
  430. HWND hWndListBox;
  431. DWORD i;
  432. HICON hicon = NULL;
  433. UNREFERENCED_PARAMETER(FocusHwnd);
  434. lpi = (PLEGACY_PAGE_INFO)lParam;
  435. SetWindowLongPtr(hDlg, DWLP_USER, (ULONG_PTR)lpi);
  436. hicon = LoadIcon(NULL, IDI_WARNING);
  437. if (hicon != NULL) {
  438. SendDlgItemMessage(hDlg, IDC_ICON_WARN_SERVICES, STM_SETICON, (WPARAM)hicon, 0L);
  439. DestroyIcon(hicon);
  440. }
  441. hWndListBox = GetDlgItem(hDlg, IDC_LIST_SERVICES);
  442. for (i=0; i<lpi->NumDependentServices; i++) {
  443. SendMessage(hWndListBox,
  444. LB_ADDSTRING,
  445. 0,
  446. (LPARAM) lpi->pDependentServiceList[i].lpDisplayName
  447. );
  448. }
  449. return TRUE;
  450. }
  451. INT_PTR
  452. APIENTRY
  453. DependentServicesDlgProc(
  454. IN HWND hDlg,
  455. IN UINT uMessage,
  456. IN WPARAM wParam,
  457. IN LPARAM lParam
  458. )
  459. {
  460. switch(uMessage) {
  461. case WM_INITDIALOG:
  462. return DependentServices_OnInitDialog(hDlg, (HWND)wParam, lParam);
  463. case WM_COMMAND:
  464. switch (LOWORD(wParam)) {
  465. case IDOK:
  466. case IDCANCEL:
  467. EndDialog(hDlg, LOWORD(wParam));
  468. break;
  469. }
  470. break;
  471. case WM_CLOSE:
  472. EndDialog(hDlg, 0);
  473. break;
  474. }
  475. return FALSE;
  476. }
  477. int
  478. pLegacyDriverMapStateToName(
  479. IN DWORD dwServiceState
  480. )
  481. {
  482. switch(dwServiceState) {
  483. case SERVICE_STOPPED:
  484. return IDS_SVC_STATUS_STOPPED;
  485. case SERVICE_STOP_PENDING:
  486. return IDS_SVC_STATUS_STOPPING;
  487. case SERVICE_RUNNING:
  488. return IDS_SVC_STATUS_STARTED;
  489. case SERVICE_START_PENDING:
  490. return IDS_SVC_STATUS_STARTING;
  491. case SERVICE_PAUSED:
  492. return IDS_SVC_STATUS_PAUSED;
  493. case SERVICE_PAUSE_PENDING:
  494. return IDS_SVC_STATUS_PAUSING;
  495. case SERVICE_CONTINUE_PENDING:
  496. return IDS_SVC_STATUS_RESUMING;
  497. default:
  498. return IDS_SVC_STATUS_UNKNOWN;
  499. }
  500. }
  501. VOID
  502. pLegacyDriverInitializeStartButtons(
  503. IN HWND hDlg,
  504. IN LPSERVICE_STATUS ServiceStatus
  505. )
  506. {
  507. //
  508. // Decide how to paint the two start/stop buttons
  509. //
  510. TCHAR szStatus[MAX_PATH];
  511. //
  512. // Set the status text
  513. //
  514. if (LoadString(MyModuleHandle,
  515. pLegacyDriverMapStateToName(ServiceStatus->dwCurrentState),
  516. szStatus,
  517. MAX_PATH)) {
  518. SetDlgItemText(hDlg, IDC_STATIC_CURRENT_STATUS, szStatus);
  519. }
  520. //
  521. // Decide if the service is started or stopped
  522. //
  523. if ((ServiceStatus->dwCurrentState == SERVICE_STOPPED) ) {
  524. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_START), TRUE);
  525. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_STOP), FALSE);
  526. } else {
  527. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_STOP), TRUE);
  528. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_START), FALSE);
  529. }
  530. //
  531. // If the service doesn't accept stops, grey the stop
  532. // button
  533. //
  534. if (!(ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_STOP)) {
  535. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_STOP), FALSE);
  536. }
  537. return;
  538. }
  539. VOID
  540. pLegacyDriverSetPropertyPageState(
  541. IN HWND hDlg,
  542. IN PLEGACY_PAGE_INFO lpi,
  543. IN BOOL ReadOnly
  544. )
  545. {
  546. DWORD_PTR Index;
  547. DWORD_PTR ServiceStartType;
  548. TCHAR szStatus[MAX_PATH];
  549. if (ReadOnly) {
  550. //
  551. // Disable everything
  552. //
  553. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_STARTUP_TYPE), FALSE);
  554. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_START), FALSE);
  555. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_STOP), FALSE);
  556. //
  557. // Set the status text
  558. //
  559. if (LoadString(MyModuleHandle,
  560. pLegacyDriverMapStateToName(lpi->ServiceStatus.dwCurrentState),
  561. szStatus,
  562. MAX_PATH)) {
  563. SetDlgItemText(hDlg, IDC_STATIC_CURRENT_STATUS, szStatus);
  564. }
  565. } else {
  566. Index = 0;
  567. while ((ServiceStartType = SendMessage(GetDlgItem(hDlg, IDC_COMBO_STARTUP_TYPE),
  568. CB_GETITEMDATA, Index, 0)) != CB_ERR) {
  569. if (ServiceStartType == lpi->dwStartType) {
  570. SendMessage(GetDlgItem(hDlg, IDC_COMBO_STARTUP_TYPE), CB_SETCURSEL, Index, 0);
  571. break;
  572. }
  573. Index++;
  574. }
  575. SendMessage(GetDlgItem(hDlg, IDC_COMBO_STARTUP_TYPE), CB_GETCURSEL, 0, 0);
  576. //
  577. // If the start type is SERVICE_DISABLED then gray out both the start
  578. // and stop buttons.
  579. //
  580. if (lpi->dwStartType == SERVICE_DISABLED) {
  581. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_START), FALSE);
  582. EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_STOP), FALSE);
  583. //
  584. // Set the status text
  585. //
  586. if (LoadString(MyModuleHandle,
  587. pLegacyDriverMapStateToName(lpi->ServiceStatus.dwCurrentState),
  588. szStatus,
  589. MAX_PATH)) {
  590. SetDlgItemText(hDlg, IDC_STATIC_CURRENT_STATUS, szStatus);
  591. }
  592. } else {
  593. pLegacyDriverInitializeStartButtons(hDlg, &lpi->ServiceStatus);
  594. }
  595. }
  596. return;
  597. }
  598. BOOL
  599. pLegacyDriverCheckServiceStatus(
  600. IN SC_HANDLE hService,
  601. IN OUT LPSERVICE_STATUS ServiceStatus,
  602. IN USHORT ControlType
  603. )
  604. {
  605. DWORD dwIntendedState;
  606. DWORD dwCummulateTimeSpent = 0;
  607. if ((ControlType != START_LEGACY_DEVICE) &&
  608. (ControlType != STOP_LEGACY_DEVICE)) {
  609. return TRUE;
  610. }
  611. if (ControlType == START_LEGACY_DEVICE) {
  612. dwIntendedState = SERVICE_RUNNING;
  613. } else {
  614. dwIntendedState = SERVICE_STOPPED;
  615. }
  616. if (!QueryServiceStatus(hService, ServiceStatus)) {
  617. return FALSE;
  618. }
  619. while (ServiceStatus->dwCurrentState != dwIntendedState) {
  620. //
  621. // Wait for the specified interval
  622. //
  623. Sleep(SERVICE_WAIT_TIME);
  624. //
  625. // Check the status again
  626. //
  627. if (!QueryServiceStatus(hService, ServiceStatus)) {
  628. return FALSE;
  629. }
  630. //
  631. // OK, add a (generous) timeout here
  632. //
  633. dwCummulateTimeSpent += SERVICE_WAIT_TIME;
  634. if (dwCummulateTimeSpent > 1000 * MAX_SECONDS_UNTIL_TIMEOUT) {
  635. SetLastError(ERROR_SERVICE_REQUEST_TIMEOUT);
  636. return FALSE;
  637. }
  638. }
  639. //
  640. // If we are here we can return only TRUE
  641. //
  642. return TRUE;
  643. }
  644. VOID
  645. pLegacyDriverDisplayErrorMsgBox(
  646. IN HWND hWnd,
  647. IN LPTSTR ServiceName,
  648. IN int ResId,
  649. IN DWORD ErrorCode
  650. )
  651. {
  652. TCHAR TextBuffer[MAX_PATH * 4];
  653. PTCHAR ErrorMsg;
  654. if (LoadString(MyModuleHandle, ResId, TextBuffer, SIZECHARS(TextBuffer))) {
  655. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  656. NULL,
  657. ErrorCode,
  658. 0,
  659. (LPTSTR)&ErrorMsg,
  660. 0,
  661. NULL
  662. )) {
  663. StringCchCat(TextBuffer, SIZECHARS(TextBuffer), ErrorMsg);
  664. MessageBox(hWnd, TextBuffer, ServiceName, MB_OK);
  665. LocalFree(ErrorMsg);
  666. }
  667. }
  668. }
  669. VOID
  670. pLegacyDriverOnStart(
  671. IN HWND hDlg
  672. )
  673. {
  674. PLEGACY_PAGE_INFO lpi;
  675. HCURSOR hOldCursor;
  676. //
  677. // Retrieve the device data structure first
  678. //
  679. lpi = (PLEGACY_PAGE_INFO)GetWindowLongPtr(hDlg, DWLP_USER);
  680. hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  681. try {
  682. if (!StartService(lpi->hService,
  683. 0,
  684. NULL)) {
  685. pLegacyDriverDisplayErrorMsgBox(hDlg,
  686. lpi->DisplayName,
  687. IDS_SVC_START_ERROR,
  688. GetLastError()
  689. );
  690. goto clean0;
  691. }
  692. pLegacyDriverCheckServiceStatus(lpi->hService,
  693. &lpi->ServiceStatus,
  694. START_LEGACY_DEVICE
  695. );
  696. clean0:
  697. //
  698. // Repaint the status part
  699. //
  700. pLegacyDriverSetPropertyPageState(hDlg, lpi, FALSE);
  701. }except (EXCEPTION_EXECUTE_HANDLER) {
  702. lpi = lpi;
  703. }
  704. SetCursor(hOldCursor);
  705. return;
  706. }
  707. VOID
  708. pLegacyDriverOnStop(
  709. IN HWND hDlg
  710. )
  711. {
  712. BOOL bStopServices = TRUE;
  713. DWORD Err;
  714. PLEGACY_PAGE_INFO lpi;
  715. HCURSOR hOldCursor;
  716. DWORD cbBytesNeeded;
  717. DWORD dwServicesReturned = 0;
  718. DWORD i;
  719. TCHAR DisplayName[MAX_PATH];
  720. SC_HANDLE hService;
  721. SERVICE_STATUS ServiceStatus;
  722. LPENUM_SERVICE_STATUS pDependentServiceList = NULL;
  723. //
  724. // Retrieve the device data structure first
  725. //
  726. lpi = (PLEGACY_PAGE_INFO)GetWindowLongPtr(hDlg, DWLP_USER);
  727. MYASSERT (lpi);
  728. if (!lpi) {
  729. return;
  730. }
  731. hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  732. try {
  733. //
  734. // Find out if this device has any dependent services, and if so then
  735. // how many bytes are needed to enumerate the dependent services.
  736. //
  737. EnumDependentServices(lpi->hService,
  738. SERVICE_ACTIVE,
  739. NULL,
  740. 0,
  741. &cbBytesNeeded,
  742. &dwServicesReturned
  743. );
  744. if (cbBytesNeeded > 0) {
  745. pDependentServiceList = (LPENUM_SERVICE_STATUS)malloc(cbBytesNeeded);
  746. if (pDependentServiceList) {
  747. EnumDependentServices(lpi->hService,
  748. SERVICE_ACTIVE,
  749. pDependentServiceList,
  750. cbBytesNeeded,
  751. &cbBytesNeeded,
  752. &dwServicesReturned
  753. );
  754. if (dwServicesReturned > 0) {
  755. //
  756. // Ask the user if they want to stop these dependet services.
  757. //
  758. lpi->NumDependentServices = dwServicesReturned;
  759. lpi->pDependentServiceList = pDependentServiceList;
  760. if (DialogBoxParam(MyModuleHandle,
  761. MAKEINTRESOURCE(IDD_SERVICE_STOP_DEPENDENCIES),
  762. hDlg,
  763. DependentServicesDlgProc,
  764. (LPARAM)lpi
  765. ) == IDCANCEL) {
  766. bStopServices = FALSE;
  767. }
  768. }
  769. }
  770. }
  771. //
  772. // Stop this service and all the dependent services if the user did
  773. // not cancel out of the dialog box.
  774. //
  775. if (bStopServices) {
  776. Err = ERROR_SUCCESS;
  777. SetCursor(LoadCursor(NULL, IDC_WAIT));
  778. //
  779. // First stop all of the dependent services if their are any.
  780. //
  781. if (pDependentServiceList && (dwServicesReturned > 0)) {
  782. for (i=0; i<dwServicesReturned; i++) {
  783. hService = OpenService(lpi->hSCManager,
  784. pDependentServiceList[i].lpServiceName,
  785. GENERIC_READ | SERVICE_STOP
  786. );
  787. if (hService == NULL) {
  788. //
  789. // Just bail out if we encountered an error. The reason
  790. // is that if one of the services cannot be stopped
  791. // then we won't be able to stop the selected service.
  792. //
  793. Err = GetLastError();
  794. StringCchCopy(DisplayName, SIZECHARS(DisplayName), pDependentServiceList[i].lpServiceName);
  795. break;
  796. }
  797. if (!ControlService(hService,
  798. SERVICE_CONTROL_STOP,
  799. &ServiceStatus
  800. )) {
  801. Err = GetLastError();
  802. StringCchCopy(DisplayName, SIZECHARS(DisplayName), pDependentServiceList[i].lpServiceName);
  803. CloseServiceHandle(hService);
  804. break;
  805. }
  806. //
  807. // Wait for the service to actually stop.
  808. //
  809. if (!pLegacyDriverCheckServiceStatus(hService,
  810. &ServiceStatus,
  811. STOP_LEGACY_DEVICE
  812. )) {
  813. Err = GetLastError();
  814. StringCchCopy(DisplayName, SIZECHARS(DisplayName), pDependentServiceList[i].lpServiceName);
  815. CloseServiceHandle(hService);
  816. break;
  817. }
  818. CloseServiceHandle(hService);
  819. }
  820. }
  821. //
  822. // Only attempt to stop the selected service if all of the dependent
  823. // services were stoped.
  824. //
  825. if (Err == ERROR_SUCCESS) {
  826. //
  827. // Tell the service to stop.
  828. //
  829. if (!ControlService(lpi->hService,
  830. SERVICE_CONTROL_STOP,
  831. &lpi->ServiceStatus)) {
  832. Err = GetLastError();
  833. StringCchCopy(DisplayName, SIZECHARS(DisplayName), lpi->DisplayName);
  834. } else {
  835. //
  836. // Wait for the service to stop.
  837. //
  838. if (!pLegacyDriverCheckServiceStatus(lpi->hService,
  839. &lpi->ServiceStatus,
  840. STOP_LEGACY_DEVICE
  841. )) {
  842. Err = GetLastError();
  843. StringCchCopy(DisplayName, SIZECHARS(DisplayName), lpi->DisplayName);
  844. }
  845. }
  846. }
  847. if (Err != ERROR_SUCCESS) {
  848. pLegacyDriverDisplayErrorMsgBox(hDlg,
  849. DisplayName,
  850. IDS_SVC_STOP_ERROR,
  851. Err
  852. );
  853. }
  854. //
  855. // Repaint the status part
  856. //
  857. pLegacyDriverSetPropertyPageState(hDlg, lpi, FALSE);
  858. }
  859. }except (EXCEPTION_EXECUTE_HANDLER) {
  860. pDependentServiceList = pDependentServiceList;
  861. }
  862. if (pDependentServiceList) {
  863. free(pDependentServiceList);
  864. }
  865. SetCursor(hOldCursor);
  866. return;
  867. }
  868. PLEGACY_PAGE_INFO
  869. LegacyDriver_CreatePageInfo(
  870. IN HDEVINFO DeviceInfoSet,
  871. IN PSP_DEVINFO_DATA DeviceInfoData)
  872. {
  873. PLEGACY_PAGE_INFO lpi = (PLEGACY_PAGE_INFO) MyMalloc(sizeof(LEGACY_PAGE_INFO));
  874. if (!lpi) {
  875. return NULL;
  876. }
  877. lpi->DeviceInfoSet = DeviceInfoSet;
  878. lpi->DeviceInfoData = DeviceInfoData;
  879. return lpi;
  880. }
  881. VOID
  882. LegacyDriver_OnApply(
  883. IN HWND hDlg,
  884. IN DWORD StartType
  885. )
  886. {
  887. PLEGACY_PAGE_INFO lpi;
  888. SC_LOCK sclLock = NULL;
  889. USHORT uCount = 0;
  890. LPQUERY_SERVICE_CONFIG lpqscBuf = NULL;
  891. LPQUERY_SERVICE_CONFIG lpqscTmp = NULL;
  892. DWORD dwBytesNeeded;
  893. //
  894. // Retrieve the device data structure first
  895. //
  896. lpi = (PLEGACY_PAGE_INFO)GetWindowLongPtr(hDlg, DWLP_USER);
  897. try {
  898. //
  899. // Decide if we need to make any changes
  900. //
  901. if ((StartType == lpi->dwStartType) &&
  902. (StartType != SERVICE_DEMAND_START)) {
  903. goto clean0;
  904. }
  905. //
  906. // I guess we need to make some changes here and there...
  907. // Get the database lock first.
  908. //
  909. do {
  910. sclLock = LockServiceDatabase(lpi->hSCManager);
  911. if (sclLock == NULL) {
  912. //
  913. // If there is another error then the database locked by
  914. // another process, bail out
  915. //
  916. if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) {
  917. goto clean0;
  918. } else {
  919. //
  920. // (Busy) wait and try again
  921. //
  922. Sleep (1000 * WAIT_TIME_SLOT);
  923. uCount++;
  924. }
  925. }
  926. } while ((uCount < TRIES_COUNT) && (sclLock == NULL));
  927. if (sclLock == NULL) {
  928. //
  929. // Bail out now, we waited enough
  930. //
  931. goto clean0;
  932. }
  933. //
  934. // I have the lock. Hurry and query, then change the config
  935. //
  936. //
  937. // Now, attempt to get the configuration
  938. //
  939. if ((lpqscBuf = (LPQUERY_SERVICE_CONFIG)malloc(SERVICE_BUFFER_SIZE)) == NULL) {
  940. //
  941. // We're out of here
  942. //
  943. goto clean0;
  944. }
  945. if (!QueryServiceConfig(lpi->hService,
  946. lpqscBuf,
  947. SERVICE_BUFFER_SIZE,
  948. &dwBytesNeeded
  949. )) {
  950. //
  951. // Try again with a new buffer
  952. //
  953. if ((lpqscTmp = realloc(lpqscBuf, dwBytesNeeded)) != NULL) {
  954. //
  955. // Make sure the realloc doesn't leak...
  956. //
  957. lpqscBuf = lpqscTmp;
  958. }
  959. else {
  960. //
  961. // We're out of here
  962. //
  963. goto clean0;
  964. }
  965. if (!QueryServiceConfig(lpi->hService,
  966. lpqscBuf,
  967. SERVICE_BUFFER_SIZE,
  968. &dwBytesNeeded
  969. )) {
  970. goto clean0;
  971. }
  972. }
  973. //
  974. // Change tye service type (we needed the service name, too,
  975. // that's why we're querying it first)
  976. //
  977. if (ChangeServiceConfig(lpi->hService,
  978. SERVICE_NO_CHANGE,
  979. StartType,
  980. SERVICE_NO_CHANGE,
  981. NULL,
  982. NULL,
  983. NULL,
  984. NULL,
  985. NULL,
  986. NULL,
  987. NULL)) {
  988. //
  989. // We succesfully changed the status.
  990. // Reflect in our page display
  991. //
  992. lpi->dwStartType = StartType;
  993. }
  994. //
  995. // Unlock the database
  996. //
  997. if (sclLock) {
  998. UnlockServiceDatabase(sclLock);
  999. sclLock = NULL;
  1000. }
  1001. //
  1002. // We want to see something different on apply, so repaint
  1003. // the whole stuff
  1004. //
  1005. pLegacyDriverSetPropertyPageState(hDlg,
  1006. lpi,
  1007. FALSE); // if we managed to apply some changes
  1008. // we are not read-only
  1009. clean0:
  1010. if (sclLock) {
  1011. UnlockServiceDatabase(sclLock);
  1012. sclLock = NULL;
  1013. }
  1014. if (lpqscBuf) {
  1015. free(lpqscBuf);
  1016. }
  1017. } except (EXCEPTION_EXECUTE_HANDLER) {
  1018. lpi = lpi;
  1019. }
  1020. return;
  1021. }
  1022. BOOL
  1023. LegacyDriver_OnInitDialog(
  1024. HWND hDlg,
  1025. HWND FocusHwnd,
  1026. LPARAM lParam
  1027. )
  1028. {
  1029. PLEGACY_PAGE_INFO lpi = (PLEGACY_PAGE_INFO) GetWindowLongPtr(hDlg, DWLP_USER);
  1030. BOOL ReadOnly = FALSE;
  1031. HICON ClassIcon;
  1032. HICON OldIcon;
  1033. TCHAR DeviceDescription[MAX_DEVICE_ID_LEN];
  1034. TCHAR DriverName[MAX_PATH];
  1035. TCHAR StartupType[MAX_PATH];
  1036. DWORD dwBytesNeeded;
  1037. LPQUERY_SERVICE_CONFIG lpqscBuf = NULL;
  1038. LPQUERY_SERVICE_CONFIG lpqscTmp = NULL;
  1039. DWORD_PTR index;
  1040. HWND hCombo;
  1041. UNREFERENCED_PARAMETER(FocusHwnd);
  1042. lpi = (PLEGACY_PAGE_INFO) ((LPPROPSHEETPAGE)lParam)->lParam;
  1043. SetWindowLongPtr(hDlg, DWLP_USER, (ULONG_PTR)lpi);
  1044. //
  1045. // First, open the Service Control Manager
  1046. //
  1047. lpi->hSCManager = OpenSCManager(NULL,
  1048. NULL,
  1049. GENERIC_WRITE | GENERIC_READ | GENERIC_EXECUTE);
  1050. if (!lpi->hSCManager && (GetLastError() == ERROR_ACCESS_DENIED)) {
  1051. //
  1052. // This is not fatal, attempt to open the database only
  1053. // for read
  1054. //
  1055. ReadOnly = FALSE;
  1056. lpi->hSCManager = OpenSCManager(NULL,
  1057. NULL,
  1058. GENERIC_READ);
  1059. if (!lpi->hSCManager) {
  1060. //
  1061. // This is fatal
  1062. //
  1063. lpi->hSCManager = NULL;
  1064. }
  1065. }
  1066. //
  1067. // Now, get the service name
  1068. //
  1069. if (!SetupDiGetDeviceRegistryProperty(lpi->DeviceInfoSet,
  1070. lpi->DeviceInfoData,
  1071. SPDRP_SERVICE,
  1072. NULL,
  1073. (PBYTE)lpi->ServiceName,
  1074. sizeof(lpi->ServiceName),
  1075. NULL)
  1076. ) {
  1077. LoadString(MyModuleHandle, IDS_UNKNOWN, lpi->ServiceName, SIZECHARS(lpi->ServiceName));
  1078. ReadOnly = TRUE;
  1079. goto clean0;
  1080. }
  1081. //
  1082. // Now we have a service name, try to open its handle
  1083. //
  1084. if (!ReadOnly) {
  1085. lpi->hService = OpenService(lpi->hSCManager,
  1086. lpi->ServiceName,
  1087. GENERIC_WRITE | GENERIC_READ |
  1088. GENERIC_EXECUTE);
  1089. if (!lpi->hService) {
  1090. //
  1091. // OK, let them try again
  1092. //
  1093. ReadOnly = TRUE;
  1094. }
  1095. }
  1096. if (ReadOnly) {
  1097. lpi->hService = OpenService(lpi->hSCManager,
  1098. lpi->ServiceName,
  1099. GENERIC_READ);
  1100. if (!lpi->hService) {
  1101. //
  1102. // Sorry, this is fatal
  1103. //
  1104. ReadOnly = TRUE;
  1105. goto clean0;
  1106. }
  1107. }
  1108. //
  1109. // Now, attempt to get the configuration
  1110. //
  1111. lpqscBuf = (LPQUERY_SERVICE_CONFIG)malloc(SERVICE_BUFFER_SIZE);
  1112. if (!lpqscBuf) {
  1113. ReadOnly = TRUE;
  1114. goto clean0;
  1115. }
  1116. if (!QueryServiceConfig(lpi->hService,
  1117. lpqscBuf,
  1118. SERVICE_BUFFER_SIZE,
  1119. &dwBytesNeeded
  1120. )) {
  1121. //
  1122. // Try again with a new buffer
  1123. //
  1124. if ((lpqscTmp = realloc(lpqscBuf, dwBytesNeeded)) != NULL) {
  1125. //
  1126. // Make sure the realloc didn't leak...
  1127. //
  1128. lpqscBuf = lpqscTmp;
  1129. }
  1130. else {
  1131. //
  1132. // We're out of here
  1133. //
  1134. ReadOnly = TRUE;
  1135. goto clean0;
  1136. }
  1137. if (!QueryServiceConfig(lpi->hService,
  1138. lpqscBuf,
  1139. SERVICE_BUFFER_SIZE,
  1140. &dwBytesNeeded
  1141. )) {
  1142. ReadOnly = TRUE;
  1143. goto clean0;
  1144. }
  1145. }
  1146. //
  1147. // We have the buffer now, get the start type from it
  1148. //
  1149. lpi->dwStartType = lpqscBuf->dwStartType;
  1150. if (!ControlService(lpi->hService,
  1151. SERVICE_CONTROL_INTERROGATE,
  1152. &lpi->ServiceStatus)) {
  1153. DWORD Err = GetLastError();
  1154. //
  1155. // If ControlService failed with one of the following errors then it is OK
  1156. // and the ServiceStatus was still filled in.
  1157. //
  1158. if ((Err != NO_ERROR) &&
  1159. (Err != ERROR_SERVICE_NOT_ACTIVE)) {
  1160. //
  1161. // Bail out,
  1162. //
  1163. ReadOnly = TRUE;
  1164. goto clean0;
  1165. }
  1166. }
  1167. //
  1168. // Add the startup types to the combo box
  1169. //
  1170. hCombo = GetDlgItem(hDlg, IDC_COMBO_STARTUP_TYPE);
  1171. LoadString(MyModuleHandle, IDS_SERVICE_STARTUP_AUTOMATIC, StartupType, SIZECHARS(StartupType));
  1172. index = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)StartupType);
  1173. SendMessage(hCombo, CB_SETITEMDATA, index, (LPARAM)SERVICE_AUTO_START);
  1174. LoadString(MyModuleHandle, IDS_SERVICE_STARTUP_BOOT, StartupType, SIZECHARS(StartupType));
  1175. index = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)StartupType);
  1176. SendMessage(hCombo, CB_SETITEMDATA, index, (LPARAM)SERVICE_BOOT_START);
  1177. LoadString(MyModuleHandle, IDS_SERVICE_STARTUP_DEMAND, StartupType, SIZECHARS(StartupType));
  1178. index = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)StartupType);
  1179. SendMessage(hCombo, CB_SETITEMDATA, index, (LPARAM)SERVICE_DEMAND_START);
  1180. LoadString(MyModuleHandle, IDS_SERVICE_STARTUP_SYSTEM, StartupType, SIZECHARS(StartupType));
  1181. index = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)StartupType);
  1182. SendMessage(hCombo, CB_SETITEMDATA, index, (LPARAM)SERVICE_SYSTEM_START);
  1183. LoadString(MyModuleHandle, IDS_SERVICE_STARTUP_DISABLED, StartupType, SIZECHARS(StartupType));
  1184. index = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)StartupType);
  1185. SendMessage(hCombo, CB_SETITEMDATA, index, (LPARAM)SERVICE_DISABLED);
  1186. clean0:
  1187. //
  1188. // Now draw the interface: first the icon
  1189. //
  1190. if (SetupDiLoadClassIcon(&lpi->DeviceInfoData->ClassGuid, &ClassIcon, NULL)) {
  1191. OldIcon = (HICON)SendDlgItemMessage(hDlg,
  1192. IDC_PROP_LEGACY_ICON,
  1193. STM_SETICON,
  1194. (WPARAM)ClassIcon,
  1195. 0);
  1196. if (OldIcon) {
  1197. DestroyIcon(OldIcon);
  1198. }
  1199. }
  1200. //
  1201. // Then the device name
  1202. //
  1203. if (SetupDiGetDeviceRegistryProperty(lpi->DeviceInfoSet,
  1204. lpi->DeviceInfoData,
  1205. SPDRP_DEVICEDESC,
  1206. NULL,
  1207. (PBYTE)DeviceDescription,
  1208. MAX_DEVICE_ID_LEN,
  1209. NULL)) {
  1210. SetDlgItemText(hDlg, IDC_PROP_LEGACY_DESC, DeviceDescription);
  1211. }
  1212. SetDlgItemText(hDlg, IDC_EDIT_SERVICE_NAME, lpi->ServiceName);
  1213. if (lpqscBuf && lpqscBuf->lpDisplayName) {
  1214. SetDlgItemText(hDlg, IDC_EDIT_DISPLAY_NAME, lpqscBuf->lpDisplayName);
  1215. StringCchCopy(lpi->DisplayName, SIZECHARS(lpi->DisplayName), lpqscBuf->lpDisplayName);
  1216. } else {
  1217. TCHAR Unknown[MAX_PATH];
  1218. LoadString(MyModuleHandle, IDS_UNKNOWN, Unknown, SIZECHARS(Unknown));
  1219. SetDlgItemText(hDlg, IDC_EDIT_DISPLAY_NAME, Unknown);
  1220. StringCchCopy(lpi->DisplayName, SIZECHARS(lpi->DisplayName), Unknown);
  1221. }
  1222. pLegacyDriverSetPropertyPageState(hDlg, lpi, ReadOnly);
  1223. //
  1224. // Show/Gray the details button
  1225. //
  1226. EnableWindow(GetDlgItem(hDlg, IDC_LEGACY_DETAILS),
  1227. (pDriverFilesGetServiceFilePath(lpi->DeviceInfoSet, lpi->DeviceInfoData, DriverName, SIZECHARS(DriverName))));
  1228. if (lpqscBuf) {
  1229. free(lpqscBuf);
  1230. }
  1231. return TRUE;
  1232. }
  1233. void
  1234. LegacyDriver_OnCommand(
  1235. HWND hDlg,
  1236. int ControlId,
  1237. HWND ControlHwnd,
  1238. UINT NotifyCode
  1239. )
  1240. {
  1241. PLEGACY_PAGE_INFO lpi = (PLEGACY_PAGE_INFO) GetWindowLongPtr(hDlg, DWLP_USER);
  1242. UNREFERENCED_PARAMETER(ControlHwnd);
  1243. if (NotifyCode == CBN_SELCHANGE) {
  1244. PropSheet_Changed(GetParent(hDlg), hDlg);
  1245. }
  1246. else {
  1247. switch (ControlId) {
  1248. case IDC_BUTTON_START:
  1249. pLegacyDriverOnStart(hDlg);
  1250. break;
  1251. case IDC_BUTTON_STOP:
  1252. pLegacyDriverOnStop(hDlg);
  1253. break;
  1254. case IDC_LEGACY_DETAILS:
  1255. {
  1256. DRIVERFILES_INFO dfi;
  1257. ZeroMemory(&dfi, sizeof(DRIVERFILES_INFO));
  1258. dfi.DeviceInfoSet = lpi->DeviceInfoSet;
  1259. dfi.DeviceInfoData = lpi->DeviceInfoData;
  1260. DialogBoxParam(MyModuleHandle, MAKEINTRESOURCE(IDD_DRIVERFILES),
  1261. hDlg, DriverFiles_DlgProc, (LPARAM)&dfi);
  1262. }
  1263. break;
  1264. default:
  1265. break;
  1266. }
  1267. }
  1268. }
  1269. BOOL
  1270. LegacyDriver_OnNotify(
  1271. HWND hDlg,
  1272. LPNMHDR NmHdr
  1273. )
  1274. {
  1275. DWORD StartType;
  1276. DWORD_PTR Index;
  1277. switch (NmHdr->code) {
  1278. //
  1279. // The user is about to change an up down control
  1280. //
  1281. case UDN_DELTAPOS:
  1282. PropSheet_Changed(GetParent(hDlg), hDlg);
  1283. return FALSE;
  1284. //
  1285. // Sent when the user clicks on Apply OR OK !!
  1286. //
  1287. case PSN_APPLY:
  1288. if (CB_ERR != (Index = SendMessage(GetDlgItem(hDlg, IDC_COMBO_STARTUP_TYPE),
  1289. CB_GETCURSEL, 0, 0))) {
  1290. StartType = (DWORD)SendMessage(GetDlgItem(hDlg, IDC_COMBO_STARTUP_TYPE), CB_GETITEMDATA, Index, 0);
  1291. LegacyDriver_OnApply(hDlg, StartType);
  1292. }
  1293. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  1294. return TRUE;
  1295. default:
  1296. return FALSE;
  1297. }
  1298. }
  1299. BOOL
  1300. LegacyDriver_OnContextMenu(
  1301. HWND HwndControl,
  1302. WORD Xpos,
  1303. WORD Ypos
  1304. )
  1305. {
  1306. UNREFERENCED_PARAMETER(Xpos);
  1307. UNREFERENCED_PARAMETER(Ypos);
  1308. WinHelp(HwndControl,
  1309. L"devmgr.hlp",
  1310. HELP_CONTEXTMENU,
  1311. (ULONG_PTR) LegacyDriver_HelpIDs);
  1312. return FALSE;
  1313. }
  1314. void
  1315. LegacyDriver_OnHelp(
  1316. HWND ParentHwnd,
  1317. LPHELPINFO HelpInfo
  1318. )
  1319. {
  1320. UNREFERENCED_PARAMETER(ParentHwnd);
  1321. if (HelpInfo->iContextType == HELPINFO_WINDOW) {
  1322. WinHelp((HWND) HelpInfo->hItemHandle,
  1323. L"devmgr.hlp",
  1324. HELP_WM_HELP,
  1325. (ULONG_PTR) LegacyDriver_HelpIDs);
  1326. }
  1327. }
  1328. INT_PTR
  1329. APIENTRY
  1330. LegacyDriver_DlgProc(
  1331. IN HWND hDlg,
  1332. IN UINT uMessage,
  1333. IN WPARAM wParam,
  1334. IN LPARAM lParam
  1335. )
  1336. {
  1337. HICON hicon;
  1338. switch(uMessage) {
  1339. case WM_COMMAND:
  1340. LegacyDriver_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam));
  1341. break;
  1342. case WM_INITDIALOG:
  1343. return LegacyDriver_OnInitDialog(hDlg, (HWND)wParam, lParam);
  1344. case WM_NOTIFY:
  1345. return LegacyDriver_OnNotify(hDlg, (NMHDR *)lParam);
  1346. case WM_CONTEXTMENU:
  1347. return LegacyDriver_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  1348. case WM_HELP:
  1349. LegacyDriver_OnHelp(hDlg, (LPHELPINFO) lParam);
  1350. break;
  1351. case WM_DESTROY:
  1352. hicon = (HICON)SendDlgItemMessage(hDlg, IDC_PROP_LEGACY_ICON, STM_GETICON, 0, 0);
  1353. if (hicon) {
  1354. DestroyIcon(hicon);
  1355. }
  1356. }
  1357. return FALSE;
  1358. }
  1359. void
  1360. LegacyDriver_DestroyPageInfo(
  1361. PLEGACY_PAGE_INFO lpi
  1362. )
  1363. {
  1364. try {
  1365. //
  1366. // Close the service handle
  1367. //
  1368. if (lpi->hService) {
  1369. CloseServiceHandle(lpi->hService);
  1370. }
  1371. //
  1372. // Close the service manager handle
  1373. //
  1374. if (lpi->hSCManager) {
  1375. CloseServiceHandle(lpi->hSCManager);
  1376. }
  1377. } except (EXCEPTION_EXECUTE_HANDLER) {
  1378. //
  1379. // Access a variable, so that the compiler will respect our statement
  1380. // order w.r.t. assignment.
  1381. //
  1382. lpi = lpi;
  1383. }
  1384. MyFree(lpi);
  1385. }
  1386. UINT CALLBACK
  1387. LegacyDriver_PropPageCallback(
  1388. HWND Hwnd,
  1389. UINT Message,
  1390. LPPROPSHEETPAGE PropSheetPage
  1391. )
  1392. {
  1393. PLEGACY_PAGE_INFO lpi;
  1394. UNREFERENCED_PARAMETER(Hwnd);
  1395. switch (Message) {
  1396. case PSPCB_CREATE:
  1397. return TRUE; // return TRUE to continue with creation of page
  1398. case PSPCB_RELEASE:
  1399. lpi = (PLEGACY_PAGE_INFO) PropSheetPage->lParam;
  1400. LegacyDriver_DestroyPageInfo(lpi);
  1401. return 0; // return value ignored
  1402. default:
  1403. break;
  1404. }
  1405. return TRUE;
  1406. }
  1407. HPROPSHEETPAGE
  1408. LegacyDriver_CreatePropertyPage(
  1409. PROPSHEETPAGE * PropSheetPage,
  1410. PLEGACY_PAGE_INFO lpi
  1411. )
  1412. {
  1413. //
  1414. // Add the Port Settings property page
  1415. //
  1416. PropSheetPage->dwSize = sizeof(PROPSHEETPAGE);
  1417. PropSheetPage->dwFlags = PSP_USECALLBACK;
  1418. PropSheetPage->dwFlags = PSP_DEFAULT;
  1419. PropSheetPage->hInstance = MyModuleHandle;
  1420. PropSheetPage->pszTemplate = MAKEINTRESOURCE(IDD_PROP_LEGACY_SERVICE);
  1421. //
  1422. // following points to the dlg window proc
  1423. //
  1424. PropSheetPage->pfnDlgProc = LegacyDriver_DlgProc;
  1425. PropSheetPage->lParam = (LPARAM)lpi;
  1426. //
  1427. // Following points to the control callback of the dlg window proc.
  1428. // The callback gets called before creation/after destruction of the page
  1429. //
  1430. PropSheetPage->pfnCallback = LegacyDriver_PropPageCallback;
  1431. //
  1432. // Allocate the actual page
  1433. //
  1434. return CreatePropertySheetPage(PropSheetPage);
  1435. }
  1436. BOOL
  1437. LegacyDriverPropPageProvider(
  1438. LPVOID Info,
  1439. LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
  1440. LPARAM lParam
  1441. )
  1442. {
  1443. SP_DEVINSTALL_PARAMS DevInstallParams;
  1444. PSP_PROPSHEETPAGE_REQUEST PropPageRequest;
  1445. PROPSHEETPAGE psp;
  1446. HPROPSHEETPAGE hpsp;
  1447. PLEGACY_PAGE_INFO lpi;
  1448. PropPageRequest = (PSP_PROPSHEETPAGE_REQUEST) Info;
  1449. if (PropPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) {
  1450. lpi = LegacyDriver_CreatePageInfo(PropPageRequest->DeviceInfoSet, PropPageRequest->DeviceInfoData);
  1451. if (!lpi) {
  1452. return FALSE;
  1453. }
  1454. hpsp = LegacyDriver_CreatePropertyPage(&psp, lpi);
  1455. if (!hpsp) {
  1456. return FALSE;
  1457. }
  1458. if (!lpfnAddPropSheetPageProc(hpsp, lParam)) {
  1459. DestroyPropertySheetPage(hpsp);
  1460. return FALSE;
  1461. }
  1462. //
  1463. // Tell device manager that we will display our own Driver tab for legacy device
  1464. //
  1465. ZeroMemory(&DevInstallParams, sizeof(DevInstallParams));
  1466. DevInstallParams.cbSize = sizeof(DevInstallParams);
  1467. SetupDiGetDeviceInstallParams(lpi->DeviceInfoSet, lpi->DeviceInfoData, &DevInstallParams);
  1468. DevInstallParams.Flags |= DI_DRIVERPAGE_ADDED;
  1469. SetupDiSetDeviceInstallParams(lpi->DeviceInfoSet, lpi->DeviceInfoData, &DevInstallParams);
  1470. }
  1471. return TRUE;
  1472. }