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.

948 lines
25 KiB

  1. /*++
  2. Copyright (C) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. devdetpg.cpp
  5. Abstract:
  6. This module implements CDeviceDetailsPage -- device details
  7. property page
  8. Author:
  9. Jason Cobb (JasonC) created
  10. Revision History:
  11. --*/
  12. #include "devmgr.h"
  13. #include "devdetpg.h"
  14. #include <wmidata.h>
  15. extern "C" {
  16. #include <initguid.h>
  17. #include <wdmguid.h>
  18. }
  19. //
  20. // help topic ids
  21. //
  22. const DWORD g_a15HelpIDs[]=
  23. {
  24. IDC_DEVDETAILS_DESC, IDH_DISABLEHELP,
  25. IDC_DEVDETAILS_ICON, IDH_DISABLEHELP,
  26. 0,0
  27. };
  28. BOOL
  29. CDeviceDetailsPage::OnInitDialog(
  30. LPPROPSHEETPAGE ppsp
  31. )
  32. {
  33. try {
  34. m_hwndDetailsList = GetDlgItem(m_hDlg, IDC_DEVDETAILS_LIST);
  35. String DetailsType;
  36. for (int i = DETAILS_DEVICEINSTANCEID; i < DETAILS_MAX; i++) {
  37. DetailsType.LoadString(g_hInstance, IDS_DETAILS_DEVICEINSTANCEID + i);
  38. SendDlgItemMessage(m_hDlg, IDC_DEVDETAILS_COMBO, CB_ADDSTRING, 0, (LPARAM)(LPTSTR)DetailsType);
  39. }
  40. SendDlgItemMessage(m_hDlg, IDC_DEVDETAILS_COMBO, CB_SETCURSEL, 0, 0);
  41. LV_COLUMN lvcCol;
  42. lvcCol.mask = LVCF_FMT | LVCF_WIDTH;
  43. lvcCol.fmt = LVCFMT_LEFT;
  44. lvcCol.iSubItem = 0;
  45. ListView_InsertColumn(m_hwndDetailsList, 0, &lvcCol);
  46. ListView_SetExtendedListViewStyle(m_hwndDetailsList, LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
  47. UpdateDetailsText();
  48. }
  49. catch (CMemoryException* e)
  50. {
  51. e->Delete();
  52. // report memory error
  53. MsgBoxParam(m_hDlg, 0, 0, 0);
  54. }
  55. return TRUE;
  56. }
  57. BOOL
  58. CDeviceDetailsPage::OnCommand(
  59. WPARAM wParam,
  60. LPARAM lParam
  61. )
  62. {
  63. switch (LOWORD(wParam)) {
  64. case IDC_DEVDETAILS_COMBO:
  65. if (CBN_SELCHANGE == HIWORD(wParam)) {
  66. UpdateDetailsText();
  67. }
  68. break;
  69. }
  70. return FALSE;
  71. }
  72. BOOL
  73. CDeviceDetailsPage::OnNotify(
  74. LPNMHDR pnmhdr
  75. )
  76. {
  77. if (pnmhdr->idFrom == IDC_DEVDETAILS_LIST) {
  78. if (pnmhdr->code == LVN_KEYDOWN) {
  79. LPNMLVKEYDOWN pnmlvKeyDown = (LPNMLVKEYDOWN)pnmhdr;
  80. if (::GetKeyState(VK_CONTROL)) {
  81. switch (pnmlvKeyDown->wVKey) {
  82. case 'C':
  83. case 'c':
  84. case VK_INSERT:
  85. CopyToClipboard();
  86. break;
  87. case 'A':
  88. case 'a':
  89. ListView_SetSelectionMark(m_hwndDetailsList, 0);
  90. ListView_SetItemState(m_hwndDetailsList, -1, LVIS_SELECTED, LVIS_SELECTED);
  91. break;
  92. }
  93. }
  94. }
  95. }
  96. return FALSE;
  97. }
  98. //
  99. // This function refreshes every control in the dialog. It may be called
  100. // when the dialog is being initialized
  101. //
  102. void
  103. CDeviceDetailsPage::UpdateControls(
  104. LPARAM lParam
  105. )
  106. {
  107. if (lParam) {
  108. m_pDevice = (CDevice*)lParam;
  109. }
  110. try {
  111. HICON hIconOld;
  112. m_IDCicon = IDC_DEVDETAILS_ICON; // Save for cleanup in OnDestroy.
  113. hIconOld = (HICON)SendDlgItemMessage(m_hDlg, IDC_DEVDETAILS_ICON, STM_SETICON,
  114. (WPARAM)(m_pDevice->LoadClassIcon()),
  115. 0
  116. );
  117. if (hIconOld)
  118. {
  119. DestroyIcon(hIconOld);
  120. }
  121. SetDlgItemText(m_hDlg, IDC_DEVDETAILS_DESC, m_pDevice->GetDisplayName());
  122. }
  123. catch (CMemoryException* e)
  124. {
  125. e->Delete();
  126. // report memory error
  127. MsgBoxParam(m_hDlg, 0, 0, 0);
  128. }
  129. }
  130. BOOL
  131. CDeviceDetailsPage::OnHelp(
  132. LPHELPINFO pHelpInfo
  133. )
  134. {
  135. WinHelp((HWND)pHelpInfo->hItemHandle, DEVMGR_HELP_FILE_NAME, HELP_WM_HELP,
  136. (ULONG_PTR)g_a15HelpIDs);
  137. return FALSE;
  138. }
  139. BOOL
  140. CDeviceDetailsPage::OnContextMenu(
  141. HWND hWnd,
  142. WORD xPos,
  143. WORD yPos
  144. )
  145. {
  146. WinHelp(hWnd, DEVMGR_HELP_FILE_NAME, HELP_CONTEXTMENU,
  147. (ULONG_PTR)g_a15HelpIDs);
  148. return FALSE;
  149. }
  150. void
  151. CDeviceDetailsPage::UpdateDetailsText()
  152. {
  153. int CurSel = (int)SendDlgItemMessage(m_hDlg, IDC_DEVDETAILS_COMBO, CB_GETCURSEL, 0, 0);
  154. if (CurSel != CB_ERR) {
  155. ListView_DeleteAllItems(m_hwndDetailsList);
  156. switch(CurSel) {
  157. case DETAILS_DEVICEINSTANCEID:
  158. LVITEM lv;
  159. ZeroMemory(&lv, sizeof(LVITEM));
  160. lv.mask = LVIF_TEXT;
  161. lv.pszText = (LPTSTR)m_pDevice->GetDeviceID();
  162. ListView_InsertItem(m_hwndDetailsList, &lv);
  163. break;
  164. case DETAILS_HARDWAREIDS:
  165. DisplayMultiSzString(SPDRP_HARDWAREID);
  166. break;
  167. case DETAILS_COMPATIDS:
  168. DisplayMultiSzString(SPDRP_COMPATIBLEIDS);
  169. break;
  170. case DETAILS_DEVICEUPPERFILTERS:
  171. DisplayMultiSzString(SPDRP_UPPERFILTERS);
  172. break;
  173. case DETAILS_DEVICELOWERFILTERS:
  174. DisplayMultiSzString(SPDRP_LOWERFILTERS);
  175. break;
  176. case DETAILS_CLASSUPPERFILTERS:
  177. case DETAILS_CLASSLOWERFILTERS:
  178. DisplayClassFilters(CurSel);
  179. break;
  180. case DETAILS_ENUMERATOR:
  181. DisplayString(SPDRP_ENUMERATOR_NAME);
  182. break;
  183. case DETAILS_SERVICE:
  184. DisplayString(SPDRP_SERVICE);
  185. break;
  186. case DETAILS_DEVNODE_FLAGS:
  187. case DETAILS_CAPABILITIES:
  188. case DETAILS_CONFIGFLAGS:
  189. case DETAILS_CSCONFIGFLAGS:
  190. case DETAILS_POWERCAPABILITIES:
  191. DisplayDevnodeFlags(CurSel);
  192. break;
  193. case DETAILS_EJECTIONRELATIONS:
  194. case DETAILS_REMOVALRELATIONS:
  195. case DETAILS_BUSRELATIONS:
  196. DisplayRelations(CurSel);
  197. break;
  198. case DETAILS_MATCHINGID:
  199. DisplayMatchingId();
  200. break;
  201. case DETAILS_CLASSINSTALLER:
  202. DisplayClassInstaller();
  203. break;
  204. case DETAILS_CLASSCOINSTALLERS:
  205. DisplayClassCoInstallers();
  206. break;
  207. case DETAILS_DEVICECOINSTALLERS:
  208. DisplayDeviceCoInstallers();
  209. break;
  210. case DETAILS_FIRMWAREREVISION:
  211. DisplayFirmwareRevision();
  212. break;
  213. case DETAILS_CURRENTPOWERSTATE:
  214. DisplayCurrentPowerState();
  215. break;
  216. case DETAILS_POWERSTATEMAPPINGS:
  217. DisplayPowerStateMappings();
  218. break;
  219. }
  220. ListView_SetColumnWidth(m_hwndDetailsList, 0, LVSCW_AUTOSIZE_USEHEADER);
  221. }
  222. }
  223. void
  224. CDeviceDetailsPage::DisplayMultiSzString(
  225. DWORD Property
  226. )
  227. {
  228. TCHAR TempBuffer[REGSTR_VAL_MAX_HCID_LEN];
  229. ULONG TempBufferLen;
  230. LPTSTR SingleItem = NULL;
  231. LVITEM lv;
  232. TempBufferLen = sizeof(TempBuffer);
  233. if (m_pDevice->m_pMachine->DiGetDeviceRegistryProperty(
  234. *m_pDevice,
  235. Property,
  236. NULL,
  237. (PBYTE)TempBuffer,
  238. TempBufferLen,
  239. &TempBufferLen
  240. ) &&
  241. (TempBufferLen > 2 * sizeof(TCHAR))) {
  242. ZeroMemory(&lv, sizeof(LVITEM));
  243. lv.mask = LVIF_TEXT;
  244. lv.iItem = 0;
  245. for (SingleItem = TempBuffer; *SingleItem; SingleItem += (lstrlen(SingleItem) + 1)) {
  246. lv.pszText = SingleItem;
  247. ListView_InsertItem(m_hwndDetailsList, &lv);
  248. lv.iItem++;
  249. }
  250. }
  251. }
  252. void
  253. CDeviceDetailsPage::DisplayString(
  254. DWORD Property
  255. )
  256. {
  257. TCHAR TempBuffer[MAX_PATH];
  258. ULONG TempBufferLen;
  259. LVITEM lv;
  260. TempBufferLen = sizeof(TempBuffer);
  261. if (m_pDevice->m_pMachine->DiGetDeviceRegistryProperty(
  262. *m_pDevice,
  263. Property,
  264. NULL,
  265. (PBYTE)TempBuffer,
  266. TempBufferLen,
  267. &TempBufferLen
  268. ) &&
  269. (TempBufferLen > 2 * sizeof(TCHAR))) {
  270. ZeroMemory(&lv, sizeof(LVITEM));
  271. lv.mask = LVIF_TEXT;
  272. lv.iItem = 0;
  273. lv.pszText = TempBuffer;
  274. ListView_InsertItem(m_hwndDetailsList, &lv);
  275. }
  276. }
  277. void
  278. CDeviceDetailsPage::DisplayDevnodeFlags(
  279. DWORD StatusType
  280. )
  281. {
  282. DWORD Flags, Problem;
  283. LVITEM lv;
  284. UINT StatusStringId;
  285. int NumFlags;
  286. String stringDevnodeFlags;
  287. ZeroMemory(&lv, sizeof(LVITEM));
  288. lv.mask = LVIF_TEXT;
  289. lv.iItem = 0;
  290. Flags = NumFlags = 0;
  291. switch(StatusType) {
  292. case DETAILS_CAPABILITIES:
  293. m_pDevice->GetCapabilities(&Flags);
  294. StatusStringId = IDS_CM_DEVCAP_LOCKSUPPORTED;
  295. NumFlags = NUM_CM_DEVCAP_FLAGS;
  296. break;
  297. case DETAILS_DEVNODE_FLAGS:
  298. m_pDevice->GetStatus(&Flags, &Problem);
  299. StatusStringId = IDS_DN_ROOT_ENUMERATED;
  300. NumFlags = NUM_DN_STATUS_FLAGS;
  301. break;
  302. case DETAILS_CONFIGFLAGS:
  303. m_pDevice->GetConfigFlags(&Flags);
  304. StatusStringId = IDS_CONFIGFLAG_DISABLED;
  305. NumFlags = NUM_CONFIGFLAGS;
  306. break;
  307. case DETAILS_CSCONFIGFLAGS:
  308. m_pDevice->GetConfigSpecificConfigFlags(&Flags);
  309. StatusStringId = IDS_CSCONFIGFLAG_DISABLED;
  310. NumFlags = NUM_CSCONFIGFLAGS;
  311. break;
  312. case DETAILS_POWERCAPABILITIES:
  313. m_pDevice->GetPowerCapabilities(&Flags);
  314. StatusStringId = IDS_PDCAP_D0_SUPPORTED;
  315. NumFlags = NUM_POWERCAPABILITIES;
  316. break;
  317. }
  318. for (int i = 0; i < NumFlags; i++) {
  319. if (Flags & 1<<i) {
  320. stringDevnodeFlags.LoadString(g_hInstance, StatusStringId + i);
  321. lv.pszText = (LPTSTR)stringDevnodeFlags;
  322. ListView_InsertItem(m_hwndDetailsList, &lv);
  323. lv.iItem++;
  324. }
  325. }
  326. }
  327. void
  328. CDeviceDetailsPage::DisplayRelations(
  329. DWORD RelationType
  330. )
  331. {
  332. DWORD FilterFlags = 0;
  333. ULONG RelationsSize = 0;
  334. LVITEM lv;
  335. LPTSTR DeviceIdRelations, CurrDevId;
  336. switch(RelationType) {
  337. case DETAILS_EJECTIONRELATIONS:
  338. FilterFlags = CM_GETIDLIST_FILTER_EJECTRELATIONS;
  339. break;
  340. case DETAILS_REMOVALRELATIONS:
  341. FilterFlags = CM_GETIDLIST_FILTER_REMOVALRELATIONS;
  342. break;
  343. case DETAILS_BUSRELATIONS:
  344. FilterFlags = CM_GETIDLIST_FILTER_BUSRELATIONS;
  345. break;
  346. }
  347. if ((CM_Get_Device_ID_List_Size_Ex(&RelationsSize,
  348. m_pDevice->GetDeviceID(),
  349. FilterFlags,
  350. m_pDevice->m_pMachine->GetHMachine()
  351. ) == CR_SUCCESS) &&
  352. (RelationsSize > 2 * sizeof(TCHAR))) {
  353. if (DeviceIdRelations = (LPTSTR)LocalAlloc(LPTR, RelationsSize * sizeof(TCHAR))) {
  354. if ((CM_Get_Device_ID_List_Ex(m_pDevice->GetDeviceID(),
  355. DeviceIdRelations,
  356. RelationsSize,
  357. FilterFlags,
  358. m_pDevice->m_pMachine->GetHMachine()
  359. ) == CR_SUCCESS) &&
  360. (*DeviceIdRelations)) {
  361. ZeroMemory(&lv, sizeof(LVITEM));
  362. lv.mask = LVIF_TEXT;
  363. lv.iItem = 0;
  364. for (CurrDevId = DeviceIdRelations; *CurrDevId; CurrDevId += lstrlen(CurrDevId) + 1) {
  365. lv.pszText = CurrDevId;
  366. ListView_InsertItem(m_hwndDetailsList, &lv);
  367. lv.iItem++;
  368. }
  369. }
  370. LocalFree(DeviceIdRelations);
  371. }
  372. }
  373. }
  374. void
  375. CDeviceDetailsPage::DisplayMatchingId(
  376. VOID
  377. )
  378. {
  379. HKEY hKey;
  380. TCHAR TempBuffer[MAX_PATH];
  381. ULONG TempBufferLen;
  382. DWORD regType;
  383. LVITEM lv;
  384. //
  385. // Open drvice's driver registry key to get the MatchingDeviceId string
  386. //
  387. hKey = m_pDevice->m_pMachine->DiOpenDevRegKey(*m_pDevice, DICS_FLAG_GLOBAL,
  388. 0, DIREG_DRV, KEY_READ);
  389. if (INVALID_HANDLE_VALUE != hKey) {
  390. CSafeRegistry regDrv(hKey);
  391. TempBufferLen = sizeof(TempBuffer);
  392. //
  393. // Get the MatchingDeviceId from the driver key
  394. //
  395. if (regDrv.GetValue(REGSTR_VAL_MATCHINGDEVID,
  396. &regType,
  397. (PBYTE)TempBuffer,
  398. &TempBufferLen) &&
  399. (TempBufferLen > 2 * sizeof(TCHAR))) {
  400. ZeroMemory(&lv, sizeof(LVITEM));
  401. lv.mask = LVIF_TEXT;
  402. lv.iItem = 0;
  403. lv.pszText = TempBuffer;
  404. ListView_InsertItem(m_hwndDetailsList, &lv);
  405. }
  406. }
  407. }
  408. void
  409. CDeviceDetailsPage::CopyToClipboard(
  410. void
  411. )
  412. {
  413. String stringClipboardData;
  414. TCHAR singleItem[REGSTR_VAL_MAX_HCID_LEN];
  415. stringClipboardData.Empty();
  416. //
  417. // Enumerate through all of the items and add the selected ones to the clipboard.
  418. //
  419. for (int index = 0;
  420. index != -1, index < ListView_GetItemCount(m_hwndDetailsList);
  421. index ++) {
  422. //
  423. // If this item is selected then add it to the clipboard.
  424. //
  425. if (ListView_GetItemState(m_hwndDetailsList, index, LVIS_SELECTED) & LVIS_SELECTED) {
  426. ListView_GetItemText(m_hwndDetailsList, index, 0, singleItem, sizeof(singleItem));
  427. if (stringClipboardData.IsEmpty()) {
  428. stringClipboardData = (LPCTSTR)singleItem;
  429. } else {
  430. stringClipboardData += (LPCTSTR)singleItem;
  431. }
  432. stringClipboardData += (LPCTSTR)TEXT("\r\n");
  433. }
  434. }
  435. if (!stringClipboardData.IsEmpty()) {
  436. HGLOBAL hMem = GlobalAlloc(GPTR, (stringClipboardData.GetLength() + 1) * sizeof(TCHAR));
  437. if (hMem) {
  438. memcpy(hMem, (LPTSTR)stringClipboardData, (stringClipboardData.GetLength() + 1) * sizeof(TCHAR));
  439. if (OpenClipboard(m_hDlg)) {
  440. EmptyClipboard();
  441. SetClipboardData(CF_UNICODETEXT, hMem);
  442. CloseClipboard();
  443. } else {
  444. GlobalFree(hMem);
  445. }
  446. }
  447. }
  448. }
  449. void
  450. CDeviceDetailsPage::DisplayClassInstaller(
  451. VOID
  452. )
  453. {
  454. HKEY hKey;
  455. TCHAR TempBuffer[MAX_PATH];
  456. ULONG TempBufferLen;
  457. DWORD regType;
  458. LVITEM lv;
  459. PTSTR StringPtr;
  460. GUID ClassGuid;
  461. m_pDevice->ClassGuid(ClassGuid);
  462. //
  463. // Open Classes registry key
  464. //
  465. hKey = m_pDevice->m_pMachine->DiOpenClassRegKey(&ClassGuid, KEY_READ, DIOCR_INSTALLER);
  466. if (INVALID_HANDLE_VALUE != hKey) {
  467. CSafeRegistry regClass(hKey);
  468. TempBufferLen = sizeof(TempBuffer);
  469. //
  470. // Get the Installer32 from the driver key
  471. //
  472. if (regClass.GetValue(REGSTR_VAL_INSTALLER_32,
  473. &regType,
  474. (PBYTE)TempBuffer,
  475. &TempBufferLen) &&
  476. (TempBufferLen > 2 * sizeof(TCHAR))) {
  477. ZeroMemory(&lv, sizeof(LVITEM));
  478. lv.mask = LVIF_TEXT;
  479. lv.iItem = 0;
  480. lv.pszText = TempBuffer;
  481. ListView_InsertItem(m_hwndDetailsList, &lv);
  482. }
  483. }
  484. }
  485. void
  486. CDeviceDetailsPage::DisplayClassCoInstallers(
  487. VOID
  488. )
  489. {
  490. TCHAR GuidString[MAX_GUID_STRING_LEN];
  491. DWORD regType, cbSize;
  492. LVITEM lv;
  493. CSafeRegistry regCoDeviceInstallers;
  494. PTSTR coinstallers;
  495. //
  496. // Get the string form of the class GUID, because that will be the name of
  497. // the multi-sz value entry under HKLM\System\CCS\Control\CoDeviceInstallers
  498. // where class-specific co-installers will be registered
  499. //
  500. GUID ClassGuid;
  501. m_pDevice->ClassGuid(ClassGuid);
  502. if (GuidToString(&ClassGuid, GuidString, ARRAYLEN(GuidString))) {
  503. if (regCoDeviceInstallers.Open(HKEY_LOCAL_MACHINE, REGSTR_PATH_CODEVICEINSTALLERS)) {
  504. //
  505. // Get the size of the coinstaller value
  506. //
  507. cbSize = 0;
  508. if (regCoDeviceInstallers.GetValue(GuidString, &regType, NULL, &cbSize) &&
  509. (cbSize > (2 * sizeof(TCHAR))) &&
  510. (regType == REG_MULTI_SZ)) {
  511. //
  512. // Allocate memory to hold the coinstaller values. First we will tack on some extra
  513. // space at the end of the buffer in case someone forgot to double NULL terminate
  514. // the multi_sz string.
  515. //
  516. coinstallers = (LPTSTR)LocalAlloc(LPTR, (cbSize + (2 * sizeof(TCHAR))));
  517. if (coinstallers) {
  518. if (regCoDeviceInstallers.GetValue(GuidString,
  519. &regType,
  520. (PBYTE)coinstallers,
  521. &cbSize
  522. )) {
  523. ZeroMemory(&lv, sizeof(LVITEM));
  524. lv.mask = LVIF_TEXT;
  525. lv.iItem = 0;
  526. for (PTSTR p = coinstallers; *p; p += (lstrlen(p) + 1)) {
  527. lv.pszText = p;
  528. ListView_InsertItem(m_hwndDetailsList, &lv);
  529. lv.iItem++;
  530. }
  531. }
  532. LocalFree(coinstallers);
  533. }
  534. }
  535. }
  536. }
  537. }
  538. void
  539. CDeviceDetailsPage::DisplayDeviceCoInstallers(
  540. VOID
  541. )
  542. {
  543. DWORD regType, cbSize;
  544. LVITEM lv;
  545. HKEY hKey;
  546. PTSTR coinstallers;
  547. //
  548. // Open drvice's driver registry key to get the Installer32 string
  549. //
  550. hKey = m_pDevice->m_pMachine->DiOpenDevRegKey(*m_pDevice, DICS_FLAG_GLOBAL,
  551. 0, DIREG_DRV, KEY_READ);
  552. if (INVALID_HANDLE_VALUE != hKey) {
  553. CSafeRegistry regCoDeviceInstallers(hKey);
  554. //
  555. // Get the size of the coinstaller value
  556. //
  557. cbSize = 0;
  558. if (regCoDeviceInstallers.GetValue(REGSTR_VAL_COINSTALLERS_32, &regType, NULL, &cbSize) &&
  559. (cbSize > (2 * sizeof(TCHAR))) &&
  560. (regType == REG_MULTI_SZ)) {
  561. //
  562. // Allocate memory to hold the coinstaller values. First we will tack on some extra
  563. // space at the end of the buffer in case someone forgot to double NULL terminate
  564. // the multi_sz string.
  565. //
  566. coinstallers = (LPTSTR)LocalAlloc(LPTR, (cbSize + (2 * sizeof(TCHAR))));
  567. if (coinstallers) {
  568. if (regCoDeviceInstallers.GetValue(REGSTR_VAL_COINSTALLERS_32,
  569. &regType,
  570. (PBYTE)coinstallers,
  571. &cbSize
  572. )) {
  573. ZeroMemory(&lv, sizeof(LVITEM));
  574. lv.mask = LVIF_TEXT;
  575. lv.iItem = 0;
  576. for (PTSTR p = coinstallers; *p; p += (lstrlen(p) + 1)) {
  577. lv.pszText = p;
  578. ListView_InsertItem(m_hwndDetailsList, &lv);
  579. lv.iItem++;
  580. }
  581. }
  582. LocalFree(coinstallers);
  583. }
  584. }
  585. }
  586. }
  587. void
  588. CDeviceDetailsPage::DisplayFirmwareRevision(
  589. VOID
  590. )
  591. {
  592. WMIHANDLE hWmiBlock;
  593. TCHAR DevInstId[MAX_DEVICE_ID_LEN + 2];
  594. LVITEM lv;
  595. WmiDevInstToInstanceName(DevInstId, ARRAYLEN(DevInstId), (PTCHAR)m_pDevice->GetDeviceID(), 0);
  596. ULONG Error;
  597. GUID Guid = DEVICE_UI_FIRMWARE_REVISION_GUID;
  598. Error = WmiOpenBlock(&Guid, 0, &hWmiBlock);
  599. if (ERROR_SUCCESS == Error) {
  600. ULONG BufferSize = 0;
  601. Error = WmiQuerySingleInstance(hWmiBlock,
  602. DevInstId,
  603. &BufferSize,
  604. NULL
  605. );
  606. if (BufferSize && (ERROR_INSUFFICIENT_BUFFER == Error)) {
  607. BYTE* pWmiInstData = new BYTE[BufferSize];
  608. if (pWmiInstData) {
  609. Error = WmiQuerySingleInstance(hWmiBlock,
  610. DevInstId,
  611. &BufferSize,
  612. pWmiInstData
  613. );
  614. if (ERROR_SUCCESS == Error &&
  615. ((PWNODE_SINGLE_INSTANCE)pWmiInstData)->SizeDataBlock) {
  616. //
  617. // The buffer that is returned using the fine UNICODE_STRING format
  618. // where the first ULONG is the length of the string and the string
  619. // is NOT NULL terminated.
  620. //
  621. TCHAR FirmwareRevision[MAX_PATH];
  622. PTCHAR WmiBuffer = ((LPTSTR)(pWmiInstData + ((PWNODE_SINGLE_INSTANCE)pWmiInstData)->DataBlockOffset));
  623. ZeroMemory(FirmwareRevision, MAX_PATH);
  624. ULONG Len = *WmiBuffer++;
  625. memcpy(FirmwareRevision, WmiBuffer, Len);
  626. ZeroMemory(&lv, sizeof(LVITEM));
  627. lv.mask = LVIF_TEXT;
  628. lv.iItem = 0;
  629. lv.pszText = FirmwareRevision;
  630. ListView_InsertItem(m_hwndDetailsList, &lv);
  631. }
  632. delete [] pWmiInstData;
  633. }
  634. }
  635. WmiCloseBlock(hWmiBlock);
  636. }
  637. }
  638. void
  639. CDeviceDetailsPage::DisplayCurrentPowerState(
  640. VOID
  641. )
  642. {
  643. CM_POWER_DATA CmPowerData;
  644. ULONG ulSize;
  645. INT PowerStringId;
  646. LVITEM lv;
  647. String stringCurrentPowerState;
  648. ulSize = sizeof(CmPowerData);
  649. if (m_pDevice->m_pMachine->CmGetRegistryProperty(m_pDevice->GetDevNode(),
  650. CM_DRP_DEVICE_POWER_DATA,
  651. &CmPowerData,
  652. &ulSize
  653. ) == CR_SUCCESS) {
  654. PowerStringId = IDS_POWERSTATE_UNSPECIFIED + CmPowerData.PD_MostRecentPowerState;
  655. if (CmPowerData.PD_MostRecentPowerState > PowerDeviceD3) {
  656. PowerStringId = IDS_POWERSTATE_UNSPECIFIED;
  657. }
  658. stringCurrentPowerState.LoadString(g_hInstance, PowerStringId);
  659. ZeroMemory(&lv, sizeof(LVITEM));
  660. lv.mask = LVIF_TEXT;
  661. lv.iItem = 0;
  662. lv.pszText = (LPTSTR)stringCurrentPowerState;
  663. ListView_InsertItem(m_hwndDetailsList, &lv);
  664. }
  665. }
  666. void
  667. CDeviceDetailsPage::DisplayPowerStateMappings(
  668. VOID
  669. )
  670. {
  671. CM_POWER_DATA CmPowerData;
  672. ULONG ulSize;
  673. LVITEM lv;
  674. INT PowerStringId;
  675. String stringPowerStateMapping;
  676. String stringPowerState;
  677. ulSize = sizeof(CmPowerData);
  678. if (m_pDevice->m_pMachine->CmGetRegistryProperty(m_pDevice->GetDevNode(),
  679. CM_DRP_DEVICE_POWER_DATA,
  680. &CmPowerData,
  681. &ulSize
  682. ) == CR_SUCCESS) {
  683. for (int i=PowerSystemWorking; i<=PowerSystemShutdown; i++) {
  684. stringPowerStateMapping.Format(TEXT("S%d -> "), (i-1));
  685. PowerStringId = IDS_POWERSTATE_UNSPECIFIED + CmPowerData.PD_PowerStateMapping[i];
  686. if (CmPowerData.PD_PowerStateMapping[i] > PowerDeviceD3) {
  687. PowerStringId = IDS_POWERSTATE_UNSPECIFIED;
  688. }
  689. stringPowerState.LoadString(g_hInstance, PowerStringId);
  690. stringPowerStateMapping+=stringPowerState;
  691. ZeroMemory(&lv, sizeof(LVITEM));
  692. lv.mask = LVIF_TEXT;
  693. lv.iItem = ListView_GetItemCount(m_hwndDetailsList);
  694. lv.pszText = (LPTSTR)stringPowerStateMapping;
  695. ListView_InsertItem(m_hwndDetailsList, &lv);
  696. }
  697. }
  698. }
  699. void
  700. CDeviceDetailsPage::DisplayClassFilters(
  701. DWORD ClassFilter
  702. )
  703. {
  704. HKEY hKey;
  705. ULONG BufferLen;
  706. DWORD regType;
  707. LVITEM lv;
  708. GUID ClassGuid;
  709. m_pDevice->ClassGuid(ClassGuid);
  710. //
  711. // Open Classes registry key
  712. //
  713. hKey = m_pDevice->m_pMachine->DiOpenClassRegKey(&ClassGuid, KEY_READ, DIOCR_INSTALLER);
  714. if (INVALID_HANDLE_VALUE != hKey) {
  715. CSafeRegistry regClass(hKey);
  716. //
  717. // Determine how much space we need.
  718. //
  719. BufferLen = 0;
  720. regClass.GetValue((ClassFilter == DETAILS_CLASSLOWERFILTERS)
  721. ? REGSTR_VAL_LOWERFILTERS
  722. : REGSTR_VAL_UPPERFILTERS,
  723. &regType,
  724. NULL,
  725. &BufferLen);
  726. if (BufferLen != 0) {
  727. PBYTE Buffer = new BYTE[BufferLen + (2 * sizeof(TCHAR))];
  728. if (Buffer) {
  729. ZeroMemory(Buffer, BufferLen + (2 * sizeof(TCHAR)));
  730. if (regClass.GetValue((ClassFilter == DETAILS_CLASSLOWERFILTERS)
  731. ? REGSTR_VAL_LOWERFILTERS
  732. : REGSTR_VAL_UPPERFILTERS,
  733. &regType,
  734. (PBYTE)Buffer,
  735. &BufferLen)) {
  736. ZeroMemory(&lv, sizeof(LVITEM));
  737. lv.mask = LVIF_TEXT;
  738. lv.iItem = 0;
  739. for (PTSTR SingleItem = (PTSTR)Buffer; *SingleItem; SingleItem += (lstrlen(SingleItem) + 1)) {
  740. lv.pszText = SingleItem;
  741. ListView_InsertItem(m_hwndDetailsList, &lv);
  742. lv.iItem++;
  743. }
  744. }
  745. delete Buffer;
  746. }
  747. }
  748. }
  749. }