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.

1302 lines
32 KiB

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright 2000 Microsoft Corporation. All Rights Reserved.
  7. //
  8. // PROGRAM: testwmi.cpp
  9. //
  10. // AUTHOR: Alok Sinha August 15, 2000
  11. //
  12. // PURPOSE: To test getting/setting custom classs of E100BEX driver.
  13. //
  14. // ENVIRONMENT: Windows 2000 user mode application.
  15. //
  16. #include "testwmi.h"
  17. //
  18. // List of custom classes as defined in E100BEX sample.
  19. //
  20. // If you want to use this application to excersize querying/setting guids
  21. // exported by your driver then, simply add the class name of the guid
  22. // to the following array and recompile the program.
  23. //
  24. LPTSTR lpszClasses[] = {
  25. TEXT("E100BExampleSetUINT_OID"),
  26. TEXT("E100BExampleQueryUINT_OID"),
  27. TEXT("E100BExampleQueryArrayOID"),
  28. TEXT("E100BExampleQueryStringOID")
  29. };
  30. //
  31. // Handle to this instance of the application.
  32. //
  33. HINSTANCE hInstance;
  34. //
  35. // Program entry point.
  36. //
  37. int APIENTRY WinMain (HINSTANCE hInst,
  38. HINSTANCE hPrevInstance,
  39. LPSTR lpCmdLine,
  40. int nCmdShow)
  41. {
  42. HRESULT hr;
  43. hInstance = hInst;
  44. //
  45. // Make sure common control DLL is loaded.
  46. //
  47. InitCommonControls();
  48. //
  49. // Initialize COM library. Must be done before invoking any
  50. // other COM function.
  51. //
  52. hr = CoInitializeEx( NULL,
  53. COINIT_MULTITHREADED );
  54. if ( hr != S_OK ) {
  55. PrintError( hr,
  56. __LINE__,
  57. TEXT(__FILE__),
  58. TEXT("Failed to initialize COM library, program exiting...") );
  59. }
  60. else {
  61. hr = CoInitializeSecurity( NULL,
  62. -1,
  63. NULL,
  64. NULL,
  65. RPC_C_AUTHN_LEVEL_CONNECT,
  66. RPC_C_IMP_LEVEL_IDENTIFY,
  67. NULL,
  68. EOAC_NONE,
  69. 0 );
  70. if ( hr == S_OK ) {
  71. if ( DialogBox(hInstance,
  72. MAKEINTRESOURCE(IDD_MAIN),
  73. NULL,
  74. MainDlgProc) == -1 ) {
  75. PrintError( HRESULT_FROM_WIN32(GetLastError()),
  76. __LINE__,
  77. TEXT(__FILE__),
  78. TEXT("Failed to create the dialog box, ")
  79. TEXT("program exiting...") );
  80. }
  81. }
  82. else {
  83. PrintError( hr,
  84. __LINE__,
  85. TEXT(__FILE__),
  86. TEXT("CoInitializeSecurity failed, program exiting...") );
  87. }
  88. CoUninitialize();
  89. }
  90. return 0;
  91. }
  92. //
  93. // Windows procedure for the main dialog box.
  94. //
  95. INT_PTR CALLBACK MainDlgProc (HWND hwndDlg,
  96. UINT uMsg,
  97. WPARAM wParam,
  98. LPARAM lParam)
  99. {
  100. IWbemServices *pIWbemServices;
  101. LPNMTREEVIEW lpnmTreeView;
  102. switch (uMsg) {
  103. case WM_INITDIALOG:
  104. //
  105. // Connect to the default namespace.
  106. //
  107. pIWbemServices = ConnectToNamespace();
  108. if ( !pIWbemServices ) {
  109. EndDialog( hwndDlg, 0 );
  110. }
  111. //
  112. // At DWLP_USER offset, we store pIWbemServices so we can
  113. // get to it later.
  114. //
  115. SetWindowLongPtr(
  116. hwndDlg,
  117. DWLP_USER,
  118. (LONG_PTR)pIWbemServices );
  119. //
  120. // Enumerate default classes and its instances. Also,
  121. // show properties of the first instance.
  122. //
  123. ListDefaults( hwndDlg );
  124. return TRUE; // Tell Windows to continue creating the dialog box.
  125. case WM_COMMAND:
  126. switch( LOWORD(wParam) ) {
  127. case IDL_CLASSES:
  128. if ( HIWORD(wParam) == LBN_SELCHANGE ) {
  129. //
  130. // User selected a class. Show its instances and
  131. // the properties of the first instance.
  132. //
  133. RefreshOnClassSelection( hwndDlg );
  134. }
  135. break;
  136. }
  137. break;
  138. case WM_NOTIFY:
  139. switch( wParam ) {
  140. case IDT_INSTANCES:
  141. lpnmTreeView = (LPNMTREEVIEW)lParam;
  142. if ( (lpnmTreeView->hdr.code == TVN_SELCHANGED) &&
  143. (lpnmTreeView->action != TVC_UNKNOWN) ) {
  144. //
  145. // User has clicked on an instance, list its properties.
  146. //
  147. ShowProperties( hwndDlg,
  148. lpnmTreeView->hdr.hwndFrom );
  149. }
  150. break;
  151. case IDT_PROPERTIES:
  152. lpnmTreeView = (LPNMTREEVIEW)lParam;
  153. if ( lpnmTreeView->hdr.code == NM_DBLCLK ) {
  154. //
  155. // User has double-clicked on a property.
  156. //
  157. EditProperty( hwndDlg,
  158. lpnmTreeView->hdr.hwndFrom );
  159. }
  160. break;
  161. }
  162. break;
  163. case WM_SYSCOMMAND:
  164. //
  165. // Before exiting...
  166. // .Make sure to disconnect from the namespace.
  167. //
  168. if ( (0xFFF0 & wParam) == SC_CLOSE ) {
  169. pIWbemServices = (IWbemServices *)GetWindowLongPtr(
  170. hwndDlg,
  171. DWLP_USER );
  172. pIWbemServices->Release();
  173. EndDialog( hwndDlg, 0 );
  174. }
  175. }
  176. return FALSE;
  177. }
  178. //
  179. // Windows procedure to view/modify scalar properties.
  180. //
  181. INT_PTR CALLBACK DlgProcScalar (HWND hwndDlg,
  182. UINT uMsg,
  183. WPARAM wParam,
  184. LPARAM lParam)
  185. {
  186. LPPROPERTY_INFO pPropInfo;
  187. VARIANT vaTemp;
  188. LPTSTR lpszValue;
  189. HRESULT hr;
  190. switch (uMsg) {
  191. case WM_INITDIALOG:
  192. //
  193. // lParam points to PROPERTY_INFO structure which contains information
  194. // the property whose valuse is to be viewed/modified. We store this
  195. // pointer at DWLP_USER offset, so we get to it later.
  196. //
  197. SetWindowLongPtr( hwndDlg,
  198. DWLP_USER,
  199. (LONG_PTR)lParam );
  200. pPropInfo = (LPPROPERTY_INFO)lParam;
  201. //
  202. // Property name is the title of the dialog box.
  203. //
  204. SetWindowText( hwndDlg,
  205. pPropInfo->lpszProperty );
  206. //
  207. // Show the property type.
  208. //
  209. if ( pPropInfo->lpszType ) {
  210. SetWindowText( GetDlgItem(hwndDlg,
  211. IDS_PROPERTY_TYPE),
  212. pPropInfo->lpszType );
  213. }
  214. //
  215. // Change the property value to a string so it can be displayed
  216. // if the property has a value.
  217. //
  218. if ( (V_VT(pPropInfo->pvaValue) != VT_NULL) &&
  219. (V_VT(pPropInfo->pvaValue) != VT_EMPTY) ) {
  220. VariantInit( &vaTemp );
  221. hr = VariantChangeType( &vaTemp,
  222. pPropInfo->pvaValue,
  223. VARIANT_LOCALBOOL,
  224. VT_BSTR );
  225. if ( hr != S_OK ) {
  226. PrintError( hr,
  227. __LINE__,
  228. TEXT(__FILE__),
  229. TEXT("Couldn't format the value of %s into ")
  230. TEXT("displayable text. The value cannot be ")
  231. TEXT(" viewed/modified."),
  232. pPropInfo->lpszProperty );
  233. EndDialog( hwndDlg, 0 );
  234. }
  235. lpszValue = BstrToString( V_BSTR(&vaTemp),
  236. -1 );
  237. if ( lpszValue ) {
  238. SetWindowText( GetDlgItem(hwndDlg,
  239. IDE_PROPERTY_VALUE),
  240. lpszValue );
  241. SysFreeString( (BSTR)lpszValue );
  242. }
  243. else {
  244. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  245. __LINE__,
  246. TEXT(__FILE__),
  247. TEXT("Cannot show the value of %s."),
  248. pPropInfo->lpszProperty );
  249. EndDialog( hwndDlg, 0 );
  250. }
  251. VariantClear( &vaTemp );
  252. }
  253. return TRUE; // Tell Windows to continue creating the dialog box.
  254. case WM_COMMAND:
  255. switch( LOWORD(wParam) ) {
  256. case IDB_MODIFY:
  257. if ( HIWORD(wParam) == BN_CLICKED ) {
  258. //
  259. // User wants to update the instance after modifying the
  260. // property value.
  261. //
  262. if ( ModifyProperty(hwndDlg) ) {
  263. EndDialog( hwndDlg, 0 );
  264. }
  265. }
  266. break;
  267. case IDB_CANCEL:
  268. if ( HIWORD(wParam) == BN_CLICKED ) {
  269. EndDialog( hwndDlg, 0 );
  270. }
  271. break;
  272. }
  273. break;
  274. case WM_SYSCOMMAND:
  275. if ( (0xFFF0 & wParam) == SC_CLOSE ) {
  276. EndDialog( hwndDlg, 0 );
  277. }
  278. }
  279. return FALSE;
  280. }
  281. //
  282. // Windows procedure to view/modify array properties.
  283. //
  284. INT_PTR CALLBACK DlgProcArray (HWND hwndDlg,
  285. UINT uMsg,
  286. WPARAM wParam,
  287. LPARAM lParam)
  288. {
  289. LPPROPERTY_INFO pPropInfo;
  290. switch (uMsg) {
  291. case WM_INITDIALOG:
  292. //
  293. // lParam points to PROPERTY_INFO structure which contains information
  294. // the property whose valuse is to be viewed/modified. We store this
  295. // pointer at DWLP_USER offset, so we get to it later.
  296. //
  297. SetWindowLongPtr( hwndDlg,
  298. DWLP_USER,
  299. (LONG_PTR)lParam );
  300. pPropInfo = (LPPROPERTY_INFO)lParam;
  301. //
  302. // Property name is the title of the dialog box.
  303. //
  304. SetWindowText( hwndDlg,
  305. pPropInfo->lpszProperty );
  306. //
  307. // Show the property type.
  308. //
  309. SetWindowText( GetDlgItem(hwndDlg,
  310. IDS_PROPERTY_TYPE),
  311. pPropInfo->lpszType );
  312. if ( DisplayArrayProperty(pPropInfo->lpszProperty,
  313. pPropInfo->pvaValue,
  314. hwndDlg) ) {
  315. return TRUE;
  316. }
  317. EndDialog( hwndDlg, 0 );
  318. case WM_COMMAND:
  319. switch( LOWORD(wParam) ) {
  320. case IDB_MODIFY:
  321. if ( HIWORD(wParam) == BN_CLICKED ) {
  322. //
  323. // User wants to update the instance after modifying the
  324. // property value.
  325. //
  326. pPropInfo = (LPPROPERTY_INFO)GetWindowLongPtr( hwndDlg,
  327. DWLP_USER );
  328. ModifyArrayProperty( hwndDlg,
  329. pPropInfo );
  330. EndDialog( hwndDlg, 0 );
  331. }
  332. break;
  333. case IDB_CANCEL:
  334. if ( HIWORD(wParam) == BN_CLICKED ) {
  335. EndDialog( hwndDlg, 0 );
  336. }
  337. break;
  338. }
  339. break;
  340. case WM_SYSCOMMAND:
  341. if ( (0xFFF0 & wParam) == SC_CLOSE ) {
  342. EndDialog( hwndDlg, 0 );
  343. }
  344. }
  345. return FALSE;
  346. }
  347. //
  348. // The function populates the combo box of the main window with the classes
  349. // defined in the lpszClasses array, selects the first class of the combo box,
  350. // shows its instances, and properties of the first instance.
  351. //
  352. VOID ListDefaults (HWND hwndDlg)
  353. {
  354. HWND hwndClassList;
  355. UINT i;
  356. hwndClassList = GetDlgItem( hwndDlg,
  357. IDL_CLASSES );
  358. //
  359. // Add the default classes to the combo box.
  360. //
  361. for (i=0; i < sizeof(lpszClasses)/sizeof(LPTSTR); ++i) {
  362. SendMessage( hwndClassList,
  363. CB_ADDSTRING,
  364. 0,
  365. (LPARAM)lpszClasses[i] );
  366. }
  367. //
  368. // By default, select the first one in the list which maybe different from
  369. // the first element in the lpszClasses array since the list is sorted.
  370. //
  371. SendMessage( hwndClassList,
  372. CB_SETCURSEL,
  373. 0,
  374. 0 );
  375. //
  376. // Show the instances and properties of the first instance.
  377. //
  378. RefreshOnClassSelection( hwndDlg );
  379. return;
  380. }
  381. //
  382. // The function lists all the properties of the class instance selected by the
  383. // user.
  384. //
  385. VOID ShowProperties (HWND hwndDlg,
  386. HWND hwndInstTree)
  387. {
  388. IWbemServices *pIWbemServices;
  389. LPTSTR lpszInstance;
  390. LPTSTR lpszClass;
  391. lpszClass = GetSelectedClass( GetDlgItem(hwndDlg,
  392. IDL_CLASSES) );
  393. lpszInstance = GetSelectedItem( hwndInstTree );
  394. if ( lpszInstance && lpszClass ) {
  395. pIWbemServices = (IWbemServices *)GetWindowLongPtr(
  396. hwndDlg,
  397. DWLP_USER );
  398. //
  399. // Show properties of the selected instance.
  400. //
  401. TreeView_DeleteAllItems( GetDlgItem(hwndDlg,
  402. IDT_PROPERTIES) );
  403. EnumProperties( pIWbemServices,
  404. lpszClass,
  405. lpszInstance,
  406. GetDlgItem(hwndDlg,
  407. IDT_PROPERTIES) );
  408. }
  409. else {
  410. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  411. __LINE__,
  412. TEXT(__FILE__),
  413. TEXT("Properties of the selected ")
  414. TEXT("instance will not be listed.") );
  415. }
  416. if ( lpszClass ) {
  417. SysFreeString( (BSTR)lpszClass );
  418. }
  419. if ( lpszInstance ) {
  420. SysFreeString( (BSTR)lpszInstance );
  421. }
  422. return;
  423. }
  424. //
  425. // The function shows a dialog box displaying the value of the selected property
  426. // and allows the user to modify it.
  427. //
  428. VOID EditProperty (HWND hwndDlg,
  429. HWND hwndPropTree)
  430. {
  431. PROPERTY_INFO propertyInfo;
  432. LPTSTR lpszInstance;
  433. LPTSTR lpszClass;
  434. VARIANT vaValue;
  435. //
  436. // Get the selected class name.
  437. //
  438. lpszClass = GetSelectedClass( GetDlgItem(hwndDlg,
  439. IDL_CLASSES) );
  440. //
  441. // Get the selected instance name which is __RELPATH value.
  442. //
  443. lpszInstance = GetSelectedItem( GetDlgItem(hwndDlg,
  444. IDT_INSTANCES) );
  445. //
  446. // Get the selected property name.
  447. //
  448. propertyInfo.lpszProperty = GetSelectedItem( hwndPropTree );
  449. if ( lpszInstance && lpszClass && propertyInfo.lpszProperty ) {
  450. propertyInfo.pIWbemServices = (IWbemServices *)GetWindowLongPtr(
  451. hwndDlg,
  452. DWLP_USER );
  453. propertyInfo.pInstance = GetInstanceReference( propertyInfo.pIWbemServices,
  454. lpszClass,
  455. lpszInstance );
  456. if ( propertyInfo.pInstance ) {
  457. if ( GetPropertyValue( propertyInfo.pInstance,
  458. propertyInfo.lpszProperty,
  459. &vaValue,
  460. &propertyInfo.lpszType) ) {
  461. propertyInfo.pvaValue = &vaValue;
  462. if ( V_ISARRAY(&vaValue) ) {
  463. DialogBoxParam( hInstance,
  464. MAKEINTRESOURCE(IDD_ARRAY_PROPERTY),
  465. hwndDlg,
  466. DlgProcArray,
  467. (LPARAM)&propertyInfo );
  468. }
  469. else {
  470. DialogBoxParam( hInstance,
  471. MAKEINTRESOURCE(IDD_SCALAR_PROPERTY),
  472. hwndDlg,
  473. DlgProcScalar,
  474. (LPARAM)&propertyInfo );
  475. }
  476. VariantClear( &vaValue );
  477. SysFreeString( (BSTR)propertyInfo.lpszType );
  478. }
  479. else {
  480. PrintError( HRESULT_FROM_WIN32(ERROR_WMI_TRY_AGAIN),
  481. __LINE__,
  482. TEXT(__FILE__),
  483. TEXT("Couldn't read %s."),
  484. propertyInfo.lpszProperty );
  485. }
  486. propertyInfo.pInstance->Release();
  487. }
  488. else {
  489. PrintError( HRESULT_FROM_WIN32(ERROR_WMI_INSTANCE_NOT_FOUND),
  490. __LINE__,
  491. TEXT(__FILE__),
  492. TEXT("Couldn't get a pointer to %s."),
  493. lpszInstance );
  494. }
  495. }
  496. else {
  497. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  498. __LINE__,
  499. TEXT(__FILE__),
  500. TEXT("Properties of the selected ")
  501. TEXT("instance will not be listed.") );
  502. }
  503. if ( lpszClass ) {
  504. SysFreeString( (BSTR)lpszClass );
  505. }
  506. if ( lpszInstance ) {
  507. SysFreeString( (BSTR)lpszInstance );
  508. }
  509. if ( propertyInfo.lpszProperty ) {
  510. SysFreeString( (BSTR)propertyInfo.lpszProperty );
  511. }
  512. return;
  513. }
  514. //
  515. // The function updates the property that is modified a the user.
  516. //
  517. BOOL ModifyProperty (HWND hwndDlg)
  518. {
  519. LPPROPERTY_INFO pPropInfo;
  520. HWND hwndValue;
  521. VARIANT vaTemp;
  522. VARIANT vaNewValue;
  523. LPTSTR lpszValue;
  524. ULONG ulLen;
  525. HRESULT hr;
  526. hr = S_FALSE;
  527. pPropInfo = (LPPROPERTY_INFO)GetWindowLongPtr( hwndDlg,
  528. DWLP_USER );
  529. //
  530. // Allocate memory and get new value of the property.
  531. //
  532. hwndValue = GetDlgItem( hwndDlg,
  533. IDE_PROPERTY_VALUE );
  534. ulLen = (ULONG)SendMessage( hwndValue,
  535. WM_GETTEXTLENGTH,
  536. 0,
  537. 0 );
  538. if ( ulLen > 0 ) {
  539. lpszValue = (LPTSTR)SysAllocStringLen( NULL,
  540. ulLen+1 );
  541. if ( lpszValue ) {
  542. SendMessage( hwndValue,
  543. WM_GETTEXT,
  544. ulLen+1,
  545. (LPARAM)lpszValue );
  546. VariantInit( &vaTemp );
  547. //
  548. // Change the new value from string to its original type.
  549. //
  550. V_VT(&vaTemp) = VT_BSTR;
  551. V_BSTR(&vaTemp) = StringToBstr( lpszValue,
  552. -1 );
  553. if ( V_BSTR(&vaTemp) == NULL ) {
  554. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  555. __LINE__,
  556. TEXT(__FILE__),
  557. TEXT("Couldn't modify the value of %s."),
  558. pPropInfo->lpszProperty );
  559. }
  560. else {
  561. VariantInit( &vaNewValue );
  562. hr = VariantChangeType( &vaNewValue,
  563. &vaTemp,
  564. VARIANT_LOCALBOOL,
  565. V_VT(pPropInfo->pvaValue) );
  566. if ( hr == S_OK ) {
  567. //
  568. // Update the property and its instance.
  569. //
  570. hr = UpdatePropertyValue( pPropInfo->pIWbemServices,
  571. pPropInfo->pInstance,
  572. pPropInfo->lpszProperty,
  573. &vaNewValue );
  574. if ( hr == WBEM_S_NO_ERROR ) {
  575. PrintError( 0,
  576. __LINE__,
  577. TEXT(__FILE__),
  578. TEXT("%s is successfully updated with value %s."),
  579. pPropInfo->lpszProperty,
  580. lpszValue );
  581. }
  582. VariantClear( &vaNewValue );
  583. }
  584. else {
  585. PrintError( hr,
  586. __LINE__,
  587. TEXT(__FILE__),
  588. TEXT("Couldn't convert the specified value '%s' of ")
  589. TEXT("property %s into %s type."),
  590. lpszValue,
  591. pPropInfo->lpszProperty,
  592. pPropInfo->lpszType );
  593. }
  594. SysFreeString( V_BSTR(&vaTemp) );
  595. }
  596. SysFreeString( (BSTR)lpszValue );
  597. }
  598. else {
  599. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  600. __LINE__,
  601. TEXT(__FILE__),
  602. TEXT("Couldn't modify the value of %s."),
  603. pPropInfo->lpszProperty );
  604. }
  605. }
  606. else {
  607. PrintError( HRESULT_FROM_WIN32(ERROR_WMI_TRY_AGAIN),
  608. __LINE__,
  609. TEXT(__FILE__),
  610. TEXT("You must specify a value to modify %s."),
  611. pPropInfo->lpszProperty );
  612. }
  613. return hr == WBEM_S_NO_ERROR;
  614. }
  615. //
  616. // The function populates a tree list with the values of a property of array
  617. // type. The property could be an array of string or integer.
  618. //
  619. BOOL DisplayArrayProperty (LPTSTR lpszProperty,
  620. VARIANT *pvaValue,
  621. HWND hwndDlg)
  622. {
  623. SAFEARRAY *psaValue;
  624. VARIANT vaTemp;
  625. VARIANT vaElement;
  626. VARTYPE vt;
  627. long lLBound;
  628. long lUBound;
  629. long i;
  630. UINT uiSize;
  631. BSTR lpsz;
  632. LPVOID pv;
  633. HRESULT hr;
  634. //
  635. // Make a copy of the property value.
  636. //
  637. psaValue = NULL;
  638. hr = SafeArrayCopy( V_ARRAY(pvaValue),
  639. &psaValue );
  640. if ( hr == S_OK ) {
  641. hr = SafeArrayGetVartype( psaValue,
  642. &vt );
  643. }
  644. if ( hr == S_OK ) {
  645. hr = SafeArrayGetLBound( psaValue,
  646. 1,
  647. &lLBound );
  648. }
  649. if ( hr == S_OK ) {
  650. hr = SafeArrayGetUBound( psaValue,
  651. 1,
  652. &lUBound );
  653. }
  654. if ( hr == S_OK ) {
  655. uiSize = SafeArrayGetElemsize( psaValue );
  656. }
  657. if ( hr == S_OK ) {
  658. hr = SafeArrayAccessData( psaValue,
  659. &pv );
  660. }
  661. if ( hr == S_OK ) {
  662. lpsz = (BSTR)pv;
  663. //
  664. // Change each element into string.
  665. //
  666. for (i=0; (hr == S_OK) && (i < (lUBound-lLBound+1)); ++i) {
  667. VariantInit( &vaElement );
  668. V_VT(&vaElement) = VT_BYREF | vt;
  669. V_BYREF(&vaElement) = (LPVOID)lpsz;
  670. VariantInit( &vaTemp );
  671. hr = VariantChangeType( &vaTemp,
  672. &vaElement,
  673. VARIANT_LOCALBOOL,
  674. VT_BSTR );
  675. if ( hr == S_OK ) {
  676. hr = AddToList( hwndDlg,
  677. &vaTemp );
  678. VariantClear( &vaTemp );
  679. }
  680. else {
  681. PrintError( hr,
  682. __LINE__,
  683. TEXT(__FILE__),
  684. TEXT("Couldn't format the value of %s into ")
  685. TEXT("displayable text. The value cannot be ")
  686. TEXT(" viewed/modified."),
  687. lpszProperty );
  688. }
  689. lpsz = (BSTR)((LONG_PTR)lpsz + uiSize);
  690. }
  691. SafeArrayUnaccessData( psaValue );
  692. }
  693. else {
  694. PrintError( hr,
  695. __LINE__,
  696. TEXT(__FILE__),
  697. TEXT("Couldn't read the values of %s."),
  698. lpszProperty );
  699. }
  700. if ( psaValue ) {
  701. SafeArrayDestroy( psaValue );
  702. }
  703. return hr == S_OK;
  704. }
  705. //
  706. // The function add a property value to the tree list.
  707. //
  708. HRESULT AddToList (HWND hwndDlg,
  709. VARIANT *pvaValue)
  710. {
  711. TV_INSERTSTRUCT tvInsertStruc;
  712. ZeroMemory(
  713. &tvInsertStruc,
  714. sizeof(TV_INSERTSTRUCT) );
  715. tvInsertStruc.hParent = TVI_ROOT;
  716. tvInsertStruc.hInsertAfter = TVI_LAST;
  717. tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM;
  718. tvInsertStruc.item.pszText = BstrToString( V_BSTR(pvaValue),
  719. -1 );
  720. if ( tvInsertStruc.item.pszText ) {
  721. tvInsertStruc.item.cchTextMax = _tcslen( tvInsertStruc.item.pszText ) +
  722. sizeof(TCHAR);
  723. tvInsertStruc.item.lParam = (LPARAM)tvInsertStruc.item.cchTextMax;
  724. TreeView_InsertItem( GetDlgItem(hwndDlg,
  725. IDT_PROPERTY_VALUE),
  726. &tvInsertStruc );
  727. SysFreeString( (BSTR)tvInsertStruc.item.pszText );
  728. }
  729. else {
  730. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  731. __LINE__,
  732. TEXT(__FILE__),
  733. TEXT("Cannot show the values of the property.") );
  734. return S_FALSE;
  735. }
  736. return S_OK;
  737. }
  738. VOID ModifyArrayProperty(HWND hwndDlg,
  739. LPPROPERTY_INFO pPropInfo)
  740. {
  741. MessageBox( hwndDlg,
  742. TEXT("This feature is currently not implemented."),
  743. TEXT("Modify Array"),
  744. MB_ICONINFORMATION | MB_OK );
  745. return;
  746. }
  747. //
  748. // The function lists the instances of the selected class and properties of
  749. // the first instance.
  750. //
  751. VOID RefreshOnClassSelection (HWND hwndDlg)
  752. {
  753. IWbemServices *pIWbemServices;
  754. HWND hwndClassList;
  755. HWND hwndInstTree;
  756. HWND hwndPropTree;
  757. LPTSTR lpszClass;
  758. LPTSTR lpszInstance;
  759. HTREEITEM hItem;
  760. pIWbemServices = (IWbemServices *)GetWindowLongPtr( hwndDlg,
  761. DWLP_USER );
  762. //
  763. // Find the selected class.
  764. //
  765. //
  766. hwndClassList = GetDlgItem( hwndDlg,
  767. IDL_CLASSES );
  768. hwndInstTree = GetDlgItem( hwndDlg,
  769. IDT_INSTANCES );
  770. hwndPropTree = GetDlgItem( hwndDlg,
  771. IDT_PROPERTIES );
  772. TreeView_DeleteAllItems( hwndInstTree );
  773. TreeView_DeleteAllItems( hwndPropTree );
  774. lpszClass = GetSelectedClass( hwndClassList );
  775. if ( lpszClass ) {
  776. //
  777. // List all the instances of the selected class.
  778. //
  779. EnumInstances( pIWbemServices,
  780. lpszClass,
  781. hwndInstTree ); // Tree to populate.
  782. //
  783. // By default, first instance is selected and its properties
  784. // are shown.
  785. //
  786. hItem = TreeView_GetChild( hwndInstTree,
  787. TVI_ROOT );
  788. //
  789. // hItem == NULL ==> No instances found.
  790. //
  791. if ( hItem ) {
  792. //
  793. // Select the first instance.
  794. //
  795. TreeView_SelectItem( hwndInstTree,
  796. hItem );
  797. //
  798. // Find the selected instance.
  799. //
  800. lpszInstance = GetSelectedItem( hwndInstTree );
  801. if ( lpszInstance ) {
  802. //
  803. // Show properties of the selected instance.
  804. //
  805. EnumProperties( pIWbemServices,
  806. lpszClass,
  807. lpszInstance,
  808. hwndPropTree ); // Tree to populate.
  809. SysFreeString( (BSTR)lpszInstance );
  810. }
  811. else {
  812. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  813. __LINE__,
  814. TEXT(__FILE__),
  815. TEXT("Properties of the selected ")
  816. TEXT("instance will not be listed.") );
  817. }
  818. }
  819. SysFreeString( (BSTR)lpszClass );
  820. }
  821. else {
  822. PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  823. __LINE__,
  824. TEXT(__FILE__),
  825. TEXT("Instances of the selected ")
  826. TEXT("class will not be listed.") );
  827. }
  828. return;
  829. }
  830. //
  831. // Given a handle to a combo box, the function returns the name of the
  832. // selected item i.e. class.
  833. //
  834. LPTSTR GetSelectedClass (HWND hwndClassList)
  835. {
  836. LPTSTR lpszClass;
  837. ULONG ulIndex;
  838. ULONG ulLen;
  839. lpszClass = NULL;
  840. //
  841. // Find the selected class.
  842. //
  843. ulIndex = (ULONG)SendMessage( hwndClassList,
  844. CB_GETCURSEL,
  845. 0,
  846. 0 );
  847. //
  848. // Find the length of the selected class name.
  849. //
  850. ulLen = (ULONG)SendMessage( hwndClassList,
  851. CB_GETLBTEXTLEN,
  852. (WPARAM)ulIndex,
  853. 0 );
  854. lpszClass = (LPTSTR)SysAllocStringLen( NULL,
  855. ulLen + 1 );
  856. if ( lpszClass ) {
  857. SendMessage( hwndClassList,
  858. CB_GETLBTEXT,
  859. (WPARAM)ulIndex,
  860. (LPARAM)lpszClass );
  861. }
  862. return lpszClass;
  863. }
  864. //
  865. // Given a handle to the tree list, the function returns the name of the
  866. // selected item.
  867. //
  868. LPTSTR GetSelectedItem (HWND hwndTree)
  869. {
  870. LPTSTR lpszItem;
  871. HTREEITEM hItem;
  872. TVITEM tvItem;
  873. lpszItem = NULL;
  874. //
  875. // Find the selected item.
  876. //
  877. hItem = TreeView_GetSelection( hwndTree );
  878. if ( hItem ) {
  879. //
  880. // Find out the length of the selected item and allocate memory.
  881. //
  882. ZeroMemory( &tvItem,
  883. sizeof(TVITEM) );
  884. tvItem.hItem = hItem;
  885. tvItem.mask = TVIF_PARAM;
  886. TreeView_GetItem( hwndTree,
  887. &tvItem );
  888. lpszItem = (LPTSTR)SysAllocStringLen( NULL,
  889. (UINT)tvItem.lParam );
  890. if ( lpszItem ) {
  891. tvItem.hItem = hItem;
  892. tvItem.mask = TVIF_TEXT;
  893. tvItem.pszText = lpszItem;
  894. tvItem.cchTextMax = (INT)tvItem.lParam;
  895. TreeView_GetItem( hwndTree,
  896. &tvItem );
  897. }
  898. }
  899. return lpszItem;
  900. }
  901. //
  902. // The function inserts an item into a tree list.
  903. //
  904. VOID InsertItem (HWND hwndTree,
  905. LPTSTR lpszItem)
  906. {
  907. TVINSERTSTRUCT tvInsertStruc;
  908. ZeroMemory(
  909. &tvInsertStruc,
  910. sizeof(TVINSERTSTRUCT) );
  911. tvInsertStruc.hParent = TVI_ROOT;
  912. tvInsertStruc.hInsertAfter = TVI_LAST;
  913. tvInsertStruc.item.mask = TVIF_TEXT | TVIF_PARAM;
  914. tvInsertStruc.item.pszText = lpszItem;
  915. tvInsertStruc.item.cchTextMax = _tcslen(lpszItem) + 1;
  916. tvInsertStruc.item.lParam = tvInsertStruc.item.cchTextMax;
  917. TreeView_InsertItem( hwndTree,
  918. &tvInsertStruc );
  919. return;
  920. }
  921. VOID PrintError (HRESULT hr,
  922. UINT uiLine,
  923. LPTSTR lpszFile,
  924. LPCTSTR lpFmt,
  925. ...)
  926. {
  927. LPTSTR lpSysMsg;
  928. TCHAR buf[400];
  929. ULONG offset;
  930. va_list vArgList;
  931. if ( hr != 0 ) {
  932. _stprintf( buf,
  933. TEXT("Error %#lx (%s, %d): "),
  934. hr,
  935. lpszFile,
  936. uiLine );
  937. }
  938. else {
  939. _stprintf( buf,
  940. TEXT("(%s, %d): "),
  941. lpszFile,
  942. uiLine );
  943. }
  944. offset = _tcslen( buf );
  945. va_start( vArgList,
  946. lpFmt );
  947. _vstprintf( buf+offset,
  948. lpFmt,
  949. vArgList );
  950. va_end( vArgList );
  951. if ( hr != 0 ) {
  952. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  953. FORMAT_MESSAGE_FROM_SYSTEM |
  954. FORMAT_MESSAGE_IGNORE_INSERTS,
  955. NULL,
  956. hr,
  957. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  958. (LPTSTR)&lpSysMsg,
  959. 0,
  960. NULL );
  961. if ( lpSysMsg ) {
  962. offset = _tcslen( buf );
  963. _stprintf( buf+offset,
  964. TEXT("\n\nPossible cause:\n\n") );
  965. offset = _tcslen( buf );
  966. _tcscat( buf+offset,
  967. lpSysMsg );
  968. LocalFree( (HLOCAL)lpSysMsg );
  969. }
  970. MessageBox( NULL,
  971. buf,
  972. TEXT("TestWMI"),
  973. MB_ICONERROR | MB_OK );
  974. }
  975. else {
  976. MessageBox( NULL,
  977. buf,
  978. TEXT("TestWMI"),
  979. MB_ICONINFORMATION | MB_OK );
  980. }
  981. return;
  982. }