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.

933 lines
20 KiB

  1. /************STARTDOC*********************************************************
  2. *
  3. * Copyright (c) 1997-1999 Microsoft Corporation
  4. * mofcall.c
  5. *
  6. * This file contains the functions used to gather infomation about
  7. * the various wmi providers registered with the system. Infomation
  8. * can be gathered from the .mof file. Then this information can be
  9. * used to query the actual provider.
  10. *
  11. *
  12. * Modification History:
  13. * --------------------
  14. *
  15. * Drew McDaniel (drewm) - Sept. 16, 1997 - Original Source
  16. *
  17. *
  18. *************ENDDOC**********************************************************/
  19. #include <windows.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <ole2.h>
  23. #include <wmium.h>
  24. #include <tchar.h>
  25. #include "print.h"
  26. // Defined constants
  27. //
  28. #define MAX_DATA 200
  29. // Modular Data
  30. //
  31. // Function Prototypes
  32. //
  33. extern ULONG
  34. WMIAPI
  35. WmiEnumerateGuids(
  36. OUT LPGUID GuidList,
  37. IN OUT ULONG *GuidCount
  38. );
  39. BOOL
  40. PrintAllGuids(
  41. LPGUID *GuidList,
  42. LPDWORD lpdwGuidCount
  43. );
  44. DWORD
  45. GetGuidList(
  46. OUT LPGUID *ppGuidList
  47. );
  48. VOID
  49. UseGuid(
  50. LPGUID lpGuid
  51. );
  52. VOID
  53. QueryWnodeAllData(
  54. LPGUID lpGuid
  55. );
  56. VOID
  57. QueryWnodeSingleInstance(
  58. LPGUID lpGuid
  59. );
  60. VOID
  61. SetWnodeSingleInstance(
  62. LPGUID lpGuid
  63. );
  64. VOID
  65. SetWnodeSingleItem(
  66. LPGUID lpGuid
  67. );
  68. //+----------------------------------------------------------
  69. //
  70. // Function: Main
  71. //
  72. // Descrip: This is the starting function. It will call
  73. // a routine to print all of the guids and a short
  74. // description. Then the user may select one of
  75. // the guids and get more mof infomation, call one
  76. // of the WMI query APIs, or call one of the WMI set
  77. // APIs
  78. //
  79. // Returns: Only returns upon program exit
  80. //
  81. // Notes: Initially this is just going to be a text based
  82. // tool. The hope is that this could later be
  83. // modified into a (possibly more useful) GUI based
  84. // tool.
  85. //
  86. // History: 09/16/97 drewm Created
  87. //-----------------------------------------------------------
  88. int _cdecl main(int argc, LPSTR *argv[])
  89. {
  90. DWORD dwRet = 0;
  91. LPGUID GuidList = NULL;
  92. DWORD dwGuidCount = 0;
  93. DWORD dwResponse = 0;
  94. DWORD dwGuidIndex = 0;
  95. BOOL bContinue = TRUE;
  96. while (bContinue == TRUE)
  97. {
  98. // Print all of the registered guids
  99. //
  100. PrintAllGuids(&GuidList, &dwGuidCount);
  101. // Check to see which guid to query
  102. //
  103. printf("\n\nSelect a guid to examine (0 to exit): ");
  104. scanf("%u", &dwResponse);
  105. printf("\n\n");
  106. if (dwResponse == 0)
  107. {
  108. bContinue = FALSE;
  109. }
  110. else
  111. {
  112. dwGuidIndex = dwResponse - 1;
  113. if (dwGuidIndex < dwGuidCount)
  114. {
  115. // Clear screen and then allow the user to play
  116. // with the selected guid.
  117. //
  118. UseGuid( &(GuidList[dwGuidIndex]) );
  119. }
  120. else
  121. {
  122. printf("Invalid guid %u\n", dwResponse);
  123. Sleep (2000);
  124. ClearScreen();
  125. }
  126. }
  127. // Free the list of guids to clean up for the next call
  128. //
  129. if (GuidList != NULL)
  130. {
  131. free(GuidList);
  132. GuidList = NULL;
  133. }
  134. }
  135. return(TRUE);
  136. }
  137. //+----------------------------------------------------------
  138. //
  139. // Function: PrintAllGuids
  140. //
  141. // Descrip: First we get a list of all of the guids register
  142. // with the system. This list is based on the
  143. // information that a provider exposes in its .mof
  144. // file. If a providers .mof file is incorrect or
  145. // if the provider does not have a .mof file then
  146. // its guids will not be accessable by this program.
  147. //
  148. // Returns: TRUE always
  149. //
  150. // Notes: If no guids are registered then this app will
  151. // be terminated.
  152. //
  153. // History: 09/16/97 drewm Created
  154. //-----------------------------------------------------------
  155. BOOL
  156. PrintAllGuids(
  157. LPGUID *GuidList,
  158. LPDWORD lpdwGuidCount
  159. )
  160. {
  161. UINT index;
  162. // Get the list of guids. Exit if no guids are registered.
  163. //
  164. *lpdwGuidCount = GetGuidList( GuidList );
  165. if (*lpdwGuidCount == 0)
  166. {
  167. printf("No Guids are registered\n");
  168. exit(0);
  169. }
  170. // Print each guid index, actual guid, and the description
  171. // of the guid.
  172. //
  173. for (index = 0; index < *lpdwGuidCount; index++)
  174. {
  175. printf("Guid %u: ", index + 1);
  176. PrintGuid(&((*GuidList)[index]));
  177. printf("\n");
  178. //No Mof Stuff
  179. // PrintDescription(&((*GuidList)[index]));
  180. printf("\n");
  181. }
  182. return (TRUE);
  183. }
  184. //+----------------------------------------------------------
  185. //
  186. // Function: GetGuidList
  187. //
  188. // Descrip: This function will first query to determine how
  189. // many WMI guids are currently registered. Then
  190. // it will allocate space for the guids and query
  191. // the system for the actual list of guids.
  192. //
  193. // Returns: The number of guids registered on the system based
  194. // on the infomation provided in each providers .mof
  195. // file.
  196. //
  197. // Notes: None
  198. //
  199. // History: 09/16/97 drewm Created
  200. //-----------------------------------------------------------
  201. DWORD
  202. GetGuidList(
  203. OUT LPGUID *ppGuidList
  204. )
  205. {
  206. DWORD dwGuidCount = 0;
  207. DWORD dwRet;
  208. GUID Guid;
  209. // Determine the present number of guids registered
  210. //
  211. dwRet = WmiEnumerateGuids( &Guid,
  212. &dwGuidCount);
  213. if (dwRet != ERROR_MORE_DATA)
  214. {
  215. printf("Call to determine number of Guids failed. (%u)\n", dwRet);
  216. return (0);
  217. }
  218. // Return if there are no guids registered
  219. //
  220. if (dwGuidCount != 0)
  221. {
  222. // Allocate buffer for Guids. Note: we will allocate room for
  223. // and extra 10 Guids in case new Guids were registed between the
  224. // previous call to WMIMofEnumeratGuid, and the next call.
  225. //
  226. dwGuidCount += 10;
  227. *ppGuidList = (LPGUID) malloc (dwGuidCount * sizeof(GUID));
  228. if (*ppGuidList == NULL)
  229. {
  230. printf("Out of Memory Failure. Unable to allocate memory"
  231. " for guid list array\n");
  232. return (0);
  233. }
  234. // Get the list of Guids
  235. //
  236. dwRet = WmiEnumerateGuids( *ppGuidList,
  237. &dwGuidCount);
  238. if ((dwRet != ERROR_SUCCESS) && (dwRet != ERROR_MORE_DATA))
  239. {
  240. printf("Failure to get guid list. (%u)\n", dwRet);
  241. return 0;
  242. }
  243. }
  244. return (dwGuidCount);
  245. } // GetGuidList
  246. //+----------------------------------------------------------
  247. //
  248. // Function: UseGuid
  249. //
  250. // Descrip: This function will ask the user what operation
  251. // they would like to do to the selected guid.
  252. //
  253. // Returns: VOID
  254. //
  255. // Notes: None
  256. //
  257. // History: 09/16/97 drewm Created
  258. //-----------------------------------------------------------
  259. VOID
  260. UseGuid(
  261. LPGUID lpGuid
  262. )
  263. {
  264. DWORD dwSelection = 0;
  265. while (1)
  266. {
  267. ClearScreen();
  268. printf("Guid: ");
  269. PrintGuid( lpGuid );
  270. printf("\n");
  271. printf("1.) Query for the full Wnode\n");
  272. printf("2.) Query a single instance\n");
  273. printf("3.) Set a single instance\n");
  274. printf("4.) Set a single item\n");
  275. printf("0.) Back to previous screen\n");
  276. printf("\nMake selection: ");
  277. scanf("%u", &dwSelection );
  278. printf("\n");
  279. switch (dwSelection)
  280. {
  281. case 0:
  282. ClearScreen();
  283. return;
  284. case 1:
  285. ClearScreen();
  286. QueryWnodeAllData( lpGuid );
  287. break;
  288. case 2:
  289. ClearScreen();
  290. QueryWnodeSingleInstance( lpGuid );
  291. break;
  292. case 3:
  293. ClearScreen();
  294. SetWnodeSingleInstance( lpGuid );
  295. break;
  296. case 4:
  297. ClearScreen();
  298. SetWnodeSingleItem( lpGuid );
  299. break;
  300. default:
  301. printf("Invalid Selection.\n");
  302. WaitForUser();
  303. break;
  304. }
  305. }
  306. } // UseGuid
  307. //+----------------------------------------------------------
  308. //
  309. // Function: SelectInstanceName
  310. //
  311. // Descrip: This function will prompt the user to select one of the
  312. // instances of the guid to use.
  313. //
  314. // Returns: VOID
  315. //
  316. // Notes: None
  317. //
  318. // History: 09/16/97 drewm Created
  319. //-----------------------------------------------------------
  320. SelectInstanceName(
  321. LPGUID lpGuid,
  322. LPTSTR lpInstanceName,
  323. LPDWORD lpdwNameSize
  324. )
  325. {
  326. HANDLE hDataBlock;
  327. BYTE Buffer[4096];
  328. DWORD dwBufferSize = 4096;
  329. DWORD dwRet;
  330. DWORD dwInstanceNumber;
  331. LPDWORD NameOffsets;
  332. BOOL bContinue = TRUE;
  333. USHORT usNameSize;
  334. UINT iLoop;
  335. LPTSTR lpStringLocal;
  336. PWNODE_ALL_DATA pWnode;
  337. // Get the entire Wnode
  338. //
  339. dwRet = WmiOpenBlock( lpGuid,
  340. 0,
  341. &hDataBlock
  342. );
  343. if (dwRet == ERROR_SUCCESS)
  344. {
  345. dwRet = WmiQueryAllData( hDataBlock,
  346. &dwBufferSize,
  347. Buffer);
  348. if ( dwRet == ERROR_SUCCESS)
  349. {
  350. WmiCloseBlock(hDataBlock);
  351. }
  352. else
  353. {
  354. printf("WMIQueryAllData returned error: %d\n", dwRet);
  355. }
  356. }
  357. else
  358. {
  359. printf("Unable to open data block (%u)\n", dwRet);
  360. }
  361. if (dwRet != ERROR_SUCCESS)
  362. {
  363. return (dwRet);
  364. }
  365. // Print Each Instance
  366. //
  367. pWnode = (PWNODE_ALL_DATA) Buffer;
  368. NameOffsets = (LPDWORD) OffsetToPtr( pWnode,
  369. pWnode->OffsetInstanceNameOffsets );
  370. for (iLoop = 0; iLoop < pWnode->InstanceCount; iLoop++)
  371. {
  372. printf("Instance %u: ", iLoop);
  373. PrintCountedString( (LPTSTR) OffsetToPtr( pWnode, NameOffsets[iLoop]) );
  374. }
  375. // Select a specific instance
  376. //
  377. while (bContinue == TRUE)
  378. {
  379. printf("Select an instance: ");
  380. scanf("%u", &dwInstanceNumber);
  381. printf("\n");
  382. if (dwInstanceNumber >= iLoop)
  383. {
  384. printf("Invalid selection\n\n");
  385. WaitForUser();
  386. printf("\n\n");
  387. }
  388. else
  389. {
  390. bContinue = FALSE;
  391. }
  392. }
  393. // Check the size of the input buffer
  394. //
  395. lpStringLocal = (LPTSTR) OffsetToPtr( pWnode, NameOffsets[dwInstanceNumber] );
  396. usNameSize = * ((USHORT *) lpStringLocal);
  397. lpStringLocal = (LPTSTR) ((PBYTE)lpStringLocal + sizeof(USHORT));
  398. if (*lpdwNameSize < (usNameSize + sizeof(TCHAR)))
  399. {
  400. *lpdwNameSize = usNameSize + sizeof(TCHAR);
  401. return (ERROR_INSUFFICIENT_BUFFER);
  402. }
  403. // Copy the instance name over to the output parameter.
  404. // Also, a null character needs to be added to the end of
  405. // the string because the counted string may not contain a
  406. // NULL character.
  407. //
  408. if (MyIsTextUnicode(lpStringLocal))
  409. {
  410. usNameSize /= 2;
  411. }
  412. _tcsncpy( lpInstanceName, lpStringLocal, usNameSize );
  413. lpInstanceName += usNameSize;
  414. _tcscpy( lpInstanceName, __T(""));
  415. return (ERROR_SUCCESS);
  416. } // SelectInstanceName
  417. //+----------------------------------------------------------
  418. //
  419. // Function: QueryWnodeAllData
  420. //
  421. // Descrip: This function will query the wnode and then
  422. // print out the wnode.
  423. //
  424. // Returns: VOID
  425. //
  426. // Notes: None
  427. //
  428. // History: 09/16/97 drewm Created
  429. //-----------------------------------------------------------
  430. VOID
  431. QueryWnodeAllData(
  432. LPGUID lpGuid
  433. )
  434. {
  435. HANDLE hDataBlock;
  436. DWORD dwRet;
  437. PBYTE Buffer;
  438. ULONG dwBufferSize = 4096;
  439. PWNODE_ALL_DATA pWnode;
  440. // Open the wnode
  441. //
  442. dwRet = WmiOpenBlock( lpGuid,
  443. 0,
  444. &hDataBlock
  445. );
  446. if (dwRet != ERROR_SUCCESS)
  447. {
  448. printf("Unable to open data block (%u)\n", dwRet);
  449. WaitForUser();
  450. return;
  451. }
  452. // Allocate an initial buffer
  453. //
  454. Buffer = (PBYTE) malloc ( dwBufferSize );
  455. if (Buffer != NULL)
  456. {
  457. // Query the data block
  458. //
  459. dwRet = WmiQueryAllData( hDataBlock,
  460. &dwBufferSize,
  461. Buffer);
  462. if (dwRet == ERROR_INSUFFICIENT_BUFFER)
  463. {
  464. #ifdef DBG
  465. printf("Initial buffer too small reallocating to %u\n", dwBufferSize);
  466. #endif
  467. Buffer = (PBYTE) realloc (Buffer, dwBufferSize);
  468. if (Buffer != NULL)
  469. {
  470. dwRet = WmiQueryAllData( hDataBlock,
  471. &dwBufferSize,
  472. Buffer);
  473. }
  474. else
  475. {
  476. printf("Reallocation failed\n");
  477. }
  478. }
  479. if ( dwRet == ERROR_SUCCESS )
  480. {
  481. pWnode = (PWNODE_ALL_DATA) Buffer;
  482. PrintAllData(pWnode);
  483. WmiCloseBlock(hDataBlock);
  484. }
  485. else
  486. {
  487. printf("WMIQueryAllData returned error: %d\n", dwRet);
  488. }
  489. }
  490. else
  491. {
  492. printf("Out of Memory Error. Unable to allocate buffer of size %u\n",
  493. dwBufferSize );
  494. }
  495. WmiCloseBlock( hDataBlock );
  496. WaitForUser ();
  497. return;
  498. } // QueryWnodeAllData
  499. //+----------------------------------------------------------
  500. //
  501. // Function: QueryWnodeSingleInstance
  502. //
  503. // Descrip: This function will query the wnode and then
  504. // print out the wnode.
  505. //
  506. // Returns: VOID
  507. //
  508. // Notes: None
  509. //
  510. // History: 09/16/97 drewm Created
  511. //-----------------------------------------------------------
  512. VOID
  513. QueryWnodeSingleInstance(
  514. LPGUID lpGuid
  515. )
  516. {
  517. HANDLE hDataBlock;
  518. DWORD dwRet;
  519. TCHAR Buffer[MAX_PATH];
  520. DWORD dwBufferSize = MAX_PATH;
  521. LPTSTR lpInstanceName;
  522. PWNODE_SINGLE_INSTANCE pWnode;
  523. // Have the user select one of the instances of a particular guid to use.
  524. //
  525. dwRet = SelectInstanceName( lpGuid,
  526. Buffer,
  527. &dwBufferSize
  528. );
  529. if (dwRet != ERROR_SUCCESS)
  530. {
  531. return;
  532. }
  533. lpInstanceName = (TCHAR *) malloc (dwBufferSize * sizeof(TCHAR));
  534. if (lpInstanceName == NULL)
  535. {
  536. printf("Out of Memory Error\n");
  537. WaitForUser();
  538. return;
  539. }
  540. else
  541. {
  542. _tcscpy( lpInstanceName, Buffer );
  543. dwBufferSize = 4096;
  544. }
  545. // Open the wnode
  546. //
  547. dwRet = WmiOpenBlock( lpGuid,
  548. 0,
  549. &hDataBlock
  550. );
  551. if (dwRet != ERROR_SUCCESS)
  552. {
  553. printf("Unable to open data block (%u)\n", dwRet);
  554. WaitForUser();
  555. return;
  556. }
  557. // Query the data block
  558. //
  559. dwRet = WmiQuerySingleInstance( hDataBlock,
  560. lpInstanceName,
  561. &dwBufferSize,
  562. Buffer);
  563. if ( dwRet != ERROR_SUCCESS)
  564. {
  565. printf("WmiQuerySingleInstance returned error: %d\n", dwRet);
  566. WmiCloseBlock( hDataBlock );
  567. WaitForUser();
  568. return;
  569. }
  570. pWnode = (PWNODE_SINGLE_INSTANCE) Buffer;
  571. PrintSingleInstance(pWnode);
  572. WaitForUser();
  573. WmiCloseBlock(hDataBlock);
  574. return;
  575. }
  576. //+----------------------------------------------------------
  577. //
  578. // Function: SetWnodeSingleInstance
  579. //
  580. // Descrip: This function will query the wnode and then
  581. // print out the wnode.
  582. //
  583. // Returns: VOID
  584. //
  585. // Notes: None
  586. //
  587. // History: 09/16/97 drewm Created
  588. //-----------------------------------------------------------
  589. VOID
  590. SetWnodeSingleInstance(
  591. LPGUID lpGuid
  592. )
  593. {
  594. DWORD dwRet;
  595. DWORD dwVersionNumber;
  596. DWORD dwData[MAX_DATA];
  597. DWORD dwDataSize;
  598. UINT iLoop;
  599. LPTSTR lpInstanceName;
  600. TCHAR Buffer[MAX_PATH];
  601. DWORD dwBufferSize = MAX_PATH;
  602. HANDLE hDataBlock;
  603. // Get the instance to set
  604. //
  605. dwRet = SelectInstanceName( lpGuid,
  606. Buffer,
  607. &dwBufferSize
  608. );
  609. if (dwRet != ERROR_SUCCESS)
  610. {
  611. return;
  612. }
  613. lpInstanceName = (TCHAR *) _alloca (dwBufferSize * sizeof(TCHAR));
  614. _tcscpy( lpInstanceName, Buffer );
  615. dwBufferSize = 4096;
  616. // Get the version number
  617. //
  618. printf("What is the version number you would like to use? ");
  619. scanf("%u", &dwVersionNumber);
  620. printf("\n");
  621. // Get the size of the data to set
  622. //
  623. printf("How many dwords is your data? ");
  624. scanf("%u", &dwDataSize);
  625. printf("\n");
  626. if (dwDataSize > MAX_DATA)
  627. {
  628. printf("Unable to handle large data\n");
  629. return;
  630. }
  631. // Get the data
  632. //
  633. for (iLoop = 0; iLoop < dwDataSize; iLoop++)
  634. {
  635. printf("Enter DWORD %u, in hex: ", iLoop);
  636. scanf("%x", &(dwData[iLoop]));
  637. printf("\n");
  638. }
  639. printf("\n");
  640. // Open the wnode
  641. //
  642. dwRet = WmiOpenBlock( lpGuid,
  643. 0,
  644. &hDataBlock
  645. );
  646. if (dwRet != ERROR_SUCCESS)
  647. {
  648. printf("Unable to open data block (%u)\n", dwRet);
  649. WaitForUser();
  650. return;
  651. }
  652. // Set the data
  653. //
  654. printf("Setting Instance: %s\n", lpInstanceName);
  655. printf("Data: ");
  656. for (iLoop = 0; iLoop < dwDataSize; iLoop++)
  657. {
  658. printf("0x%x ", dwData[iLoop]);
  659. }
  660. printf("\n");
  661. dwRet = WmiSetSingleInstance( hDataBlock,
  662. lpInstanceName,
  663. dwVersionNumber,
  664. dwDataSize * sizeof(DWORD),
  665. dwData );
  666. if ( dwRet != ERROR_SUCCESS)
  667. {
  668. printf("WMISetSingleInstance returned error: %d\n", dwRet);
  669. }
  670. else
  671. {
  672. printf("Set Success\n\n");
  673. }
  674. WmiCloseBlock( hDataBlock );
  675. WaitForUser();
  676. }
  677. //+----------------------------------------------------------
  678. //
  679. // Function: SetWnodeSingleItem
  680. //
  681. // Descrip: This function will query the wnode and then
  682. // print out the wnode.
  683. //
  684. // Returns: VOID
  685. //
  686. // Notes: None
  687. //
  688. // History: 09/16/97 drewm Created
  689. //-----------------------------------------------------------
  690. VOID
  691. SetWnodeSingleItem(
  692. LPGUID lpGuid
  693. )
  694. {
  695. DWORD dwRet;
  696. DWORD dwVersionNumber;
  697. DWORD dwItemNumber;
  698. DWORD dwData;
  699. DWORD dwDataSize;
  700. UINT iLoop;
  701. LPTSTR lpInstanceName;
  702. TCHAR Buffer[MAX_PATH];
  703. DWORD dwBufferSize = MAX_PATH;
  704. HANDLE hDataBlock;
  705. // Get the instance to set
  706. //
  707. dwRet = SelectInstanceName( lpGuid,
  708. Buffer,
  709. &dwBufferSize
  710. );
  711. if (dwRet != ERROR_SUCCESS)
  712. {
  713. return;
  714. }
  715. lpInstanceName = (TCHAR *) _alloca (dwBufferSize * sizeof(TCHAR));
  716. _tcscpy( lpInstanceName, Buffer );
  717. dwBufferSize = 4096;
  718. // Get the version number
  719. //
  720. printf("What is the version number you would like to use? ");
  721. scanf("%u", &dwVersionNumber);
  722. printf("\n");
  723. // Get the item number
  724. //
  725. printf("What is the item number you would like to set? ");
  726. scanf("%u", &dwItemNumber);
  727. printf("\n");
  728. // Get the data
  729. //
  730. printf("Enter data (must be a DWORD in hex): ");
  731. scanf("%x", &dwData);
  732. printf("\n");
  733. printf("\n");
  734. // Open the wnode
  735. //
  736. dwRet = WmiOpenBlock( lpGuid,
  737. 0,
  738. &hDataBlock
  739. );
  740. if (dwRet != ERROR_SUCCESS)
  741. {
  742. printf("Unable to open data block (%u)\n", dwRet);
  743. WaitForUser();
  744. return;
  745. }
  746. // Set the data
  747. //
  748. printf("Setting Instance: %s\n", lpInstanceName);
  749. printf("Data: 0x%x\n\n", dwData);
  750. dwRet = WmiSetSingleItem( hDataBlock,
  751. lpInstanceName,
  752. dwItemNumber,
  753. dwVersionNumber,
  754. sizeof(DWORD),
  755. &dwData );
  756. if ( dwRet != ERROR_SUCCESS)
  757. {
  758. printf("WMISetSingleInstance returned error: %d\n", dwRet);
  759. }
  760. else
  761. {
  762. printf("Set Success\n\n");
  763. }
  764. WmiCloseBlock( hDataBlock );
  765. WaitForUser();
  766. }
  767.