Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6983 lines
223 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. mofcheck.c
  5. Abstract:
  6. TODO: Enable localization
  7. Tool to validate that a binary MOF is valid for use with WMI
  8. Usage:
  9. wmimofck <binary mof file>
  10. Rules that are enforced by this program:
  11. * Any classes that do not have the WMI qualifier are ignored. Any class
  12. with the qualifier is a WMI class.
  13. * All WMI classes must have guids, including embedded classes.
  14. * All WMI classes that do not have special HMOM qualifiers [Dynamic,
  15. Provider("WMIProv")] are embedded only classes.
  16. * All non embedded WMI classes must have a property with the [key]
  17. qualifier named InstanceName, be of type string and NOT have a
  18. WmiDataId qualifier.
  19. * Embedded only classes should not have InstanceName or Active properties
  20. * All other properties in a WMI class must have a WmiDataId qualifier
  21. that specifies the position of the data item represented by the property
  22. within the data block represented by the class.
  23. * The property for the first data item in the data block must have
  24. WmiDataId(1). WmiDataId(0) is reserved.
  25. * WmiDataId qualifier values must be contiguous, ie, 1,2,3,4,5... There may
  26. not be any duplicate or missing WmiDataId values in a class.
  27. * The order of the properties as specified in the mof does not need to
  28. follow that of the WmiDataId
  29. * A property with a greater WmiDataId can not be marked with a WmiVersion
  30. qualifier whose value is lower than any properties with a lower WmiDataId
  31. * All embedded classes must be defined in the same mof
  32. * Only the following types are valid for properties:
  33. string, sint32, uint32, sint64, uint64, bool, sint16, uint16, char16
  34. sint8, uint8, datetime
  35. * Any variable length array must have a WmiSizeIs qualifier that specifies
  36. the property that holds the number of elements in the array. This
  37. property must be part of the same class as the variable length array,
  38. and this property must be an unsigned integer type (uint8, uint16,
  39. uint32, uint64)
  40. * Fixed length arrays must have the max qualifier.
  41. * An array may not be both fixed and variable length
  42. * Methods must have WmiMethodId qualifier with a unique value
  43. * Methods must have the Implemented qualifier
  44. * Methods must have a void return
  45. * Classes derrived from WmiEvent may not be abstract
  46. Author:
  47. 16-Jan-1997 AlanWar
  48. Revision History:
  49. --*/
  50. #define STRSAFE_NO_DEPRECATE
  51. #define WMI_USER_MODE
  52. #include <stdio.h>
  53. #include <fcntl.h>
  54. #include <io.h>
  55. #include <ctype.h>
  56. #include "wmiump.h"
  57. #include "bmof.h"
  58. #include "mrcicode.h"
  59. #ifdef WmipUnreferenceMC
  60. #undef WmipUnreferenceMC
  61. #endif
  62. #define WmipUnreferenceMC(MofClass)
  63. #ifdef WmipUnreferenceMR
  64. #undef WmipUnreferenceMR
  65. #endif
  66. #define WmipUnreferenceMR(MofClass)
  67. #ifdef WmipAllocMofResource
  68. #undef WmipAllocMofResource
  69. #endif
  70. #define WmipAllocMofResource() WmipAlloc(sizeof(MOFRESOURCE))
  71. #ifdef WmipAllocMofClass
  72. #undef WmipAllocMofClass
  73. #endif
  74. #define WmipAllocMofClass() WmipAlloc(sizeof(MOFCLASS))
  75. BOOL wGUIDFromString(LPCWSTR lpsz, LPGUID pguid);
  76. #if DBG
  77. BOOLEAN EtwpLoggingEnabled = FALSE;
  78. #endif
  79. #ifdef MEMPHIS
  80. #if DBG
  81. void __cdecl DebugOut(char *Format, ...)
  82. {
  83. char Buffer[1024];
  84. va_list pArg;
  85. ULONG i;
  86. va_start(pArg, Format);
  87. i = _vsnprintf(Buffer, sizeof(Buffer), Format, pArg);
  88. OutputDebugString(Buffer);
  89. }
  90. #endif
  91. #endif
  92. TCHAR *MessageText[ERROR_WMIMOF_COUNT + 5] =
  93. {
  94. TEXT("This file is not a valid binary mof file"),
  95. TEXT("There was not enough memory to complete an operation"),
  96. TEXT("Binary Mof file %s could not be opened"),
  97. TEXT("Unknown error code %d\n"),
  98. //
  99. // ERROR_WMIMOF_ messages start here
  100. TEXT("ERROR_WMIMOF_INCORRECT_DATA_TYPE"),
  101. TEXT("ERROR_WMIMOF_NO_DATA"),
  102. TEXT("ERROR_WMIMOF_NOT_FOUND"),
  103. TEXT("ERROR_WMIMOF_UNUSED"),
  104. TEXT("Property %ws in class %ws has no embedded class name"),
  105. TEXT("Property %ws in class %ws has an unknown data type"),
  106. TEXT("Property %ws in class %ws has no syntax qualifier"),
  107. TEXT("ERROR_WMIMOF_NO_SYNTAX_QUALIFIER"),
  108. TEXT("ERROR_WMIMOF_NO_CLASS_NAME"),
  109. TEXT("ERROR_WMIMOF_BAD_DATA_FORMAT"),
  110. TEXT("Property %ws in class %ws has the same WmiDataId %d as property %ws"),
  111. TEXT("Property %ws in class %ws has a WmiDataId of %d which is out of range"),
  112. TEXT("ERROR_WMIMOF_MISSING_DATAITEM"),
  113. TEXT("Property for WmiDataId %d is not defined in class %ws"),
  114. TEXT("Embedded class %ws not defined for Property %ws in Class %ws"),
  115. TEXT("Property %ws in class %ws has an incorrect [WmiVersion] qualifier"),
  116. TEXT("ERROR_WMIMOF_NO_PROPERTY_QUALIFERS"),
  117. TEXT("Class %ws has a badly formed or missing [guid] qualifier"),
  118. TEXT("Could not find property %ws which is the array size for property %ws in class %ws"),
  119. TEXT("A class could not be parsed properly"),
  120. TEXT("Wmi class %ws requires the qualifiers [Dynamic, Provider(\"WmiProv\")]"),
  121. TEXT("Error accessing binary mof file %s, code %d"),
  122. TEXT("Property InstanceName in class %ws must be type string and not %ws"),
  123. TEXT("Property Active in class %ws must be type bool and not %ws"),
  124. TEXT("Property %ws in class %ws does not have [WmiDataId()] qualifier"),
  125. TEXT("Property InstanceName in class %ws must have [key] qualifier"),
  126. TEXT("Class %ws and all its base classes do not have an InstanceName property"),
  127. TEXT("Class %ws and all its base classes do not have an Active qualifier"),
  128. TEXT("Property %ws in class %ws is an array, but doesn't specify a dimension"),
  129. TEXT("The element count property %ws for the variable length array %ws in class %ws is not an integral type"),
  130. TEXT("Property %ws in class %ws is both a fixed and variable length array"),
  131. TEXT("Embedded class %ws should be abstract or not have InstaneName or Active properties"),
  132. TEXT("Implemented qualifier required on method %ws in class %ws"),
  133. TEXT("WmiMethodId for method %ws in class %ws must be unique"),
  134. TEXT("WmiMethodId for method %ws in class %ws must be specified"),
  135. TEXT("WmiMethodId for method %ws in class %ws must not be 0"),
  136. TEXT("Class %ws is derived from WmiEvent and may not be [abstract]"),
  137. TEXT("The element count property for the variable length array %ws in class %ws is not a property of the class"),
  138. TEXT("An error occured resolving the variable length array property %ws in class %ws to element count property"),
  139. TEXT("Method %ws in class %ws must have return type void\n"),
  140. TEXT("Embedded class %ws should not have any methods\n")
  141. };
  142. HANDLE FileHandle, MappingHandle;
  143. TCHAR *BMofFileName;
  144. BOOLEAN DoMethodHeaderGeneration;
  145. BOOLEAN ForceHeaderGeneration;
  146. //
  147. // These global variables hold the compressed buffer and size
  148. PVOID CompressedFileBuffer;
  149. ULONG CompressedSize;
  150. //
  151. // These global variables hold the uncompressed buffer and size
  152. PVOID FileBuffer;
  153. ULONG UncompressedSize;
  154. BOOLEAN SkipEmbedClassCheck;
  155. void __cdecl ErrorMessage(
  156. BOOLEAN ExitProgram,
  157. ULONG ErrorCode,
  158. ...
  159. )
  160. {
  161. va_list pArg;
  162. LONG Index;
  163. TCHAR *ErrorText;
  164. TCHAR Buffer[1024];
  165. UnmapViewOfFile(CompressedFileBuffer);
  166. CloseHandle(MappingHandle);
  167. CloseHandle(FileHandle);
  168. DeleteFile(BMofFileName);
  169. if (ErrorCode == ERROR_WMI_INVALID_MOF)
  170. {
  171. Index = 0;
  172. } else if (ErrorCode == ERROR_NOT_ENOUGH_MEMORY) {
  173. Index = 1;
  174. } else if (ErrorCode == ERROR_FILE_NOT_FOUND) {
  175. Index = 2;
  176. } else {
  177. Index = (-1 * ((LONG)ErrorCode)) + 4;
  178. }
  179. fprintf(stderr, "%s (0) : error RC2135 : ", BMofFileName);
  180. if ( (Index < 0) || (Index > (ERROR_WMIMOF_COUNT+4)))
  181. {
  182. ErrorText = MessageText[3];
  183. fprintf(stderr, ErrorText, ErrorCode);
  184. } else {
  185. ErrorText = MessageText[Index];
  186. va_start(pArg, ErrorCode);
  187. _vsnprintf(Buffer, sizeof(Buffer), ErrorText, pArg);
  188. Buffer[1023] = 0;
  189. fprintf(stderr, Buffer);
  190. fprintf(stderr, "\n");
  191. }
  192. if (ExitProgram)
  193. {
  194. ExitProcess(ErrorCode);
  195. }
  196. }
  197. typedef struct
  198. {
  199. DWORD Signature;
  200. DWORD CompressionType;
  201. DWORD CompressedSize;
  202. DWORD UncompressedSize;
  203. BYTE Buffer[];
  204. } COMPRESSEDHEADER, *PCOMPRESSEDHEADER;
  205. ULONG WmipDecompressBuffer(
  206. IN PVOID CompressedBuffer,
  207. OUT PVOID *UncompressedBuffer,
  208. OUT ULONG *UncompressedSize
  209. )
  210. /*++
  211. Routine Description:
  212. This routine will decompress a compressed MOF blob into a buffer
  213. that can be used to interpert the blob.
  214. Arguments:
  215. CompressedBuffer points at the compressed MOF blob
  216. *UncompressedBuffer returns with a pointer to the uncompressed
  217. MOF blob
  218. Return Value:
  219. ERROR_SUCCESS or an error code
  220. --*/
  221. {
  222. PCOMPRESSEDHEADER CompressedHeader = (PCOMPRESSEDHEADER)CompressedBuffer;
  223. BYTE *Buffer;
  224. ULONG Status;
  225. if ((CompressedHeader->Signature != BMOF_SIG) ||
  226. (CompressedHeader->CompressionType != 1))
  227. {
  228. WmipDebugPrint(("WMI: Invalid compressed mof header\n"));
  229. Status = ERROR_WMI_INVALID_MOF;
  230. } else {
  231. Buffer = WmipAlloc(CompressedHeader->UncompressedSize);
  232. if (Buffer == NULL)
  233. {
  234. Status = ERROR_NOT_ENOUGH_MEMORY;
  235. } else {
  236. *UncompressedSize = Mrci1Decompress(&CompressedHeader->Buffer[0],
  237. CompressedHeader->CompressedSize,
  238. Buffer,
  239. CompressedHeader->UncompressedSize);
  240. if (*UncompressedSize != CompressedHeader->UncompressedSize)
  241. {
  242. WmipDebugPrint(("WMI: Invalid compressed mof buffer\n"));
  243. WmipFree(Buffer);
  244. Status = ERROR_WMI_INVALID_MOF;
  245. } else {
  246. *UncompressedBuffer = Buffer;
  247. Status = ERROR_SUCCESS;
  248. }
  249. }
  250. }
  251. return(Status);
  252. }
  253. ULONG WmipGetDataItemIdInMofClass(
  254. PMOFCLASSINFOW MofClassInfo,
  255. PWCHAR PropertyName,
  256. ULONG *DataItemIndex
  257. )
  258. {
  259. PMOFDATAITEMW MofDataItem;
  260. ULONG i;
  261. for (i = 0; i < MofClassInfo->DataItemCount; i++)
  262. {
  263. MofDataItem = &MofClassInfo->DataItems[i];
  264. WmipAssert(MofDataItem->Name != NULL);
  265. if (_wcsicmp(PropertyName, MofDataItem->Name) == 0)
  266. {
  267. //
  268. // data item ids are 0 or 1 based depending if they are parameters
  269. // for a method or part of a data class. They match the
  270. // value in the MOF file while data item indexes within
  271. // the MofClassInfo structure are 0 based.
  272. *DataItemIndex = i;
  273. return(ERROR_SUCCESS);
  274. }
  275. }
  276. return(ERROR_WMIMOF_DATAITEM_NOT_FOUND);
  277. }
  278. PMOFCLASS WmipFindClassInMofResourceByGuid(
  279. PMOFRESOURCE MofResource,
  280. LPGUID Guid
  281. )
  282. {
  283. PLIST_ENTRY MofClassList;
  284. PMOFCLASS MofClass;
  285. MofClassList = MofResource->MRMCHead.Flink;
  286. while (MofClassList != &MofResource->MRMCHead)
  287. {
  288. MofClass = CONTAINING_RECORD(MofClassList,
  289. MOFCLASS,
  290. MCMRList);
  291. if (IsEqualGUID(&MofClass->MofClassInfo->Guid, Guid))
  292. {
  293. return(MofClass);
  294. }
  295. MofClassList = MofClassList->Flink;
  296. }
  297. return(NULL);
  298. }
  299. PMOFCLASS WmipFindClassInMofResourceByName(
  300. PMOFRESOURCE MofResource,
  301. PWCHAR ClassName
  302. )
  303. {
  304. PLIST_ENTRY MofClassList;
  305. PMOFCLASS MofClass;
  306. MofClassList = MofResource->MRMCHead.Flink;
  307. while (MofClassList != &MofResource->MRMCHead)
  308. {
  309. MofClass = CONTAINING_RECORD(MofClassList,
  310. MOFCLASS,
  311. MCMRList);
  312. if (_wcsicmp(MofClass->MofClassInfo->Name, ClassName) == 0)
  313. {
  314. return(MofClass);
  315. }
  316. MofClassList = MofClassList->Flink;
  317. }
  318. return(NULL);
  319. }
  320. ULONG WmipFillEmbeddedClasses(
  321. PMOFRESOURCE MofResource,
  322. PMOFCLASSINFOW MofClassInfo,
  323. BOOLEAN CleanupOnly
  324. )
  325. {
  326. PWCHAR ClassName;
  327. PMOFDATAITEMW MofDataItem;
  328. ULONG i;
  329. PMOFCLASS EmbeddedMofClass;
  330. ULONG Status = ERROR_SUCCESS;
  331. WCHAR *EmbeddedClassName;
  332. for (i = 0; i < MofClassInfo->DataItemCount; i++)
  333. {
  334. MofDataItem = &MofClassInfo->DataItems[i];
  335. if (MofDataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)
  336. {
  337. ClassName = (PWCHAR)MofDataItem->EcTempPtr;
  338. #if DBG
  339. printf("Look for embdedded class %ws (%x) for %ws in class %ws\n",
  340. ClassName, (ULONG_PTR)ClassName, MofDataItem->Name, MofClassInfo->Name);
  341. #endif
  342. if (! CleanupOnly)
  343. {
  344. EmbeddedClassName = ClassName+(sizeof(L"object") / sizeof(WCHAR));
  345. EmbeddedMofClass = WmipFindClassInMofResourceByName(
  346. MofResource,
  347. EmbeddedClassName);
  348. if (EmbeddedMofClass != NULL)
  349. {
  350. memcpy(&MofDataItem->EmbeddedClassGuid,
  351. &EmbeddedMofClass->MofClassInfo->Guid,
  352. sizeof(GUID));
  353. } else if (SkipEmbedClassCheck) {
  354. MofDataItem->Flags |= MOFDI_FLAG_EC_GUID_NOT_SET;
  355. } else {
  356. Status = ERROR_WMIMOF_EMBEDDED_CLASS_NOT_FOUND;
  357. ErrorMessage(TRUE,
  358. ERROR_WMIMOF_EMBEDDED_CLASS_NOT_FOUND,
  359. EmbeddedClassName,
  360. MofDataItem->Name,
  361. MofClassInfo->Name);
  362. }
  363. }
  364. // Don't free ClassName since we may use MofDataItem->EcTempPtr later
  365. }
  366. }
  367. //
  368. // Resolve guids for embedded classes in any method parameter classinfo
  369. //
  370. for (i = 0; i < MofClassInfo->MethodCount; i++)
  371. {
  372. MofDataItem = &MofClassInfo->DataItems[i+MofClassInfo->DataItemCount];
  373. WmipFillEmbeddedClasses(MofResource,
  374. MofDataItem->MethodClassInfo,
  375. CleanupOnly);
  376. }
  377. return(Status);
  378. }
  379. void WmipFreeMofClassInfo(
  380. PMOFCLASSINFOW MofClassInfo
  381. )
  382. /*++
  383. Routine Description:
  384. This routine frees any memory allocated for the MofClassInfo and then
  385. the MofClassInfo itself
  386. Arguments:
  387. MofClassInfo is a pointer to a MofClassInfo structure
  388. Return Value:
  389. --*/
  390. {
  391. ULONG i;
  392. PMOFDATAITEMW MofDataItem;
  393. WmipAssert(MofClassInfo != NULL);
  394. if (MofClassInfo != NULL)
  395. {
  396. if (MofClassInfo->Name != NULL)
  397. {
  398. WmipFree(MofClassInfo->Name);
  399. }
  400. if (MofClassInfo->Description != NULL)
  401. {
  402. WmipFree(MofClassInfo->Description);
  403. }
  404. for (i = 0; i < MofClassInfo->DataItemCount + MofClassInfo->MethodCount; i++)
  405. {
  406. MofDataItem = &MofClassInfo->DataItems[i];
  407. if (MofDataItem->Name != NULL)
  408. {
  409. WmipFree(MofDataItem->Name);
  410. }
  411. if (MofDataItem->Description != NULL)
  412. {
  413. WmipFree(MofDataItem->Description);
  414. }
  415. }
  416. }
  417. }
  418. ULONG WmipFindProperty(
  419. CBMOFObj * ClassObject,
  420. WCHAR * PropertyName,
  421. CBMOFDataItem *MofPropertyData,
  422. DWORD *ValueType,
  423. PVOID ValueBuffer
  424. )
  425. /*++
  426. Routine Description:
  427. This routine will find a named property within a class object
  428. Arguments:
  429. ClassObject is the class object in which to search
  430. PropertyName is the name of the property to search for
  431. MofPropertyData returns with the property data
  432. *ValueType on entry has the property data type being searched for. On exit
  433. it has the actual qualifier type for the qualifier value. If on entry
  434. *ValueType is 0xffffffff then any data type is acceptable
  435. ValueBuffer points to a buffer that returns the value of the
  436. property. If the property is a simple type (int or int64) then
  437. the value is returned in the buffer. If qualifier value is a string
  438. then a pointer to the string is returned in the buffer
  439. Return Value:
  440. ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
  441. --*/
  442. {
  443. ULONG Status;
  444. LONG i;
  445. if (FindProp(ClassObject, PropertyName, MofPropertyData))
  446. {
  447. if ((*ValueType != 0xffffffff) &&
  448. (MofPropertyData->m_dwType != *ValueType))
  449. {
  450. Status = ERROR_WMIMOF_INCORRECT_DATA_TYPE;
  451. }
  452. i = 0;
  453. if (GetData(MofPropertyData, (BYTE *)ValueBuffer, &i) == 0)
  454. {
  455. Status = ERROR_WMIMOF_NO_DATA;
  456. } else {
  457. *ValueType = MofPropertyData->m_dwType;
  458. Status = ERROR_SUCCESS;
  459. }
  460. } else {
  461. Status = ERROR_WMIMOF_NOT_FOUND;
  462. }
  463. return(Status);
  464. }
  465. ULONG WmipFindMofQualifier(
  466. CBMOFQualList *QualifierList,
  467. LPCWSTR QualifierName,
  468. DWORD *QualifierType,
  469. DWORD *NumberElements,
  470. PVOID QualifierValueBuffer
  471. )
  472. /*++
  473. Routine Description:
  474. This routine will find a MOF qualifier within the qualifier list passed,
  475. ensure that its type matches the type requested and return the qualifier's
  476. value
  477. Arguments:
  478. QualifierList is the MOF qualifier list
  479. QualifierName is the name of the qualifier to search for
  480. *QualifierType on entry has the qualifier type being searched for. On exit
  481. it has the actual qualifier type for the qualifier value. If on entry
  482. *QualifierType is 0xffffffff then any qualifier type is acceptable
  483. *NumberElements returns the number of elements in the array if the result
  484. of the qualifier is an array
  485. QualifierValueBuffer points to a buffer that returns the value of the
  486. qualifier. If the qualifier is a simple type (int or int64) then
  487. the value is returned in the buffer. If qualifier value is a string
  488. then a pointer to the string is returned in the buffer
  489. Return Value:
  490. ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
  491. --*/
  492. {
  493. CBMOFDataItem MofDataItem;
  494. ULONG Status;
  495. PUCHAR List, ListPtr;
  496. ULONG BaseTypeSize;
  497. ULONG ElementCount;
  498. ULONG i;
  499. if (FindQual(QualifierList, (PWCHAR)QualifierName, &MofDataItem))
  500. {
  501. if ((*QualifierType != 0xffffffff) &&
  502. (MofDataItem.m_dwType != *QualifierType))
  503. {
  504. Status = ERROR_WMIMOF_INCORRECT_DATA_TYPE;
  505. }
  506. if (MofDataItem.m_dwType & VT_ARRAY)
  507. {
  508. if (MofDataItem.m_dwType == (VT_BSTR | VT_ARRAY))
  509. {
  510. BaseTypeSize = sizeof(PWCHAR);
  511. } else {
  512. BaseTypeSize = iTypeSize(MofDataItem.m_dwType);
  513. }
  514. ElementCount = GetNumElements(&MofDataItem, 0);
  515. if (NumberElements != NULL)
  516. {
  517. *NumberElements = ElementCount;
  518. }
  519. if (ElementCount != -1)
  520. {
  521. List = WmipAlloc(ElementCount * BaseTypeSize);
  522. if (List != NULL)
  523. {
  524. ListPtr = List;
  525. for (i = 0; i < ElementCount; i++)
  526. {
  527. if ((GetData(&MofDataItem,
  528. (BYTE *)ListPtr,
  529. &i)) == 0)
  530. {
  531. WmipFree(List);
  532. Status = ERROR_WMIMOF_NO_DATA;
  533. return(Status);
  534. }
  535. ListPtr += BaseTypeSize;
  536. }
  537. Status = ERROR_SUCCESS;
  538. *QualifierType = MofDataItem.m_dwType;
  539. *((PVOID *)QualifierValueBuffer) = List;
  540. } else {
  541. Status = ERROR_NOT_ENOUGH_MEMORY;
  542. }
  543. } else {
  544. Status = ERROR_WMIMOF_NOT_FOUND;
  545. }
  546. } else {
  547. if (GetData(&MofDataItem, (BYTE *)QualifierValueBuffer, 0) == 0)
  548. {
  549. Status = ERROR_WMIMOF_NO_DATA;
  550. } else {
  551. *QualifierType = MofDataItem.m_dwType;
  552. Status = ERROR_SUCCESS;
  553. }
  554. }
  555. } else {
  556. Status = ERROR_WMIMOF_NOT_FOUND;
  557. }
  558. return(Status);
  559. }
  560. MOFDATATYPE VTToMofDataTypeMap[] =
  561. {
  562. MOFUnknown, /* VT_EMPTY= 0, */
  563. MOFUnknown, /* VT_NULL = 1, */
  564. MOFInt16, /* VT_I2 = 2, */
  565. MOFInt32, /* VT_I4 = 3, */
  566. MOFUnknown, /* VT_R4 = 4, */
  567. MOFUnknown, /* VT_R8 = 5, */
  568. MOFUnknown, /* VT_CY = 6, */
  569. MOFUnknown, /* VT_DATE = 7, */
  570. MOFString, /* VT_BSTR = 8, */
  571. MOFUnknown, /* VT_DISPATCH = 9, */
  572. MOFUnknown, /* VT_ERROR = 10, */
  573. MOFBoolean, /* VT_BOOL = 11, */
  574. MOFUnknown, /* VT_VARIANT = 12, */
  575. MOFUnknown, /* VT_UNKNOWN = 13, */
  576. MOFUnknown, /* VT_DECIMAL = 14, */
  577. MOFChar, /* VT_I1 = 16, */
  578. MOFByte, /* VT_UI1 = 17, */
  579. MOFUInt16, /* VT_UI2 = 18, */
  580. MOFUInt32, /* VT_UI4 = 19, */
  581. MOFInt64, /* VT_I8 = 20, */
  582. MOFUInt64, /* VT_UI8 = 21, */
  583. };
  584. MOFDATATYPE WmipVTToMofDataType(
  585. DWORD VariantType
  586. )
  587. {
  588. MOFDATATYPE MofDataType;
  589. if (VariantType < (sizeof(VTToMofDataTypeMap) / sizeof(MOFDATATYPE)))
  590. {
  591. MofDataType = VTToMofDataTypeMap[VariantType];
  592. } else {
  593. MofDataType = MOFUnknown;
  594. }
  595. return(MofDataType);
  596. }
  597. ULONG WmipGetClassDataItemCount(
  598. CBMOFObj * ClassObject,
  599. PWCHAR QualifierToFind
  600. )
  601. /*++
  602. Routine Description:
  603. This routine will count the number of WMI data items in the class and
  604. the total number of properties in the class.
  605. Arguments:
  606. ClassObject is class for which we count the number of data items
  607. *TotalCount returns the total number of properties
  608. Return Value:
  609. Count of methods
  610. --*/
  611. {
  612. CBMOFQualList *PropQualifierList;
  613. CBMOFDataItem MofPropertyData;
  614. DWORD QualifierType;
  615. ULONG Counter = 0;
  616. WCHAR *PropertyName;
  617. ULONG Status;
  618. ULONG Index;
  619. ResetObj(ClassObject);
  620. while ((NextProp(ClassObject, &PropertyName, &MofPropertyData)) &&
  621. PropertyName != NULL)
  622. {
  623. PropQualifierList = GetPropQualList(ClassObject, PropertyName);
  624. if (PropQualifierList != NULL)
  625. {
  626. //
  627. // Get the id of the property so we know it order in class
  628. QualifierType = VT_I4;
  629. Status = WmipFindMofQualifier(PropQualifierList,
  630. QualifierToFind,
  631. &QualifierType,
  632. NULL,
  633. (PVOID)&Index);
  634. if (Status == ERROR_SUCCESS)
  635. {
  636. Counter++;
  637. }
  638. BMOFFree(PropQualifierList);
  639. }
  640. BMOFFree(PropertyName);
  641. }
  642. return(Counter);
  643. }
  644. ULONG WmipGetClassMethodCount(
  645. CBMOFObj * ClassObject
  646. )
  647. /*++
  648. Routine Description:
  649. This routine will count the number of WMI data items in the class
  650. Arguments:
  651. ClassObject is class for which we count the number of data items
  652. Return Value:
  653. Count of methods
  654. --*/
  655. {
  656. ULONG MethodCount;
  657. WCHAR *MethodName;
  658. CBMOFDataItem MofMethodData;
  659. ResetObj(ClassObject);
  660. MethodCount = 0;
  661. while(NextMeth(ClassObject, &MethodName, &MofMethodData))
  662. {
  663. MethodCount++;
  664. if (MethodName != NULL)
  665. {
  666. BMOFFree(MethodName);
  667. }
  668. }
  669. return(MethodCount);
  670. }
  671. ULONG WmipParsePropertyObject(
  672. OUT PMOFDATAITEMW MofDataItem,
  673. IN CBMOFDataItem *MofPropertyData,
  674. IN CBMOFQualList *PropQualifierList
  675. )
  676. /*++
  677. Routine Description:
  678. This routine will parse a BMOF object that is known to be an object that
  679. contains a property and fill int the MofDataItem that holds its
  680. information. If the routine detects an error then parsing will stop as
  681. the whole class will need to be rejected.
  682. No error messages are generated from this routine. The return error
  683. code is checked and an appropriate message generated.
  684. Arguments:
  685. MofDataItem is the mof data item information structure to fill in
  686. MofPropertyData has the property information for the data item
  687. PropQualifierList has the qualifier list for the property
  688. Return Value:
  689. ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
  690. --*/
  691. {
  692. short BooleanValue;
  693. DWORD QualifierType;
  694. ULONG Status;
  695. WCHAR *StringPtr;
  696. ULONG FixedArraySize;
  697. DWORD VTDataType;
  698. DWORD VersionValue;
  699. BOOLEAN FreeString = TRUE;
  700. PMOFCLASSINFOW MethodClassInfo;
  701. ULONG MaxLen;
  702. //
  703. // Keep track of property and property qualifier objects
  704. MofDataItem->PropertyQualifierHandle = (ULONG_PTR)PropQualifierList;
  705. //
  706. // Get the description string which is not required
  707. QualifierType = VT_BSTR;
  708. Status = WmipFindMofQualifier(PropQualifierList,
  709. L"description",
  710. &QualifierType,
  711. NULL,
  712. (PVOID)&MofDataItem->Description);
  713. //
  714. // Get the version value which is not required
  715. QualifierType = VT_I4;
  716. Status = WmipFindMofQualifier(PropQualifierList,
  717. L"WmiVersion",
  718. &QualifierType,
  719. NULL,
  720. (PVOID)&VersionValue);
  721. if (Status == ERROR_SUCCESS)
  722. {
  723. MofDataItem->Version = VersionValue;
  724. }
  725. //
  726. // Get read qualifier which is not required
  727. QualifierType = VT_BOOL;
  728. Status = WmipFindMofQualifier(PropQualifierList,
  729. L"read",
  730. &QualifierType,
  731. NULL,
  732. (PVOID)&BooleanValue);
  733. if ((Status == ERROR_SUCCESS) && BooleanValue)
  734. {
  735. MofDataItem->Flags |= MOFDI_FLAG_READABLE;
  736. }
  737. //
  738. // Get write qualifier which is not required
  739. QualifierType = VT_BOOL;
  740. Status = WmipFindMofQualifier(PropQualifierList,
  741. L"write",
  742. &QualifierType,
  743. NULL,
  744. (PVOID)&BooleanValue);
  745. if ((Status == ERROR_SUCCESS) && BooleanValue)
  746. {
  747. MofDataItem->Flags |= MOFDI_FLAG_WRITEABLE;
  748. }
  749. //
  750. // Get WmiEvent qualifier which is not required
  751. QualifierType = VT_BOOL;
  752. Status = WmipFindMofQualifier(PropQualifierList,
  753. L"WmiEvent",
  754. &QualifierType,
  755. NULL,
  756. (PVOID)&BooleanValue);
  757. if ((Status == ERROR_SUCCESS) && BooleanValue)
  758. {
  759. MofDataItem->Flags |= MOFDI_FLAG_EVENT;
  760. }
  761. //
  762. // See if this is a fixed length array
  763. QualifierType = VT_I4;
  764. Status = WmipFindMofQualifier(PropQualifierList,
  765. L"max",
  766. &QualifierType,
  767. NULL,
  768. (PVOID)&FixedArraySize);
  769. if (Status == ERROR_SUCCESS)
  770. {
  771. MofDataItem->Flags |= MOFDI_FLAG_FIXED_ARRAY;
  772. MofDataItem->FixedArrayElements = FixedArraySize;
  773. #if DBG
  774. printf(" Fixed Array");
  775. #endif
  776. }
  777. //
  778. // See if this is a fixed length array
  779. QualifierType = VT_I4;
  780. Status = WmipFindMofQualifier(PropQualifierList,
  781. L"MaxLen",
  782. &QualifierType,
  783. NULL,
  784. (PVOID)&MaxLen);
  785. if (Status == ERROR_SUCCESS)
  786. {
  787. MofDataItem->MaxLen = MaxLen;
  788. }
  789. //
  790. // See if maxmium length
  791. QualifierType = VT_BSTR;
  792. Status = WmipFindMofQualifier(PropQualifierList,
  793. L"WmiSizeIs",
  794. &QualifierType,
  795. NULL,
  796. (PVOID)&StringPtr);
  797. if (Status == ERROR_SUCCESS)
  798. {
  799. if (MofDataItem->Flags & MOFDI_FLAG_FIXED_ARRAY)
  800. {
  801. BMOFFree(StringPtr);
  802. return(ERROR_WMIMOF_BOTH_FIXED_AND_VARIABLE_ARRAY);
  803. }
  804. MofDataItem->Flags |= MOFDI_FLAG_VARIABLE_ARRAY;
  805. //
  806. // When all properties are parsed we will come back and compute the
  807. // data item id for the data item that holds the number of elements
  808. // in the array. For now we'll hang onto the string pointer
  809. MofDataItem->VarArrayTempPtr = StringPtr;
  810. #if DBG
  811. printf(" Variable Array of %ws", StringPtr);
  812. #endif
  813. }
  814. if ((MofPropertyData->m_dwType & VT_ARRAY) &&
  815. ((MofDataItem->Flags & (MOFDI_FLAG_VARIABLE_ARRAY | MOFDI_FLAG_FIXED_ARRAY)) == 0))
  816. {
  817. return(ERROR_WMIMOF_MUST_DIM_ARRAY);
  818. }
  819. //
  820. // Now figure out the data type and size of the data item
  821. VTDataType = MofPropertyData->m_dwType & ~(VT_ARRAY | VT_BYREF);
  822. QualifierType = VT_BSTR;
  823. Status = WmipFindMofQualifier(PropQualifierList,
  824. L"CIMTYPE",
  825. &QualifierType,
  826. NULL,
  827. (PVOID)&StringPtr);
  828. if (VTDataType == VT_DISPATCH)
  829. {
  830. //
  831. // This is an embedded class
  832. MofDataItem->DataType = MOFEmbedded;
  833. if (Status == ERROR_SUCCESS)
  834. {
  835. //
  836. // We will resolve the class name to its guid later so we
  837. // just hang onto the embedded class name here.
  838. MofDataItem->EcTempPtr = StringPtr;
  839. MofDataItem->Flags |= MOFDI_FLAG_EMBEDDED_CLASS;
  840. #if DBG
  841. printf(" Embedded Class of %ws (%x)", StringPtr, (ULONG_PTR)StringPtr);
  842. #endif
  843. } else {
  844. return(ERROR_WMIMOF_NO_EMBEDDED_CLASS_NAME);
  845. }
  846. } else {
  847. if (Status == ERROR_SUCCESS)
  848. {
  849. if (_wcsnicmp(StringPtr, L"object:", 7) == 0) {
  850. MofDataItem->DataType = MOFEmbedded;
  851. MofDataItem->EcTempPtr = StringPtr;
  852. MofDataItem->Flags |= MOFDI_FLAG_EMBEDDED_CLASS;
  853. FreeString = FALSE;
  854. #if DBG
  855. printf(" Embedded Class of %ws (%x)", StringPtr, (ULONG_PTR)StringPtr);
  856. #endif
  857. } else if (_wcsicmp(StringPtr, L"string") == 0) {
  858. MofDataItem->DataType = MOFString;
  859. } else if (_wcsicmp(StringPtr, L"sint32") == 0) {
  860. MofDataItem->DataType = MOFInt32;
  861. MofDataItem->SizeInBytes = 4;
  862. } else if (_wcsicmp(StringPtr, L"uint32") == 0) {
  863. MofDataItem->DataType = MOFUInt32;
  864. MofDataItem->SizeInBytes = 4;
  865. } else if (_wcsicmp(StringPtr, L"boolean") == 0) {
  866. MofDataItem->DataType = MOFBoolean;
  867. MofDataItem->SizeInBytes = 1;
  868. } else if (_wcsicmp(StringPtr, L"sint64") == 0) {
  869. MofDataItem->DataType = MOFInt64;
  870. MofDataItem->SizeInBytes = 8;
  871. } else if (_wcsicmp(StringPtr, L"uint64") == 0) {
  872. MofDataItem->DataType = MOFUInt64;
  873. MofDataItem->SizeInBytes = 8;
  874. } else if ((_wcsicmp(StringPtr, L"sint16") == 0) ||
  875. (_wcsicmp(StringPtr, L"char16") == 0)) {
  876. MofDataItem->DataType = MOFInt16;
  877. MofDataItem->SizeInBytes = 2;
  878. } else if (_wcsicmp(StringPtr, L"uint16") == 0) {
  879. MofDataItem->DataType = MOFUInt16;
  880. MofDataItem->SizeInBytes = 2;
  881. } else if (_wcsicmp(StringPtr, L"sint8") == 0) {
  882. MofDataItem->DataType = MOFChar;
  883. MofDataItem->SizeInBytes = 1;
  884. } else if (_wcsicmp(StringPtr, L"uint8") == 0) {
  885. MofDataItem->DataType = MOFByte;
  886. MofDataItem->SizeInBytes = 1;
  887. } else if (_wcsicmp(StringPtr, L"datetime") == 0) {
  888. MofDataItem->DataType = MOFDate;
  889. MofDataItem->SizeInBytes = 25;
  890. } else {
  891. WmipDebugPrint(("WMI: Unknown data item syntax %ws\n",
  892. StringPtr));
  893. BMOFFree(StringPtr);
  894. return(ERROR_WMIMOF_UNKNOWN_DATA_TYPE);
  895. }
  896. if (FreeString)
  897. {
  898. BMOFFree(StringPtr);
  899. }
  900. //
  901. // If fixed array then multiply number elements by element size
  902. if ((MofDataItem->SizeInBytes != 0) &&
  903. (MofDataItem->Flags & MOFDI_FLAG_FIXED_ARRAY))
  904. {
  905. MofDataItem->SizeInBytes *= MofDataItem->FixedArrayElements;
  906. }
  907. } else {
  908. WmipDebugPrint(("WMI: No Syntax qualifier for %ws\n",
  909. MofDataItem->Name));
  910. return(ERROR_WMIMOF_NO_SYNTAX_QUALIFIER);
  911. }
  912. }
  913. return(ERROR_SUCCESS);
  914. }
  915. ULONG WmipParseMethodObject(
  916. CBMOFDataItem *MofMethodData,
  917. CBMOFQualList *PropQualifierList,
  918. PULONG MethodId
  919. )
  920. {
  921. ULONG UlongValue;
  922. ULONG Status;
  923. DWORD QualifierType;
  924. short BooleanValue;
  925. QualifierType = VT_BOOL;
  926. Status = WmipFindMofQualifier(PropQualifierList,
  927. L"Implemented",
  928. &QualifierType,
  929. NULL,
  930. (PVOID)&BooleanValue);
  931. if ((Status != ERROR_SUCCESS) || (! BooleanValue))
  932. {
  933. return(ERROR_WMIMOF_IMPLEMENTED_REQUIRED);
  934. }
  935. QualifierType = VT_I4;
  936. Status = WmipFindMofQualifier(PropQualifierList,
  937. L"WmiMethodId",
  938. &QualifierType,
  939. NULL,
  940. (PVOID)&UlongValue);
  941. if (Status != ERROR_SUCCESS)
  942. {
  943. return(ERROR_WMIMOF_IMPLEMENTED_REQUIRED);
  944. }
  945. if (UlongValue == 0)
  946. {
  947. return(ERROR_WMIMOF_METHODID_ZERO);
  948. }
  949. *MethodId = UlongValue;
  950. return(ERROR_SUCCESS);
  951. }
  952. ULONG WmipResolveVLArray(
  953. IN PMOFCLASSINFOW MofClassInfo,
  954. IN OUT PMOFDATAITEMW MofDataItem,
  955. IN ULONG FinalStatus
  956. )
  957. /*++
  958. Routine Description:
  959. This routine will resolve the array index for a variable length array
  960. Arguments:
  961. MofCLassInfo is the class info for the class
  962. MofDataItem is the mof data item that is a variable length array and
  963. whole index needs to be resolved.
  964. FinalStatus is the status of the mof parsing previously done for the
  965. class
  966. Return Value:
  967. ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
  968. --*/
  969. {
  970. MOFDATATYPE ArraySizeDataType;
  971. PWCHAR PropertyName;
  972. ULONG Status;
  973. ULONG Index;
  974. PropertyName = (PWCHAR)MofDataItem->VarArrayTempPtr;
  975. if (FinalStatus == ERROR_SUCCESS)
  976. {
  977. //
  978. // Only resolve this in the case where the class parsing
  979. // has not failed. We kept the name of the property containing the
  980. // number of elements in the array handy, so we need to
  981. // resolve it to its data item id and free the name.
  982. //
  983. Status = WmipGetDataItemIdInMofClass(MofClassInfo,
  984. PropertyName,
  985. &Index);
  986. if (Status != ERROR_SUCCESS)
  987. {
  988. FinalStatus = Status;
  989. } else {
  990. if ((MofClassInfo->Flags & MOFCI_FLAG_METHOD_PARAMS) ==
  991. MOFCI_FLAG_METHOD_PARAMS)
  992. {
  993. MofDataItem->VariableArraySizeId = Index;
  994. } else {
  995. MofDataItem->VariableArraySizeId = Index + 1;
  996. }
  997. ArraySizeDataType = MofClassInfo->DataItems[Index].DataType;
  998. if ((ArraySizeDataType != MOFInt32) &&
  999. (ArraySizeDataType != MOFUInt32) &&
  1000. (ArraySizeDataType != MOFInt64) &&
  1001. (ArraySizeDataType != MOFUInt64) &&
  1002. (ArraySizeDataType != MOFInt16) &&
  1003. (ArraySizeDataType != MOFUInt16))
  1004. {
  1005. FinalStatus = ERROR_WMIMOF_BAD_VL_ARRAY_SIZE_TYPE;
  1006. }
  1007. }
  1008. }
  1009. BMOFFree(PropertyName);
  1010. PropertyName = NULL;
  1011. return(FinalStatus);
  1012. }
  1013. ULONG WmipParseMethodInOutObject(
  1014. CBMOFObj *ClassObject,
  1015. PMOFCLASSINFOW ClassInfo,
  1016. ULONG DataItemCount
  1017. )
  1018. /*++
  1019. Routine Description:
  1020. This routine will parse a class object that is either the in or out
  1021. parameters for a method.
  1022. Arguments:
  1023. ClassObject is the in or out parameter class object to parse
  1024. ClassInfo returns updated with information from ClassObject
  1025. DataItemCount is the number of data items in the ClassInfo
  1026. Return Value:
  1027. ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
  1028. --*/
  1029. {
  1030. ULONG Status = ERROR_WMIMOF_NO_DATA;
  1031. CBMOFDataItem MofPropertyData;
  1032. PWCHAR PropertyName = NULL;
  1033. ULONG Index;
  1034. PMOFDATAITEMW MofDataItem;
  1035. CBMOFQualList *PropQualifierList = NULL;
  1036. DWORD QualifierType;
  1037. short BooleanValue;
  1038. ResetObj(ClassObject);
  1039. ClassInfo->ClassQualifierHandle = (ULONG_PTR)GetQualList(ClassObject);
  1040. while (NextProp(ClassObject, &PropertyName, &MofPropertyData))
  1041. {
  1042. PropQualifierList = GetPropQualList(ClassObject, PropertyName);
  1043. if (PropQualifierList != NULL)
  1044. {
  1045. //
  1046. // Get the id of the property so we know its order in class
  1047. //
  1048. QualifierType = VT_I4;
  1049. Status = WmipFindMofQualifier(PropQualifierList,
  1050. L"Id",
  1051. &QualifierType,
  1052. NULL,
  1053. (PVOID)&Index);
  1054. if (Status == ERROR_SUCCESS)
  1055. {
  1056. //
  1057. // Method ids are 0 based
  1058. //
  1059. if (Index < DataItemCount)
  1060. {
  1061. //
  1062. // Valid data item id, make sure it already isn't
  1063. // in use. Note that we could have the same property
  1064. // be in both the in and the out class objects
  1065. //
  1066. MofDataItem = &ClassInfo->DataItems[Index];
  1067. //
  1068. // See if this is an input, output or both
  1069. //
  1070. QualifierType = VT_BOOL;
  1071. Status = WmipFindMofQualifier(PropQualifierList,
  1072. L"in",
  1073. &QualifierType,
  1074. NULL,
  1075. (PVOID)&BooleanValue);
  1076. if ((Status == ERROR_SUCCESS) && BooleanValue)
  1077. {
  1078. MofDataItem->Flags |= MOFDI_FLAG_INPUT_METHOD;
  1079. }
  1080. QualifierType = VT_BOOL;
  1081. Status = WmipFindMofQualifier(PropQualifierList,
  1082. L"out",
  1083. &QualifierType,
  1084. NULL,
  1085. (PVOID)&BooleanValue);
  1086. if ((Status == ERROR_SUCCESS) && BooleanValue)
  1087. {
  1088. MofDataItem->Flags |= MOFDI_FLAG_OUTPUT_METHOD;
  1089. }
  1090. if ((MofDataItem->Name != NULL) &&
  1091. (wcscmp(MofDataItem->Name, PropertyName) != 0))
  1092. {
  1093. //
  1094. // id already in use
  1095. //
  1096. Status = ERROR_WMIMOF_DUPLICATE_ID;
  1097. goto done;
  1098. }
  1099. if (MofDataItem->Name == NULL)
  1100. {
  1101. MofDataItem->Name = PropertyName;
  1102. } else {
  1103. BMOFFree(PropertyName);
  1104. }
  1105. PropertyName = NULL;
  1106. Status = WmipParsePropertyObject(
  1107. MofDataItem,
  1108. &MofPropertyData,
  1109. PropQualifierList);
  1110. if (Status != ERROR_SUCCESS)
  1111. {
  1112. if (Status == ERROR_WMIMOF_MUST_DIM_ARRAY)
  1113. {
  1114. ErrorMessage(TRUE,
  1115. ERROR_WMIMOF_MUST_DIM_ARRAY,
  1116. MofDataItem->Name,
  1117. L"<Method>");
  1118. }
  1119. goto done;
  1120. }
  1121. } else {
  1122. //
  1123. // Method ID qualifier is out of range
  1124. //
  1125. Status = ERROR_WMIMOF_BAD_DATAITEM_ID;
  1126. ErrorMessage(TRUE,
  1127. ERROR_WMIMOF_BAD_DATAITEM_ID,
  1128. MofDataItem->Name,
  1129. L"<Method>",
  1130. Index+1);
  1131. goto done;
  1132. }
  1133. } else {
  1134. //
  1135. // property is supposed to have a method id !!
  1136. //
  1137. Status = ERROR_WMIMOF_METHOD_RETURN_NOT_VOID;
  1138. goto done;
  1139. }
  1140. }
  1141. }
  1142. done:
  1143. if (PropertyName != NULL)
  1144. {
  1145. BMOFFree(PropertyName);
  1146. PropertyName = NULL;
  1147. }
  1148. if (PropQualifierList != NULL)
  1149. {
  1150. BMOFFree(PropQualifierList);
  1151. }
  1152. return(Status);
  1153. }
  1154. ULONG WmipParseMethodParameterObjects(
  1155. IN CBMOFObj *InObject,
  1156. IN CBMOFObj *OutObject,
  1157. OUT PMOFCLASSINFOW *ClassInfo
  1158. )
  1159. /*++
  1160. Routine Description:
  1161. This routine will parse the in and out method parameter obejcts to create
  1162. a MOFCLASSINFO that describes the method call.
  1163. Arguments:
  1164. InObject is the object with the input parameters
  1165. OutObject is the object with the output parameters
  1166. *ClassInfo returns with the class info for the method call
  1167. Return Value:
  1168. ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
  1169. --*/
  1170. {
  1171. PMOFCLASSINFOW MofClassInfo;
  1172. ULONG Status, FinalStatus;
  1173. DWORD QualifierType;
  1174. ULONG DataItemCount;
  1175. ULONG MofClassInfoSize;
  1176. WCHAR *StringPtr;
  1177. ULONG i, Index;
  1178. ULONG InItemCount, OutItemCount;
  1179. ULONG Size;
  1180. PMOFDATAITEMW MofDataItem;
  1181. ULONG Count;
  1182. FinalStatus = ERROR_SUCCESS;
  1183. if (InObject != NULL)
  1184. {
  1185. ResetObj(InObject);
  1186. InItemCount = WmipGetClassDataItemCount(InObject, L"Id");
  1187. } else {
  1188. InItemCount = 0;
  1189. }
  1190. if (OutObject != NULL)
  1191. {
  1192. ResetObj(OutObject);
  1193. OutItemCount = WmipGetClassDataItemCount(OutObject, L"Id");
  1194. } else {
  1195. OutItemCount = 0;
  1196. }
  1197. DataItemCount = InItemCount + OutItemCount;
  1198. Size = sizeof(MOFCLASSINFOW) + DataItemCount * sizeof(MOFDATAITEMW);
  1199. MofClassInfo = WmipAlloc(Size);
  1200. if (MofClassInfo == NULL)
  1201. {
  1202. return(ERROR_NOT_ENOUGH_MEMORY);
  1203. }
  1204. //
  1205. // Get the essential information to fill in the MOF class info
  1206. memset(MofClassInfo, 0, Size);
  1207. MofClassInfo->Flags |= MOFCI_FLAG_METHOD_PARAMS;
  1208. MofClassInfo->DataItems = (PMOFDATAITEMW) ((PUCHAR)MofClassInfo +
  1209. sizeof(MOFCLASSINFOW));
  1210. //
  1211. // number of properties/data items in class
  1212. MofClassInfo->DataItemCount = DataItemCount;
  1213. MofClassInfo->MethodCount = 0;
  1214. //
  1215. // Parse the input parameter class object
  1216. //
  1217. if (InObject != NULL)
  1218. {
  1219. Status = WmipParseMethodInOutObject(InObject,
  1220. MofClassInfo,
  1221. DataItemCount);
  1222. if (Status == ERROR_SUCCESS)
  1223. {
  1224. if (OutObject != NULL)
  1225. {
  1226. //
  1227. // Parse the output parameter class object
  1228. //
  1229. Status = WmipParseMethodInOutObject(OutObject,
  1230. MofClassInfo,
  1231. DataItemCount);
  1232. }
  1233. //
  1234. // Now do any post parsing validation and fixup any variable
  1235. // length array properties
  1236. //
  1237. FinalStatus = Status;
  1238. Count = MofClassInfo->DataItemCount;
  1239. for (Index = 0; Index < Count; Index++)
  1240. {
  1241. MofDataItem = &MofClassInfo->DataItems[Index];
  1242. if (MofDataItem->Name == NULL)
  1243. {
  1244. MofClassInfo->DataItemCount--;
  1245. }
  1246. if (MofDataItem->Flags & MOFDI_FLAG_VARIABLE_ARRAY)
  1247. {
  1248. FinalStatus = WmipResolveVLArray(MofClassInfo,
  1249. MofDataItem,
  1250. FinalStatus);
  1251. if (FinalStatus != ERROR_SUCCESS)
  1252. {
  1253. ErrorMessage(TRUE,
  1254. ERROR_WMIMOF_VL_ARRAY_NOT_FOUND,
  1255. MofDataItem->Name,
  1256. L"<Method>");
  1257. }
  1258. }
  1259. }
  1260. } else {
  1261. FinalStatus = Status;
  1262. }
  1263. }
  1264. *ClassInfo = MofClassInfo;
  1265. return(FinalStatus);
  1266. }
  1267. ULONG WmipParseMethodParameters(
  1268. CBMOFDataItem *MofMethodData,
  1269. PMOFCLASSINFOW *MethodClassInfo
  1270. )
  1271. {
  1272. ULONG Status = ERROR_SUCCESS;
  1273. CBMOFObj *InObject;
  1274. CBMOFObj *OutObject;
  1275. ULONG i;
  1276. ULONG NumberDimensions;
  1277. ULONG NumberElements;
  1278. VARIANT InVar, OutVar;
  1279. DWORD SimpleType;
  1280. SimpleType = MofMethodData->m_dwType & ~VT_ARRAY & ~VT_BYREF;
  1281. NumberDimensions = GetNumDimensions(MofMethodData);
  1282. if (NumberDimensions > 0)
  1283. {
  1284. NumberElements = GetNumElements(MofMethodData, 0);
  1285. WmipAssert(NumberDimensions == 1);
  1286. WmipAssert((NumberElements == 1) || (NumberElements == 2));
  1287. i = 0;
  1288. memset((void *)&InVar.lVal, 0, 8);
  1289. if (GetData(MofMethodData, (BYTE *)&(InVar.lVal), &i))
  1290. {
  1291. InObject = (CBMOFObj *)InVar.bstrVal;
  1292. InVar.vt = (VARTYPE)SimpleType;
  1293. WmipAssert(InVar.vt == VT_UNKNOWN);
  1294. if (NumberElements == 2)
  1295. {
  1296. i = 1;
  1297. memset((void *)&OutVar.lVal, 0, 8);
  1298. if (GetData(MofMethodData, (BYTE *)&(OutVar.lVal), &i))
  1299. {
  1300. OutVar.vt = (VARTYPE)SimpleType;
  1301. WmipAssert(OutVar.vt == VT_UNKNOWN);
  1302. OutObject = (CBMOFObj *)OutVar.bstrVal;
  1303. } else {
  1304. Status = ERROR_WMIMOF_NOT_FOUND;
  1305. }
  1306. } else {
  1307. OutObject = NULL;
  1308. }
  1309. } else {
  1310. Status = ERROR_WMIMOF_NOT_FOUND;
  1311. }
  1312. } else {
  1313. InObject = NULL;
  1314. OutObject = NULL;
  1315. }
  1316. if (Status == ERROR_SUCCESS)
  1317. {
  1318. Status = WmipParseMethodParameterObjects(InObject,
  1319. OutObject,
  1320. MethodClassInfo);
  1321. }
  1322. return(Status);
  1323. }
  1324. ULONG WmipParseClassObject(
  1325. PMOFRESOURCE MofResource,
  1326. CBMOFObj * ClassObject
  1327. )
  1328. /*++
  1329. Routine Description:
  1330. This routine will parse a BMOF object that is known to be an object that
  1331. contains a class. If we run into a parsing error then we immediate
  1332. quit parsing the class and return an error.
  1333. Arguments:
  1334. MofResource is the Mof Resource structure
  1335. ClassObject is BMOF object to parse
  1336. Return Value:
  1337. ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
  1338. --*/
  1339. {
  1340. PMOFCLASSINFOW MofClassInfo;
  1341. CBMOFQualList *ClassQualifierList = NULL;
  1342. CBMOFQualList *PropQualifierList = NULL;
  1343. CBMOFQualList *MethQualifierList = NULL;
  1344. CBMOFDataItem MofPropertyData, MofMethodData;
  1345. ULONG Status;
  1346. DWORD QualifierType;
  1347. ULONG DataItemCount;
  1348. ULONG MofClassInfoSize;
  1349. WCHAR *PropertyName = NULL;
  1350. WCHAR *MethodName = NULL;
  1351. ULONG Index;
  1352. PMOFDATAITEMW MofDataItem;
  1353. WCHAR *StringPtr;
  1354. PMOFCLASS MofClass;
  1355. ULONG FailedStatus;
  1356. ULONG Version;
  1357. short BooleanValue;
  1358. WCHAR *ClassName;
  1359. BOOLEAN DynamicQualifier, ProviderQualifier;
  1360. PULONG MethodList = 0;
  1361. ULONG MethodCount, MethodId;
  1362. ULONG i, Size;
  1363. BOOLEAN IsEvent;
  1364. PMOFCLASSINFOW MethodClassInfo;
  1365. BOOLEAN AbstractClass = FALSE;
  1366. //
  1367. // Get the class name which is required
  1368. if (! GetName(ClassObject, &ClassName))
  1369. {
  1370. WmipDebugPrint(("WMI: MofClass does not have a name\n"));
  1371. Status = ERROR_WMIMOF_NO_CLASS_NAME;
  1372. ErrorMessage(TRUE, ERROR_WMI_INVALID_MOF);
  1373. return(Status);
  1374. }
  1375. #if DBG
  1376. printf("Parsing class %ws\n", ClassName);
  1377. #endif
  1378. ResetObj(ClassObject);
  1379. ClassQualifierList = GetQualList(ClassObject);
  1380. if (ClassQualifierList == NULL)
  1381. {
  1382. WmipDebugPrint(("WMI: MofClass %ws does not have a qualifier list\n",
  1383. ClassName));
  1384. Status = ERROR_WMIMOF_NO_CLASS_NAME;
  1385. ErrorMessage(TRUE, ERROR_WMI_INVALID_MOF);
  1386. return(Status);
  1387. }
  1388. //
  1389. // Classes derived from WmiEvent may not be [abstract]
  1390. QualifierType = VT_BSTR;
  1391. Status = WmipFindProperty(ClassObject,
  1392. L"__SUPERCLASS",
  1393. &MofPropertyData,
  1394. &QualifierType,
  1395. (PVOID)&StringPtr);
  1396. if (Status == ERROR_SUCCESS)
  1397. {
  1398. IsEvent = (_wcsicmp(StringPtr, L"WmiEvent") == 0);
  1399. } else {
  1400. IsEvent = FALSE;
  1401. }
  1402. QualifierType = VT_BOOL;
  1403. Status = WmipFindMofQualifier(ClassQualifierList,
  1404. L"Abstract",
  1405. &QualifierType,
  1406. NULL,
  1407. (PVOID)&BooleanValue);
  1408. if ((Status == ERROR_SUCCESS) && BooleanValue)
  1409. {
  1410. //
  1411. // This is an abstract class - make sure it is not derived from
  1412. // WmiEvent
  1413. AbstractClass = TRUE;
  1414. QualifierType = VT_BSTR;
  1415. Status = WmipFindProperty(ClassObject,
  1416. L"__SUPERCLASS",
  1417. &MofPropertyData,
  1418. &QualifierType,
  1419. (PVOID)&StringPtr);
  1420. if (Status == ERROR_SUCCESS)
  1421. {
  1422. if (_wcsicmp(StringPtr, L"WmiEvent") == 0)
  1423. {
  1424. ErrorMessage(TRUE,
  1425. ERROR_WMIMOF_WMIEVENT_ABSTRACT,
  1426. ClassName);
  1427. return(ERROR_WMIMOF_WMIEVENT_ABSTRACT);
  1428. }
  1429. BMOFFree(StringPtr);
  1430. }
  1431. }
  1432. //
  1433. // See if this is a WMI class. Wmi classes have the [WMI] qualifier
  1434. QualifierType = VT_BOOL;
  1435. Status = WmipFindMofQualifier(ClassQualifierList,
  1436. L"WMI",
  1437. &QualifierType,
  1438. NULL,
  1439. (PVOID)&BooleanValue);
  1440. if (! ((Status == ERROR_SUCCESS) && BooleanValue))
  1441. {
  1442. //
  1443. // Skip this non-wmi class
  1444. return(ERROR_SUCCESS);
  1445. }
  1446. //
  1447. // Now check for WBEM required qualifiers
  1448. QualifierType = VT_BOOL;
  1449. Status = WmipFindMofQualifier(ClassQualifierList,
  1450. L"Dynamic",
  1451. &QualifierType,
  1452. NULL,
  1453. (PVOID)&BooleanValue);
  1454. DynamicQualifier = ((Status == ERROR_SUCCESS) && BooleanValue);
  1455. QualifierType = VT_BSTR;
  1456. Status = WmipFindMofQualifier(ClassQualifierList,
  1457. L"Provider",
  1458. &QualifierType,
  1459. NULL,
  1460. (PVOID)&StringPtr);
  1461. if (Status == ERROR_SUCCESS)
  1462. {
  1463. if (_wcsicmp(StringPtr, L"WmiProv") != 0)
  1464. {
  1465. Status = ERROR_WMIMOF_MISSING_HMOM_QUALIFIERS;
  1466. }
  1467. BMOFFree(StringPtr);
  1468. ProviderQualifier = TRUE;
  1469. } else {
  1470. ProviderQualifier = FALSE;
  1471. }
  1472. if ((ProviderQualifier && ! DynamicQualifier) ||
  1473. (! ProviderQualifier && DynamicQualifier))
  1474. {
  1475. //
  1476. // Both or neither [Dynamic, Provider(WmiProv)] qualifiers are required
  1477. ErrorMessage(TRUE,
  1478. ERROR_WMIMOF_MISSING_HMOM_QUALIFIERS,
  1479. ClassName);
  1480. return(ERROR_WMIMOF_MISSING_HMOM_QUALIFIERS);
  1481. }
  1482. MofClass = WmipAllocMofClass();
  1483. if (MofClass == NULL)
  1484. {
  1485. //
  1486. // No memory for MofClass so give up
  1487. return(ERROR_NOT_ENOUGH_MEMORY);
  1488. }
  1489. //
  1490. // Reference the MofResource so it stays around while the MofClass
  1491. // stays around
  1492. MofClass->MofResource = MofResource;
  1493. WmipReferenceMR(MofResource);
  1494. DataItemCount = WmipGetClassDataItemCount(ClassObject, L"WmiDataId");
  1495. MethodCount = WmipGetClassMethodCount(ClassObject);
  1496. ResetObj(ClassObject);
  1497. Size = sizeof(MOFCLASSINFO);
  1498. MofClassInfoSize = Size +
  1499. (DataItemCount+MethodCount) * sizeof(MOFDATAITEMW);
  1500. MofClassInfo = WmipAlloc(MofClassInfoSize);
  1501. if (MofClassInfo == NULL)
  1502. {
  1503. // WmipMCCleanup will unreference the MofResource
  1504. WmipUnreferenceMC(MofClass);
  1505. return(ERROR_NOT_ENOUGH_MEMORY);
  1506. } else {
  1507. MofClass->MofClassInfo = MofClassInfo;
  1508. MofClass->ClassObjectHandle = (ULONG_PTR)ClassObject;
  1509. //
  1510. // Get the essential information to fill in the MOF class info
  1511. memset(MofClassInfo, 0, MofClassInfoSize);
  1512. MofClass->MofClassInfo->ClassQualifierHandle = (ULONG_PTR)GetQualList(ClassObject);
  1513. WmipAssert(MofClass->MofClassInfo->ClassQualifierHandle != 0);
  1514. MofClassInfo->Flags = MOFCI_FLAG_READONLY;
  1515. MofClassInfo->Flags |= IsEvent ? MOFCI_FLAG_EVENT : 0;
  1516. MofClassInfo->Flags |= ProviderQualifier ? MOFCI_RESERVED0 : 0;
  1517. if (!ProviderQualifier && !DynamicQualifier)
  1518. {
  1519. //
  1520. // If neither the provider qualifier and Dynamic qualifier are
  1521. // specified then this is an embedded class
  1522. //
  1523. MofClassInfo->Flags |= MOFCI_FLAG_EMBEDDED_CLASS;
  1524. }
  1525. MofClassInfo->DataItems = (PMOFDATAITEMW) ((PUCHAR)MofClassInfo +
  1526. Size);
  1527. //
  1528. // number of properties/data items in class
  1529. MofClassInfo->DataItemCount = DataItemCount;
  1530. MofClassInfo->MethodCount = MethodCount;
  1531. MofClassInfo->Name = ClassName;
  1532. ClassQualifierList = GetQualList(ClassObject);
  1533. if (ClassQualifierList == NULL)
  1534. {
  1535. WmipDebugPrint(("WMI: MofClass %ws does not have a qualifier list\n",
  1536. MofClassInfo->Name));
  1537. Status = ERROR_WMIMOF_NO_CLASS_NAME;
  1538. ErrorMessage(TRUE, ERROR_WMI_INVALID_MOF);
  1539. goto done;
  1540. }
  1541. //
  1542. // Get the class guid which is required. Then convert it into
  1543. // binary form.
  1544. QualifierType = VT_BSTR;
  1545. Status = WmipFindMofQualifier(ClassQualifierList,
  1546. L"guid",
  1547. &QualifierType,
  1548. NULL,
  1549. (PVOID)&StringPtr);
  1550. if (Status == ERROR_SUCCESS)
  1551. {
  1552. Status = wGUIDFromString(StringPtr , &MofClassInfo->Guid) ?
  1553. ERROR_SUCCESS :
  1554. ERROR_WMIMOF_BAD_DATA_FORMAT;
  1555. BMOFFree((PVOID)StringPtr);
  1556. }
  1557. if (Status != ERROR_SUCCESS)
  1558. {
  1559. WmipDebugPrint(("WMI: MofClass %ws guid not found or in incorrect format\n",
  1560. MofClassInfo->Name));
  1561. ErrorMessage(TRUE,
  1562. ERROR_WMIMOF_BAD_OR_MISSING_GUID,
  1563. MofClassInfo->Name);
  1564. goto done;
  1565. }
  1566. //
  1567. // Get the description string which is not required
  1568. QualifierType = VT_BSTR;
  1569. Status = WmipFindMofQualifier(ClassQualifierList,
  1570. L"description",
  1571. &QualifierType,
  1572. NULL,
  1573. (PVOID)&MofClassInfo->Description);
  1574. //
  1575. // Get the header name string which is not required
  1576. QualifierType = VT_BSTR;
  1577. Status = WmipFindMofQualifier(ClassQualifierList,
  1578. L"HeaderName",
  1579. &QualifierType,
  1580. NULL,
  1581. (PVOID)&MofClassInfo->HeaderName);
  1582. //
  1583. // Get the header name string which is not required
  1584. QualifierType = VT_BSTR;
  1585. Status = WmipFindMofQualifier(ClassQualifierList,
  1586. L"GuidName1",
  1587. &QualifierType,
  1588. NULL,
  1589. (PVOID)&MofClassInfo->GuidName1);
  1590. //
  1591. // Get the header name string which is not required
  1592. QualifierType = VT_BSTR;
  1593. Status = WmipFindMofQualifier(ClassQualifierList,
  1594. L"GuidName2",
  1595. &QualifierType,
  1596. NULL,
  1597. (PVOID)&MofClassInfo->GuidName2);
  1598. //
  1599. // Now gather all of the information about the data items/properties
  1600. ResetObj(ClassObject);
  1601. Status = ERROR_SUCCESS;
  1602. while (NextProp(ClassObject, &PropertyName, &MofPropertyData))
  1603. {
  1604. #if DBG
  1605. printf(" %ws - ", PropertyName);
  1606. #endif
  1607. PropQualifierList = GetPropQualList(ClassObject, PropertyName);
  1608. if (PropQualifierList != NULL)
  1609. {
  1610. //
  1611. // Get the id of the property so we know its order in class
  1612. // If it doesn't have an id then we ignore it
  1613. QualifierType = VT_I4;
  1614. Status = WmipFindMofQualifier(PropQualifierList,
  1615. L"WmiDataId",
  1616. &QualifierType,
  1617. NULL,
  1618. (PVOID)&Index);
  1619. if (Status == ERROR_SUCCESS)
  1620. {
  1621. //
  1622. // Wmi Data Item ids are 1 based in the MOF
  1623. Index--;
  1624. if (Index < DataItemCount)
  1625. {
  1626. //
  1627. // Valid data item id, make sure it already isn't
  1628. // in use.
  1629. MofDataItem = &MofClassInfo->DataItems[Index];
  1630. if (MofDataItem->Name != NULL)
  1631. {
  1632. WmipDebugPrint(("WMI: Mof Class %ws has duplicate data item id %d for %ws and %ws\n",
  1633. MofClassInfo->Name, Index,
  1634. MofDataItem->Name, PropertyName));
  1635. Status = ERROR_WMIMOF_DUPLICATE_ID;
  1636. ErrorMessage(TRUE,
  1637. ERROR_WMIMOF_DUPLICATE_ID,
  1638. MofDataItem->Name,
  1639. MofClassInfo->Name,
  1640. Index+1,
  1641. PropertyName);
  1642. goto done;
  1643. }
  1644. MofDataItem->Name = PropertyName;
  1645. PropertyName = NULL;
  1646. Status = WmipParsePropertyObject(
  1647. MofDataItem,
  1648. &MofPropertyData,
  1649. PropQualifierList);
  1650. if (Status != ERROR_SUCCESS)
  1651. {
  1652. WmipDebugPrint(("WMI: MofClass %ws Property %ws not parsed properly %x\n",
  1653. MofClassInfo->Name, MofDataItem->Name, Status));
  1654. ErrorMessage(TRUE,
  1655. Status,
  1656. MofDataItem->Name,
  1657. MofClassInfo->Name);
  1658. goto done;
  1659. }
  1660. if (MofDataItem->Flags & MOFDI_FLAG_WRITEABLE)
  1661. {
  1662. MofClassInfo->Flags &= ~MOFCI_FLAG_READONLY;
  1663. }
  1664. } else {
  1665. WmipDebugPrint(("WMI: MofClass %ws has DataItem Id for %ws out of range %d\n",
  1666. MofClassInfo->Name, PropertyName, Index));
  1667. Status = ERROR_WMIMOF_BAD_DATAITEM_ID;
  1668. ErrorMessage(TRUE,
  1669. ERROR_WMIMOF_BAD_DATAITEM_ID,
  1670. PropertyName,
  1671. MofClassInfo->Name,
  1672. Index+1);
  1673. goto done;
  1674. }
  1675. } else {
  1676. //
  1677. // This property does not have a WmiDataId qualifier
  1678. // so see if it is Active or InstanceName
  1679. QualifierType = VT_BSTR;
  1680. Status = WmipFindMofQualifier(PropQualifierList,
  1681. L"CIMTYPE",
  1682. &QualifierType,
  1683. NULL,
  1684. (PVOID)&StringPtr);
  1685. if (_wcsicmp(PropertyName, L"InstanceName") == 0)
  1686. {
  1687. if ((Status != ERROR_SUCCESS) ||
  1688. (_wcsicmp(StringPtr, L"string") != 0))
  1689. {
  1690. Status = ERROR_WMIMOF_INSTANCENAME_BAD_TYPE;
  1691. ErrorMessage(TRUE,
  1692. ERROR_WMIMOF_INSTANCENAME_BAD_TYPE,
  1693. MofClassInfo->Name,
  1694. StringPtr);
  1695. BMOFFree(StringPtr);
  1696. goto done;
  1697. } else {
  1698. BMOFFree(StringPtr);
  1699. if ((! ProviderQualifier) && (! AbstractClass))
  1700. {
  1701. //
  1702. // If InstanceName specified, but this is an
  1703. // embedded class then an error
  1704. Status = ERROR_WMIMOF_EMBEDDED_CLASS;
  1705. ErrorMessage(TRUE,
  1706. ERROR_WMIMOF_EMBEDDED_CLASS,
  1707. MofClassInfo->Name);
  1708. goto done;
  1709. }
  1710. QualifierType = VT_BOOL;
  1711. Status = WmipFindMofQualifier(PropQualifierList,
  1712. L"key",
  1713. &QualifierType,
  1714. NULL,
  1715. (PVOID)&BooleanValue);
  1716. if ((Status == ERROR_SUCCESS) && BooleanValue)
  1717. {
  1718. MofClassInfo->Flags |= MOFCI_RESERVED1;
  1719. } else {
  1720. Status = ERROR_WMIMOF_INSTANCENAME_NOT_KEY;
  1721. ErrorMessage(TRUE,
  1722. ERROR_WMIMOF_INSTANCENAME_NOT_KEY,
  1723. MofClassInfo->Name);
  1724. goto done;
  1725. }
  1726. }
  1727. } else if (_wcsicmp(PropertyName, L"Active") == 0)
  1728. {
  1729. if ((Status != ERROR_SUCCESS) ||
  1730. (_wcsicmp(StringPtr, L"boolean") != 0))
  1731. {
  1732. Status = ERROR_WMIMOF_ACTIVE_BAD_TYPE;
  1733. ErrorMessage(TRUE,
  1734. ERROR_WMIMOF_ACTIVE_BAD_TYPE,
  1735. MofClassInfo->Name,
  1736. StringPtr);
  1737. BMOFFree(StringPtr);
  1738. goto done;
  1739. } else {
  1740. BMOFFree(StringPtr);
  1741. if ((! ProviderQualifier) && (! AbstractClass))
  1742. {
  1743. //
  1744. // If Boolean specified, but this is an
  1745. // embedded class then an error
  1746. Status = ERROR_WMIMOF_EMBEDDED_CLASS;
  1747. ErrorMessage(TRUE,
  1748. ERROR_WMIMOF_EMBEDDED_CLASS,
  1749. MofClassInfo->Name);
  1750. goto done;
  1751. }
  1752. MofClassInfo->Flags |= MOFCI_RESERVED2;
  1753. }
  1754. } else {
  1755. Status = ERROR_WMIMOF_NO_WMIDATAID;
  1756. ErrorMessage(TRUE,
  1757. ERROR_WMIMOF_NO_WMIDATAID,
  1758. PropertyName,
  1759. MofClassInfo->Name);
  1760. BMOFFree(StringPtr);
  1761. goto done;
  1762. }
  1763. }
  1764. // Do not free PropQualifierList since it is needed for
  1765. // generating header files
  1766. PropQualifierList= NULL;
  1767. }
  1768. #if DBG
  1769. printf("\n");
  1770. #endif
  1771. if (PropertyName != NULL)
  1772. {
  1773. BMOFFree(PropertyName);
  1774. PropertyName = NULL;
  1775. }
  1776. }
  1777. //
  1778. // Now parse the methods
  1779. #if DBG
  1780. printf("Parsing methods\n");
  1781. #endif
  1782. if (MethodCount > 0)
  1783. {
  1784. //
  1785. // Don't enable this yet as 1394wmi.mof has methods within an embedded
  1786. // class.
  1787. //
  1788. #if 0
  1789. if (! ProviderQualifier)
  1790. {
  1791. // methods don't belong in embedded classes
  1792. Status = ERROR_WMIMOF_EMBEDDED_CLASS_HAS_METHODS;
  1793. ErrorMessage(TRUE,
  1794. ERROR_WMIMOF_EMBEDDED_CLASS_HAS_METHODS,
  1795. MofClassInfo->Name);
  1796. }
  1797. #endif
  1798. MethodList = (PULONG)BMOFAlloc(MethodCount * sizeof(ULONG));
  1799. if (MethodList == NULL)
  1800. {
  1801. WmipDebugPrint(("WMI: Not enough memory for Method List\n"));
  1802. return(ERROR_NOT_ENOUGH_MEMORY);
  1803. }
  1804. }
  1805. MethodCount = 0;
  1806. ResetObj(ClassObject);
  1807. while(NextMeth(ClassObject, &MethodName, &MofMethodData))
  1808. {
  1809. #if DBG
  1810. printf(" %ws - ", MethodName);
  1811. #endif
  1812. MethQualifierList = GetMethQualList(ClassObject, MethodName);
  1813. if (MethQualifierList != NULL)
  1814. {
  1815. Status = WmipParseMethodObject(&MofMethodData,
  1816. MethQualifierList,
  1817. &MethodId);
  1818. if (Status != ERROR_SUCCESS)
  1819. {
  1820. WmipDebugPrint(("WMI: MofClass %ws Method %ws not parsed properly %x\n",
  1821. MofClassInfo->Name, MethodName, Status));
  1822. ErrorMessage(TRUE,
  1823. Status,
  1824. MethodName,
  1825. MofClassInfo->Name);
  1826. goto done;
  1827. }
  1828. for (i = 0; i < MethodCount; i++)
  1829. {
  1830. if (MethodId == MethodList[i])
  1831. {
  1832. ErrorMessage(TRUE,
  1833. ERROR_WMIMOF_DUPLICATE_METHODID,
  1834. MethodName,
  1835. MofClassInfo->Name);
  1836. goto done;
  1837. }
  1838. }
  1839. MofDataItem = &MofClassInfo->DataItems[DataItemCount+MethodCount];
  1840. MethodList[MethodCount++] = MethodId;
  1841. MofDataItem->Flags = MOFDI_FLAG_METHOD;
  1842. MofDataItem->Name = MethodName;
  1843. MofDataItem->MethodId = MethodId;
  1844. //
  1845. // Keep track of property and property qualifier objects
  1846. MofDataItem->PropertyQualifierHandle = (ULONG_PTR)MethQualifierList;
  1847. //
  1848. // Get the header name string which is not required
  1849. QualifierType = VT_BSTR;
  1850. Status = WmipFindMofQualifier(MethQualifierList,
  1851. L"HeaderName",
  1852. &QualifierType,
  1853. NULL,
  1854. (PVOID)&MofDataItem->HeaderName);
  1855. MethQualifierList = NULL;
  1856. //
  1857. // parse the parameters for the method call
  1858. //
  1859. Status = WmipParseMethodParameters(&MofMethodData,
  1860. &MethodClassInfo);
  1861. if (Status == ERROR_SUCCESS)
  1862. {
  1863. MofDataItem->MethodClassInfo = MethodClassInfo;
  1864. } else if (Status == ERROR_WMIMOF_METHOD_RETURN_NOT_VOID) {
  1865. ErrorMessage(TRUE,
  1866. ERROR_WMIMOF_METHOD_RETURN_NOT_VOID,
  1867. MethodName,
  1868. MofClassInfo->Name);
  1869. }
  1870. }
  1871. #if DBG
  1872. printf("\n");
  1873. #endif
  1874. // DOn't free method name, kept in MofDataItem
  1875. MethodName = NULL;
  1876. }
  1877. }
  1878. done:
  1879. //
  1880. // Cleanup any loose pointers
  1881. if (MethodList != NULL)
  1882. {
  1883. BMOFFree(MethodList);
  1884. MethodList = NULL;
  1885. }
  1886. if (PropertyName != NULL)
  1887. {
  1888. BMOFFree(PropertyName);
  1889. PropertyName = NULL;
  1890. }
  1891. if (MethodName != NULL)
  1892. {
  1893. BMOFFree(MethodName);
  1894. MethodName = NULL;
  1895. }
  1896. if (PropQualifierList != NULL)
  1897. {
  1898. BMOFFree(PropQualifierList);
  1899. }
  1900. if (MethQualifierList != NULL)
  1901. {
  1902. BMOFFree(MethQualifierList);
  1903. }
  1904. if (ClassQualifierList != NULL)
  1905. {
  1906. BMOFFree(ClassQualifierList);
  1907. }
  1908. //
  1909. // Validate that we have all data item ids filled in, fixup any
  1910. // property references for variable length arrays and setup
  1911. // the appropriate version number in the data items.
  1912. FailedStatus = Status;
  1913. Version = 1;
  1914. for (Index = 0; Index < MofClassInfo->DataItemCount; Index++)
  1915. {
  1916. MofDataItem = &MofClassInfo->DataItems[Index];
  1917. if (MofDataItem->Flags & MOFDI_FLAG_VARIABLE_ARRAY)
  1918. {
  1919. //
  1920. // Resolve the variable length array
  1921. //
  1922. Status = WmipResolveVLArray(MofClassInfo,
  1923. MofDataItem,
  1924. FailedStatus);
  1925. if (Status != ERROR_SUCCESS)
  1926. {
  1927. if (Status == ERROR_WMIMOF_VL_ARRAY_SIZE_NOT_FOUND)
  1928. {
  1929. WmipDebugPrint(("WMI: Could not resolve vl array size property %ws in class %ws\n",
  1930. PropertyName, MofClassInfo->Name));
  1931. ErrorMessage(TRUE,
  1932. ERROR_WMIMOF_VL_ARRAY_SIZE_NOT_FOUND,
  1933. PropertyName,
  1934. MofDataItem->Name,
  1935. MofClassInfo->Name);
  1936. } else if (Status == ERROR_WMIMOF_BAD_VL_ARRAY_SIZE_TYPE) {
  1937. ErrorMessage(TRUE,
  1938. ERROR_WMIMOF_BAD_VL_ARRAY_SIZE_TYPE,
  1939. MofClassInfo->DataItems[MofDataItem->VariableArraySizeId-1].Name,
  1940. MofDataItem->Name,
  1941. MofClassInfo->Name);
  1942. } else if (Status == ERROR_WMIMOF_DATAITEM_NOT_FOUND) {
  1943. ErrorMessage(TRUE,
  1944. ERROR_WMIMOF_VL_ARRAY_NOT_FOUND,
  1945. MofDataItem->Name,
  1946. MofClassInfo->Name);
  1947. } else {
  1948. ErrorMessage(TRUE,
  1949. ERROR_WMIMOF_VL_ARRAY_NOT_RESOLVED,
  1950. MofDataItem->Name,
  1951. MofClassInfo->Name);
  1952. }
  1953. FailedStatus = Status;
  1954. }
  1955. }
  1956. //
  1957. // Ensure that this data item has got a name, that is the mof
  1958. // writer didn't skip a data item id
  1959. if (MofDataItem->Name == NULL)
  1960. {
  1961. //
  1962. // This data item was not filled in
  1963. Status = ERROR_WMIMOF_MISSING_DATAITEM;
  1964. WmipDebugPrint(("WMI: Missing data item %d in class %ws\n",
  1965. Index, MofClassInfo->Name));
  1966. ErrorMessage(TRUE,
  1967. ERROR_WMIMOF_MISSING_DATAITEM,
  1968. Index+1,
  1969. MofClassInfo->Name);
  1970. FailedStatus = Status;
  1971. }
  1972. if (FailedStatus != ERROR_SUCCESS)
  1973. {
  1974. continue;
  1975. }
  1976. //
  1977. // Establish version for data item
  1978. if (MofDataItem->Version == 0)
  1979. {
  1980. MofDataItem->Version = Version;
  1981. } else if ((MofDataItem->Version == Version) ||
  1982. (MofDataItem->Version == Version+1)) {
  1983. Version = MofDataItem->Version;
  1984. } else {
  1985. Status = ERROR_WMIMOF_INCONSISTENT_VERSIONING;
  1986. WmipDebugPrint(("WMI: Inconsistent versioning in class %ws at data item id %d\n",
  1987. MofClassInfo->Name, Index));
  1988. ErrorMessage(TRUE,
  1989. ERROR_WMIMOF_INCONSISTENT_VERSIONING,
  1990. MofDataItem->Name,
  1991. MofClassInfo->Name);
  1992. FailedStatus = Status;
  1993. // fall thru......
  1994. // continue;
  1995. }
  1996. }
  1997. if (FailedStatus == ERROR_SUCCESS)
  1998. {
  1999. //
  2000. // Mof class parsed OK so we set its version number and link it
  2001. // into the list of classes for the MOF resource
  2002. MofClassInfo->Version = Version;
  2003. //
  2004. // Link this into the list of MofClasses for this mof resource
  2005. InsertTailList(&MofResource->MRMCHead, &MofClass->MCMRList);
  2006. } else {
  2007. WmipUnreferenceMC(MofClass);
  2008. Status = FailedStatus;
  2009. }
  2010. return(Status);
  2011. }
  2012. //
  2013. // The routines below were blantenly stolen without remorse from the ole
  2014. // sources in \nt\private\ole32\com\class\compapi.cxx. They are copied here
  2015. // so that WMI doesn't need to load in ole32 only to convert a guid string
  2016. // into its binary representation.
  2017. //
  2018. //+-------------------------------------------------------------------------
  2019. //
  2020. // Function: HexStringToDword (private)
  2021. //
  2022. // Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
  2023. // return value in Value; check for chDelim;
  2024. //
  2025. // Arguments: [lpsz] - the hex string to convert
  2026. // [Value] - the returned value
  2027. // [cDigits] - count of digits
  2028. //
  2029. // Returns: TRUE for success
  2030. //
  2031. //--------------------------------------------------------------------------
  2032. BOOL HexStringToDword(LPCWSTR lpsz, DWORD * RetValue,
  2033. int cDigits, WCHAR chDelim)
  2034. {
  2035. int Count;
  2036. DWORD Value;
  2037. Value = 0;
  2038. for (Count = 0; Count < cDigits; Count++, lpsz++)
  2039. {
  2040. if (*lpsz >= '0' && *lpsz <= '9')
  2041. Value = (Value << 4) + *lpsz - '0';
  2042. else if (*lpsz >= 'A' && *lpsz <= 'F')
  2043. Value = (Value << 4) + *lpsz - 'A' + 10;
  2044. else if (*lpsz >= 'a' && *lpsz <= 'f')
  2045. Value = (Value << 4) + *lpsz - 'a' + 10;
  2046. else
  2047. return(FALSE);
  2048. }
  2049. *RetValue = Value;
  2050. if (chDelim != 0)
  2051. return *lpsz++ == chDelim;
  2052. else
  2053. return TRUE;
  2054. }
  2055. //+-------------------------------------------------------------------------
  2056. //
  2057. // Function: wUUIDFromString (internal)
  2058. //
  2059. // Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000
  2060. //
  2061. // Arguments: [lpsz] - Supplies the UUID string to convert
  2062. // [pguid] - Returns the GUID.
  2063. //
  2064. // Returns: TRUE if successful
  2065. //
  2066. //--------------------------------------------------------------------------
  2067. BOOL wUUIDFromString(LPCWSTR lpsz, LPGUID pguid)
  2068. {
  2069. DWORD dw;
  2070. if (!HexStringToDword(lpsz, &pguid->Data1, sizeof(DWORD)*2, '-'))
  2071. return FALSE;
  2072. lpsz += sizeof(DWORD)*2 + 1;
  2073. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  2074. return FALSE;
  2075. lpsz += sizeof(WORD)*2 + 1;
  2076. pguid->Data2 = (WORD)dw;
  2077. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  2078. return FALSE;
  2079. lpsz += sizeof(WORD)*2 + 1;
  2080. pguid->Data3 = (WORD)dw;
  2081. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  2082. return FALSE;
  2083. lpsz += sizeof(BYTE)*2;
  2084. pguid->Data4[0] = (BYTE)dw;
  2085. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, '-'))
  2086. return FALSE;
  2087. lpsz += sizeof(BYTE)*2+1;
  2088. pguid->Data4[1] = (BYTE)dw;
  2089. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  2090. return FALSE;
  2091. lpsz += sizeof(BYTE)*2;
  2092. pguid->Data4[2] = (BYTE)dw;
  2093. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  2094. return FALSE;
  2095. lpsz += sizeof(BYTE)*2;
  2096. pguid->Data4[3] = (BYTE)dw;
  2097. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  2098. return FALSE;
  2099. lpsz += sizeof(BYTE)*2;
  2100. pguid->Data4[4] = (BYTE)dw;
  2101. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  2102. return FALSE;
  2103. lpsz += sizeof(BYTE)*2;
  2104. pguid->Data4[5] = (BYTE)dw;
  2105. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  2106. return FALSE;
  2107. lpsz += sizeof(BYTE)*2;
  2108. pguid->Data4[6] = (BYTE)dw;
  2109. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  2110. return FALSE;
  2111. lpsz += sizeof(BYTE)*2;
  2112. pguid->Data4[7] = (BYTE)dw;
  2113. return TRUE;
  2114. }
  2115. //+-------------------------------------------------------------------------
  2116. //
  2117. // Function: wGUIDFromString (internal)
  2118. //
  2119. // Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000}
  2120. //
  2121. // Arguments: [lpsz] - the guid string to convert
  2122. // [pguid] - guid to return
  2123. //
  2124. // Returns: TRUE if successful
  2125. //
  2126. //--------------------------------------------------------------------------
  2127. BOOL wGUIDFromString(LPCWSTR lpsz, LPGUID pguid)
  2128. {
  2129. DWORD dw;
  2130. if (*lpsz == '{' )
  2131. lpsz++;
  2132. if(wUUIDFromString(lpsz, pguid) != TRUE)
  2133. return FALSE;
  2134. lpsz +=36;
  2135. if (*lpsz == '}' )
  2136. lpsz++;
  2137. if (*lpsz != '\0') // check for zero terminated string - test bug #18307
  2138. {
  2139. return FALSE;
  2140. }
  2141. return TRUE;
  2142. }
  2143. ULONG GetRootObjectList(
  2144. char *BMofFile,
  2145. CBMOFObjList **ObjectList
  2146. )
  2147. {
  2148. ULONG Status;
  2149. ULONG CompressedSizeHigh;
  2150. BMofFileName = BMofFile;
  2151. FileHandle = CreateFile(BMofFile,
  2152. GENERIC_READ,
  2153. FILE_SHARE_READ,
  2154. NULL,
  2155. OPEN_EXISTING,
  2156. FILE_ATTRIBUTE_NORMAL,
  2157. NULL);
  2158. if (FileHandle == INVALID_HANDLE_VALUE)
  2159. {
  2160. Status = GetLastError();
  2161. ErrorMessage(TRUE, ERROR_WMIMOF_CANT_ACCESS_FILE, BMofFile, Status);
  2162. return(Status);
  2163. }
  2164. CompressedSize = GetFileSize(FileHandle, &CompressedSizeHigh);
  2165. MappingHandle = CreateFileMapping(FileHandle,
  2166. NULL,
  2167. PAGE_READONLY,
  2168. 0, 0,
  2169. NULL);
  2170. if (MappingHandle == NULL)
  2171. {
  2172. CloseHandle(FileHandle);
  2173. Status = GetLastError();
  2174. ErrorMessage(TRUE, ERROR_WMIMOF_CANT_ACCESS_FILE, BMofFile, Status);
  2175. return(Status);
  2176. }
  2177. CompressedFileBuffer = MapViewOfFile(MappingHandle,
  2178. FILE_MAP_READ,
  2179. 0, 0,
  2180. 0);
  2181. if (CompressedFileBuffer == NULL)
  2182. {
  2183. CloseHandle(MappingHandle);
  2184. CloseHandle(FileHandle);
  2185. Status = GetLastError();
  2186. ErrorMessage(TRUE, ERROR_WMIMOF_CANT_ACCESS_FILE, BMofFile, Status);
  2187. return(Status);
  2188. }
  2189. Status = WmipDecompressBuffer(CompressedFileBuffer,
  2190. &FileBuffer,
  2191. &UncompressedSize);
  2192. if (Status != ERROR_SUCCESS)
  2193. {
  2194. UnmapViewOfFile(CompressedFileBuffer);
  2195. CloseHandle(MappingHandle);
  2196. CloseHandle(FileHandle);
  2197. Status = GetLastError();
  2198. ErrorMessage(TRUE, ERROR_WMIMOF_CANT_ACCESS_FILE, BMofFile, Status);
  2199. return(Status);
  2200. }
  2201. fprintf(stderr, "Binary mof file %s expanded to %d bytes\n", BMofFile,
  2202. UncompressedSize);
  2203. //
  2204. // Create an object list structure of all the objects in the MOF
  2205. *ObjectList = CreateObjList(FileBuffer);
  2206. if(*ObjectList == NULL)
  2207. {
  2208. UnmapViewOfFile(CompressedFileBuffer);
  2209. CloseHandle(MappingHandle);
  2210. CloseHandle(FileHandle);
  2211. ErrorMessage(TRUE, ERROR_WMI_INVALID_MOF);
  2212. return(ERROR_WMI_INVALID_MOF);
  2213. }
  2214. return(ERROR_SUCCESS);
  2215. }
  2216. ULONG VerifyClassProperties(
  2217. PMOFRESOURCE MofResource,
  2218. PWCHAR ClassName,
  2219. PWCHAR BaseClassName,
  2220. PMOFCLASS MofClass
  2221. )
  2222. {
  2223. CBMOFObj *ClassObject;
  2224. PMOFCLASSINFOW MofClassInfo;
  2225. CBMOFDataItem MofPropertyData;
  2226. DWORD QualifierType;
  2227. WCHAR *StringPtr;
  2228. ULONG Status = ERROR_SUCCESS;
  2229. PMOFCLASS MofSuperClass;
  2230. ClassObject = (CBMOFObj *)MofClass->ClassObjectHandle;
  2231. MofClassInfo = MofClass->MofClassInfo;
  2232. if ( ((MofClassInfo->Flags & MOFCI_RESERVED1) == 0) &&
  2233. ((MofClassInfo->Flags & MOFCI_RESERVED2) == 0) )
  2234. {
  2235. //
  2236. // This class does not have the instanceName and Active properties
  2237. // so we expect that a superclass should. Look for the superclass
  2238. // and check that
  2239. //
  2240. QualifierType = VT_BSTR;
  2241. Status = WmipFindProperty(ClassObject,
  2242. L"__SUPERCLASS",
  2243. &MofPropertyData,
  2244. &QualifierType,
  2245. (PVOID)&StringPtr);
  2246. if (Status == ERROR_SUCCESS)
  2247. {
  2248. //
  2249. // Find the MofClass for the superclass and see if it has
  2250. // the required properties
  2251. //
  2252. MofSuperClass = WmipFindClassInMofResourceByName(MofResource,
  2253. StringPtr);
  2254. if (MofSuperClass != NULL)
  2255. {
  2256. Status = VerifyClassProperties(MofResource,
  2257. MofSuperClass->MofClassInfo->Name,
  2258. BaseClassName,
  2259. MofSuperClass);
  2260. } else {
  2261. //
  2262. // We could not find the superclass, but we will assume
  2263. // that this is ok
  2264. //
  2265. fprintf(stderr, "%s (0): warning RC2135 : Class %ws and all of its base classes do not have InstanceName and Active properties\n",
  2266. BMofFileName, BaseClassName);
  2267. Status = ERROR_SUCCESS;
  2268. }
  2269. BMOFFree(StringPtr);
  2270. } else {
  2271. Status = ERROR_WMIMOF_NO_INSTANCENAME;
  2272. ErrorMessage(TRUE,
  2273. ERROR_WMIMOF_NO_INSTANCENAME,
  2274. BaseClassName);
  2275. }
  2276. } else {
  2277. //
  2278. // If its got one of the properties make sure that it has
  2279. // both of them.
  2280. if ((MofClassInfo->Flags & MOFCI_RESERVED1) == 0)
  2281. {
  2282. Status = ERROR_WMIMOF_NO_INSTANCENAME;
  2283. ErrorMessage(TRUE,
  2284. ERROR_WMIMOF_NO_INSTANCENAME,
  2285. BaseClassName);
  2286. }
  2287. if ((MofClassInfo->Flags & MOFCI_RESERVED2) == 0)
  2288. {
  2289. Status = ERROR_WMIMOF_NO_ACTIVE;
  2290. ErrorMessage(TRUE,
  2291. ERROR_WMIMOF_NO_ACTIVE,
  2292. BaseClassName);
  2293. }
  2294. }
  2295. return(Status);
  2296. }
  2297. ULONG ParseBinaryMofFile(
  2298. char *BMofFile,
  2299. PMOFRESOURCE *ReturnMofResource
  2300. )
  2301. {
  2302. ULONG Status;
  2303. CBMOFObjList *MofObjList;
  2304. CBMOFObj *ClassObject;
  2305. PMOFRESOURCE MofResource;
  2306. PLIST_ENTRY MofClassList;
  2307. PMOFCLASS MofClass;
  2308. BOOLEAN CleanupOnly;
  2309. PMOFCLASSINFOW MofClassInfo;
  2310. MofResource = WmipAllocMofResource();
  2311. if (MofResource == NULL)
  2312. {
  2313. return(ERROR_NOT_ENOUGH_MEMORY);
  2314. }
  2315. *ReturnMofResource = MofResource;
  2316. InitializeListHead(&MofResource->MRMCHead);
  2317. Status = GetRootObjectList(BMofFile, &MofObjList);
  2318. if (Status == ERROR_SUCCESS)
  2319. {
  2320. ResetObjList (MofObjList);
  2321. while((Status == ERROR_SUCCESS) &&
  2322. (ClassObject = NextObj(MofObjList)) )
  2323. {
  2324. Status = WmipParseClassObject(MofResource, ClassObject);
  2325. if (Status != ERROR_SUCCESS)
  2326. {
  2327. ErrorMessage(TRUE, ERROR_WMIMOF_CLASS_NOT_PARSED);
  2328. }
  2329. }
  2330. //
  2331. // Now that all classes are parsed we need to go back and find
  2332. // the guids for any embedded classes, or if a class failed
  2333. // to parse then we need to free any embedded class names
  2334. CleanupOnly = (Status != ERROR_SUCCESS);
  2335. MofClassList = MofResource->MRMCHead.Flink;
  2336. while (MofClassList != &MofResource->MRMCHead)
  2337. {
  2338. MofClass = CONTAINING_RECORD(MofClassList,
  2339. MOFCLASS,
  2340. MCMRList);
  2341. MofClassInfo = MofClass->MofClassInfo;
  2342. if ((! CleanupOnly) &&
  2343. (MofClassInfo->Flags & MOFCI_RESERVED0))
  2344. {
  2345. //
  2346. // if the class has Provider qualifier, it better have
  2347. // an instancename and Active properties in itself or in a
  2348. // superclass
  2349. //
  2350. Status = VerifyClassProperties(MofResource,
  2351. MofClassInfo->Name,
  2352. MofClassInfo->Name,
  2353. MofClass);
  2354. CleanupOnly = (Status != ERROR_SUCCESS);
  2355. }
  2356. Status = WmipFillEmbeddedClasses(MofResource,
  2357. MofClassInfo,
  2358. CleanupOnly);
  2359. if (Status != ERROR_SUCCESS)
  2360. {
  2361. CleanupOnly = TRUE;
  2362. }
  2363. MofClassList = MofClassList->Flink;
  2364. }
  2365. if (CleanupOnly)
  2366. {
  2367. Status = ERROR_WMI_INVALID_MOF;
  2368. }
  2369. BMOFFree(MofObjList);
  2370. if (Status != ERROR_SUCCESS)
  2371. {
  2372. //
  2373. // Make sure we have a useful Win32 error code and not
  2374. // an internal WMIMOF error code
  2375. Status = ERROR_WMI_INVALID_MOF;
  2376. }
  2377. }
  2378. return(Status);
  2379. }
  2380. ULONG FilePrintVaList(
  2381. HANDLE FileHandle,
  2382. CHAR *Format,
  2383. va_list pArg
  2384. )
  2385. {
  2386. PCHAR Buffer;
  2387. ULONG Size, Written;
  2388. ULONG Status;
  2389. Buffer = WmipAlloc(8192);
  2390. if (Buffer != NULL)
  2391. {
  2392. Size = _vsnprintf(Buffer, 8192, Format, pArg);
  2393. Buffer[8191] = 0;
  2394. if (WriteFile(FileHandle,
  2395. Buffer,
  2396. Size,
  2397. &Written,
  2398. NULL))
  2399. {
  2400. Status = ERROR_SUCCESS;
  2401. } else {
  2402. Status = GetLastError();
  2403. }
  2404. WmipFree(Buffer);
  2405. } else {
  2406. Status = ERROR_NOT_ENOUGH_MEMORY;
  2407. }
  2408. return(Status);
  2409. }
  2410. ULONG FilePrint(
  2411. HANDLE FileHandle,
  2412. char *Format,
  2413. ...
  2414. )
  2415. {
  2416. ULONG Status;
  2417. va_list pArg;
  2418. va_start(pArg, Format);
  2419. Status = FilePrintVaList(FileHandle, Format, pArg);
  2420. return(Status);
  2421. }
  2422. ULONG GenerateASLTemplate(
  2423. PCHAR TemplateFile
  2424. )
  2425. {
  2426. return(ERROR_SUCCESS);
  2427. }
  2428. ULONG GenerateBinaryMofData(
  2429. HANDLE FileHandle
  2430. )
  2431. {
  2432. ULONG Lines;
  2433. ULONG LastLine;
  2434. ULONG i;
  2435. ULONG Index;
  2436. PUCHAR BMofBuffer = (PUCHAR)CompressedFileBuffer;
  2437. PCHAR IndentString = " ";
  2438. ULONG Status;
  2439. Lines = CompressedSize / 16;
  2440. LastLine = CompressedSize % 16;
  2441. if (LastLine == 0)
  2442. {
  2443. LastLine = 16;
  2444. Lines--;
  2445. }
  2446. for (i = 0; i < Lines; i++)
  2447. {
  2448. Index = i * 16;
  2449. Status = FilePrint(FileHandle, "%s0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\r\n",
  2450. IndentString,
  2451. BMofBuffer[Index],
  2452. BMofBuffer[Index+1],
  2453. BMofBuffer[Index+2],
  2454. BMofBuffer[Index+3],
  2455. BMofBuffer[Index+4],
  2456. BMofBuffer[Index+5],
  2457. BMofBuffer[Index+6],
  2458. BMofBuffer[Index+7],
  2459. BMofBuffer[Index+8],
  2460. BMofBuffer[Index+9],
  2461. BMofBuffer[Index+10],
  2462. BMofBuffer[Index+11],
  2463. BMofBuffer[Index+12],
  2464. BMofBuffer[Index+13],
  2465. BMofBuffer[Index+14],
  2466. BMofBuffer[Index+15]);
  2467. if (Status != ERROR_SUCCESS)
  2468. {
  2469. return(Status);
  2470. }
  2471. }
  2472. LastLine--;
  2473. FilePrint(FileHandle, "%s", IndentString);
  2474. Index = Lines * 16;
  2475. for (i = 0; i < LastLine; i++)
  2476. {
  2477. Status = FilePrint(FileHandle, "0x%02x, ",
  2478. BMofBuffer[Index+i]);
  2479. if (Status != ERROR_SUCCESS)
  2480. {
  2481. return(Status);
  2482. }
  2483. }
  2484. Status = FilePrint(FileHandle, "0x%02x\r\n",
  2485. BMofBuffer[Index+i]);
  2486. return(Status);
  2487. }
  2488. //
  2489. // This will loop over the mof class list and print out once for each class
  2490. // in the list.
  2491. //
  2492. // Handle is the file handle to which to write
  2493. // MR is the MofResource whose classes are being enumerated
  2494. // NamePtr is the variable to place the name of the class
  2495. // Counter is the variable to use as a counter
  2496. // Format is the format template to use to write out
  2497. //
  2498. HANDLE GlobalFilePrintHandle;
  2499. ULONG FilePrintGlobal(CHAR *Format, ...)
  2500. {
  2501. ULONG Status;
  2502. va_list pArg;
  2503. va_start(pArg, Format);
  2504. Status = FilePrintVaList(GlobalFilePrintHandle, Format, pArg);
  2505. return(Status);
  2506. }
  2507. #define FilePrintMofClassLoop( \
  2508. Handle, \
  2509. MR, \
  2510. NamePtr, \
  2511. Counter, \
  2512. DiscardEmbedded, \
  2513. Format \
  2514. ) \
  2515. { \
  2516. PLIST_ENTRY MofClassList; \
  2517. PMOFCLASSINFOW ClassInfo; \
  2518. PMOFCLASS MofClass; \
  2519. GlobalFilePrintHandle = TemplateHandle; \
  2520. (Counter) = 0; \
  2521. MofClassList = (MR)->MRMCHead.Flink; \
  2522. while (MofClassList != &(MR)->MRMCHead) \
  2523. { \
  2524. MofClass = CONTAINING_RECORD(MofClassList, MOFCLASS, MCMRList); \
  2525. ClassInfo = MofClass->MofClassInfo; \
  2526. if (! ((DiscardEmbedded) && \
  2527. (ClassInfo->Flags & MOFCI_FLAG_EMBEDDED_CLASS)) ) \
  2528. { \
  2529. (NamePtr) = ClassInfo->Name; \
  2530. FilePrintGlobal Format; \
  2531. (Counter)++; \
  2532. } \
  2533. MofClassList = MofClassList->Flink; \
  2534. } \
  2535. }
  2536. typedef void (*ENUMMOFCLASSCALLBACK)(
  2537. HANDLE TemplateHandle,
  2538. PMOFCLASS MofClass,
  2539. ULONG Counter,
  2540. PVOID Context
  2541. );
  2542. void EnumerateMofClasses(
  2543. HANDLE TemplateHandle,
  2544. PMOFRESOURCE MR,
  2545. ENUMMOFCLASSCALLBACK Callback,
  2546. PVOID Context
  2547. )
  2548. {
  2549. PLIST_ENTRY MofClassList;
  2550. PMOFCLASS MofClass;
  2551. ULONG Counter;
  2552. Counter = 0;
  2553. MofClassList = MR->MRMCHead.Flink;
  2554. while (MofClassList != &MR->MRMCHead)
  2555. {
  2556. MofClass = CONTAINING_RECORD(MofClassList, MOFCLASS, MCMRList);
  2557. (*Callback)(TemplateHandle,
  2558. MofClass,
  2559. Counter,
  2560. Context);
  2561. MofClassList = MofClassList->Flink;
  2562. Counter++;
  2563. }
  2564. }
  2565. void GenerateGuidListTemplate(
  2566. HANDLE TemplateHandle,
  2567. PMOFCLASS MofClass,
  2568. ULONG Counter,
  2569. PVOID Context
  2570. )
  2571. {
  2572. PMOFCLASSINFOW ClassInfo;
  2573. PWCHAR GuidName1, GuidSuffix1;
  2574. ClassInfo = MofClass->MofClassInfo;
  2575. if ( ! (ClassInfo->Flags & MOFCI_FLAG_EMBEDDED_CLASS))
  2576. {
  2577. //
  2578. // Only generate code for non embedded classes
  2579. //
  2580. if (ClassInfo->GuidName1 != NULL)
  2581. {
  2582. GuidName1 = ClassInfo->GuidName1;
  2583. GuidSuffix1 = L"";
  2584. } else {
  2585. GuidName1 = ClassInfo->Name;
  2586. GuidSuffix1 = L"Guid";
  2587. }
  2588. FilePrint(TemplateHandle,
  2589. "GUID %wsGUID = %ws%ws;\r\n",
  2590. ClassInfo->Name,
  2591. GuidName1, GuidSuffix1);
  2592. }
  2593. }
  2594. void GenerateFunctionControlListTemplate(
  2595. HANDLE TemplateHandle,
  2596. PMOFCLASS MofClass,
  2597. ULONG Counter,
  2598. PVOID Context
  2599. )
  2600. {
  2601. PMOFCLASSINFOW ClassInfo;
  2602. ClassInfo = MofClass->MofClassInfo;
  2603. if (! (ClassInfo->Flags & MOFCI_FLAG_EMBEDDED_CLASS) )
  2604. {
  2605. FilePrint(TemplateHandle,
  2606. " case %wsGuidIndex:\r\n"
  2607. " {\r\n",
  2608. ClassInfo->Name);
  2609. if (ClassInfo->Flags & MOFCI_FLAG_EVENT)
  2610. {
  2611. FilePrint(TemplateHandle,
  2612. " if (Enable)\r\n"
  2613. " {\r\n"
  2614. " //\r\n"
  2615. " // TODO: Event is being enabled, do anything required to\r\n"
  2616. " // allow the event to be fired\r\n"
  2617. " //\r\n"
  2618. " } else {\r\n"
  2619. " //\r\n"
  2620. " // TODO: Event is being disabled, do anything required to\r\n"
  2621. " // keep the event from being fired\r\n"
  2622. " //\r\n"
  2623. " }\r\n");
  2624. } else {
  2625. FilePrint(TemplateHandle,
  2626. " //\r\n"
  2627. " // TODO: Delete this entire case if data block does not have the\r\n"
  2628. " // WMIREG_FLAG_EXPENSIVE flag set\r\n"
  2629. " //\r\n"
  2630. " if (Enable)\r\n"
  2631. " {\r\n"
  2632. " //\r\n"
  2633. " // TODO: Datablock collection is being enabled. If this\r\n"
  2634. " // data block has been marked as expensive in the\r\n"
  2635. " // guid list then this code will be called when the\r\n"
  2636. " // first data consumer opens this data block. If\r\n"
  2637. " // anything needs to be done to allow data to be \r\n"
  2638. " // collected for this data block then it should be\r\n"
  2639. " // done here\r\n"
  2640. " //\r\n"
  2641. " } else {\r\n"
  2642. " //\r\n"
  2643. " // TODO: Datablock collection is being disabled. If this\r\n"
  2644. " // data block has been marked as expensive in the\r\n"
  2645. " // guid list then this code will be called when the\r\n"
  2646. " // last data consumer closes this data block. If\r\n"
  2647. " // anything needs to be done to cleanup after data has \r\n"
  2648. " // been collected for this data block then it should be\r\n"
  2649. " // done here\r\n"
  2650. " //\r\n"
  2651. " }\r\n");
  2652. }
  2653. FilePrint(TemplateHandle,
  2654. " break;\r\n"
  2655. " }\r\n\r\n");
  2656. }
  2657. }
  2658. void GenerateSetList(
  2659. HANDLE TemplateHandle,
  2660. PMOFCLASS MofClass,
  2661. ULONG Counter,
  2662. PVOID Context
  2663. )
  2664. {
  2665. PCHAR Format = (PCHAR)Context;
  2666. PMOFCLASSINFOW ClassInfo;
  2667. ClassInfo = MofClass->MofClassInfo;
  2668. if (! (ClassInfo->Flags & MOFCI_FLAG_EMBEDDED_CLASS) )
  2669. {
  2670. if (! (ClassInfo->Flags & MOFCI_FLAG_READONLY))
  2671. {
  2672. FilePrint(TemplateHandle, Format, ClassInfo->Name);
  2673. } else {
  2674. FilePrint(TemplateHandle,
  2675. " case %wsGuidIndex:\r\n"
  2676. " { \r\n"
  2677. " status = STATUS_WMI_READ_ONLY;\r\n"
  2678. " break;\r\n"
  2679. " }\r\n\r\n",
  2680. ClassInfo->Name);
  2681. }
  2682. }
  2683. }
  2684. void GenerateMethodCTemplate(
  2685. HANDLE TemplateHandle,
  2686. PMOFCLASS MofClass,
  2687. ULONG Counter,
  2688. PVOID Context
  2689. )
  2690. {
  2691. PMOFCLASSINFOW ClassInfo;
  2692. ULONG i;
  2693. PMOFDATAITEMW DataItem;
  2694. ClassInfo = MofClass->MofClassInfo;
  2695. if (ClassInfo->MethodCount > 0)
  2696. {
  2697. FilePrint(TemplateHandle,
  2698. " case %wsGuidIndex:\r\n"
  2699. " {\r\n"
  2700. " switch(MethodId)\r\n"
  2701. " {\r\n",
  2702. ClassInfo->Name);
  2703. for (i = 0; i < ClassInfo->MethodCount; i++)
  2704. {
  2705. DataItem = &ClassInfo->DataItems[i+ClassInfo->DataItemCount];
  2706. FilePrint(TemplateHandle,
  2707. " case %ws:\r\n"
  2708. " { \r\n"
  2709. " //\r\n"
  2710. " // TODO: Validate InstanceIndex, InBufferSize \r\n"
  2711. " // and Buffer contents to ensure that the \r\n"
  2712. " // input buffer is valid and OutBufferSize is\r\n"
  2713. " // large enough to return the output data.\r\n"
  2714. " //\r\n"
  2715. " break;\r\n"
  2716. " }\r\n\r\n",
  2717. DataItem->Name);
  2718. }
  2719. FilePrint(TemplateHandle,
  2720. " default:\r\n"
  2721. " {\r\n"
  2722. " status = STATUS_WMI_ITEMID_NOT_FOUND;\r\n"
  2723. " break;\r\n"
  2724. " }\r\n"
  2725. " }\r\n"
  2726. " break;\r\n"
  2727. " }\r\n"
  2728. "\r\n"
  2729. );
  2730. }
  2731. }
  2732. BOOLEAN DoesSupportMethods(
  2733. PMOFRESOURCE MR
  2734. )
  2735. {
  2736. PLIST_ENTRY MofClassList;
  2737. PMOFCLASS MofClass;
  2738. MofClassList = MR->MRMCHead.Flink;
  2739. while (MofClassList != &MR->MRMCHead)
  2740. {
  2741. MofClass = CONTAINING_RECORD(MofClassList, MOFCLASS, MCMRList);
  2742. if (MofClass->MofClassInfo->MethodCount > 0)
  2743. {
  2744. return(TRUE);
  2745. }
  2746. MofClassList = MofClassList->Flink;
  2747. }
  2748. return(FALSE);
  2749. }
  2750. BOOLEAN DoesReadOnly(
  2751. PMOFRESOURCE MR
  2752. )
  2753. {
  2754. PLIST_ENTRY MofClassList;
  2755. PMOFCLASS MofClass;
  2756. PMOFCLASSINFOW ClassInfo;
  2757. ULONG i;
  2758. MofClassList = MR->MRMCHead.Flink;
  2759. while (MofClassList != &MR->MRMCHead)
  2760. {
  2761. MofClass = CONTAINING_RECORD(MofClassList, MOFCLASS, MCMRList);
  2762. ClassInfo = MofClass->MofClassInfo;
  2763. for (i = 0; i < ClassInfo->DataItemCount; i++)
  2764. {
  2765. if (ClassInfo->DataItems[i].Flags & MOFDI_FLAG_WRITEABLE)
  2766. {
  2767. return(FALSE);
  2768. }
  2769. }
  2770. MofClassList = MofClassList->Flink;
  2771. }
  2772. return(TRUE);
  2773. }
  2774. PCHAR GetBaseNameFromFileName(
  2775. PCHAR FileName,
  2776. PCHAR BaseName
  2777. )
  2778. {
  2779. PCHAR p, p1;
  2780. ULONG Len;
  2781. p = FileName;
  2782. p1 = FileName;
  2783. while ((*p != '.') && (*p != 0))
  2784. {
  2785. if (*p == '\\')
  2786. {
  2787. p1 = p+1;
  2788. }
  2789. p++;
  2790. }
  2791. Len = (ULONG)(p - p1);
  2792. memcpy(BaseName, p1, Len);
  2793. BaseName[Len] = 0;
  2794. return(BaseName);
  2795. }
  2796. ULONG GenerateCTemplate(
  2797. PCHAR TemplateFile,
  2798. PCHAR HFileName,
  2799. PCHAR XFileName,
  2800. PMOFRESOURCE MofResource
  2801. )
  2802. {
  2803. BOOLEAN SupportsMethods, SupportsFunctionControl, IsReadOnly;
  2804. HANDLE TemplateHandle;
  2805. CHAR BaseName[MAX_PATH], BaseXFileName[MAX_PATH], BaseHFileName[MAX_PATH];
  2806. ULONG i;
  2807. PWCHAR ClassName;
  2808. GetBaseNameFromFileName(TemplateFile, BaseName);
  2809. GetBaseNameFromFileName(XFileName, BaseXFileName);
  2810. GetBaseNameFromFileName(XFileName, BaseHFileName);
  2811. BaseName[0] = (CHAR)toupper(BaseName[0]);
  2812. SupportsMethods = DoesSupportMethods(MofResource);
  2813. SupportsFunctionControl = TRUE;
  2814. IsReadOnly = DoesReadOnly(MofResource);
  2815. TemplateHandle = CreateFile(TemplateFile,
  2816. GENERIC_WRITE,
  2817. 0,
  2818. NULL,
  2819. CREATE_ALWAYS,
  2820. FILE_ATTRIBUTE_NORMAL,
  2821. NULL);
  2822. if ((TemplateHandle == NULL) || (TemplateHandle == INVALID_HANDLE_VALUE))
  2823. {
  2824. return(GetLastError());
  2825. }
  2826. FilePrint(TemplateHandle,
  2827. "//\r\n"
  2828. "// %s.c - Code generated by wmimofck tool\r\n"
  2829. "//\r\n"
  2830. "// Finish code by doing all TODO: sections\r\n"
  2831. "//\r\n"
  2832. "\r\n"
  2833. "#include <wdm.h>\r\n"
  2834. "#include <wmistr.h>\r\n"
  2835. "#include <wmiguid.h>\r\n"
  2836. "#include <wmilib.h>\r\n"
  2837. "\r\n"
  2838. "//\r\n"
  2839. "// Include data header for classes\r\n"
  2840. "#include \"%s.h\"\r\n"
  2841. "\r\n"
  2842. "\r\n",
  2843. BaseName,
  2844. BaseHFileName
  2845. );
  2846. FilePrint(TemplateHandle,
  2847. "//\r\n"
  2848. "// TODO: Place the contents in this device extension into the driver's\r\n"
  2849. "// actual device extension. It is only defined here to supply\r\n"
  2850. "// a device extension so that this file can be compiled on its own\r\n"
  2851. "//\r\n"
  2852. "#ifdef MAKE_THIS_COMPILE\r\n"
  2853. "typedef struct DEVICE_EXTENSION\r\n"
  2854. "{\r\n"
  2855. " WMILIB_CONTEXT WmiLib;\r\n"
  2856. " PDEVICE_OBJECT physicalDevObj;\r\n"
  2857. "} DEVICE_EXTENSION, *PDEVICE_EXTENSION;\r\n"
  2858. "#endif\r\n\r\n"
  2859. );
  2860. FilePrint(TemplateHandle,
  2861. "NTSTATUS\r\n"
  2862. "%sInitializeWmilibContext(\r\n"
  2863. " IN PWMILIB_CONTEXT WmilibContext\r\n"
  2864. " );\r\n"
  2865. "\r\n"
  2866. "NTSTATUS\r\n"
  2867. "%sFunctionControl(\r\n"
  2868. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  2869. " IN PIRP Irp,\r\n"
  2870. " IN ULONG GuidIndex,\r\n"
  2871. " IN WMIENABLEDISABLECONTROL Function,\r\n"
  2872. " IN BOOLEAN Enable\r\n"
  2873. " );\r\n"
  2874. "\r\n"
  2875. "NTSTATUS\r\n"
  2876. "%sExecuteWmiMethod(\r\n"
  2877. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  2878. " IN PIRP Irp,\r\n"
  2879. " IN ULONG GuidIndex,\r\n"
  2880. " IN ULONG InstanceIndex,\r\n"
  2881. " IN ULONG MethodId,\r\n"
  2882. " IN ULONG InBufferSize,\r\n"
  2883. " IN ULONG OutBufferSize,\r\n"
  2884. " IN PUCHAR Buffer\r\n"
  2885. " );\r\n"
  2886. "\r\n"
  2887. "NTSTATUS\r\n"
  2888. "%sSetWmiDataItem(\r\n"
  2889. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  2890. " IN PIRP Irp,\r\n"
  2891. " IN ULONG InstanceIndex,\r\n"
  2892. " IN ULONG GuidIndex,\r\n"
  2893. " IN ULONG DataItemId,\r\n"
  2894. " IN ULONG BufferSize,\r\n"
  2895. " IN PUCHAR Buffer\r\n"
  2896. " );\r\n"
  2897. "\r\n"
  2898. "NTSTATUS\r\n"
  2899. "%sSetWmiDataBlock(\r\n"
  2900. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  2901. " IN PIRP Irp,\r\n"
  2902. " IN ULONG GuidIndex,\r\n"
  2903. " IN ULONG InstanceIndex,\r\n"
  2904. " IN ULONG BufferSize,\r\n"
  2905. " IN PUCHAR Buffer\r\n"
  2906. " );\r\n"
  2907. "\r\n"
  2908. "NTSTATUS\r\n"
  2909. "%sQueryWmiDataBlock(\r\n"
  2910. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  2911. " IN PIRP Irp,\r\n"
  2912. " IN ULONG GuidIndex,\r\n"
  2913. " IN ULONG InstanceIndex,\r\n"
  2914. " IN ULONG InstanceCount,\r\n"
  2915. " IN OUT PULONG InstanceLengthArray,\r\n"
  2916. " IN ULONG BufferAvail,\r\n"
  2917. " OUT PUCHAR Buffer\r\n"
  2918. " );\r\n"
  2919. "\r\n"
  2920. "NTSTATUS\r\n"
  2921. "%sQueryWmiRegInfo(\r\n"
  2922. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  2923. " OUT ULONG *RegFlags,\r\n"
  2924. " OUT PUNICODE_STRING InstanceName,\r\n"
  2925. " OUT PUNICODE_STRING *RegistryPath,\r\n"
  2926. " OUT PUNICODE_STRING MofResourceName,\r\n"
  2927. " OUT PDEVICE_OBJECT *Pdo\r\n"
  2928. " );\r\n"
  2929. "\r\n"
  2930. "#ifdef ALLOC_PRAGMA\r\n"
  2931. "#pragma alloc_text(PAGE,%sQueryWmiRegInfo)\r\n"
  2932. "#pragma alloc_text(PAGE,%sQueryWmiDataBlock)\r\n"
  2933. "#pragma alloc_text(PAGE,%sSetWmiDataBlock)\r\n"
  2934. "#pragma alloc_text(PAGE,%sSetWmiDataItem)\r\n"
  2935. "#pragma alloc_text(PAGE,%sExecuteWmiMethod)\r\n"
  2936. "#pragma alloc_text(PAGE,%sFunctionControl)\r\n"
  2937. "#pragma alloc_text(PAGE,%sInitializeWmilibContext)\r\n"
  2938. "#endif\r\n"
  2939. "\r\n",
  2940. BaseName,
  2941. BaseName,
  2942. BaseName,
  2943. BaseName,
  2944. BaseName,
  2945. BaseName,
  2946. BaseName,
  2947. BaseName,
  2948. BaseName,
  2949. BaseName,
  2950. BaseName,
  2951. BaseName,
  2952. BaseName,
  2953. BaseName
  2954. );
  2955. FilePrint(TemplateHandle,
  2956. "//\r\n"
  2957. "// TODO: Decide if your MOF is going to be part of your driver as a resource\r\n"
  2958. "// attached to it. If this is done then all MOF in the resource will be\r\n"
  2959. "// added to the schema. If this is the case be sure that \r\n"
  2960. "// USE_BINARY_MOF_RESOURCE is defined. MOF can also be reported at \r\n"
  2961. "// runtime via a query to the driver. This can be useful if you want\r\n"
  2962. "// the MOF reported to the schema to be dynamic. If MOF is reported via\r\n"
  2963. "// a query then USE_BINARY_MOF_QUERY should be defined.\r\n"
  2964. "\r\n"
  2965. "#define USE_BINARY_MOF_QUERY\r\n"
  2966. "#define USE_BINARY_MOF_RESOURCE\r\n"
  2967. "\r\n"
  2968. "#ifdef USE_BINARY_MOF_QUERY\r\n"
  2969. "//\r\n"
  2970. "// MOF data can be reported by a device driver via a resource attached to\r\n"
  2971. "// the device drivers image file or in response to a query on the binary\r\n"
  2972. "// mof data guid. Here we define global variables containing the binary mof\r\n"
  2973. "// data to return in response to a binary mof guid query. Note that this\r\n"
  2974. "// data is defined to be in a PAGED data segment since it does not need to\r\n"
  2975. "// be in nonpaged memory. Note that instead of a single large mof file\r\n"
  2976. "// we could have broken it into multiple individual files. Each file would\r\n"
  2977. "// have its own binary mof data buffer and get reported via a different\r\n"
  2978. "// instance of the binary mof guid. By mixing and matching the different\r\n"
  2979. "// sets of binary mof data buffers a \"dynamic\" composite mof would be created.\r\n"
  2980. "\r\n"
  2981. "#ifdef ALLOC_DATA_PRAGMA\r\n"
  2982. " #pragma data_seg(\"PAGED\")\r\n"
  2983. "#endif\r\n"
  2984. "\r\n"
  2985. "UCHAR %sBinaryMofData[] =\r\n"
  2986. "{\r\n"
  2987. " #include \"%s.x\"\r\n"
  2988. "};\r\n"
  2989. "#ifdef ALLOC_DATA_PRAGMA\r\n"
  2990. " #pragma data_seg()\r\n"
  2991. "#endif\r\n"
  2992. "#endif\r\n"
  2993. "\r\n",
  2994. BaseName,
  2995. BaseXFileName
  2996. );
  2997. FilePrint(TemplateHandle,
  2998. "//\r\n"
  2999. "// Define symbolic names for the guid indexes\r\n"
  3000. );
  3001. FilePrintMofClassLoop(TemplateHandle, MofResource, ClassName, i, TRUE,
  3002. ("#define %wsGuidIndex %d\r\n",
  3003. ClassName, i));
  3004. FilePrint(TemplateHandle,
  3005. "#ifdef USE_BINARY_MOF_QUERY\r\n"
  3006. "#define BinaryMofGuidIndex %d\r\n"
  3007. "#endif\r\n",
  3008. i
  3009. );
  3010. FilePrint(TemplateHandle,
  3011. "//\r\n"
  3012. "// List of guids supported\r\n\r\n"
  3013. );
  3014. EnumerateMofClasses(TemplateHandle,
  3015. MofResource,
  3016. GenerateGuidListTemplate,
  3017. NULL);
  3018. FilePrint(TemplateHandle,
  3019. "#ifdef USE_BINARY_MOF_QUERY\r\n"
  3020. "GUID %sBinaryMofGUID = BINARY_MOF_GUID;\r\n"
  3021. "#endif\r\n"
  3022. "\r\n"
  3023. "//\r\n"
  3024. "// TODO: Make sure the instance count and flags are set properly for each\r\n"
  3025. "// guid\r\n"
  3026. "WMIGUIDREGINFO %sGuidList[] =\r\n"
  3027. "{\r\n",
  3028. BaseName, BaseName);
  3029. FilePrintMofClassLoop(TemplateHandle, MofResource, ClassName, i, TRUE,
  3030. (" {\r\n"
  3031. " &%wsGUID, // Guid\r\n"
  3032. " 1, // # of instances in each device\r\n"
  3033. " 0 // Flags\r\n"
  3034. " },\r\n",
  3035. ClassName));
  3036. FilePrint(TemplateHandle,
  3037. "#ifdef USE_BINARY_MOF_QUERY\r\n"
  3038. " {\r\n"
  3039. " &%sBinaryMofGUID,\r\n"
  3040. " 1,\r\n"
  3041. " 0\r\n"
  3042. " }\r\n"
  3043. "#endif\r\n"
  3044. "};\r\n\r\n"
  3045. "#define %sGuidCount (sizeof(%sGuidList) / sizeof(WMIGUIDREGINFO))\r\n"
  3046. "\r\n",
  3047. BaseName, BaseName, BaseName);
  3048. FilePrint(TemplateHandle,
  3049. "//\r\n"
  3050. "// We need to hang onto the registry path passed to our driver entry so that\r\n"
  3051. "// we can return it in the QueryWmiRegInfo callback. Be sure to store a copy\r\n"
  3052. "// of it into %sRegistryPath in the DriverEntry routine\r\n"
  3053. "//\r\n"
  3054. "extern UNICODE_STRING %sRegistryPath;\r\n\r\n",
  3055. BaseName, BaseName);
  3056. FilePrint(TemplateHandle,
  3057. "NTSTATUS %sSystemControl(\r\n"
  3058. " PDEVICE_OBJECT DeviceObject,\r\n"
  3059. " PIRP Irp\r\n"
  3060. " )\r\n"
  3061. "/*++\r\n"
  3062. "\r\n"
  3063. "Routine Description:\r\n"
  3064. "\r\n"
  3065. " Dispatch routine for System Control IRPs (MajorFunction == IRP_MJ_SYSTEM_CONTROL)\r\n"
  3066. "\r\n"
  3067. "Arguments:\r\n"
  3068. "\r\n"
  3069. " DeviceObject \r\n"
  3070. " Irp\r\n"
  3071. "\r\n"
  3072. "Return Value:\r\n"
  3073. "\r\n"
  3074. " NT status code\r\n"
  3075. "\r\n"
  3076. "--*/\r\n"
  3077. "{\r\n"
  3078. " PWMILIB_CONTEXT wmilibContext;\r\n"
  3079. " NTSTATUS status;\r\n"
  3080. " SYSCTL_IRP_DISPOSITION disposition;\r\n"
  3081. " PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;\r\n"
  3082. "\r\n"
  3083. " //\r\n"
  3084. " // TODO: Point at the WMILIB context within the device extension\r\n"
  3085. " wmilibContext = &devExt->WmiLib;\r\n"
  3086. "\r\n"
  3087. " //\r\n"
  3088. " // Call Wmilib helper function to crack the irp. If this is a wmi irp\r\n"
  3089. " // that is targetted for this device then WmiSystemControl will callback\r\n"
  3090. " // at the appropriate callback routine.\r\n"
  3091. " //\r\n"
  3092. " status = WmiSystemControl(wmilibContext,\r\n"
  3093. " DeviceObject,\r\n"
  3094. " Irp,\r\n"
  3095. " &disposition);\r\n"
  3096. "\r\n"
  3097. " switch(disposition)\r\n"
  3098. " {\r\n"
  3099. " case IrpProcessed:\r\n"
  3100. " {\r\n"
  3101. " //\r\n"
  3102. " // This irp has been processed and may be completed or pending.\r\n"
  3103. " break;\r\n"
  3104. " }\r\n"
  3105. "\r\n"
  3106. " case IrpNotCompleted:\r\n"
  3107. " {\r\n"
  3108. " //\r\n"
  3109. " // This irp has not been completed, but has been fully processed.\r\n"
  3110. " // we will complete it now.\r\n"
  3111. " IoCompleteRequest(Irp, IO_NO_INCREMENT);\r\n"
  3112. " break;\r\n"
  3113. " }\r\n"
  3114. "\r\n"
  3115. " case IrpForward:\r\n"
  3116. " case IrpNotWmi:\r\n"
  3117. " default:\r\n"
  3118. " {\r\n"
  3119. " //\r\n"
  3120. " // This irp is either not a WMI irp or is a WMI irp targetted\r\n"
  3121. " // at a device lower in the stack.\r\n"
  3122. "\r\n"
  3123. " // TODO: Forward IRP down the device stack to the next device\r\n"
  3124. " // Or if this is a PDO then just complete the irp without\r\n"
  3125. " // touching it.\r\n"
  3126. " break;\r\n"
  3127. " }\r\n"
  3128. "\r\n"
  3129. " }\r\n"
  3130. "\r\n"
  3131. " return(status);\r\n"
  3132. "}\r\n",
  3133. BaseName);
  3134. FilePrint(TemplateHandle,
  3135. "NTSTATUS\r\n"
  3136. "%sQueryWmiRegInfo(\r\n"
  3137. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  3138. " OUT ULONG *RegFlags,\r\n"
  3139. " OUT PUNICODE_STRING InstanceName,\r\n"
  3140. " OUT PUNICODE_STRING *RegistryPath,\r\n"
  3141. " OUT PUNICODE_STRING MofResourceName,\r\n"
  3142. " OUT PDEVICE_OBJECT *Pdo\r\n"
  3143. " )\r\n"
  3144. "/*++\r\n"
  3145. "\r\n"
  3146. "Routine Description:\r\n"
  3147. "\r\n"
  3148. " This routine is a callback into the driver to retrieve the list of\r\n"
  3149. " guids or data blocks that the driver wants to register with WMI. This\r\n"
  3150. " routine may not pend or block. Driver should NOT call\r\n"
  3151. " WmiCompleteRequest.\r\n"
  3152. "\r\n"
  3153. "Arguments:\r\n"
  3154. "\r\n"
  3155. " DeviceObject is the device whose registration info is being queried\r\n"
  3156. "\r\n"
  3157. " *RegFlags returns with a set of flags that describe the guids being\r\n"
  3158. " registered for this device. If the device wants enable and disable\r\n"
  3159. " collection callbacks before receiving queries for the registered\r\n"
  3160. " guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the\r\n"
  3161. " returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case\r\n"
  3162. " the instance name is determined from the PDO associated with the\r\n"
  3163. " device object. Note that the PDO must have an associated devnode. If\r\n"
  3164. " WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique\r\n"
  3165. " name for the device.\r\n"
  3166. "\r\n"
  3167. " InstanceName returns with the instance name for the guids if\r\n"
  3168. " WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The\r\n"
  3169. " caller will call ExFreePool with the buffer returned.\r\n"
  3170. "\r\n"
  3171. " *RegistryPath returns with the registry path of the driver. The caller\r\n"
  3172. " does NOT free this buffer.\r\n"
  3173. "\r\n"
  3174. " *MofResourceName returns with the name of the MOF resource attached to\r\n"
  3175. " the binary file. If the driver does not have a mof resource attached\r\n"
  3176. " then this can be returned as NULL. The caller does NOT free this\r\n"
  3177. " buffer.\r\n"
  3178. "\r\n"
  3179. " *Pdo returns with the device object for the PDO associated with this\r\n"
  3180. " device if the WMIREG_FLAG_INSTANCE_PDO flag is retured in\r\n"
  3181. " *RegFlags.\r\n"
  3182. "\r\n"
  3183. "Return Value:\r\n"
  3184. "\r\n"
  3185. " status\r\n"
  3186. "\r\n"
  3187. "--*/\r\n"
  3188. "{\r\n"
  3189. " struct DEVICE_EXTENSION * devExt = DeviceObject->DeviceExtension;\r\n"
  3190. "\r\n"
  3191. " //\r\n"
  3192. " // Return the registry path for this driver. This is required so WMI\r\n"
  3193. " // can find your driver image and can attribute any eventlog messages to\r\n"
  3194. " // your driver.\r\n"
  3195. " *RegistryPath = &%sRegistryPath;\r\n"
  3196. " \r\n"
  3197. "#ifndef USE_BINARY_MOF_RESOURCE\r\n"
  3198. " //\r\n"
  3199. " // Return the name specified in the .rc file of the resource which\r\n"
  3200. " // contains the bianry mof data. By default WMI will look for this\r\n"
  3201. " // resource in the driver image (.sys) file, however if the value\r\n"
  3202. " // MofImagePath is specified in the driver's registry key\r\n"
  3203. " // then WMI will look for the resource in the file specified there.\r\n"
  3204. " RtlInitUnicodeString(MofResourceName, L\"MofResourceName\");\r\n"
  3205. "#endif\r\n"
  3206. "\r\n"
  3207. " //\r\n"
  3208. " // Specify that the driver wants WMI to automatically generate instance\r\n"
  3209. " // names for all of the data blocks based upon the device stack's\r\n"
  3210. " // device instance id. Doing this is STRONGLY recommended since additional\r\n"
  3211. " // information about the device would then be available to callers.\r\n"
  3212. " *RegFlags = WMIREG_FLAG_INSTANCE_PDO;\r\n"
  3213. "\r\n"
  3214. " //\r\n"
  3215. " // TODO: Assign the physical device object for the device stack to *Pdo\r\n"
  3216. " *Pdo = devExt->physicalDevObj;\r\n"
  3217. "\r\n"
  3218. " return(STATUS_SUCCESS);\r\n"
  3219. "}\r\n"
  3220. "\r\n",
  3221. BaseName, BaseName);
  3222. FilePrint(TemplateHandle,
  3223. "NTSTATUS\r\n"
  3224. "%sQueryWmiDataBlock(\r\n"
  3225. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  3226. " IN PIRP Irp,\r\n"
  3227. " IN ULONG GuidIndex,\r\n"
  3228. " IN ULONG InstanceIndex,\r\n"
  3229. " IN ULONG InstanceCount,\r\n"
  3230. " IN OUT PULONG InstanceLengthArray,\r\n"
  3231. " IN ULONG BufferAvail,\r\n"
  3232. " OUT PUCHAR Buffer\r\n"
  3233. " )\r\n"
  3234. "/*++\r\n"
  3235. "\r\n"
  3236. "Routine Description:\r\n"
  3237. "\r\n"
  3238. " This routine is a callback into the driver to query for the contents of\r\n"
  3239. " all instances of a data block. If the driver can satisfy the query within\r\n"
  3240. " the callback it should call WmiCompleteRequest to complete the irp before\r\n"
  3241. " returning to the caller. Or the driver can return STATUS_PENDING if the\r\n"
  3242. " irp cannot be completed immediately and must then call WmiCompleteRequest\r\n"
  3243. " once the query is satisfied.\r\n"
  3244. "\r\n"
  3245. "Arguments:\r\n"
  3246. "\r\n"
  3247. " DeviceObject is the device whose data block is being queried\r\n"
  3248. "\r\n"
  3249. " Irp is the Irp that makes this request\r\n"
  3250. "\r\n"
  3251. " GuidIndex is the index into the list of guids provided when the\r\n"
  3252. " device registered\r\n"
  3253. "\r\n"
  3254. " InstanceCount is the number of instnaces expected to be returned for\r\n"
  3255. " the data block.\r\n"
  3256. "\r\n"
  3257. " InstanceLengthArray is a pointer to an array of ULONG that returns the\r\n"
  3258. " lengths of each instance of the data block. If this is NULL then\r\n"
  3259. " there was not enough space in the output buffer to fufill the request\r\n"
  3260. " so the irp should be completed with the buffer needed.\r\n"
  3261. "\r\n"
  3262. " BufferAvail on entry has the maximum size available to write the data\r\n"
  3263. " blocks.\r\n"
  3264. "\r\n"
  3265. " Buffer on return is filled with the returned data blocks. Note that each\r\n"
  3266. " instance of the data block must be aligned on a 8 byte boundry.\r\n"
  3267. "\r\n"
  3268. "\r\n"
  3269. "Return Value:\r\n"
  3270. "\r\n"
  3271. " status\r\n"
  3272. "\r\n"
  3273. "--*/\r\n"
  3274. "{\r\n"
  3275. " NTSTATUS status = STATUS_UNSUCCESSFUL;\r\n"
  3276. " struct DEVICE_EXTENSION * devExt = DeviceObject->DeviceExtension;\r\n"
  3277. " ULONG sizeNeeded;\r\n"
  3278. "\r\n"
  3279. " switch(GuidIndex)\r\n"
  3280. " {\r\n"
  3281. ,BaseName );
  3282. FilePrintMofClassLoop(TemplateHandle, MofResource, ClassName, i, TRUE, (
  3283. " case %wsGuidIndex:\r\n"
  3284. " {\r\n"
  3285. " //\r\n"
  3286. " // TODO: Check that the size of the buffer passed is large enough\r\n"
  3287. " // for all of the instances requested and if so fill Buffer\r\n"
  3288. " // with the data. Make sure that each instance begins on an\r\n"
  3289. " // 8 byte boundry.\r\n"
  3290. " //\r\n"
  3291. " break;\r\n"
  3292. " }\r\n\r\n",
  3293. ClassName));
  3294. FilePrint(TemplateHandle,
  3295. "#ifdef USE_BINARY_MOF_QUERY\r\n"
  3296. " case BinaryMofGuidIndex:\r\n"
  3297. " {\r\n"
  3298. " //\r\n"
  3299. " // TODO: If the driver supports reporting MOF dynamically, \r\n"
  3300. " // change this code to handle multiple instances of the\r\n"
  3301. " // binary mof guid and return only those instances that\r\n"
  3302. " // should be reported to the schema\r\n"
  3303. " //\r\n"
  3304. " sizeNeeded = sizeof(%sBinaryMofData);\r\n"
  3305. "\r\n"
  3306. " if (BufferAvail < sizeNeeded)\r\n"
  3307. " {\r\n"
  3308. " status = STATUS_BUFFER_TOO_SMALL;\r\n"
  3309. " } else {\r\n"
  3310. " RtlCopyMemory(Buffer, %sBinaryMofData, sizeNeeded);\r\n"
  3311. " *InstanceLengthArray = sizeNeeded;\r\n"
  3312. " status = STATUS_SUCCESS;\r\n"
  3313. " }\r\n"
  3314. " break;\r\n"
  3315. " }\r\n"
  3316. "#endif\r\n"
  3317. "\r\n"
  3318. " default:\r\n"
  3319. " {\r\n"
  3320. " status = STATUS_WMI_GUID_NOT_FOUND;\r\n"
  3321. " break;\r\n"
  3322. " }\r\n"
  3323. " }\r\n"
  3324. "\r\n"
  3325. " //\r\n"
  3326. " // Complete the irp. If there was not enough room in the output buffer\r\n"
  3327. " // then status is STATUS_BUFFER_TOO_SMALL and sizeNeeded has the size\r\n"
  3328. " // needed to return all of the data. If there was enough room then\r\n"
  3329. " // status is STATUS_SUCCESS and sizeNeeded is the actual number of bytes\r\n"
  3330. " // being returned.\r\n"
  3331. " status = WmiCompleteRequest(\r\n"
  3332. " DeviceObject,\r\n"
  3333. " Irp,\r\n"
  3334. " status,\r\n"
  3335. " sizeNeeded,\r\n"
  3336. " IO_NO_INCREMENT);\r\n"
  3337. "\r\n"
  3338. " return(status);\r\n"
  3339. "}\r\n"
  3340. , BaseName, BaseName);
  3341. if (! IsReadOnly)
  3342. {
  3343. FilePrint(TemplateHandle,
  3344. "\r\n"
  3345. "NTSTATUS\r\n"
  3346. "%sSetWmiDataBlock(\r\n"
  3347. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  3348. " IN PIRP Irp,\r\n"
  3349. " IN ULONG GuidIndex,\r\n"
  3350. " IN ULONG InstanceIndex,\r\n"
  3351. " IN ULONG BufferSize,\r\n"
  3352. " IN PUCHAR Buffer\r\n"
  3353. " )\r\n"
  3354. "/*++\r\n"
  3355. "\r\n"
  3356. "Routine Description:\r\n"
  3357. "\r\n"
  3358. " This routine is a callback into the driver to change the contents of\r\n"
  3359. " a data block. If the driver can change the data block within\r\n"
  3360. " the callback it should call WmiCompleteRequest to complete the irp before\r\n"
  3361. " returning to the caller. Or the driver can return STATUS_PENDING if the\r\n"
  3362. " irp cannot be completed immediately and must then call WmiCompleteRequest\r\n"
  3363. " once the data is changed.\r\n"
  3364. "\r\n"
  3365. "Arguments:\r\n"
  3366. "\r\n"
  3367. " DeviceObject is the device whose data block is being queried\r\n"
  3368. "\r\n"
  3369. " Irp is the Irp that makes this request\r\n"
  3370. "\r\n"
  3371. " GuidIndex is the index into the list of guids provided when the\r\n"
  3372. " device registered\r\n"
  3373. "\r\n"
  3374. " BufferSize has the size of the data block passed\r\n"
  3375. "\r\n"
  3376. " Buffer has the new values for the data block\r\n"
  3377. "\r\n"
  3378. "\r\n"
  3379. "Return Value:\r\n"
  3380. "\r\n"
  3381. " status\r\n"
  3382. "\r\n"
  3383. "--*/\r\n"
  3384. "{\r\n"
  3385. " NTSTATUS status;\r\n"
  3386. " struct DEVICE_EXTENSION * devExt = DeviceObject->DeviceExtension;\r\n"
  3387. "\r\n"
  3388. "\r\n"
  3389. " switch(GuidIndex)\r\n"
  3390. " {\r\n"
  3391. , BaseName);
  3392. EnumerateMofClasses(TemplateHandle,
  3393. MofResource,
  3394. GenerateSetList,
  3395. "\r\n"
  3396. " case %wsGuidIndex:\r\n"
  3397. " { \r\n"
  3398. " //\r\n"
  3399. " // TODO: Validate InstanceIndex, BufferSize and Buffer contents\r\n"
  3400. " // and if valid then set the underlying data block, write\r\n"
  3401. " // to the hardware, etc.\r\n"
  3402. " break;\r\n"
  3403. " }\r\n"
  3404. "\r\n"
  3405. );
  3406. FilePrint(TemplateHandle,
  3407. " default:\r\n"
  3408. " {\r\n"
  3409. " status = STATUS_WMI_GUID_NOT_FOUND;\r\n"
  3410. " break;\r\n"
  3411. " }\r\n"
  3412. " }\r\n"
  3413. "\r\n"
  3414. " status = WmiCompleteRequest(\r\n"
  3415. " DeviceObject,\r\n"
  3416. " Irp,\r\n"
  3417. " status,\r\n"
  3418. " 0,\r\n"
  3419. " IO_NO_INCREMENT);\r\n"
  3420. "\r\n"
  3421. " return(status);\r\n"
  3422. "\r\n"
  3423. "\r\n"
  3424. "}\r\n"
  3425. );
  3426. FilePrint(TemplateHandle,
  3427. " \r\n"
  3428. "NTSTATUS\r\n"
  3429. "%sSetWmiDataItem(\r\n"
  3430. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  3431. " IN PIRP Irp,\r\n"
  3432. " IN ULONG GuidIndex,\r\n"
  3433. " IN ULONG InstanceIndex,\r\n"
  3434. " IN ULONG DataItemId,\r\n"
  3435. " IN ULONG BufferSize,\r\n"
  3436. " IN PUCHAR Buffer\r\n"
  3437. " )\r\n"
  3438. "/*++\r\n"
  3439. "\r\n"
  3440. "Routine Description:\r\n"
  3441. "\r\n"
  3442. " This routine is a callback into the driver to change the contents of\r\n"
  3443. " a data block. If the driver can change the data block within\r\n"
  3444. " the callback it should call WmiCompleteRequest to complete the irp before\r\n"
  3445. " returning to the caller. Or the driver can return STATUS_PENDING if the\r\n"
  3446. " irp cannot be completed immediately and must then call WmiCompleteRequest\r\n"
  3447. " once the data is changed.\r\n"
  3448. "\r\n"
  3449. "Arguments:\r\n"
  3450. "\r\n"
  3451. " DeviceObject is the device whose data block is being changed\r\n"
  3452. "\r\n"
  3453. " Irp is the Irp that makes this request\r\n"
  3454. "\r\n"
  3455. " GuidIndex is the index into the list of guids provided when the\r\n"
  3456. " device registered\r\n"
  3457. "\r\n"
  3458. " DataItemId has the id of the data item being set\r\n"
  3459. "\r\n"
  3460. " BufferSize has the size of the data item passed\r\n"
  3461. "\r\n"
  3462. " Buffer has the new values for the data item\r\n"
  3463. "\r\n"
  3464. "\r\n"
  3465. "Return Value:\r\n"
  3466. "\r\n"
  3467. " status\r\n"
  3468. "\r\n"
  3469. "--*/\r\n"
  3470. "{\r\n"
  3471. " NTSTATUS status;\r\n"
  3472. "\r\n"
  3473. " switch(GuidIndex)\r\n"
  3474. " {\r\n"
  3475. , BaseName);
  3476. EnumerateMofClasses(TemplateHandle,
  3477. MofResource,
  3478. GenerateSetList,
  3479. " case %wsGuidIndex:\r\n"
  3480. " { \r\n"
  3481. " //\r\n"
  3482. " // TODO: Validate InstanceIndex, DataItemId, BufferSize \r\n"
  3483. " // and Buffer contents\r\n"
  3484. " // and if valid then set the underlying data item, write\r\n"
  3485. " // to the hardware, etc.\r\n"
  3486. " break;\r\n"
  3487. " }\r\n");
  3488. FilePrint(TemplateHandle,
  3489. " default:\r\n"
  3490. " {\r\n"
  3491. " status = STATUS_WMI_GUID_NOT_FOUND;\r\n"
  3492. " break;\r\n"
  3493. " }\r\n"
  3494. " }\r\n"
  3495. "\r\n"
  3496. " status = WmiCompleteRequest(\r\n"
  3497. " DeviceObject,\r\n"
  3498. " Irp,\r\n"
  3499. " status,\r\n"
  3500. " 0,\r\n"
  3501. " IO_NO_INCREMENT);\r\n"
  3502. "\r\n"
  3503. " return(status);\r\n"
  3504. "}\r\n"
  3505. );
  3506. }
  3507. if (SupportsMethods)
  3508. {
  3509. FilePrint(TemplateHandle,
  3510. "NTSTATUS\r\n"
  3511. "%sExecuteWmiMethod(\r\n"
  3512. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  3513. " IN PIRP Irp,\r\n"
  3514. " IN ULONG GuidIndex,\r\n"
  3515. " IN ULONG InstanceIndex,\r\n"
  3516. " IN ULONG MethodId,\r\n"
  3517. " IN ULONG InBufferSize,\r\n"
  3518. " IN ULONG OutBufferSize,\r\n"
  3519. " IN PUCHAR Buffer\r\n"
  3520. " )\r\n"
  3521. "/*++\r\n"
  3522. "\r\n"
  3523. "Routine Description:\r\n"
  3524. "\r\n"
  3525. " This routine is a callback into the driver to execute a method. If\r\n"
  3526. " the driver can complete the method within the callback it should\r\n"
  3527. " call WmiCompleteRequest to complete the irp before returning to the\r\n"
  3528. " caller. Or the driver can return STATUS_PENDING if the irp cannot be\r\n"
  3529. " completed immediately and must then call WmiCompleteRequest once the\r\n"
  3530. " data is changed.\r\n"
  3531. "\r\n"
  3532. "Arguments:\r\n"
  3533. "\r\n"
  3534. " DeviceObject is the device whose method is being executed\r\n"
  3535. "\r\n"
  3536. " Irp is the Irp that makes this request\r\n"
  3537. "\r\n"
  3538. " GuidIndex is the index into the list of guids provided when the\r\n"
  3539. " device registered\r\n"
  3540. "\r\n"
  3541. " MethodId has the id of the method being called\r\n"
  3542. "\r\n"
  3543. " InBufferSize has the size of the data block passed in as the input to\r\n"
  3544. " the method.\r\n"
  3545. "\r\n"
  3546. " OutBufferSize on entry has the maximum size available to write the\r\n"
  3547. " returned data block.\r\n"
  3548. "\r\n"
  3549. " Buffer is filled with the input buffer on entry and returns with\r\n"
  3550. " the output data block\r\n"
  3551. "\r\n"
  3552. "Return Value:\r\n"
  3553. "\r\n"
  3554. " status\r\n"
  3555. "\r\n"
  3556. "--*/\r\n"
  3557. "{\r\n"
  3558. " ULONG sizeNeeded = 0;\r\n"
  3559. " NTSTATUS status;\r\n"
  3560. "\r\n"
  3561. " switch(GuidIndex)\r\n"
  3562. " {\r\n"
  3563. " \r\n"
  3564. , BaseName);
  3565. EnumerateMofClasses(TemplateHandle,
  3566. MofResource,
  3567. GenerateMethodCTemplate,
  3568. NULL);
  3569. FilePrint(TemplateHandle,
  3570. " default:\r\n"
  3571. " {\r\n"
  3572. " status = STATUS_WMI_GUID_NOT_FOUND;\r\n"
  3573. " }\r\n"
  3574. " }\r\n"
  3575. "\r\n"
  3576. " status = WmiCompleteRequest(\r\n"
  3577. " DeviceObject,\r\n"
  3578. " Irp,\r\n"
  3579. " status,\r\n"
  3580. " sizeNeeded,\r\n"
  3581. " IO_NO_INCREMENT);\r\n"
  3582. "\r\n"
  3583. " return(status);\r\n"
  3584. "}\r\n"
  3585. );
  3586. }
  3587. if (SupportsFunctionControl)
  3588. {
  3589. FilePrint(TemplateHandle,
  3590. "NTSTATUS\r\n"
  3591. "%sFunctionControl(\r\n"
  3592. " IN PDEVICE_OBJECT DeviceObject,\r\n"
  3593. " IN PIRP Irp,\r\n"
  3594. " IN ULONG GuidIndex,\r\n"
  3595. " IN WMIENABLEDISABLECONTROL Function,\r\n"
  3596. " IN BOOLEAN Enable\r\n"
  3597. " )\r\n"
  3598. "/*++\r\n"
  3599. "\r\n"
  3600. "Routine Description:\r\n"
  3601. "\r\n"
  3602. " This routine is a callback into the driver to enabled or disable event\r\n"
  3603. " generation or data block collection. A device should only expect a\r\n"
  3604. " single enable when the first event or data consumer enables events or\r\n"
  3605. " data collection and a single disable when the last event or data\r\n"
  3606. " consumer disables events or data collection. Data blocks will only\r\n"
  3607. " receive collection enable/disable if they were registered as requiring\r\n"
  3608. " it. If the driver can complete enabling/disabling within the callback it\r\n"
  3609. " should call WmiCompleteRequest to complete the irp before returning to\r\n"
  3610. " the caller. Or the driver can return STATUS_PENDING if the irp cannot be\r\n"
  3611. " completed immediately and must then call WmiCompleteRequest once the\r\n"
  3612. " data is changed.\r\n"
  3613. "\r\n"
  3614. "Arguments:\r\n"
  3615. "\r\n"
  3616. " DeviceObject is the device object\r\n"
  3617. "\r\n"
  3618. " GuidIndex is the index into the list of guids provided when the\r\n"
  3619. " device registered\r\n"
  3620. "\r\n"
  3621. " Function specifies which functionality is being enabled or disabled\r\n"
  3622. "\r\n"
  3623. " Enable is TRUE then the function is being enabled else disabled\r\n"
  3624. "\r\n"
  3625. "Return Value:\r\n"
  3626. "\r\n"
  3627. " status\r\n"
  3628. "\r\n"
  3629. "--*/\r\n"
  3630. "{\r\n"
  3631. " NTSTATUS status;\r\n"
  3632. "\r\n"
  3633. " switch(GuidIndex)\r\n"
  3634. " {\r\n",
  3635. BaseName);
  3636. EnumerateMofClasses(TemplateHandle,
  3637. MofResource,
  3638. GenerateFunctionControlListTemplate,
  3639. NULL);
  3640. FilePrint(TemplateHandle,
  3641. " \r\n"
  3642. " default:\r\n"
  3643. " {\r\n"
  3644. " status = STATUS_WMI_GUID_NOT_FOUND;\r\n"
  3645. " break;\r\n"
  3646. " }\r\n"
  3647. " }\r\n"
  3648. " \r\n"
  3649. " status = WmiCompleteRequest(\r\n"
  3650. " DeviceObject,\r\n"
  3651. " Irp,\r\n"
  3652. " STATUS_SUCCESS,\r\n"
  3653. " 0,\r\n"
  3654. " IO_NO_INCREMENT);\r\n"
  3655. " return(status);\r\n"
  3656. "}\r\n"
  3657. );
  3658. }
  3659. FilePrint(TemplateHandle,
  3660. "NTSTATUS\r\n"
  3661. "%sInitializeWmilibContext(\r\n"
  3662. " IN PWMILIB_CONTEXT WmilibContext\r\n"
  3663. " )\r\n"
  3664. "/*++\r\n"
  3665. "\r\n"
  3666. "Routine Description:\r\n"
  3667. "\r\n"
  3668. " This routine will initialize the wmilib context structure with the\r\n"
  3669. " guid list and the pointers to the wmilib callback functions. This routine\r\n"
  3670. " should be called before calling IoWmiRegistrationControl to register\r\n"
  3671. " your device object.\r\n"
  3672. "\r\n"
  3673. "Arguments:\r\n"
  3674. "\r\n"
  3675. " WmilibContext is pointer to the wmilib context.\r\n"
  3676. "\r\n"
  3677. "Return Value:\r\n"
  3678. "\r\n"
  3679. " status\r\n"
  3680. "\r\n"
  3681. "--*/\r\n"
  3682. "{\r\n"
  3683. " RtlZeroMemory(WmilibContext, sizeof(WMILIB_CONTEXT));\r\n"
  3684. " \r\n"
  3685. " WmilibContext->GuidCount = %sGuidCount;\r\n"
  3686. " WmilibContext->GuidList = %sGuidList; \r\n"
  3687. " \r\n"
  3688. " WmilibContext->QueryWmiRegInfo = %sQueryWmiRegInfo;\r\n"
  3689. " WmilibContext->QueryWmiDataBlock = %sQueryWmiDataBlock;\r\n",
  3690. BaseName,
  3691. BaseName,
  3692. BaseName,
  3693. BaseName,
  3694. BaseName);
  3695. if (! IsReadOnly)
  3696. {
  3697. FilePrint(TemplateHandle,
  3698. " WmilibContext->SetWmiDataBlock = %sSetWmiDataBlock;\r\n"
  3699. " WmilibContext->SetWmiDataItem = %sSetWmiDataItem;\r\n",
  3700. BaseName, BaseName);
  3701. }
  3702. if (SupportsMethods)
  3703. {
  3704. FilePrint(TemplateHandle,
  3705. " WmilibContext->ExecuteWmiMethod = %sExecuteWmiMethod;\r\n",
  3706. BaseName);
  3707. }
  3708. if (SupportsFunctionControl)
  3709. {
  3710. FilePrint(TemplateHandle,
  3711. " WmilibContext->WmiFunctionControl = %sFunctionControl;\r\n",
  3712. BaseName);
  3713. }
  3714. FilePrint(TemplateHandle,
  3715. "\r\n"
  3716. " return(STATUS_SUCCESS);\r\n"
  3717. "}"
  3718. );
  3719. CloseHandle(TemplateHandle);
  3720. return(ERROR_SUCCESS);
  3721. }
  3722. //
  3723. // A data item is variable length if it is a variable length array or a
  3724. // string that does not have a maxiumum length specified
  3725. //
  3726. #define WmipIsDataitemVariableLen(DataItem) \
  3727. ( (DataItem->Flags & MOFDI_FLAG_VARIABLE_ARRAY) || \
  3728. ((DataItem->DataType == MOFString) && \
  3729. (DataItem->MaxLen == 0)) || \
  3730. (DataItem->DataType == MOFZTString) || \
  3731. (DataItem->DataType == MOFAnsiString) )
  3732. BOOLEAN ClassCanCreateHeader(
  3733. PMOFCLASSINFOW ClassInfo,
  3734. ULONG RequiredFlags,
  3735. PULONG ItemCount
  3736. )
  3737. {
  3738. ULONG i;
  3739. BOOLEAN HasVariableLength = FALSE;
  3740. PMOFDATAITEMW DataItem;
  3741. ULONG Count;
  3742. Count = 0;
  3743. for (i = 0; i < ClassInfo->DataItemCount; i++)
  3744. {
  3745. DataItem = &ClassInfo->DataItems[i];
  3746. if ((RequiredFlags == 0xffffffff) ||
  3747. (DataItem->Flags & RequiredFlags))
  3748. {
  3749. if (HasVariableLength)
  3750. {
  3751. *ItemCount = Count;
  3752. return(FALSE);
  3753. }
  3754. Count++;
  3755. HasVariableLength = (! ForceHeaderGeneration) &&
  3756. WmipIsDataitemVariableLen(DataItem);
  3757. }
  3758. }
  3759. *ItemCount = Count;
  3760. return(TRUE);
  3761. }
  3762. ULONG DumpCppQuote(
  3763. HANDLE TemplateHandle,
  3764. CBMOFQualList *QualifierList
  3765. )
  3766. {
  3767. DWORD QualifierType;
  3768. ULONG Status;
  3769. WCHAR *StringPtr;
  3770. if (QualifierList != NULL)
  3771. {
  3772. QualifierType = VT_BSTR;
  3773. Status = WmipFindMofQualifier(QualifierList,
  3774. L"cpp_quote",
  3775. &QualifierType,
  3776. NULL,
  3777. &StringPtr);
  3778. if (Status == ERROR_SUCCESS)
  3779. {
  3780. Status = FilePrint(TemplateHandle,
  3781. "\n%ws\n",
  3782. StringPtr);
  3783. BMOFFree(StringPtr);
  3784. }
  3785. } else {
  3786. Status = ERROR_SUCCESS;
  3787. }
  3788. return(Status);
  3789. }
  3790. PWCHAR MofDataTypeText[15] =
  3791. {
  3792. L"LONG", // 32bit integer
  3793. L"ULONG", // 32bit unsigned integer
  3794. L"LONGLONG", // 64bit integer
  3795. L"ULONGLONG", // 32bit unsigned integer
  3796. L"SHORT", // 16bit integer
  3797. L"USHORT", // 16bit unsigned integer
  3798. L"CHAR", // 8bit integer
  3799. L"UCHAR", // 8bit unsigned integer
  3800. L"WCHAR", // Wide (16bit) character
  3801. L"DATETIME", // Date field
  3802. L"BOOLEAN", // 8bit Boolean value
  3803. L"MOFEmbedded", // Embedded class
  3804. L"MOFString", // Counted String type
  3805. L"MOFZTString", // NULL terminated unicode string
  3806. L"MOFAnsiString" // NULL terminated ansi string
  3807. };
  3808. ULONG GenerateClassHeader(
  3809. HANDLE TemplateHandle,
  3810. PMOFRESOURCE MofResource,
  3811. PWCHAR ClassName,
  3812. PMOFCLASSINFOW ClassInfo,
  3813. ULONG RequiredFlags
  3814. )
  3815. {
  3816. ULONG Status;
  3817. CBMOFDataItem *PropertyObject;
  3818. CBMOFQualList *PropertyQualifier;
  3819. ULONG Status2, QualifierType;
  3820. PVOID ptr;
  3821. ULONG ValueMapCount, DefineValuesCount, ValuesCount;
  3822. PWCHAR *ValueMapPtr, *DefineValuesPtr, *ValuesPtr;
  3823. ULONG BitMapCount, DefineBitMapCount, BitValuesCount, BitMapValue;
  3824. PWCHAR *BitMapPtr, *DefineBitMapPtr, *BitValuesPtr;
  3825. PWCHAR DefineDataId;
  3826. WCHAR DefineDataIdText[MAX_PATH];
  3827. PMOFDATAITEMW DataItem, LastDataItem = NULL;
  3828. PWCHAR Description;
  3829. PMOFCLASS EmbeddedClass;
  3830. ULONG i, j;
  3831. PWCHAR DataTypeText;
  3832. ULONG ItemCount;
  3833. PWCHAR VLCommentText = L" ";
  3834. WCHAR *StringPtr;
  3835. WmipDebugPrint(("Generate class header for %ws\n", ClassName));
  3836. if ((ClassCanCreateHeader(ClassInfo, RequiredFlags, &ItemCount)) &&
  3837. (ItemCount != 0))
  3838. {
  3839. Status = FilePrint(TemplateHandle,
  3840. "typedef struct _%ws\r\n{\r\n",
  3841. ClassName);
  3842. for (i = 0; i < ClassInfo->DataItemCount; i++)
  3843. {
  3844. DataItem = &ClassInfo->DataItems[i];
  3845. if ((RequiredFlags == 0xffffffff) ||
  3846. (DataItem->Flags & RequiredFlags))
  3847. {
  3848. LastDataItem = DataItem;
  3849. PropertyQualifier = (CBMOFQualList *)DataItem->PropertyQualifierHandle;
  3850. DumpCppQuote(TemplateHandle,
  3851. PropertyQualifier);
  3852. //
  3853. // Handle any bit maps via the DefineBitMap qualifier
  3854. //
  3855. DefineBitMapCount = 0;
  3856. DefineBitMapPtr = NULL;
  3857. BitValuesCount = 0;
  3858. BitValuesPtr = NULL;
  3859. BitMapCount = 0;
  3860. BitMapPtr = NULL;
  3861. QualifierType = VT_ARRAY | VT_BSTR;
  3862. if (WmipFindMofQualifier(PropertyQualifier,
  3863. L"DefineBitMap",
  3864. &QualifierType,
  3865. &DefineBitMapCount,
  3866. &DefineBitMapPtr) == ERROR_SUCCESS)
  3867. {
  3868. QualifierType = VT_ARRAY | VT_BSTR;
  3869. if (WmipFindMofQualifier(PropertyQualifier,
  3870. L"BitValues",
  3871. &QualifierType,
  3872. &BitValuesCount,
  3873. &BitValuesPtr) == ERROR_SUCCESS)
  3874. {
  3875. if (DefineBitMapCount == BitValuesCount)
  3876. {
  3877. QualifierType = VT_ARRAY | VT_BSTR;
  3878. if (WmipFindMofQualifier(PropertyQualifier,
  3879. L"BitMap",
  3880. &QualifierType,
  3881. &BitMapCount,
  3882. &BitMapPtr) != ERROR_SUCCESS)
  3883. {
  3884. BitMapPtr = NULL;
  3885. }
  3886. FilePrint(TemplateHandle,
  3887. "\r\n");
  3888. for (j = 0; j < DefineBitMapCount; j++)
  3889. {
  3890. if ((BitMapPtr != NULL) &&
  3891. (j < BitMapCount) &&
  3892. (BitMapPtr[j] != NULL))
  3893. {
  3894. FilePrint(TemplateHandle,
  3895. "// %ws\r\n",
  3896. BitMapPtr[j]);
  3897. }
  3898. BitMapValue = 1 << _wtoi(BitValuesPtr[j]);
  3899. FilePrint(TemplateHandle,
  3900. "#define %ws 0x%x\r\n",
  3901. DefineBitMapPtr[j],
  3902. BitMapValue);
  3903. }
  3904. FilePrint(TemplateHandle,
  3905. "\r\n");
  3906. } else {
  3907. FilePrint(TemplateHandle, "// Warning: Cannot create Bitmap definitions\r\n// Requires DefineBitMap and BitValues qualifier with same number of elements\r\n\r\n");
  3908. }
  3909. for (j = 0; j < BitValuesCount; j++)
  3910. {
  3911. BMOFFree(BitValuesPtr[j]);
  3912. }
  3913. BMOFFree(BitValuesPtr);
  3914. if (BitMapPtr != NULL)
  3915. {
  3916. for (j = 0; j < BitMapCount; j++)
  3917. {
  3918. BMOFFree(BitMapPtr[j]);
  3919. }
  3920. BMOFFree(BitMapPtr);
  3921. }
  3922. } else {
  3923. FilePrint(TemplateHandle, "// Warning: Cannot create Bitmap definitions\r\n// Requires DefineBitMap and BitValues qualifier with same number of elements\r\n\r\n");
  3924. }
  3925. for (j = 0; j < DefineBitMapCount; j++)
  3926. {
  3927. BMOFFree(DefineBitMapPtr[j]);
  3928. }
  3929. BMOFFree(DefineBitMapPtr);
  3930. }
  3931. //
  3932. // Handle any enumerations via the DefineValueMap qualifier
  3933. //
  3934. DefineValuesCount = 0;
  3935. DefineValuesPtr = NULL;
  3936. ValuesCount = 0;
  3937. ValuesPtr = NULL;
  3938. ValueMapCount = 0;
  3939. ValueMapPtr = NULL;
  3940. QualifierType = VT_ARRAY | VT_BSTR;
  3941. if (WmipFindMofQualifier(PropertyQualifier,
  3942. L"DefineValues",
  3943. &QualifierType,
  3944. &DefineValuesCount,
  3945. &DefineValuesPtr) == ERROR_SUCCESS)
  3946. {
  3947. QualifierType = VT_ARRAY | VT_BSTR;
  3948. if (WmipFindMofQualifier(PropertyQualifier,
  3949. L"ValueMap",
  3950. &QualifierType,
  3951. &ValueMapCount,
  3952. &ValueMapPtr) == ERROR_SUCCESS)
  3953. {
  3954. if (DefineValuesCount == ValueMapCount)
  3955. {
  3956. QualifierType = VT_ARRAY | VT_BSTR;
  3957. if (WmipFindMofQualifier(PropertyQualifier,
  3958. L"Values",
  3959. &QualifierType,
  3960. &ValuesCount,
  3961. &ValuesPtr) != ERROR_SUCCESS)
  3962. {
  3963. ValuesPtr = NULL;
  3964. }
  3965. FilePrint(TemplateHandle,
  3966. "\r\n");
  3967. for (j = 0; j < DefineValuesCount; j++)
  3968. {
  3969. if ((ValuesPtr != NULL) &&
  3970. (j < ValuesCount) &&
  3971. (ValuesPtr[j] != NULL))
  3972. {
  3973. FilePrint(TemplateHandle,
  3974. "// %ws\r\n",
  3975. ValuesPtr[j]);
  3976. }
  3977. FilePrint(TemplateHandle,
  3978. "#define %ws %ws\r\n",
  3979. DefineValuesPtr[j],
  3980. ValueMapPtr[j]);
  3981. }
  3982. FilePrint(TemplateHandle,
  3983. "\r\n");
  3984. } else {
  3985. FilePrint(TemplateHandle, "// Warning: Cannot create ValueMap enumeration definitions\r\n// Requires DefineValues and ValueMap qualifier with same number of elements\r\n\r\n");
  3986. }
  3987. for (j = 0; j < ValueMapCount; j++)
  3988. {
  3989. BMOFFree(ValueMapPtr[j]);
  3990. }
  3991. BMOFFree(ValueMapPtr);
  3992. if (ValuesPtr != NULL)
  3993. {
  3994. for (j = 0; j < ValuesCount; j++)
  3995. {
  3996. BMOFFree(ValuesPtr[j]);
  3997. }
  3998. BMOFFree(ValuesPtr);
  3999. }
  4000. } else {
  4001. FilePrint(TemplateHandle, "// Warning: Cannot create ValueMap enumeration definitions\r\n// Requires DefineValues and ValueMap qualifier with same number of elements\r\n\r\n");
  4002. }
  4003. for (j = 0; j < DefineValuesCount; j++)
  4004. {
  4005. BMOFFree(DefineValuesPtr[j]);
  4006. }
  4007. BMOFFree(DefineValuesPtr);
  4008. }
  4009. //
  4010. // Generate structure element from property information
  4011. //
  4012. if (DataItem->Description != NULL)
  4013. {
  4014. Description = DataItem->Description;
  4015. } else {
  4016. Description = L"";
  4017. }
  4018. //
  4019. // Produce a #define for the data id of the property
  4020. //
  4021. QualifierType = VT_BSTR;
  4022. if (WmipFindMofQualifier(PropertyQualifier,
  4023. L"DefineDataId",
  4024. &QualifierType,
  4025. NULL,
  4026. &DefineDataId) != ERROR_SUCCESS)
  4027. {
  4028. swprintf(DefineDataIdText,
  4029. L"%ws_%ws",
  4030. ClassName,
  4031. DataItem->Name);
  4032. DefineDataId = DefineDataIdText;
  4033. }
  4034. if (DataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)
  4035. {
  4036. // Get Embedded Class name
  4037. EmbeddedClass = WmipFindClassInMofResourceByGuid(
  4038. MofResource,
  4039. &DataItem->EmbeddedClassGuid);
  4040. if (EmbeddedClass != NULL)
  4041. {
  4042. if (EmbeddedClass->MofClassInfo->HeaderName != NULL)
  4043. {
  4044. DataTypeText = EmbeddedClass->MofClassInfo->HeaderName;
  4045. } else {
  4046. DataTypeText = EmbeddedClass->MofClassInfo->Name;
  4047. }
  4048. } else {
  4049. DataTypeText = L"UNKNOWN";
  4050. }
  4051. } else {
  4052. // Standard data type
  4053. if ((DataItem->DataType == MOFString) ||
  4054. (DataItem->DataType == MOFZTString) ||
  4055. (DataItem->DataType == MOFAnsiString) ||
  4056. (DataItem->DataType == MOFDate))
  4057. {
  4058. DataTypeText = L"WCHAR";
  4059. } else {
  4060. DataTypeText = MofDataTypeText[DataItem->DataType];
  4061. }
  4062. }
  4063. if (DataItem->Flags & MOFDI_FLAG_FIXED_ARRAY)
  4064. {
  4065. Status = FilePrint(TemplateHandle,
  4066. " // %ws\r\n%ws %ws %ws[%d];\r\n"
  4067. " #define %ws_SIZE sizeof(%ws[%d])\r\n",
  4068. Description,
  4069. VLCommentText,
  4070. DataTypeText,
  4071. DataItem->Name,
  4072. DataItem->FixedArrayElements,
  4073. DefineDataId,
  4074. DataTypeText,
  4075. DataItem->FixedArrayElements);
  4076. } else if (DataItem->Flags & MOFDI_FLAG_VARIABLE_ARRAY) {
  4077. Status = FilePrint(TemplateHandle,
  4078. " // %ws\r\n%ws %ws %ws[1];\r\n",
  4079. Description,
  4080. VLCommentText,
  4081. DataTypeText,
  4082. DataItem->Name);
  4083. } else if (DataItem->DataType == MOFDate) {
  4084. Status = FilePrint(TemplateHandle,
  4085. " // %ws\r\n%ws WCHAR %ws[25];\r\n"
  4086. " #define %ws_SIZE sizeof(WCHAR[25])\r\n",
  4087. Description,
  4088. VLCommentText,
  4089. DataItem->Name,
  4090. DefineDataId);
  4091. } else if ((DataItem->DataType == MOFString) ||
  4092. (DataItem->DataType == MOFZTString) ||
  4093. (DataItem->DataType == MOFAnsiString)) {
  4094. if (DataItem->MaxLen == 0)
  4095. {
  4096. Status = FilePrint(TemplateHandle,
  4097. " // %ws\r\n%ws CHAR VariableData[1];\r\n",
  4098. Description,
  4099. VLCommentText);
  4100. } else {
  4101. Status = FilePrint(TemplateHandle,
  4102. " // %ws\r\n%ws WCHAR %ws[%d + 1];\r\n",
  4103. Description,
  4104. VLCommentText,
  4105. DataItem->Name,
  4106. DataItem->MaxLen
  4107. );
  4108. }
  4109. } else {
  4110. Status = FilePrint(TemplateHandle,
  4111. " // %ws\r\n%ws %ws %ws;\r\n"
  4112. " #define %ws_SIZE sizeof(%ws)\r\n",
  4113. Description,
  4114. VLCommentText,
  4115. DataTypeText,
  4116. DataItem->Name,
  4117. DefineDataId,
  4118. DataTypeText);
  4119. }
  4120. if (WmipIsDataitemVariableLen(DataItem))
  4121. {
  4122. VLCommentText = L"//";
  4123. }
  4124. Status = FilePrint(TemplateHandle,
  4125. " #define %ws_ID %d\r\n\r\n",
  4126. DefineDataId,
  4127. i+1
  4128. );
  4129. if (DefineDataId != DefineDataIdText)
  4130. {
  4131. BMOFFree(DefineDataId);
  4132. }
  4133. }
  4134. }
  4135. Status = FilePrint(TemplateHandle,
  4136. "} %ws, *P%ws;\r\n\r\n",
  4137. ClassName,
  4138. ClassName);
  4139. if ((LastDataItem != NULL) &&
  4140. ! ( (LastDataItem->Flags & MOFDI_FLAG_VARIABLE_ARRAY) ||
  4141. (LastDataItem->DataType == MOFString) ||
  4142. (LastDataItem->DataType == MOFZTString) ||
  4143. (LastDataItem->DataType == MOFAnsiString) ) )
  4144. {
  4145. FilePrint(TemplateHandle,
  4146. "#define %ws_SIZE (FIELD_OFFSET(%ws, %ws) + %ws_%ws_SIZE)\r\n\r\n",
  4147. ClassName,
  4148. ClassName,
  4149. LastDataItem->Name,
  4150. ClassName,
  4151. LastDataItem->Name);
  4152. }
  4153. } else {
  4154. #if DBG
  4155. printf("Warning: Header for class %ws cannot be created\n",
  4156. ClassName);
  4157. #endif
  4158. if (ItemCount != 0)
  4159. {
  4160. Status = FilePrint(TemplateHandle,
  4161. "// Warning: Header for class %ws cannot be created\r\n"
  4162. "typedef struct _%ws\r\n{\r\n char VariableData[1];\r\n\r\n",
  4163. ClassName,
  4164. ClassName);
  4165. Status = FilePrint(TemplateHandle,
  4166. "} %ws, *P%ws;\r\n\r\n",
  4167. ClassName,
  4168. ClassName);
  4169. } else {
  4170. Status = ERROR_SUCCESS;
  4171. }
  4172. }
  4173. return(Status);
  4174. }
  4175. ULONG GenerateHTemplate(
  4176. PCHAR TemplateFile,
  4177. PMOFRESOURCE MofResource
  4178. )
  4179. {
  4180. HANDLE TemplateHandle;
  4181. ULONG Status;
  4182. ULONG i,j;
  4183. PWCHAR DataTypeText, ClassName;
  4184. WCHAR MethodClassName[MAX_PATH];
  4185. PWCHAR GuidName1, GuidName2;
  4186. PWCHAR GuidSuffix1, GuidSuffix2;
  4187. PMOFDATAITEMW DataItem;
  4188. PMOFCLASSINFOW ClassInfo, MethodClassInfo;
  4189. PLIST_ENTRY MofClassList;
  4190. PMOFCLASS MofClass;
  4191. PCHAR p;
  4192. ULONG Len;
  4193. CBMOFObj *ClassObject;
  4194. PWCHAR MethodBaseClassName;
  4195. DWORD QualifierType;
  4196. short BooleanValue;
  4197. TemplateHandle = CreateFile(TemplateFile,
  4198. GENERIC_WRITE,
  4199. 0,
  4200. NULL,
  4201. CREATE_ALWAYS,
  4202. FILE_ATTRIBUTE_NORMAL,
  4203. NULL);
  4204. if ((TemplateHandle == NULL) || (TemplateHandle == INVALID_HANDLE_VALUE))
  4205. {
  4206. return(GetLastError());
  4207. }
  4208. //
  4209. // move back to only get the last part of the path and convert any
  4210. // . into _
  4211. //
  4212. Len = strlen(TemplateFile);
  4213. p = TemplateFile + Len;
  4214. while ((p >= TemplateFile) && (*p != '\\'))
  4215. {
  4216. if (*p == '.')
  4217. {
  4218. *p = '_';
  4219. }
  4220. p--;
  4221. }
  4222. p++;
  4223. Status = FilePrint(TemplateHandle,
  4224. "#ifndef _%s_\r\n#define _%s_\r\n\r\n",
  4225. p, p);
  4226. //
  4227. // Loop over all mof classes
  4228. MofClassList = MofResource->MRMCHead.Flink;
  4229. while (MofClassList != &MofResource->MRMCHead)
  4230. {
  4231. MofClass = CONTAINING_RECORD(MofClassList,
  4232. MOFCLASS,
  4233. MCMRList);
  4234. ClassInfo = MofClass->MofClassInfo;
  4235. ClassObject = (CBMOFObj *)MofClass->ClassObjectHandle;
  4236. QualifierType = VT_BOOL;
  4237. Status = WmipFindMofQualifier((CBMOFQualList *)ClassInfo->ClassQualifierHandle,
  4238. L"WmiGenerateHeader",
  4239. &QualifierType,
  4240. NULL,
  4241. (PVOID)&BooleanValue);
  4242. if ((Status != ERROR_SUCCESS) ||
  4243. ((Status == ERROR_SUCCESS) && BooleanValue))
  4244. {
  4245. if (ClassInfo->HeaderName != NULL)
  4246. {
  4247. ClassName = ClassInfo->HeaderName;
  4248. } else {
  4249. ClassName = ClassInfo->Name;
  4250. }
  4251. if (ClassInfo->GuidName1 != NULL)
  4252. {
  4253. GuidName1 = ClassInfo->GuidName1;
  4254. GuidSuffix1 = L"";
  4255. } else {
  4256. GuidName1 = ClassInfo->Name;
  4257. GuidSuffix1 = L"Guid";
  4258. }
  4259. if (ClassInfo->GuidName2 != NULL)
  4260. {
  4261. GuidName2 = ClassInfo->GuidName2;
  4262. GuidSuffix2 = L"";
  4263. } else {
  4264. GuidName2 = ClassInfo->Name;
  4265. GuidSuffix2 = L"_GUID";
  4266. }
  4267. Status = FilePrint(TemplateHandle,
  4268. "// %ws - %ws\r\n",
  4269. ClassInfo->Name,
  4270. ClassName);
  4271. if (ClassInfo->Description != NULL)
  4272. {
  4273. Status = FilePrint(TemplateHandle,
  4274. "// %ws\r\n",
  4275. ClassInfo->Description);
  4276. }
  4277. Status = DumpCppQuote(TemplateHandle,
  4278. (CBMOFQualList *)ClassInfo->ClassQualifierHandle);
  4279. Status = FilePrint(TemplateHandle,
  4280. "#define %ws%ws \\\r\n"
  4281. " { 0x%08x,0x%04x,0x%04x, { 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x } }\r\n\r\n",
  4282. GuidName1, GuidSuffix1,
  4283. ClassInfo->Guid.Data1, ClassInfo->Guid.Data2,
  4284. ClassInfo->Guid.Data3,
  4285. ClassInfo->Guid.Data4[0], ClassInfo->Guid.Data4[1],
  4286. ClassInfo->Guid.Data4[2], ClassInfo->Guid.Data4[3],
  4287. ClassInfo->Guid.Data4[4], ClassInfo->Guid.Data4[5],
  4288. ClassInfo->Guid.Data4[6], ClassInfo->Guid.Data4[7]);
  4289. Status = FilePrint(TemplateHandle,
  4290. "#if ! (defined(MIDL_PASS))\r\n"
  4291. "DEFINE_GUID(%ws%ws, \\\r\n"
  4292. " 0x%08x,0x%04x,0x%04x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\r\n"
  4293. "#endif\r\n\r\n",
  4294. GuidName2, GuidSuffix2,
  4295. ClassInfo->Guid.Data1, ClassInfo->Guid.Data2,
  4296. ClassInfo->Guid.Data3,
  4297. ClassInfo->Guid.Data4[0], ClassInfo->Guid.Data4[1],
  4298. ClassInfo->Guid.Data4[2], ClassInfo->Guid.Data4[3],
  4299. ClassInfo->Guid.Data4[4], ClassInfo->Guid.Data4[5],
  4300. ClassInfo->Guid.Data4[6], ClassInfo->Guid.Data4[7]);
  4301. if (ClassInfo->MethodCount > 0)
  4302. {
  4303. Status = FilePrint(TemplateHandle,
  4304. "//\r\n// Method id definitions for %ws\r\n",
  4305. ClassInfo->Name);
  4306. }
  4307. for (i = 0; i < ClassInfo->MethodCount; i++)
  4308. {
  4309. DataItem = &ClassInfo->DataItems[i+ClassInfo->DataItemCount];
  4310. Status = DumpCppQuote(TemplateHandle,
  4311. (CBMOFQualList *)DataItem->PropertyQualifierHandle);
  4312. Status = FilePrint(TemplateHandle,
  4313. "#define %ws %d\r\n",
  4314. DataItem->Name,
  4315. DataItem->MethodId);
  4316. MethodClassInfo = DataItem->MethodClassInfo;
  4317. if (DataItem->HeaderName != NULL)
  4318. {
  4319. MethodBaseClassName = DataItem->HeaderName;
  4320. } else {
  4321. MethodBaseClassName = DataItem->Name;
  4322. }
  4323. if (DoMethodHeaderGeneration)
  4324. {
  4325. swprintf(MethodClassName, L"%ws_IN", MethodBaseClassName);
  4326. Status = GenerateClassHeader(TemplateHandle,
  4327. MofResource,
  4328. MethodClassName,
  4329. MethodClassInfo,
  4330. MOFDI_FLAG_INPUT_METHOD);
  4331. swprintf(MethodClassName, L"%ws_OUT", MethodBaseClassName);
  4332. Status = GenerateClassHeader(TemplateHandle,
  4333. MofResource,
  4334. MethodClassName,
  4335. MethodClassInfo,
  4336. MOFDI_FLAG_OUTPUT_METHOD);
  4337. }
  4338. }
  4339. Status = FilePrint(TemplateHandle,
  4340. "\r\n");
  4341. Status = GenerateClassHeader(TemplateHandle,
  4342. MofResource,
  4343. ClassName,
  4344. ClassInfo,
  4345. 0xffffffff);
  4346. }
  4347. MofClassList = MofClassList->Flink;
  4348. }
  4349. Status = FilePrint(TemplateHandle,
  4350. "#endif\r\n");
  4351. CloseHandle(TemplateHandle);
  4352. if (Status != ERROR_SUCCESS)
  4353. {
  4354. DeleteFile(TemplateFile);
  4355. }
  4356. return(Status);
  4357. }
  4358. ULONG FilePrintDataItem(
  4359. HANDLE TemplateHandle,
  4360. PMOFRESOURCE MofResource,
  4361. ULONG Level,
  4362. PCHAR Prefix,
  4363. PCHAR DisplayPrefix,
  4364. PMOFCLASSINFOW ClassInfo,
  4365. PMOFDATAITEMW DataItem
  4366. )
  4367. {
  4368. ULONG Status = ERROR_SUCCESS;
  4369. CHAR NewPrefix[MAX_PATH];
  4370. CHAR NewDisplayPrefix[MAX_PATH];
  4371. CHAR ArrayLenBuffer[MAX_PATH];
  4372. PCHAR ArrayLen;
  4373. PMOFCLASSINFOW EmbeddedClassInfo;
  4374. PMOFCLASS EmbeddedClass;
  4375. PMOFDATAITEMW NewDataItem;
  4376. ULONG j;
  4377. if (DataItem->Flags & MOFDI_FLAG_FIXED_ARRAY)
  4378. {
  4379. sprintf(ArrayLenBuffer, "%d",
  4380. DataItem->FixedArrayElements);
  4381. ArrayLen = ArrayLenBuffer;
  4382. } else if (DataItem->Flags & MOFDI_FLAG_VARIABLE_ARRAY) {
  4383. sprintf(ArrayLenBuffer, "%s%ws",
  4384. Prefix,
  4385. ClassInfo->DataItems[DataItem->VariableArraySizeId-1].Name);
  4386. ArrayLen = ArrayLenBuffer;
  4387. } else {
  4388. ArrayLen = NULL;
  4389. }
  4390. if (ArrayLen != NULL)
  4391. {
  4392. Status = FilePrint(TemplateHandle,
  4393. " for i%d = 0 to (%s-1)\r\n",
  4394. Level,
  4395. ArrayLen);
  4396. sprintf(NewPrefix, "%s%ws(i%d)",
  4397. Prefix,
  4398. DataItem->Name,
  4399. Level);
  4400. sprintf(NewDisplayPrefix, "%s%ws(\"&i%d&\")",
  4401. DisplayPrefix,
  4402. DataItem->Name,
  4403. Level);
  4404. } else {
  4405. sprintf(NewPrefix, "%s%ws",
  4406. Prefix,
  4407. DataItem->Name);
  4408. sprintf(NewDisplayPrefix, "%s%ws",
  4409. DisplayPrefix,
  4410. DataItem->Name);
  4411. }
  4412. if (DataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)
  4413. {
  4414. EmbeddedClass = WmipFindClassInMofResourceByGuid(
  4415. MofResource,
  4416. &DataItem->EmbeddedClassGuid);
  4417. if (EmbeddedClass != NULL)
  4418. {
  4419. strcat(NewPrefix, ".");
  4420. strcat(NewDisplayPrefix, ".");
  4421. EmbeddedClassInfo = EmbeddedClass->MofClassInfo;
  4422. for (j = 0; j < EmbeddedClassInfo->DataItemCount; j++)
  4423. {
  4424. NewDataItem = &EmbeddedClassInfo->DataItems[j];
  4425. Status = FilePrintDataItem(TemplateHandle,
  4426. MofResource,
  4427. Level+1,
  4428. NewPrefix,
  4429. NewDisplayPrefix,
  4430. EmbeddedClassInfo,
  4431. NewDataItem);
  4432. }
  4433. } else {
  4434. #if DBG
  4435. printf("WARNING - Cannot create test for %s, cannot find embedded class\n",
  4436. NewPrefix);
  4437. #endif
  4438. FilePrint(TemplateHandle, "REM WARNING - Cannot create test for %s, cannot find embedded class\r\n",
  4439. NewPrefix);
  4440. }
  4441. } else {
  4442. Status = FilePrint(TemplateHandle,
  4443. " a.WriteLine(\" %s=\" & %s)\r\n",
  4444. NewDisplayPrefix,
  4445. NewPrefix);
  4446. }
  4447. if (ArrayLen != NULL)
  4448. {
  4449. Status = FilePrint(TemplateHandle,
  4450. " next 'i%d\r\n",
  4451. Level);
  4452. }
  4453. return(Status);
  4454. }
  4455. BOOLEAN CanCreateTest(
  4456. PMOFCLASSINFOW ClassInfo
  4457. )
  4458. {
  4459. //
  4460. // Cannot create tests for embedded classes or events
  4461. if (((ClassInfo->Flags & MOFCI_RESERVED1) == 0) ||
  4462. (ClassInfo->Flags & MOFCI_FLAG_EVENT))
  4463. {
  4464. return(FALSE);
  4465. }
  4466. return(TRUE);
  4467. }
  4468. ULONG GenerateTTemplate(
  4469. PCHAR TemplateFile,
  4470. PMOFRESOURCE MofResource
  4471. )
  4472. {
  4473. HANDLE TemplateHandle;
  4474. ULONG Status;
  4475. ULONG i;
  4476. PMOFDATAITEMW DataItem;
  4477. PMOFCLASSINFOW ClassInfo;
  4478. PLIST_ENTRY MofClassList;
  4479. PMOFCLASS MofClass;
  4480. PCHAR p, p1;
  4481. TemplateHandle = CreateFile(TemplateFile,
  4482. GENERIC_WRITE,
  4483. 0,
  4484. NULL,
  4485. CREATE_ALWAYS,
  4486. FILE_ATTRIBUTE_NORMAL,
  4487. NULL);
  4488. if ((TemplateHandle != NULL) && (TemplateHandle != INVALID_HANDLE_VALUE))
  4489. {
  4490. p = TemplateFile;
  4491. p1 = TemplateFile;
  4492. while ((*p != '.') && (*p != 0))
  4493. {
  4494. if (*p == '\\')
  4495. {
  4496. p1 = p+1;
  4497. }
  4498. p++;
  4499. }
  4500. if (*p == '.')
  4501. {
  4502. *p = 0;
  4503. }
  4504. Status = FilePrint(TemplateHandle,
  4505. "REM Note that missing classes in log file mean tthe hat WMI cannot access them.\r\n"
  4506. "REM Most likely this indicates a problem with the driver.\r\n"
  4507. "REM See %%windir%%\\system32\\wbem\\wmiprov.log and nt eventlog for more details.\r\n"
  4508. "REM You could also delete the line On Error Resume Next and examine the\r\n"
  4509. "REM specific VBScript error\r\n\r\n\r\n");
  4510. Status = FilePrint(TemplateHandle,
  4511. "On Error Resume Next\r\n\r\n");
  4512. Status = FilePrint(TemplateHandle,
  4513. "Set fso = CreateObject(\"Scripting.FileSystemObject\")\r\n");
  4514. Status = FilePrint(TemplateHandle,
  4515. "Set a = fso.CreateTextFile(\"%s.log\", True)\r\n",
  4516. p1);
  4517. Status = FilePrint(TemplateHandle,
  4518. "Set Service = GetObject(\"winmgmts:{impersonationLevel=impersonate}!root/wmi\")\r\n");
  4519. //
  4520. // Loop over all mof classes
  4521. MofClassList = MofResource->MRMCHead.Flink;
  4522. while (MofClassList != &MofResource->MRMCHead)
  4523. {
  4524. MofClass = CONTAINING_RECORD(MofClassList,
  4525. MOFCLASS,
  4526. MCMRList);
  4527. ClassInfo = MofClass->MofClassInfo;
  4528. if (CanCreateTest(ClassInfo))
  4529. {
  4530. Status = FilePrint(TemplateHandle,
  4531. "Rem %ws - %ws\r\n",
  4532. ClassInfo->Name,
  4533. ClassInfo->Description ? ClassInfo->Description : L"");
  4534. Status = FilePrint(TemplateHandle,
  4535. "Set enumSet = Service.InstancesOf (\"%ws\")\r\n"
  4536. "a.WriteLine(\"%ws\")\r\n",
  4537. ClassInfo->Name,
  4538. ClassInfo->Name);
  4539. Status = FilePrint(TemplateHandle,
  4540. "for each instance in enumSet\r\n");
  4541. Status = FilePrint(TemplateHandle,
  4542. " a.WriteLine(\" InstanceName=\" & instance.InstanceName)\r\n");
  4543. for (i = 0; i < ClassInfo->DataItemCount; i++)
  4544. {
  4545. DataItem = &ClassInfo->DataItems[i];
  4546. FilePrintDataItem(TemplateHandle,
  4547. MofResource,
  4548. 1,
  4549. "instance.",
  4550. "instance.",
  4551. ClassInfo,
  4552. DataItem);
  4553. }
  4554. Status = FilePrint(TemplateHandle,
  4555. "next 'instance\r\n\r\n");
  4556. }
  4557. MofClassList = MofClassList->Flink;
  4558. }
  4559. Status = FilePrint(TemplateHandle,
  4560. "a.Close\r\n"
  4561. "Wscript.Echo \"%s Test Completed, see %s.log for details\"\r\n",
  4562. p1, p1);
  4563. CloseHandle(TemplateHandle);
  4564. if (Status != ERROR_SUCCESS)
  4565. {
  4566. DeleteFile(TemplateFile);
  4567. }
  4568. } else {
  4569. Status = GetLastError();
  4570. }
  4571. return(Status);
  4572. }
  4573. ULONG GenerateXTemplate(
  4574. PCHAR TemplateFile
  4575. )
  4576. {
  4577. HANDLE TemplateHandle;
  4578. ULONG Status;
  4579. TemplateHandle = CreateFile(TemplateFile,
  4580. GENERIC_WRITE,
  4581. 0,
  4582. NULL,
  4583. CREATE_ALWAYS,
  4584. FILE_ATTRIBUTE_NORMAL,
  4585. NULL);
  4586. if ((TemplateHandle == NULL) || (TemplateHandle == INVALID_HANDLE_VALUE))
  4587. {
  4588. return(GetLastError());
  4589. }
  4590. Status = GenerateBinaryMofData(TemplateHandle);
  4591. CloseHandle(TemplateHandle);
  4592. if (Status != ERROR_SUCCESS)
  4593. {
  4594. DeleteFile(TemplateFile);
  4595. }
  4596. return(Status);
  4597. }
  4598. typedef void (*PROPERTYCALLBACK)(
  4599. HANDLE TemplateHandle,
  4600. PWCHAR FormName,
  4601. PWCHAR InstanceName,
  4602. PWCHAR InstancePrefix,
  4603. PMOFRESOURCE MofResource,
  4604. PMOFCLASSINFOW ClassInfo,
  4605. PMOFDATAITEMW DataItem,
  4606. ULONG Counter,
  4607. PVOID Context,
  4608. ULONG RecursionLevel
  4609. );
  4610. void EnumerateClassProperties(
  4611. HANDLE TemplateHandle,
  4612. PWCHAR FormName,
  4613. PWCHAR InstanceName,
  4614. PMOFRESOURCE MofResource,
  4615. PMOFCLASSINFOW ClassInfo,
  4616. PROPERTYCALLBACK Callback,
  4617. BOOLEAN Recurse,
  4618. PVOID Context,
  4619. ULONG RecursionLevel
  4620. )
  4621. {
  4622. ULONG i;
  4623. WCHAR I[1];
  4624. WCHAR F[1];
  4625. if (InstanceName == NULL)
  4626. {
  4627. I[0] = UNICODE_NULL;
  4628. InstanceName = I;
  4629. }
  4630. if (FormName == NULL)
  4631. {
  4632. F[0] = UNICODE_NULL;
  4633. FormName = F;
  4634. }
  4635. for (i = 0; i < ClassInfo->DataItemCount; i++)
  4636. {
  4637. WCHAR FName[MAX_PATH];
  4638. WCHAR IName[MAX_PATH];
  4639. PMOFCLASS EmbeddedClass;
  4640. PMOFDATAITEMW DataItem;
  4641. DataItem = &ClassInfo->DataItems[i];
  4642. wcscpy(IName, InstanceName);
  4643. wcscat(IName, L".");
  4644. wcscat(IName, DataItem->Name);
  4645. wcscpy(FName, FormName);
  4646. wcscat(FName, DataItem->Name);
  4647. if (DataItem->Flags & (MOFDI_FLAG_FIXED_ARRAY |
  4648. MOFDI_FLAG_VARIABLE_ARRAY))
  4649. {
  4650. wcscat(IName, L"(");
  4651. wcscat(IName, FName);
  4652. wcscat(IName, L"Index)");
  4653. }
  4654. (*Callback)(TemplateHandle,
  4655. FName,
  4656. IName,
  4657. InstanceName,
  4658. MofResource,
  4659. ClassInfo,
  4660. DataItem,
  4661. i,
  4662. Context,
  4663. RecursionLevel);
  4664. if (Recurse && (DataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS))
  4665. {
  4666. EmbeddedClass = WmipFindClassInMofResourceByGuid(
  4667. MofResource,
  4668. &DataItem->EmbeddedClassGuid);
  4669. if (EmbeddedClass != NULL)
  4670. {
  4671. EnumerateClassProperties(TemplateHandle,
  4672. FName,
  4673. IName,
  4674. MofResource,
  4675. EmbeddedClass->MofClassInfo,
  4676. Callback,
  4677. Recurse,
  4678. Context,
  4679. RecursionLevel+1);
  4680. }
  4681. }
  4682. }
  4683. }
  4684. void GenerateChangeText(
  4685. HANDLE TemplateHandle,
  4686. PWCHAR FormName,
  4687. PWCHAR InstanceName,
  4688. PWCHAR InstancePrefix,
  4689. PMOFRESOURCE MofResource,
  4690. PMOFCLASSINFOW ClassInfo,
  4691. PMOFDATAITEMW DataItem,
  4692. ULONG Counter,
  4693. PVOID Context,
  4694. ULONG RecursionLevel
  4695. )
  4696. {
  4697. //
  4698. // Generate code to change the contents of a property
  4699. //
  4700. if (! (DataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS))
  4701. {
  4702. FilePrint(TemplateHandle,
  4703. " Instance%ws = TheForm.%wsText.Value\r\n",
  4704. InstanceName,
  4705. FormName);
  4706. }
  4707. }
  4708. void GenerateReloadText(
  4709. HANDLE TemplateHandle,
  4710. PWCHAR FormName,
  4711. PWCHAR InstanceName,
  4712. PWCHAR InstancePrefix,
  4713. PMOFRESOURCE MofResource,
  4714. PMOFCLASSINFOW ClassInfo,
  4715. PMOFDATAITEMW DataItem,
  4716. ULONG Counter,
  4717. PVOID Context,
  4718. ULONG RecursionLevel
  4719. )
  4720. {
  4721. //
  4722. // Generate code to redisplay the contents of the property
  4723. //
  4724. if (! (DataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS))
  4725. {
  4726. FilePrint(TemplateHandle,
  4727. " TheForm.%wsText.Value = Instance%ws\r\n",
  4728. FormName,
  4729. InstanceName);
  4730. }
  4731. if (DataItem->Flags & (MOFDI_FLAG_FIXED_ARRAY | MOFDI_FLAG_VARIABLE_ARRAY))
  4732. {
  4733. FilePrint(TemplateHandle,
  4734. " TheForm.%wsIndexText.Value = %wsIndex\r\n",
  4735. FormName, FormName);
  4736. if (DataItem->Flags & MOFDI_FLAG_FIXED_ARRAY)
  4737. {
  4738. FilePrint(TemplateHandle,
  4739. " %wsMaxIndex = %d\r\n",
  4740. FormName, DataItem->FixedArrayElements);
  4741. } else {
  4742. FilePrint(TemplateHandle,
  4743. " %wsMaxIndex = Instance%ws.%ws\r\n",
  4744. FormName, InstancePrefix,
  4745. ClassInfo->DataItems[DataItem->VariableArraySizeId-1].Name);
  4746. }
  4747. }
  4748. }
  4749. void GenerateTextFormText(
  4750. HANDLE TemplateHandle,
  4751. PWCHAR FormName,
  4752. PWCHAR InstanceName,
  4753. PWCHAR InstancePrefix,
  4754. PMOFRESOURCE MofResource,
  4755. PMOFCLASSINFOW ClassInfo,
  4756. PMOFDATAITEMW DataItem,
  4757. ULONG Counter,
  4758. PVOID Context,
  4759. ULONG RecursionLevel
  4760. )
  4761. {
  4762. if (! (DataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)) {
  4763. FilePrint(TemplateHandle,
  4764. "<p class=MsoNormal>%ws: <span style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><INPUT TYPE=\"TEXT\" SIZE=\"96\" NAME=\"%wsText\"></p>\r\n"
  4765. "\r\n",
  4766. FormName, FormName);
  4767. }
  4768. if (DataItem->Flags &
  4769. (MOFDI_FLAG_FIXED_ARRAY | MOFDI_FLAG_VARIABLE_ARRAY))
  4770. {
  4771. FilePrint(TemplateHandle,
  4772. "\r\n"
  4773. "<input name=Next%wsButton type=BUTTON value=Next OnClick=\"NextIndexButton_OnClick %wsIndex, %wsMaxIndex\">\r\n"
  4774. "\r\n"
  4775. "<input name=Prev%wsButton type=BUTTON value=Previous OnClick=\"PrevIndexButton_OnClick %wsIndex, %wsMaxIndex\">\r\n"
  4776. "\r\n"
  4777. "%wsArrayIndex: <INPUT TYPE=\"TEXT\" SIZE=\"5\" NAME=\"%wsIndexText\">\r\n"
  4778. "\r\n"
  4779. "<input name=GoTo%wsButton type=BUTTON value=GoTo OnClick=\"GoToIndexButton_OnClick %wsIndex, %wsMaxIndex, Document.ClassForm.%wsIndexText.Value\">\r\n"
  4780. "\r\n",
  4781. FormName,
  4782. FormName,
  4783. FormName,
  4784. FormName,
  4785. FormName,
  4786. FormName,
  4787. FormName,
  4788. FormName,
  4789. FormName,
  4790. FormName,
  4791. FormName,
  4792. FormName);
  4793. }
  4794. }
  4795. void GenerateArrayDimsText(
  4796. HANDLE TemplateHandle,
  4797. PWCHAR FormName,
  4798. PWCHAR InstanceName,
  4799. PWCHAR InstancePrefix,
  4800. PMOFRESOURCE MofResource,
  4801. PMOFCLASSINFOW ClassInfo,
  4802. PMOFDATAITEMW MofDataItem,
  4803. ULONG Counter,
  4804. PVOID Context,
  4805. ULONG RecursionLevel
  4806. )
  4807. {
  4808. //
  4809. // Declare an index variable that tracks the current index of an array
  4810. //
  4811. if (MofDataItem->Flags &
  4812. (MOFDI_FLAG_FIXED_ARRAY | MOFDI_FLAG_VARIABLE_ARRAY))
  4813. {
  4814. FilePrint(TemplateHandle,
  4815. "Dim %wsIndex\r\n"
  4816. "%wsIndex = 0\r\n"
  4817. "Dim %wsMaxIndex\r\n"
  4818. "%wsMaxIndex = 1\r\n",
  4819. FormName,
  4820. FormName,
  4821. FormName,
  4822. FormName);
  4823. }
  4824. }
  4825. void GenerateMethodInL2Text(
  4826. HANDLE TemplateHandle,
  4827. PWCHAR FormName,
  4828. PWCHAR InstanceName,
  4829. PWCHAR InstancePrefix,
  4830. PMOFRESOURCE MofResource,
  4831. PMOFCLASSINFOW ClassInfo,
  4832. PMOFDATAITEMW MofDataItem,
  4833. ULONG Counter,
  4834. PVOID Context,
  4835. ULONG RecursionLevel
  4836. )
  4837. {
  4838. if (! (MofDataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS))
  4839. {
  4840. FilePrint(TemplateHandle,
  4841. " %ws = TheForm.%ws%wsText.Value\r\n",
  4842. InstanceName,
  4843. Context,
  4844. FormName);
  4845. } else {
  4846. FilePrint(TemplateHandle,
  4847. " %ws = Service.Get(\"%ws\")\r\n",
  4848. InstanceName,
  4849. (PWCHAR)MofDataItem->EcTempPtr +
  4850. (sizeof(L"object") / sizeof(WCHAR)));
  4851. }
  4852. }
  4853. void GenerateMethodInText(
  4854. HANDLE TemplateHandle,
  4855. PWCHAR FormName,
  4856. PWCHAR InstanceName,
  4857. PWCHAR InstancePrefix,
  4858. PMOFRESOURCE MofResource,
  4859. PMOFCLASSINFOW ClassInfo,
  4860. PMOFDATAITEMW MofDataItem,
  4861. ULONG Counter,
  4862. PVOID Context,
  4863. ULONG RecursionLevel
  4864. )
  4865. {
  4866. //
  4867. // Declare classes for all IN and OUT embedded classes
  4868. //
  4869. if (MofDataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)
  4870. {
  4871. PWCHAR EmbeddedClassName = (PWCHAR)MofDataItem->EcTempPtr +
  4872. (sizeof(L"object") / sizeof(WCHAR));
  4873. if (MofDataItem->Flags & (MOFDI_FLAG_INPUT_METHOD))
  4874. {
  4875. FilePrint(TemplateHandle,
  4876. " Set %ws = Service.Get(\"%ws\").SpawnInstance_\r\n",
  4877. FormName,
  4878. EmbeddedClassName);
  4879. } else {
  4880. FilePrint(TemplateHandle,
  4881. " Dim %ws\r\n",
  4882. FormName);
  4883. }
  4884. }
  4885. if (MofDataItem->Flags & (MOFDI_FLAG_INPUT_METHOD))
  4886. {
  4887. if (MofDataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)
  4888. {
  4889. PMOFCLASS EmbeddedClass;
  4890. EmbeddedClass = WmipFindClassInMofResourceByGuid(
  4891. MofResource,
  4892. &MofDataItem->EmbeddedClassGuid);
  4893. if (EmbeddedClass != NULL)
  4894. {
  4895. EnumerateClassProperties(TemplateHandle,
  4896. FormName,
  4897. FormName,
  4898. MofResource,
  4899. EmbeddedClass->MofClassInfo,
  4900. GenerateMethodInL2Text,
  4901. TRUE,
  4902. Context,
  4903. RecursionLevel+1);
  4904. }
  4905. } else {
  4906. FilePrint(TemplateHandle,
  4907. " %ws = TheForm.%ws%wsText.Value\r\n",
  4908. FormName,
  4909. Context,
  4910. FormName);
  4911. }
  4912. }
  4913. }
  4914. void GenerateMethodOutL2Text(
  4915. HANDLE TemplateHandle,
  4916. PWCHAR FormName,
  4917. PWCHAR InstanceName,
  4918. PWCHAR InstancePrefix,
  4919. PMOFRESOURCE MofResource,
  4920. PMOFCLASSINFOW ClassInfo,
  4921. PMOFDATAITEMW MofDataItem,
  4922. ULONG Counter,
  4923. PVOID Context,
  4924. ULONG RecursionLevel
  4925. )
  4926. {
  4927. if (! (MofDataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS))
  4928. {
  4929. FilePrint(TemplateHandle,
  4930. " TheForm.%ws%wsText.Value = %ws\r\n",
  4931. Context,
  4932. FormName,
  4933. InstanceName);
  4934. }
  4935. }
  4936. void GenerateMethodOutText(
  4937. HANDLE TemplateHandle,
  4938. PWCHAR FormName,
  4939. PWCHAR InstanceName,
  4940. PWCHAR InstancePrefix,
  4941. PMOFRESOURCE MofResource,
  4942. PMOFCLASSINFOW ClassInfo,
  4943. PMOFDATAITEMW MofDataItem,
  4944. ULONG Counter,
  4945. PVOID Context,
  4946. ULONG RecursionLevel
  4947. )
  4948. {
  4949. if (MofDataItem->Flags & (MOFDI_FLAG_OUTPUT_METHOD))
  4950. {
  4951. if (MofDataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)
  4952. {
  4953. PMOFCLASS EmbeddedClass;
  4954. PWCHAR EmbeddedClassName = (PWCHAR)MofDataItem->EcTempPtr +
  4955. (sizeof(L"object") / sizeof(WCHAR));
  4956. EmbeddedClass = WmipFindClassInMofResourceByGuid(
  4957. MofResource,
  4958. &MofDataItem->EmbeddedClassGuid);
  4959. if (EmbeddedClass != NULL)
  4960. {
  4961. EnumerateClassProperties(TemplateHandle,
  4962. FormName,
  4963. FormName,
  4964. MofResource,
  4965. EmbeddedClass->MofClassInfo,
  4966. GenerateMethodOutL2Text,
  4967. TRUE,
  4968. Context,
  4969. RecursionLevel+1);
  4970. }
  4971. } else {
  4972. FilePrint(TemplateHandle,
  4973. " TheForm.%ws%wsText.Value = %ws\r\n",
  4974. Context,
  4975. FormName,
  4976. FormName);
  4977. }
  4978. }
  4979. }
  4980. void GenerateMethodCallText(
  4981. HANDLE TemplateHandle,
  4982. PWCHAR FormName,
  4983. PWCHAR InstanceName,
  4984. PWCHAR InstancePrefix,
  4985. PMOFRESOURCE MofResource,
  4986. PMOFCLASSINFOW ClassInfo,
  4987. PMOFDATAITEMW MofDataItem,
  4988. ULONG Counter,
  4989. PVOID Context,
  4990. ULONG RecursionLevel
  4991. )
  4992. {
  4993. //
  4994. // Declare an index variable that tracks the current index of an array
  4995. //
  4996. FilePrint(TemplateHandle,
  4997. " %ws",
  4998. FormName);
  4999. if (Counter != PtrToUlong(Context))
  5000. {
  5001. FilePrint(TemplateHandle, ", ");
  5002. }
  5003. }
  5004. void GenerateMethodControlText(
  5005. HANDLE TemplateHandle,
  5006. PWCHAR FormName,
  5007. PWCHAR InstanceName,
  5008. PWCHAR InstancePrefix,
  5009. PMOFRESOURCE MofResource,
  5010. PMOFCLASSINFOW ClassInfo,
  5011. PMOFDATAITEMW MofDataItem,
  5012. ULONG Counter,
  5013. PVOID Context,
  5014. ULONG RecursionLevel
  5015. )
  5016. {
  5017. PWCHAR MethodName = (PWCHAR)Context;
  5018. FilePrint(TemplateHandle,
  5019. "<p> "
  5020. );
  5021. if (MofDataItem->Flags & (MOFDI_FLAG_INPUT_METHOD))
  5022. {
  5023. FilePrint(TemplateHandle,
  5024. " [in] ");
  5025. }
  5026. if (MofDataItem->Flags & (MOFDI_FLAG_OUTPUT_METHOD))
  5027. {
  5028. FilePrint(TemplateHandle,
  5029. " [out] ");
  5030. }
  5031. if (MofDataItem->Flags & MOFDI_FLAG_EMBEDDED_CLASS)
  5032. {
  5033. FilePrint(TemplateHandle, "%ws </p>\r\n", FormName);
  5034. } else {
  5035. FilePrint(TemplateHandle,
  5036. " %ws <INPUT TYPE=\"TEXT\" SIZE=\"70\" NAME=\"%ws%wsText\"></p>\r\n",
  5037. FormName,
  5038. MethodName,
  5039. FormName);
  5040. }
  5041. if (MofDataItem->Flags &
  5042. (MOFDI_FLAG_FIXED_ARRAY | MOFDI_FLAG_VARIABLE_ARRAY))
  5043. {
  5044. FilePrint(TemplateHandle,
  5045. "\r\n"
  5046. "<input name=Next%wsButton type=BUTTON value=Next OnClick=\"NextIndexButton_OnClick %ws%wsIndex, %ws%wsMaxIndex\">\r\n"
  5047. "\r\n"
  5048. "<input name=Prev%wsButton type=BUTTON value=Previous OnClick=\"PrevIndexButton_OnClick %ws%wsIndex, %ws%wsMaxIndex\">\r\n"
  5049. "\r\n"
  5050. "%ws%wsArrayIndex: <INPUT TYPE=\"TEXT\" SIZE=\"5\" NAME=\"%ws%wsIndexText\">\r\n"
  5051. "\r\n"
  5052. "<input name=GoTo%ws%wsButton type=BUTTON value=GoTo OnClick=\"GoToIndexButton_OnClick %ws%wsIndex, %ws%wsMaxIndex, Document.ClassForm.%ws%wsIndexText.Value\">\r\n"
  5053. "\r\n",
  5054. FormName,
  5055. MethodName,
  5056. FormName,
  5057. MethodName,
  5058. FormName,
  5059. MethodName,
  5060. FormName,
  5061. MethodName,
  5062. FormName,
  5063. MethodName,
  5064. FormName,
  5065. MethodName,
  5066. FormName,
  5067. MethodName,
  5068. FormName,
  5069. MethodName,
  5070. FormName,
  5071. MethodName,
  5072. FormName,
  5073. MethodName,
  5074. FormName,
  5075. MethodName,
  5076. FormName,
  5077. MethodName);
  5078. }
  5079. }
  5080. typedef void (*METHODCALLBACK)(
  5081. HANDLE TemplateHandle,
  5082. PWCHAR MethodName,
  5083. PMOFRESOURCE MofResource,
  5084. PMOFCLASSINFOW ClassInfo,
  5085. PMOFDATAITEMW MethodDataItem,
  5086. ULONG Counter,
  5087. PVOID Context
  5088. );
  5089. void EnumerateClassMethods(
  5090. HANDLE TemplateHandle,
  5091. PMOFRESOURCE MofResource,
  5092. PMOFCLASSINFOW ClassInfo,
  5093. METHODCALLBACK Callback,
  5094. PVOID Context
  5095. )
  5096. {
  5097. PMOFDATAITEMW DataItem;
  5098. ULONG i;
  5099. for (i = 0; i < ClassInfo->MethodCount; i++)
  5100. {
  5101. DataItem = &ClassInfo->DataItems[i+ClassInfo->DataItemCount];
  5102. WmipAssert(DataItem->Flags & MOFDI_FLAG_METHOD);
  5103. (*Callback)(TemplateHandle,
  5104. DataItem->Name,
  5105. MofResource,
  5106. ClassInfo,
  5107. DataItem,
  5108. i,
  5109. Context);
  5110. }
  5111. }
  5112. void GenerateMethodButtonsText(
  5113. HANDLE TemplateHandle,
  5114. PWCHAR MethodName,
  5115. PMOFRESOURCE MofResource,
  5116. PMOFCLASSINFOW ClassInfo,
  5117. PMOFDATAITEMW MethodDataItem,
  5118. ULONG Counter,
  5119. PVOID Context
  5120. )
  5121. {
  5122. PMOFCLASSINFOW MethodClassInfo;
  5123. FilePrint(TemplateHandle,
  5124. "<p class=MsoNormal>Method %ws: <input name=%wsButton type=BUTTON value=Execute> </p>\r\n",
  5125. MethodName, MethodName);
  5126. MethodClassInfo = MethodDataItem->MethodClassInfo;
  5127. EnumerateClassProperties(TemplateHandle,
  5128. NULL,
  5129. NULL,
  5130. MofResource,
  5131. MethodClassInfo,
  5132. GenerateMethodControlText,
  5133. TRUE,
  5134. MethodName,
  5135. 0);
  5136. }
  5137. void GenerateMethodSubsText(
  5138. HANDLE TemplateHandle,
  5139. PWCHAR MethodName,
  5140. PMOFRESOURCE MofResource,
  5141. PMOFCLASSINFOW ClassInfo,
  5142. PMOFDATAITEMW MethodDataItem,
  5143. ULONG Counter,
  5144. PVOID Context
  5145. )
  5146. {
  5147. PMOFCLASSINFOW MethodClassInfo;
  5148. FilePrint(TemplateHandle,
  5149. "Sub %wsButton_OnClick\r\n"
  5150. " if InstanceCount <> 0 Then\r\n"
  5151. " On Error Resume Next\r\n"
  5152. " Err.Clear\r\n"
  5153. " Set Instance = Service.Get(InstancePaths(CurrentInstanceIndex))\r\n"
  5154. " if Err.Number = 0 Then\r\n"
  5155. " Set TheForm = Document.ClassForm\r\n"
  5156. " Err.Clear\r\n",
  5157. MethodName);
  5158. MethodClassInfo = MethodDataItem->MethodClassInfo;
  5159. EnumerateClassProperties(TemplateHandle,
  5160. NULL,
  5161. NULL,
  5162. MofResource,
  5163. MethodClassInfo,
  5164. GenerateMethodInText,
  5165. FALSE,
  5166. MethodName,
  5167. 0);
  5168. FilePrint(TemplateHandle,
  5169. " Instance.%ws ",
  5170. MethodName);
  5171. EnumerateClassProperties(TemplateHandle,
  5172. NULL,
  5173. NULL,
  5174. MofResource,
  5175. MethodClassInfo,
  5176. GenerateMethodCallText,
  5177. FALSE,
  5178. UlongToPtr(MethodClassInfo->DataItemCount-1),
  5179. 0);
  5180. FilePrint(TemplateHandle,
  5181. "\r\n if Err.Number = 0 Then\r\n"
  5182. );
  5183. EnumerateClassProperties(TemplateHandle,
  5184. NULL,
  5185. NULL,
  5186. MofResource,
  5187. MethodClassInfo,
  5188. GenerateMethodOutText,
  5189. FALSE,
  5190. MethodName,
  5191. 0);
  5192. FilePrint(TemplateHandle,
  5193. " MsgBox \"Method Execution Succeeded\"\r\n"
  5194. " Else\r\n"
  5195. " MsgBox Err.Description,, \"Method Execution Failed\"\r\n"
  5196. " End if\r\n"
  5197. " End if\r\n"
  5198. " End if\r\n"
  5199. "End Sub\r\n\r\n"
  5200. );
  5201. }
  5202. ULONG GenerateClassWebPage(
  5203. HANDLE TemplateHandle,
  5204. PMOFCLASS MofClass,
  5205. PMOFRESOURCE MofResource
  5206. )
  5207. {
  5208. PMOFCLASSINFOW ClassInfo = MofClass->MofClassInfo;
  5209. BOOLEAN IsEvent=(ClassInfo->Flags & MOFCI_FLAG_EVENT) == MOFCI_FLAG_EVENT;
  5210. FilePrint(TemplateHandle,
  5211. "<html xmlns:v=\"urn:schemas-microsoft-com:vml\"\r\n"
  5212. "xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n"
  5213. "xmlns:w=\"urn:schemas-microsoft-com:office:word\"\r\n"
  5214. "xmlns=\"http://www.w3.org/TR/REC-html40\">\r\n"
  5215. "\r\n"
  5216. "<head>\r\n"
  5217. "<meta http-equiv=Content-Type content=\"text/html; charset=us-ascii\">\r\n"
  5218. "<meta name=ProgId content=Word.Document>\r\n"
  5219. "<meta name=Generator content=\"Microsoft Word 9\">\r\n"
  5220. "<meta name=Originator content=\"Microsoft Word 9\">\r\n"
  5221. "<link rel=File-List href=\"./valid_files/filelist.xml\">\r\n"
  5222. "<link rel=Edit-Time-Data href=\"./valid_files/editdata.mso\">\r\n"
  5223. "<!--[if !mso]>\r\n"
  5224. "<style>\r\n"
  5225. "v\\:* {behavior:url(#default#VML);}\r\n"
  5226. "o\\:* {behavior:url(#default#VML);}\r\n"
  5227. "w\\:* {behavior:url(#default#VML);}\r\n"
  5228. ".shape {behavior:url(#default#VML);}\r\n"
  5229. "</style>\r\n"
  5230. "<![endif]-->\r\n"
  5231. "<title>Class %ws</title>\r\n"
  5232. "<!--[if gte mso 9]><xml>\r\n"
  5233. " <o:DocumentProperties>\r\n"
  5234. " <o:Author>Wmi Mof Checking Tool</o:Author>\r\n"
  5235. " <o:Template>Normal</o:Template>\r\n"
  5236. " <o:LastAuthor>Wmi Mof Checking Tool</o:LastAuthor>\r\n"
  5237. " <o:Revision>2</o:Revision>\r\n"
  5238. " <o:TotalTime>3</o:TotalTime>\r\n"
  5239. " <o:Created>1999-09-10T01:09:00Z</o:Created>\r\n"
  5240. " <o:LastSaved>1999-09-10T01:12:00Z</o:LastSaved>\r\n"
  5241. " <o:Pages>1</o:Pages>\r\n"
  5242. " <o:Words>51</o:Words>\r\n"
  5243. " <o:Characters>292</o:Characters>\r\n"
  5244. " <o:Company>Microsoft</o:Company>\r\n"
  5245. " <o:Lines>2</o:Lines>\r\n"
  5246. " <o:Paragraphs>1</o:Paragraphs>\r\n"
  5247. " <o:CharactersWithSpaces>358</o:CharactersWithSpaces>\r\n"
  5248. " <o:Version>9.2720</o:Version>\r\n"
  5249. " </o:DocumentProperties>\r\n"
  5250. "</xml><![endif]--><!--[if gte mso 9]><xml>\r\n"
  5251. " <w:WordDocument>\r\n"
  5252. " <w:Compatibility>\r\n"
  5253. " <w:UseFELayout/>\r\n"
  5254. " </w:Compatibility>\r\n"
  5255. " </w:WordDocument>\r\n"
  5256. "</xml><![endif]-->\r\n"
  5257. "<style>\r\n"
  5258. "<!--\r\n"
  5259. " /* Font Definitions */\r\n"
  5260. "@font-face\r\n"
  5261. " {font-family:\"MS Mincho\";\r\n"
  5262. " panose-1:2 2 6 9 4 2 5 8 3 4;\r\n"
  5263. " mso-font-alt:\"\\FF2D\\FF33 \\660E\\671D\";\r\n"
  5264. " mso-font-charset:128;\r\n"
  5265. " mso-generic-font-family:roman;\r\n"
  5266. " mso-font-format:other;\r\n"
  5267. " mso-font-pitch:fixed;\r\n"
  5268. " mso-font-signature:1 134676480 16 0 131072 0;}\r\n"
  5269. "@font-face\r\n"
  5270. " {font-family:\"\\@MS Mincho\";\r\n"
  5271. " panose-1:2 2 6 9 4 2 5 8 3 4;\r\n"
  5272. " mso-font-charset:128;\r\n"
  5273. " mso-generic-font-family:modern;\r\n"
  5274. " mso-font-pitch:fixed;\r\n"
  5275. " mso-font-signature:-1610612033 1757936891 16 0 131231 0;}\r\n"
  5276. " /* Style Definitions */\r\n"
  5277. "p.MsoNormal, li.MsoNormal, div.MsoNormal\r\n"
  5278. " {mso-style-parent:\"\";\r\n"
  5279. " margin:0in;\r\n"
  5280. " margin-bottom:.0001pt;\r\n"
  5281. " mso-pagination:widow-orphan;\r\n"
  5282. " font-size:12.0pt;\r\n"
  5283. " font-family:\"Times New Roman\";\r\n"
  5284. " mso-fareast-font-family:\"MS Mincho\";}\r\n"
  5285. "@page Section1\r\n"
  5286. " {size:8.5in 11.0in;\r\n"
  5287. " margin:1.0in 1.25in 1.0in 1.25in;\r\n"
  5288. " mso-header-margin:.5in;\r\n"
  5289. " mso-footer-margin:.5in;\r\n"
  5290. " mso-paper-source:0;}\r\n"
  5291. "div.Section1\r\n"
  5292. " {page:Section1;}\r\n"
  5293. "-->\r\n"
  5294. "</style>\r\n"
  5295. "<!--[if gte mso 9]><xml>\r\n"
  5296. " <o:shapedefaults v:ext=\"edit\" spidmax=\"1026\"/>\r\n"
  5297. "</xml><![endif]--><!--[if gte mso 9]><xml>\r\n"
  5298. " <o:shapelayout v:ext=\"edit\">\r\n"
  5299. " <o:idmap v:ext=\"edit\" data=\"1\"/>\r\n"
  5300. " </o:shapelayout></xml><![endif]-->\r\n"
  5301. "</head>\r\n"
  5302. "\r\n"
  5303. "<body lang=EN-US style='tab-interval:.5in'>\r\n"
  5304. "\r\n"
  5305. "<div class=Section1>\r\n"
  5306. "\r\n"
  5307. "<h3>Class %ws</h3>\r\n"
  5308. "\r\n"
  5309. "\r\n"
  5310. "<div class=MsoNormal align=center style='text-align:center'>\r\n"
  5311. "\r\n"
  5312. "<hr size=2 width=\"100%\" align=center>\r\n"
  5313. "\r\n"
  5314. "</div>\r\n"
  5315. "\r\n"
  5316. "\r\n"
  5317. "<form NAME=ClassForm>\r\n"
  5318. "\r\n"
  5319. "<p class=MsoNormal><span style='display:none;mso-hide:all'><script language=\"VBScript\">\r\n"
  5320. "<!--\r\n"
  5321. "On Error Resume Next\r\n"
  5322. "Dim Locator\r\n"
  5323. "Dim Service\r\n"
  5324. "Dim Collection\r\n"
  5325. "Dim InstancePaths()\r\n"
  5326. "Dim InstanceCount\r\n"
  5327. "Dim CurrentInstanceIndex\r\n"
  5328. "\r\n",
  5329. ClassInfo->Name, ClassInfo->Name, ClassInfo->Name);
  5330. EnumerateClassProperties(TemplateHandle,
  5331. NULL,
  5332. NULL,
  5333. MofResource,
  5334. ClassInfo,
  5335. GenerateArrayDimsText,
  5336. TRUE,
  5337. NULL,
  5338. 0);
  5339. FilePrint(TemplateHandle, "\r\n");
  5340. if (IsEvent)
  5341. {
  5342. FilePrint(TemplateHandle,
  5343. "Dim LastEventObject\r\n"
  5344. "Dim ReceivedEvent\r\n"
  5345. "ReceivedEvent = FALSE\r\n"
  5346. "InstanceCount = 1\r\n"
  5347. "\r\n"
  5348. "Sub window_onLoad \r\n"
  5349. " Set Locator = CreateObject(\"WbemScripting.SWbemLocator\")\r\n"
  5350. " Locator.Security_.Privileges.AddAsString \"SeSecurityPrivilege\"\r\n"
  5351. " Set Service = Locator.ConnectServer(, \"root\\wmi\")\r\n"
  5352. " Service.Security_.ImpersonationLevel=3\r\n"
  5353. " On Error Resume Next\r\n"
  5354. " Err.Clear\r\n"
  5355. " Service.ExecNotificationQueryAsync mysink, _\r\n"
  5356. " \"select * from %ws\"\r\n"
  5357. "\r\n"
  5358. " if Err.Number <> 0 Then\r\n"
  5359. " MsgBox Err.Description,, \"Error Registering for event\"\r\n"
  5360. " End If\r\n"
  5361. "End Sub\r\n"
  5362. "\r\n",
  5363. ClassInfo->Name);
  5364. FilePrint(TemplateHandle,
  5365. "Sub ReloadInstance\r\n"
  5366. " Set TheForm = Document.ClassForm\r\n"
  5367. " if ReceivedEvent Then\r\n"
  5368. " Set Instance = LastEventObject\r\n"
  5369. " TheForm.InstanceNameText.Value = Instance.InstanceName\r\n"
  5370. );
  5371. EnumerateClassProperties(TemplateHandle,
  5372. NULL,
  5373. NULL,
  5374. MofResource,
  5375. ClassInfo,
  5376. GenerateReloadText,
  5377. TRUE,
  5378. NULL,
  5379. 0);
  5380. FilePrint(TemplateHandle,
  5381. " End If\r\n"
  5382. "\r\n"
  5383. "End Sub\r\n"
  5384. "\r\n"
  5385. );
  5386. } else {
  5387. FilePrint(TemplateHandle,
  5388. "Set Locator = CreateObject(\"WbemScripting.SWbemLocator\")\r\n"
  5389. "' Note that Locator.ConnectServer can be used to connect to remote computers\r\n"
  5390. "Set Service = Locator.ConnectServer(, \"root\\wmi\")\r\n"
  5391. "Service.Security_.ImpersonationLevel=3\r\n"
  5392. );
  5393. FilePrint(TemplateHandle,
  5394. "Set Collection = Service.InstancesOf (\"%ws\")\r\n"
  5395. "\r\n"
  5396. "InstanceCount = 0\r\n"
  5397. "Err.Clear\r\n"
  5398. "for each Instance in Collection\r\n"
  5399. " if Err.Number = 0 Then\r\n"
  5400. " InstanceCount = InstanceCount + 1\r\n"
  5401. "\r\n"
  5402. " ReDim Preserve InstancePaths(InstanceCount)\r\n"
  5403. "\r\n"
  5404. " Set ObjectPath = Instance.Path_\r\n"
  5405. " InstancePaths(InstanceCount) = ObjectPath.Path\r\n"
  5406. " End If\r\n"
  5407. "next 'Instance\r\n"
  5408. "\r\n"
  5409. "if InstanceCount = 0 Then\r\n"
  5410. " MsgBox \"No instances available for this class\"\r\n"
  5411. "Else\r\n"
  5412. " CurrentInstanceIndex = 1\r\n"
  5413. "End if\r\n"
  5414. "\r\n",
  5415. ClassInfo->Name
  5416. );
  5417. FilePrint(TemplateHandle,
  5418. "Sub ChangeButton_OnClick\r\n"
  5419. " Set TheForm = Document.ClassForm\r\n"
  5420. " if InstanceCount = 0 Then\r\n"
  5421. " MsgBox \"No instances available for this class\"\r\n"
  5422. " Else\r\n"
  5423. " On Error Resume Next\r\n"
  5424. " Err.Clear\r\n"
  5425. " Set Instance = Service.Get(InstancePaths(CurrentInstanceIndex))\r\n"
  5426. " if Err.Number = 0 Then\r\n"
  5427. );
  5428. EnumerateClassProperties(TemplateHandle,
  5429. NULL,
  5430. NULL,
  5431. MofResource,
  5432. ClassInfo,
  5433. GenerateChangeText,
  5434. TRUE,
  5435. NULL,
  5436. 0);
  5437. FilePrint(TemplateHandle,
  5438. "\r\n"
  5439. " Err.Clear\r\n"
  5440. " Instance.Put_()\r\n"
  5441. " if Err.Number <> 0 Then\r\n"
  5442. " MsgBox Err.Description, ,CurrentObjectPath\r\n"
  5443. " End If\r\n"
  5444. " Else\r\n"
  5445. " MsgBox Err.Description, ,CurrentObjectPath\r\n"
  5446. " End If\r\n"
  5447. " End If\r\n"
  5448. "End Sub\r\n"
  5449. "\r\n"
  5450. "Sub ReloadInstance\r\n"
  5451. " Set TheForm = Document.ClassForm\r\n"
  5452. " if InstanceCount = 0 Then\r\n"
  5453. " TheForm.InstanceNameText.Value = \"No Instances Available\"\r\n"
  5454. " Else\r\n"
  5455. " On Error Resume Next\r\n"
  5456. " Err.Clear\r\n"
  5457. " Set Instance = Service.Get(InstancePaths(CurrentInstanceIndex))\r\n"
  5458. " if Err.Number = 0 Then\r\n"
  5459. "\r\n"
  5460. " TheForm.InstanceNameText.Value = InstancePaths(CurrentInstanceIndex)\r\n"
  5461. );
  5462. EnumerateClassProperties(TemplateHandle,
  5463. NULL,
  5464. NULL,
  5465. MofResource,
  5466. ClassInfo,
  5467. GenerateReloadText,
  5468. TRUE,
  5469. NULL,
  5470. 0);
  5471. FilePrint(TemplateHandle,
  5472. " Else\r\n"
  5473. " MsgBox Err.Description, ,CurrentObjectPath\r\n"
  5474. " End If\r\n"
  5475. " End If\r\n"
  5476. "\r\n"
  5477. "End Sub\r\n"
  5478. "\r\n"
  5479. "Sub RefreshButton_OnClick\r\n"
  5480. " if InstanceCount = 0 Then\r\n"
  5481. " MsgBox \"No instances available for this class\"\r\n"
  5482. " Else\r\n"
  5483. " call ReloadInstance\r\n"
  5484. " End If\r\n"
  5485. "End Sub\r\n"
  5486. "\r\n"
  5487. "Sub NextButton_OnClick\r\n"
  5488. "\r\n"
  5489. " if InstanceCount = 0 Then\r\n"
  5490. " MsgBox \"No instances available for this class\"\r\n"
  5491. " Else\r\n"
  5492. " if CurrentInstanceIndex = InstanceCount Then\r\n"
  5493. " CurrentInstanceIndex = 1\r\n"
  5494. " Else \r\n"
  5495. " CurrentInstanceIndex = CurrentInstanceIndex + 1\r\n"
  5496. " End If\r\n"
  5497. " call ReloadInstance\r\n"
  5498. " End if\r\n"
  5499. "\r\n"
  5500. "\r\n"
  5501. "End Sub\r\n"
  5502. "\r\n"
  5503. "Sub PrevButton_OnClick\r\n"
  5504. "\r\n"
  5505. " if InstanceCount = 0 Then\r\n"
  5506. " MsgBox \"No instances available for this class\"\r\n"
  5507. " Else\r\n"
  5508. " if CurrentInstanceIndex = 1 Then\r\n"
  5509. " CurrentInstanceIndex = InstanceCount\r\n"
  5510. " Else\r\n"
  5511. " CurrentInstanceIndex = CurrentInstanceIndex - 1\r\n"
  5512. " End if\r\n"
  5513. " call ReloadInstance\r\n"
  5514. " End if\r\n"
  5515. "\r\n"
  5516. "\r\n"
  5517. "End Sub\r\n"
  5518. "\r\n");
  5519. }
  5520. FilePrint(TemplateHandle,
  5521. "Sub NextIndexButton_OnClick(ByRef Index, MaxIndex)\r\n"
  5522. " if InstanceCount <> 0 Then\r\n"
  5523. " Index = Index + 1\r\n"
  5524. " if Index = MaxIndex Then\r\n"
  5525. " Index = 0\r\n"
  5526. " End If\r\n"
  5527. " Call ReloadInstance\r\n"
  5528. " End If\r\n"
  5529. "End Sub\r\n"
  5530. "\r\n"
  5531. "Sub PrevIndexButton_OnClick(ByRef Index, MaxIndex)\r\n"
  5532. " if InstanceCount <> 0 Then\r\n"
  5533. " if Index = 0 Then\r\n"
  5534. " Index = MaxIndex - 1\r\n"
  5535. " Else\r\n"
  5536. " Index = Index - 1\r\n"
  5537. " End If\r\n"
  5538. " Call ReloadInstance\r\n"
  5539. " End If\r\n"
  5540. "End Sub\r\n"
  5541. "\r\n"
  5542. "Sub GotoIndexButton_OnClick(ByRef Index, MaxIndex, NewIndex)\r\n"
  5543. " if InstanceCount <> 0 Then\r\n"
  5544. " DestIndex = NewIndex + 0\r\n"
  5545. " if DestIndex >= 0 And DestIndex < MaxIndex Then\r\n"
  5546. " Index = DestIndex\r\n"
  5547. " Call ReloadInstance\r\n"
  5548. " Else\r\n"
  5549. " MsgBox \"Enter an index between 0 and \" & MaxIndex-1, ,\"Index out of range\"\r\n"
  5550. " End If\r\n"
  5551. " End If\r\n"
  5552. "End Sub\r\n"
  5553. "\r\n");
  5554. EnumerateClassMethods(TemplateHandle,
  5555. MofResource,
  5556. ClassInfo,
  5557. GenerateMethodSubsText,
  5558. NULL);
  5559. FilePrint(TemplateHandle,
  5560. "-->\r\n"
  5561. "</script></span>"
  5562. "<INPUT TYPE=\"TEXT\" SIZE=\"128\" NAME=\"InstanceNameText\" VALUE=\"\"></p>\r\n"
  5563. );
  5564. if (IsEvent)
  5565. {
  5566. FilePrint(TemplateHandle,
  5567. "<SCRIPT FOR=\"mysink\" EVENT=\"OnObjectReady(Instance, objAsyncContext)\" LANGUAGE=\"VBScript\">\r\n"
  5568. );
  5569. FilePrint(TemplateHandle,
  5570. " Set LastEventObject = Instance\r\n"
  5571. " ReceivedEvent = TRUE\r\n"
  5572. " Call ReloadInstance\r\n"
  5573. );
  5574. FilePrint(TemplateHandle,
  5575. "</SCRIPT>\r\n"
  5576. );
  5577. } else {
  5578. FilePrint(TemplateHandle,
  5579. "\r\n"
  5580. "<input name=NextButton type=BUTTON value=Next>\r\n"
  5581. "\r\n"
  5582. "<input name=PrevButton type=BUTTON value=Previous>\r\n"
  5583. "\r\n"
  5584. "<input name=ChangeButton type=BUTTON value=Change>\r\n"
  5585. "\r\n"
  5586. "<input name=RefreshButton type=BUTTON value=Refresh>\r\n"
  5587. "\r\n"
  5588. "<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>\r\n"
  5589. "\r\n"
  5590. );
  5591. }
  5592. EnumerateClassProperties(TemplateHandle,
  5593. NULL,
  5594. NULL,
  5595. MofResource,
  5596. ClassInfo,
  5597. GenerateTextFormText,
  5598. TRUE,
  5599. NULL,
  5600. 0);
  5601. EnumerateClassMethods(TemplateHandle,
  5602. MofResource,
  5603. ClassInfo,
  5604. GenerateMethodButtonsText,
  5605. NULL);
  5606. FilePrint(TemplateHandle,
  5607. "<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>\r\n"
  5608. "\r\n"
  5609. "<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>\r\n"
  5610. "\r\n"
  5611. "<p class=MsoNormal><a href=\"index.htm\"\r\n"
  5612. "title=\"Goes back to list of classes in this MOF\">Back to List</a></p>\r\n"
  5613. "\r\n"
  5614. "</form>\r\n"
  5615. "\r\n"
  5616. );
  5617. if (! IsEvent)
  5618. {
  5619. FilePrint(TemplateHandle,
  5620. "<p class=MsoNormal><span style='display:none;mso-hide:all'><script language=\"VBScript\">\r\n"
  5621. "<!--\r\n"
  5622. " call ReloadInstance\r\n"
  5623. "-->\r\n"
  5624. "</script></span></p>\r\n"
  5625. "\r\n"
  5626. );
  5627. }
  5628. FilePrint(TemplateHandle,
  5629. "</div>\r\n"
  5630. "\r\n"
  5631. );
  5632. if (IsEvent)
  5633. {
  5634. FilePrint(TemplateHandle,
  5635. "<OBJECT ID=\"mysink\" CLASSID=\"CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223\"></OBJECT>\r\n"
  5636. );
  5637. }
  5638. FilePrint(TemplateHandle,
  5639. "</body>\r\n"
  5640. "\r\n"
  5641. "</html>\r\n"
  5642. );
  5643. return(ERROR_SUCCESS);
  5644. }
  5645. ULONG GenerateWebFiles(
  5646. PCHAR WebDir,
  5647. PMOFRESOURCE MofResource
  5648. )
  5649. {
  5650. ULONG Status;
  5651. HANDLE IndexHandle, TemplateHandle;
  5652. CHAR PathName[MAX_PATH];
  5653. PCHAR FileName;
  5654. ULONG Len, Index;
  5655. PLIST_ENTRY MofClassList;
  5656. PMOFCLASS MofClass;
  5657. PMOFCLASSINFOW ClassInfo;
  5658. CBMOFObj *ClassObject;
  5659. if (! CreateDirectory(WebDir, NULL))
  5660. {
  5661. Status = GetLastError();
  5662. if (Status != ERROR_ALREADY_EXISTS)
  5663. {
  5664. return(Status);
  5665. }
  5666. }
  5667. strcpy(PathName, WebDir);
  5668. Len = strlen(PathName)-1;
  5669. if (PathName[Len] != '\\')
  5670. {
  5671. PathName[++Len] = '\\';
  5672. PathName[++Len] = 0;
  5673. } else {
  5674. Len++;
  5675. }
  5676. FileName = &PathName[Len];
  5677. strcpy(FileName, "index.htm");
  5678. IndexHandle = CreateFile(PathName,
  5679. GENERIC_WRITE,
  5680. 0,
  5681. NULL,
  5682. CREATE_ALWAYS,
  5683. FILE_ATTRIBUTE_NORMAL,
  5684. NULL);
  5685. if ((IndexHandle == NULL) || (IndexHandle == INVALID_HANDLE_VALUE))
  5686. {
  5687. return(GetLastError());
  5688. }
  5689. FilePrint(IndexHandle,
  5690. "<HTML>\r\n<HEAD><TITLE>Class List</TITLE></HEAD><BODY>\r\n");
  5691. //
  5692. // Loop over all mof classes
  5693. Index = 0;
  5694. MofClassList = MofResource->MRMCHead.Flink;
  5695. while (MofClassList != &MofResource->MRMCHead)
  5696. {
  5697. MofClass = CONTAINING_RECORD(MofClassList,
  5698. MOFCLASS,
  5699. MCMRList);
  5700. ClassInfo = MofClass->MofClassInfo;
  5701. ClassObject = (CBMOFObj *)MofClass->ClassObjectHandle;
  5702. if (! (ClassInfo->Flags & MOFCI_FLAG_EMBEDDED_CLASS))
  5703. {
  5704. //
  5705. // don't create pages for embedded classes or events
  5706. sprintf(FileName, "%ws.htm", ClassInfo->Name);
  5707. TemplateHandle = CreateFile(PathName,
  5708. GENERIC_WRITE,
  5709. 0,
  5710. NULL,
  5711. CREATE_ALWAYS,
  5712. FILE_ATTRIBUTE_NORMAL,
  5713. NULL);
  5714. if ((TemplateHandle == NULL) || (TemplateHandle == INVALID_HANDLE_VALUE))
  5715. {
  5716. CloseHandle(IndexHandle);
  5717. return(GetLastError());
  5718. }
  5719. FilePrint(IndexHandle,
  5720. "<H3><A href=\"%ws.htm\">%ws</A></H3><HR>",
  5721. ClassInfo->Name,
  5722. ClassInfo->Name);
  5723. Status = GenerateClassWebPage(TemplateHandle,
  5724. MofClass,
  5725. MofResource);
  5726. CloseHandle(TemplateHandle);
  5727. }
  5728. MofClassList = MofClassList->Flink;
  5729. }
  5730. FilePrint(IndexHandle, "</BODY>\r\n</HTML>\r\n");
  5731. CloseHandle(IndexHandle);
  5732. return(ERROR_SUCCESS);
  5733. }
  5734. ULONG AppendUnicodeTextFiles(
  5735. char *DestFile,
  5736. char *SrcFile1,
  5737. char *SrcFile2
  5738. )
  5739. {
  5740. #define READ_BLOCK_SIZE 0x8000
  5741. HANDLE DestHandle, SrcHandle;
  5742. ULONG BytesRead, BytesWritten;
  5743. PUCHAR Buffer, p;
  5744. BOOL b;
  5745. ULONG Status = ERROR_SUCCESS;
  5746. BOOLEAN FirstTime;
  5747. ULONG TotalBytesRead = 0;
  5748. ULONG TotalBytesWritten = 0;
  5749. ULONG ReadSize;
  5750. CHAR c;
  5751. //
  5752. // This is a very simple procedure. We append the second file onto
  5753. // the end of the first file, however we always skip the first 2
  5754. // bytes of the second file if they are a 0xFEFF. This signature
  5755. // denotes that the file is a unicode text file, but if it gets
  5756. // appended in the middle of the file then mofcomp will get really
  5757. // pissed off and barf.
  5758. //
  5759. Buffer = (PUCHAR)WmipAlloc(READ_BLOCK_SIZE);
  5760. if (Buffer != NULL)
  5761. {
  5762. DestHandle = CreateFile(DestFile,
  5763. GENERIC_READ | GENERIC_WRITE,
  5764. 0,
  5765. NULL,
  5766. CREATE_ALWAYS,
  5767. FILE_ATTRIBUTE_NORMAL,
  5768. NULL);
  5769. if (DestHandle != INVALID_HANDLE_VALUE)
  5770. {
  5771. SrcHandle = CreateFile(SrcFile1,
  5772. GENERIC_READ,
  5773. 0,
  5774. NULL,
  5775. OPEN_EXISTING,
  5776. FILE_ATTRIBUTE_NORMAL,
  5777. NULL);
  5778. if (SrcHandle != INVALID_HANDLE_VALUE)
  5779. {
  5780. //
  5781. // Just copy over all data from first file into
  5782. // destination
  5783. //
  5784. do
  5785. {
  5786. b = ReadFile(SrcHandle,
  5787. Buffer,
  5788. READ_BLOCK_SIZE,
  5789. &BytesRead,
  5790. NULL);
  5791. if (b)
  5792. {
  5793. TotalBytesRead += BytesRead;
  5794. WmipDebugPrint(("Read 0x%x/0x%x from Source 1\n",
  5795. BytesRead, TotalBytesRead));
  5796. b = WriteFile(DestHandle,
  5797. Buffer,
  5798. BytesRead,
  5799. &BytesWritten,
  5800. NULL);
  5801. if (!b)
  5802. {
  5803. Status = GetLastError();
  5804. break;
  5805. } else if (BytesWritten != BytesRead) {
  5806. Status = ERROR_BAD_LENGTH;
  5807. break;
  5808. }
  5809. TotalBytesWritten += BytesWritten;
  5810. WmipDebugPrint(("Wrote 0x%x/0x%x to Dest\n",
  5811. BytesWritten, TotalBytesWritten));
  5812. } else {
  5813. Status = GetLastError();
  5814. break;
  5815. }
  5816. } while (BytesRead == READ_BLOCK_SIZE);
  5817. CloseHandle(SrcHandle);
  5818. //
  5819. // Now copy the data from the second file, but make
  5820. // sure we skip any 0xFFFE at the beginning of the
  5821. // second file
  5822. //
  5823. TotalBytesRead = 0;
  5824. SrcHandle = CreateFile(SrcFile2,
  5825. GENERIC_READ,
  5826. 0,
  5827. NULL,
  5828. OPEN_EXISTING,
  5829. FILE_ATTRIBUTE_NORMAL,
  5830. NULL);
  5831. if (SrcHandle != INVALID_HANDLE_VALUE)
  5832. {
  5833. FirstTime = TRUE;
  5834. do
  5835. {
  5836. b = ReadFile(SrcHandle,
  5837. Buffer,
  5838. READ_BLOCK_SIZE,
  5839. &BytesRead,
  5840. NULL);
  5841. if (b)
  5842. {
  5843. ReadSize = READ_BLOCK_SIZE;
  5844. TotalBytesRead += BytesRead;
  5845. WmipDebugPrint(("Read 0x%x/0x%x from Source 2\n",
  5846. BytesRead, TotalBytesRead));
  5847. if (FirstTime)
  5848. {
  5849. FirstTime = FALSE;
  5850. if (BytesRead >= 2)
  5851. {
  5852. if ( *((PWCHAR)Buffer) == 0xFEFF )
  5853. {
  5854. WmipDebugPrint(("First Time and need to skip 2 bytes\n"));
  5855. p = Buffer + 2;
  5856. BytesRead -= 2;
  5857. ReadSize -= 2;
  5858. }
  5859. }
  5860. } else {
  5861. p = Buffer;
  5862. }
  5863. b = WriteFile(DestHandle,
  5864. p,
  5865. BytesRead,
  5866. &BytesWritten,
  5867. NULL);
  5868. if (!b)
  5869. {
  5870. Status = GetLastError();
  5871. break;
  5872. } else if (BytesWritten != BytesRead) {
  5873. Status = ERROR_BAD_LENGTH;
  5874. break;
  5875. }
  5876. TotalBytesWritten += BytesWritten;
  5877. WmipDebugPrint(("Wrote 0x%x/0x%x to Dest\n",
  5878. BytesWritten, TotalBytesWritten));
  5879. } else {
  5880. Status = GetLastError();
  5881. break;
  5882. }
  5883. } while (BytesRead == ReadSize);
  5884. if (Status == ERROR_SUCCESS)
  5885. {
  5886. //
  5887. // Copy put a ^Z at the end so well do that too
  5888. //
  5889. c = 0x1a;
  5890. b = WriteFile(DestHandle,
  5891. &c,
  5892. 1,
  5893. &BytesWritten,
  5894. NULL);
  5895. if (!b)
  5896. {
  5897. Status = GetLastError();
  5898. } else if (BytesWritten != 1) {
  5899. Status = ERROR_BAD_LENGTH;
  5900. }
  5901. TotalBytesWritten += BytesWritten;
  5902. WmipDebugPrint(("Wrote 0x%x/0x%x to Dest\n",
  5903. BytesWritten, TotalBytesWritten));
  5904. }
  5905. CloseHandle(SrcHandle);
  5906. }
  5907. } else {
  5908. Status = GetLastError();
  5909. }
  5910. CloseHandle(DestHandle);
  5911. } else {
  5912. Status = GetLastError();
  5913. }
  5914. WmipFree(Buffer);
  5915. } else {
  5916. Status = ERROR_NOT_ENOUGH_MEMORY;
  5917. }
  5918. return(Status);
  5919. }
  5920. void Usage(
  5921. void
  5922. )
  5923. {
  5924. printf("WMI Mof Check Tool - Revision 25\n");
  5925. printf("\n");
  5926. printf("WmiMofCk validates that the classes, properties, methods and events specified \n");
  5927. printf("in a binary mof file (.bmf) are valid for use with WMI. It also generates \n");
  5928. printf("useful output files needed to build and test the WMI data provider.\n");
  5929. printf("\n");
  5930. printf("If the -h parameter is specified then a C language header file is created\n");
  5931. printf("that defines the guids, data structures and method indicies specified in the\n");
  5932. printf("MOF file.\n");
  5933. printf("\n");
  5934. printf("If the -t parameter is specified then a VBScript applet is created that will\n");
  5935. printf("query all data blocks and properties specified in the MOF file. This can be\n");
  5936. printf("useful for testing WMI data providers.\n");
  5937. printf("\n");
  5938. printf("If the -x parameter is specified then a text file is created that contains\n");
  5939. printf("the text representation of the binary mof data. This can be included in \n");
  5940. printf("the source of the driver if the driver supports reporting the binary mof \n");
  5941. printf("via a WMI query rather than a resource on the driver image file.\n\n");
  5942. printf("If the -c parameter is specified then a C language source file is\n");
  5943. printf("generated that contains a template for implementing WMI code in\n");
  5944. printf("a device driver\n\n");
  5945. printf("if the -w parameter is specified then a set of HTML files are\n");
  5946. printf("generated that create a rudimentary UI that can be used to access\n");
  5947. printf("the wmi data blocks\n\n");
  5948. printf("if the -m parameter is specified then structure definitions for\n");
  5949. printf("method parameter lists are generated in the generated header file.\n\n");
  5950. printf("if the -u parameter is specified then structure definitions for all\n");
  5951. printf("data blocks are generated unconditionally\n\n");
  5952. printf("\n");
  5953. printf("Usage:\n");
  5954. printf(" wmimofck -h<C Source Language Header output file>\n");
  5955. printf(" -c<C Source Language Code output file>\n");
  5956. printf(" -x<Hexdump output file>\n");
  5957. printf(" -t<Command line VBScript test output file>\n");
  5958. printf(" -w<HTML UI output file directory>\n");
  5959. printf(" -y<MofFile> -z<MflFile>\n");
  5960. printf(" -m\n");
  5961. printf(" -u\n");
  5962. printf(" <binary mof input file>\n\n");
  5963. }
  5964. #define IsWhiteSpace(c) ( (c == ' ') || (c == '\t') )
  5965. ULONG GetParameter(
  5966. char *Parameter,
  5967. ULONG ParameterSize,
  5968. char *CommandLine
  5969. )
  5970. {
  5971. ULONG i;
  5972. i = 0;
  5973. ParameterSize--;
  5974. while ( (! IsWhiteSpace(*CommandLine)) &&
  5975. ( *CommandLine != 0) &&
  5976. (i < ParameterSize) )
  5977. {
  5978. *Parameter++ = *CommandLine++;
  5979. i++;
  5980. }
  5981. *Parameter = 0;
  5982. return(i);
  5983. }
  5984. int _cdecl main(int argc, char *argv[])
  5985. {
  5986. char BMofFile[MAX_PATH];
  5987. char *Parameter;
  5988. int i;
  5989. ULONG Status;
  5990. char ASLFile[MAX_PATH];
  5991. char CFile[MAX_PATH];
  5992. char HFile[MAX_PATH];
  5993. char XFile[MAX_PATH];
  5994. char TFile[MAX_PATH];
  5995. char WebDir[MAX_PATH];
  5996. char MofFile[MAX_PATH];
  5997. char MflFile[MAX_PATH];
  5998. char c;
  5999. PMOFRESOURCE MofResource;
  6000. *ASLFile = 0;
  6001. *CFile = 0;
  6002. *HFile = 0;
  6003. *XFile = 0;
  6004. *TFile = 0;
  6005. *WebDir = 0;
  6006. *MofFile = 0;
  6007. *MflFile = 0;
  6008. *BMofFile = 0;
  6009. printf("Microsoft (R) WDM Extensions To WMI MOF Checking Utility Version 1.50.0000\n");
  6010. printf("Copyright (c) Microsoft Corp. 1997-2000. All rights reserved.\n\n");
  6011. SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT); // BUGBUG: Remove when MOF format maintains alignment correctly
  6012. if (argc == 1)
  6013. {
  6014. Usage();
  6015. return(1);
  6016. }
  6017. i = 1;
  6018. while (i < argc)
  6019. {
  6020. Parameter = argv[i++];
  6021. if (IsWhiteSpace(*Parameter))
  6022. {
  6023. Parameter++;
  6024. continue;
  6025. }
  6026. if (*Parameter != '-')
  6027. {
  6028. //
  6029. // Parameter does not start with -, must be bmof filename
  6030. if (*BMofFile != 0)
  6031. {
  6032. //
  6033. // Only one filename allowed
  6034. Usage();
  6035. }
  6036. GetParameter(BMofFile, sizeof(BMofFile), Parameter);
  6037. } else {
  6038. Parameter++;
  6039. // Check for - parameters here
  6040. c = (CHAR)toupper(*Parameter);
  6041. Parameter++;
  6042. switch (c)
  6043. {
  6044. case 'A' :
  6045. {
  6046. GetParameter(ASLFile, sizeof(ASLFile), Parameter);
  6047. break;
  6048. }
  6049. case 'C':
  6050. {
  6051. GetParameter(CFile, sizeof(CFile), Parameter);
  6052. break;
  6053. }
  6054. case 'H':
  6055. {
  6056. GetParameter(HFile, sizeof(HFile), Parameter);
  6057. break;
  6058. }
  6059. case 'U':
  6060. {
  6061. ForceHeaderGeneration = TRUE;
  6062. }
  6063. case 'M':
  6064. {
  6065. DoMethodHeaderGeneration = TRUE;
  6066. break;
  6067. }
  6068. case 'X':
  6069. {
  6070. GetParameter(XFile, sizeof(XFile), Parameter);
  6071. break;
  6072. }
  6073. case 'T':
  6074. {
  6075. GetParameter(TFile, sizeof(TFile), Parameter);
  6076. break;
  6077. }
  6078. case 'W':
  6079. {
  6080. GetParameter(WebDir, sizeof(WebDir), Parameter);
  6081. break;
  6082. }
  6083. case 'Y':
  6084. {
  6085. GetParameter(MofFile, sizeof(MofFile), Parameter);
  6086. break;
  6087. }
  6088. case 'Z':
  6089. {
  6090. GetParameter(MflFile, sizeof(MflFile), Parameter);
  6091. break;
  6092. }
  6093. default: {
  6094. Usage();
  6095. return(1);
  6096. }
  6097. }
  6098. }
  6099. }
  6100. if (*BMofFile == 0)
  6101. {
  6102. //
  6103. // We must have a filename
  6104. Usage();
  6105. return(1);
  6106. }
  6107. if (*MofFile != 0)
  6108. {
  6109. if (*MflFile != 0)
  6110. {
  6111. Status = AppendUnicodeTextFiles(BMofFile, MofFile, MflFile);
  6112. } else {
  6113. Usage();
  6114. return(1);
  6115. }
  6116. return(Status);
  6117. }
  6118. Status = ParseBinaryMofFile(BMofFile, &MofResource);
  6119. if (Status == ERROR_SUCCESS)
  6120. {
  6121. if (*HFile != 0)
  6122. {
  6123. //
  6124. // Generate C Header file
  6125. Status = GenerateHTemplate(HFile, MofResource);
  6126. if (Status != ERROR_SUCCESS)
  6127. {
  6128. //
  6129. // TODO: Better message
  6130. printf("Error %d creating C Header Template file \n", Status);
  6131. }
  6132. }
  6133. if (*XFile != 0)
  6134. {
  6135. //
  6136. // Generate X Header file
  6137. Status = GenerateXTemplate(XFile);
  6138. if (Status != ERROR_SUCCESS)
  6139. {
  6140. //
  6141. // TODO: Better message
  6142. printf("Error %d creating X Header Template file \n", Status);
  6143. }
  6144. }
  6145. if (*TFile != 0)
  6146. {
  6147. //
  6148. // Generate C output template
  6149. Status = GenerateTTemplate(TFile, MofResource);
  6150. if (Status != ERROR_SUCCESS)
  6151. {
  6152. //
  6153. // TODO: Better message
  6154. printf("Error %d creating C Template file \n", Status);
  6155. }
  6156. }
  6157. if (*CFile != 0)
  6158. {
  6159. //
  6160. // Generate C output template
  6161. Status = GenerateCTemplate(CFile,
  6162. HFile,
  6163. *XFile == 0 ? CFile : XFile,
  6164. MofResource);
  6165. if (Status != ERROR_SUCCESS)
  6166. {
  6167. //
  6168. // TODO: Better message
  6169. printf("Error %d creating C Template file \n", Status);
  6170. }
  6171. }
  6172. if (*WebDir != 0)
  6173. {
  6174. //
  6175. // Generate HTML UI for classes
  6176. //
  6177. Status = GenerateWebFiles(WebDir,
  6178. MofResource);
  6179. }
  6180. if (*ASLFile != 0)
  6181. {
  6182. //
  6183. // Generate ASL output template
  6184. Status = GenerateASLTemplate(ASLFile);
  6185. }
  6186. }
  6187. return(Status);
  6188. }