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.

1857 lines
50 KiB

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