Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2521 lines
65 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. wmiump.h
  5. Abstract:
  6. Private headers for WMI user mode
  7. Author:
  8. 16-Jan-1997 AlanWar
  9. Revision History:
  10. --*/
  11. #define _WMI_SOURCE_
  12. //
  13. // Define this to track reference counts
  14. //#define TRACK_REFERNECES
  15. //
  16. // Define this to get extra checks on heap validation
  17. //#define HEAPVALIDATION
  18. //
  19. // Define this to get a trace of critical section
  20. //#define CRITSECTTRACE
  21. //
  22. // Define this to compile WMI to run as a service under NT
  23. #define RUN_AS_SERVICE
  24. //
  25. // Define this to include WMI user mode functionality. Note that if you enable
  26. // this then you also need to fix the files: wmi\dll\sources and wmi\makefil0.
  27. //#define WMI_USER_MODE
  28. //
  29. // Define this to track memory leaks
  30. //#define TRACK_MEMORY_LEAKS
  31. #ifndef MEMPHIS
  32. #define UNICODE
  33. #define _UNICODE
  34. #include <nt.h>
  35. #include <ntrtl.h>
  36. #include <nturtl.h>
  37. #endif
  38. #include <windows.h>
  39. #include <ole2.h>
  40. #include <tchar.h>
  41. #include <stdio.h>
  42. #ifndef MEMPHIS
  43. #include "svcs.h"
  44. #endif
  45. #include <netevent.h>
  46. #ifdef MEMPHIS
  47. //
  48. // CONSIDER: Is there a better place to get this stuff on MEMPHIS
  49. //
  50. // Doubly-linked list manipulation routines. Implemented as macros
  51. // but logically these are procedures.
  52. //
  53. //
  54. // VOID
  55. // InitializeListHead(
  56. // PLIST_ENTRY ListHead
  57. // );
  58. //
  59. #define InitializeListHead(ListHead) (\
  60. (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  61. //
  62. // BOOLEAN
  63. // IsListEmpty(
  64. // PLIST_ENTRY ListHead
  65. // );
  66. //
  67. #define IsListEmpty(ListHead) \
  68. ((ListHead)->Flink == (ListHead))
  69. //
  70. // PLIST_ENTRY
  71. // RemoveHeadList(
  72. // PLIST_ENTRY ListHead
  73. // );
  74. //
  75. #define RemoveHeadList(ListHead) \
  76. (ListHead)->Flink;\
  77. {RemoveEntryList((ListHead)->Flink)}
  78. //
  79. // PLIST_ENTRY
  80. // RemoveTailList(
  81. // PLIST_ENTRY ListHead
  82. // );
  83. //
  84. #define RemoveTailList(ListHead) \
  85. (ListHead)->Blink;\
  86. {RemoveEntryList((ListHead)->Blink)}
  87. //
  88. // VOID
  89. // RemoveEntryList(
  90. // PLIST_ENTRY Entry
  91. // );
  92. //
  93. #define RemoveEntryList(Entry) {\
  94. PLIST_ENTRY _EX_Blink;\
  95. PLIST_ENTRY _EX_Flink;\
  96. _EX_Flink = (Entry)->Flink;\
  97. _EX_Blink = (Entry)->Blink;\
  98. _EX_Blink->Flink = _EX_Flink;\
  99. _EX_Flink->Blink = _EX_Blink;\
  100. }
  101. //
  102. // VOID
  103. // InsertTailList(
  104. // PLIST_ENTRY ListHead,
  105. // PLIST_ENTRY Entry
  106. // );
  107. //
  108. #define InsertTailList(ListHead,Entry) {\
  109. PLIST_ENTRY _EX_Blink;\
  110. PLIST_ENTRY _EX_ListHead;\
  111. _EX_ListHead = (ListHead);\
  112. _EX_Blink = _EX_ListHead->Blink;\
  113. (Entry)->Flink = _EX_ListHead;\
  114. (Entry)->Blink = _EX_Blink;\
  115. _EX_Blink->Flink = (Entry);\
  116. _EX_ListHead->Blink = (Entry);\
  117. }
  118. //
  119. // VOID
  120. // InsertHeadList(
  121. // PLIST_ENTRY ListHead,
  122. // PLIST_ENTRY Entry
  123. // );
  124. //
  125. #define InsertHeadList(ListHead,Entry) {\
  126. PLIST_ENTRY _EX_Flink;\
  127. PLIST_ENTRY _EX_ListHead;\
  128. _EX_ListHead = (ListHead);\
  129. _EX_Flink = _EX_ListHead->Flink;\
  130. (Entry)->Flink = _EX_Flink;\
  131. (Entry)->Blink = _EX_ListHead;\
  132. _EX_Flink->Blink = (Entry);\
  133. _EX_ListHead->Flink = (Entry);\
  134. }
  135. //
  136. //
  137. // PSINGLE_LIST_ENTRY
  138. // PopEntryList(
  139. // PSINGLE_LIST_ENTRY ListHead
  140. // );
  141. //
  142. #define PopEntryList(ListHead) \
  143. (ListHead)->Next;\
  144. {\
  145. PSINGLE_LIST_ENTRY FirstEntry;\
  146. FirstEntry = (ListHead)->Next;\
  147. if (FirstEntry != NULL) { \
  148. (ListHead)->Next = FirstEntry->Next;\
  149. } \
  150. }
  151. //
  152. // VOID
  153. // PushEntryList(
  154. // PSINGLE_LIST_ENTRY ListHead,
  155. // PSINGLE_LIST_ENTRY Entry
  156. // );
  157. //
  158. #define PushEntryList(ListHead,Entry) \
  159. (Entry)->Next = (ListHead)->Next; \
  160. (ListHead)->Next = (Entry)
  161. //
  162. // Define the various device type values. Note that values used by Microsoft
  163. // Corporation are in the range 0-32767, and 32768-65535 are reserved for use
  164. // by customers.
  165. //
  166. #define DEVICE_TYPE ULONG
  167. #define FILE_DEVICE_BEEP 0x00000001
  168. #define FILE_DEVICE_CD_ROM 0x00000002
  169. #define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
  170. #define FILE_DEVICE_CONTROLLER 0x00000004
  171. #define FILE_DEVICE_DATALINK 0x00000005
  172. #define FILE_DEVICE_DFS 0x00000006
  173. #define FILE_DEVICE_DISK 0x00000007
  174. #define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
  175. #define FILE_DEVICE_FILE_SYSTEM 0x00000009
  176. #define FILE_DEVICE_INPORT_PORT 0x0000000a
  177. #define FILE_DEVICE_KEYBOARD 0x0000000b
  178. #define FILE_DEVICE_MAILSLOT 0x0000000c
  179. #define FILE_DEVICE_MIDI_IN 0x0000000d
  180. #define FILE_DEVICE_MIDI_OUT 0x0000000e
  181. #define FILE_DEVICE_MOUSE 0x0000000f
  182. #define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
  183. #define FILE_DEVICE_NAMED_PIPE 0x00000011
  184. #define FILE_DEVICE_NETWORK 0x00000012
  185. #define FILE_DEVICE_NETWORK_BROWSER 0x00000013
  186. #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
  187. #define FILE_DEVICE_NULL 0x00000015
  188. #define FILE_DEVICE_PARALLEL_PORT 0x00000016
  189. #define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
  190. #define FILE_DEVICE_PRINTER 0x00000018
  191. #define FILE_DEVICE_SCANNER 0x00000019
  192. #define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
  193. #define FILE_DEVICE_SERIAL_PORT 0x0000001b
  194. #define FILE_DEVICE_SCREEN 0x0000001c
  195. #define FILE_DEVICE_SOUND 0x0000001d
  196. #define FILE_DEVICE_STREAMS 0x0000001e
  197. #define FILE_DEVICE_TAPE 0x0000001f
  198. #define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
  199. #define FILE_DEVICE_TRANSPORT 0x00000021
  200. #define FILE_DEVICE_UNKNOWN 0x00000022
  201. #define FILE_DEVICE_VIDEO 0x00000023
  202. #define FILE_DEVICE_VIRTUAL_DISK 0x00000024
  203. #define FILE_DEVICE_WAVE_IN 0x00000025
  204. #define FILE_DEVICE_WAVE_OUT 0x00000026
  205. #define FILE_DEVICE_8042_PORT 0x00000027
  206. #define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
  207. #define FILE_DEVICE_BATTERY 0x00000029
  208. #define FILE_DEVICE_BUS_EXTENDER 0x0000002a
  209. #define FILE_DEVICE_MODEM 0x0000002b
  210. #define FILE_DEVICE_VDM 0x0000002c
  211. #define FILE_DEVICE_MASS_STORAGE 0x0000002d
  212. #define FILE_DEVICE_SMB 0x0000002e
  213. #define FILE_DEVICE_KS 0x0000002f
  214. #define FILE_DEVICE_CHANGER 0x00000030
  215. #define FILE_DEVICE_SMARTCARD 0x00000031
  216. #define FILE_DEVICE_ACPI 0x00000032
  217. #define FILE_DEVICE_DVD 0x00000033
  218. //
  219. // Macro definition for defining IOCTL and FSCTL function control codes. Note
  220. // that function codes 0-2047 are reserved for Microsoft Corporation, and
  221. // 2048-4095 are reserved for customers.
  222. //
  223. #define CTL_CODE( DeviceType, Function, Method, Access ) ( \
  224. ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
  225. )
  226. //
  227. // Define the method codes for how buffers are passed for I/O and FS controls
  228. //
  229. #define METHOD_BUFFERED 0
  230. #define METHOD_IN_DIRECT 1
  231. #define METHOD_OUT_DIRECT 2
  232. #define METHOD_NEITHER 3
  233. //
  234. // Define the access check value for any access
  235. //
  236. //
  237. // The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
  238. // ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
  239. // constants *MUST* always be in sync.
  240. //
  241. #define FILE_ANY_ACCESS 0
  242. #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
  243. #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
  244. typedef LONG NTSTATUS;
  245. typedef NTSTATUS (*PUSER_THREAD_START_ROUTINE)(
  246. PVOID ThreadParameter
  247. );
  248. #include <stdio.h>
  249. #endif
  250. #include "wmium.h"
  251. #include "wmiumkm.h"
  252. #include "ntwmi.h"
  253. #include "wmiguid.h"
  254. #if DBG
  255. #define WmipAssert(x) if (! (x) ) { \
  256. BOOLEAN OldLoggingEnabled = WmipLoggingEnabled; \
  257. WmipLoggingEnabled = TRUE; \
  258. WmipDbgPrint(("WMI Assertion: "#x" at %s %d\n", __FILE__, __LINE__)); \
  259. WmipLoggingEnabled = OldLoggingEnabled; \
  260. DebugBreak(); }
  261. #else
  262. #define WmipAssert(x)
  263. #endif
  264. #if DBG
  265. extern BOOLEAN WmipLoggingEnabled;
  266. #ifdef MEMPHIS
  267. void __cdecl DebugOut(char *Format, ...);
  268. #define WmipDebugPrint(_x_) { if (WmipLoggingEnabled) DebugOut _x_; }
  269. #define WmipDbgPrint(_x_) { if (WmipLoggingEnabled) DebugOut _x_; }
  270. #else
  271. #define WmipDebugPrint(_x_) { if (WmipLoggingEnabled) DbgPrint _x_; }
  272. #define WmipDbgPrint(_x_) { if (WmipLoggingEnabled) DbgPrint _x_; }
  273. #endif
  274. #else
  275. #define WmipDebugPrint(_x_)
  276. #define WmipDbgPrint(_x_)
  277. #endif
  278. #define NULL_GUID {0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  279. //
  280. // Registry based config options. Only available on checked builds
  281. //
  282. #define WmiRegKeyText TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI")
  283. #define PumpTimeoutRegValueText TEXT("NotificationPumpTimeout")
  284. #define LoggingEnableValueText TEXT("LoggingEnabled")
  285. //
  286. // WMI RPC related definitions
  287. typedef struct
  288. {
  289. WNODE_HEADER WnodeHeader;
  290. BYTE Data[1];
  291. } WNODE_INTERNAL, *PWNODE_INTERNAL;
  292. #define INTERNAL_PROVIDER_ID 1
  293. //
  294. // Size of initial buffer used to read notifications from kernel mode
  295. #define STARTNOTIFICATIONBUFFERSIZE 4096
  296. #ifdef MEMPHIS
  297. #define WmiRpcProtocolSequence TEXT("ncalrpc")
  298. #define WmiServiceRpcProtocolSequence TEXT("ncalrpc")
  299. #define WmiServiceRpcEndpoint TEXT("WmiRpcEndpoint")
  300. #else
  301. //#define WmiRpcProtocolSequence TEXT("ncalrpc")
  302. //#define WmiRpcEndpointPrefix TEXT("NT")
  303. #define WmiRpcProtocolSequence TEXT("ncacn_np")
  304. #define WmiRpcEndpointPrefix TEXT("\\pipe\\")
  305. #define WmiServiceRpcProtocolSequence TEXT("ncacn_np")
  306. #define WmiServiceRpcEndpoint SVCS_RPC_PIPE
  307. #endif
  308. #define MinRpcCalls 1
  309. #define MaxRpcCalls RPC_C_PROTSEQ_MAX_REQS_DEFAULT
  310. //
  311. // Time to wait between retrying an RPC call that was too busy to complete
  312. #define RPC_BUSY_WAIT_TIMER 500
  313. //
  314. // Number of times to retry an RPC call that was too busy to complete
  315. #define RPC_BUSY_WAIT_RETRIES 5
  316. //
  317. // WMI RPC interface principle name
  318. #define WMI_RPC_PRINC_NAME TEXT("WMI_RPC_PRINC_NAME")
  319. //
  320. // This macro will break CountedString into a pointer to the actual string
  321. // and the actual length of the string excluding any trailing nul characters
  322. #define WmipBreakCountedString(CountedString, CountedStringLen) { \
  323. CountedStringLen = *CountedString++; \
  324. if (CountedString[(CountedStringLen-sizeof(WCHAR))/sizeof(WCHAR)] == UNICODE_NULL) \
  325. { \
  326. CountedStringLen -= sizeof(WCHAR); \
  327. } \
  328. }
  329. typedef struct
  330. {
  331. HANDLE GuidHandle;
  332. PVOID DeliveryInfo;
  333. ULONG_PTR DeliveryContext;
  334. ULONG Flags;
  335. } NOTIFYEE, *PNOTIFYEE;
  336. #define STATIC_NOTIFYEE_COUNT 2
  337. typedef struct
  338. {
  339. LIST_ENTRY GNList;
  340. GUID Guid;
  341. ULONG RefCount;
  342. ULONG NotifyeeCount;
  343. PNOTIFYEE Notifyee;
  344. NOTIFYEE StaticNotifyee[STATIC_NOTIFYEE_COUNT];
  345. } GUIDNOTIFICATION, *PGUIDNOTIFICATION;
  346. #define WmipAllocGNEntry() (PGUIDNOTIFICATION)WmipAlloc(sizeof(GUIDNOTIFICATION))
  347. #define WmipFreeGNEntry(GNEntry) WmipFree(GNEntry)
  348. #define WmipReferenceGNEntry(GNEntry) InterlockedIncrement(&GNEntry->RefCount);
  349. //
  350. // Notification Cookie data structures
  351. #if DBG
  352. #define NOTIFYCOOKIESPERCHUNK 2
  353. #else
  354. #define NOTIFYCOOKIESPERCHUNK 128
  355. #endif
  356. typedef struct
  357. {
  358. PVOID DeliveryContext;
  359. PVOID DeliveryInfo;
  360. GUID Guid;
  361. BOOLEAN InUse;
  362. } NOTIFYCOOKIE, *PNOTIFYCOOKIE;
  363. typedef struct
  364. {
  365. LIST_ENTRY Next; // Next cookie chunk
  366. ULONG BaseSlot; // Index of first slot number
  367. USHORT FreeSlot; // Index to a free cookie
  368. BOOLEAN Full; // TRUE if this chunk is full
  369. NOTIFYCOOKIE Cookies[NOTIFYCOOKIESPERCHUNK];
  370. } NOTIFYCOOKIECHUNK, *PNOTIFYCOOKIECHUNK;
  371. //
  372. // Useful macro to establish a WNODE_HEADER quickly
  373. #ifdef _WIN64
  374. #define WmipBuildWnodeHeader(Wnode, WnodeSize, FlagsUlong, Handle) { \
  375. (Wnode)->Flags = FlagsUlong; \
  376. (Wnode)->KernelHandle = Handle; \
  377. (Wnode)->BufferSize = WnodeSize; \
  378. (Wnode)->Linkage = 0; \
  379. }
  380. #else
  381. #define WmipBuildWnodeHeader(Wnode, WnodeSize, FlagsUlong, Handle) { \
  382. (Wnode)->Flags = FlagsUlong; \
  383. *((PULONG64)(&((Wnode)->TimeStamp))) = (ULONG64)(IntToPtr(PtrToInt(Handle))); \
  384. (Wnode)->BufferSize = WnodeSize; \
  385. (Wnode)->Linkage = 0; \
  386. }
  387. #endif
  388. #ifdef MEMPHIS
  389. extern HANDLE PMMutex;
  390. #define WmipEnterPMCritSection() WaitForSingleObject(PMMutex, INFINITE)
  391. #define WmipLeavePMCritSection() ReleaseMutex(PMMutex)
  392. #else
  393. extern RTL_CRITICAL_SECTION PMCritSect;
  394. #if DBG
  395. #define WmipEnterPMCritSection() \
  396. WmipAssert(NT_SUCCESS(RtlEnterCriticalSection(&PMCritSect)));
  397. #define WmipLeavePMCritSection() { \
  398. WmipAssert(PMCritSect.LockCount >= 0); \
  399. WmipAssert(NT_SUCCESS(RtlLeaveCriticalSection(&PMCritSect))); }
  400. #else
  401. #define WmipEnterPMCritSection() RtlEnterCriticalSection(&PMCritSect)
  402. #define WmipLeavePMCritSection() RtlLeaveCriticalSection(&PMCritSect)
  403. #endif // DBG
  404. #endif // MEMPHIS
  405. typedef struct
  406. {
  407. NOTIFICATIONCALLBACK Callback;
  408. ULONG_PTR Context;
  409. PWNODE_HEADER Wnode;
  410. BYTE WnodeBuffer[1];
  411. } NOTIFDELIVERYCTX, *PNOTIFDELIVERYCTX;
  412. // from handle.c
  413. #define WmipVerifyToken() \
  414. { \
  415. ULONG VerifyStatus; \
  416. VerifyStatus = WmipCheckImpersonationTokenType(); \
  417. if (VerifyStatus != ERROR_SUCCESS) \
  418. { \
  419. SetLastError(VerifyStatus); \
  420. return(VerifyStatus); \
  421. } \
  422. }
  423. ULONG WmipCheckImpersonationTokenType(
  424. void
  425. );
  426. ULONG WmipCopyStringToCountedUnicode(
  427. LPCWSTR String,
  428. PWCHAR CountedString,
  429. ULONG *BytesUsed,
  430. BOOLEAN ConvertFromAnsi
  431. );
  432. ULONG WmipCountedAnsiToCountedUnicode(
  433. PCHAR Ansi,
  434. PWCHAR Unicode
  435. );
  436. ULONG WmipCountedUnicodeToCountedAnsi(
  437. PWCHAR Unicode,
  438. PCHAR Ansi
  439. );
  440. #ifndef MEMPHIS
  441. ULONG WmipCheckGuidAccess(
  442. LPGUID Guid,
  443. ACCESS_MASK DesiredAccess
  444. );
  445. ULONG WmipOpenKernelGuid(
  446. LPGUID Guid,
  447. ACCESS_MASK DesiredAccess,
  448. PHANDLE Handle,
  449. ULONG Ioctl
  450. );
  451. #endif
  452. ULONG WmipAllocateCookie(
  453. PVOID DeliveryInfo,
  454. PVOID DeliveryContext,
  455. LPGUID Guid
  456. );
  457. BOOLEAN WmipLookupCookie(
  458. ULONG CookieSlot,
  459. LPGUID Guid,
  460. PVOID *DeliveryInfo,
  461. PVOID *DeliveryContext
  462. );
  463. void WmipGetGuidInCookie(
  464. ULONG CookieSlot,
  465. LPGUID Guid
  466. );
  467. void WmipFreeCookie(
  468. ULONG CookieSlot
  469. );
  470. PGUIDNOTIFICATION
  471. WmipFindGuidNotification(
  472. LPGUID Guid
  473. );
  474. ULONG
  475. WmipAddToGNList(
  476. LPGUID Guid,
  477. PVOID DeliveryInfo,
  478. ULONG_PTR DeliveryContext,
  479. ULONG Flags,
  480. HANDLE GuidHandle
  481. );
  482. ULONG
  483. WmipRemoveFromGNList(
  484. LPGUID Guid,
  485. PVOID DeliveryInfo
  486. );
  487. BOOLEAN
  488. WmipDereferenceGNEntry(
  489. PGUIDNOTIFICATION GNEntry
  490. );
  491. PTCHAR GuidToString(
  492. PTCHAR s,
  493. LPGUID piid
  494. );
  495. PCHAR GuidToStringA(
  496. PCHAR s,
  497. LPGUID piid
  498. );
  499. // from request.c
  500. ULONG WmipSendWmiRequest(
  501. ULONG ActionCode,
  502. PWNODE_HEADER Wnode,
  503. ULONG WnodeSize,
  504. PVOID OutBuffer,
  505. ULONG MaxBufferSize,
  506. ULONG *RetSize
  507. );
  508. ULONG WmipSendWmiKMRequest(
  509. HANDLE Handle,
  510. ULONG Ioctl,
  511. PVOID InBuffer,
  512. ULONG InBufferSize,
  513. PVOID OutBuffer,
  514. ULONG MaxBufferSize,
  515. ULONG *ReturnSize,
  516. LPOVERLAPPED Overlapped
  517. );
  518. ULONG WmipConvertWADToAnsi(
  519. PWNODE_ALL_DATA Wnode
  520. );
  521. ULONG WmipConvertWADToUnicode(
  522. PWNODE_ALL_DATA WnodeAllData,
  523. ULONG *BufferSize
  524. );
  525. ULONG WmipRegisterGuids(
  526. IN LPGUID MasterGuid,
  527. IN ULONG RegistrationCookie,
  528. IN PWMIREGINFOW RegInfo,
  529. IN ULONG GuidCount,
  530. OUT PTRACEGUIDMAP *GuidMapHandle,
  531. OUT ULONG64 *LoggerContext,
  532. OUT HANDLE *RegistrationHandle
  533. );
  534. //
  535. // from intrnldp.c
  536. ULONG WmipInternalProvider(
  537. ULONG ActionCode,
  538. PWNODE_HEADER Wnode,
  539. ULONG MaxWnodeSize,
  540. PVOID OutBuffer,
  541. ULONG *RetSize
  542. );
  543. ULONG
  544. WmipEnumRegGuids(
  545. PWMIGUIDLISTINFO *pGuidInfo
  546. );
  547. //
  548. // from dcapi.c
  549. ULONG
  550. WmipNotificationRegistration(
  551. IN LPGUID InGuid,
  552. IN BOOLEAN Enable,
  553. IN PVOID DeliveryInfo,
  554. IN ULONG_PTR DeliveryContext,
  555. IN ULONG64 LoggerContext,
  556. IN ULONG Flags,
  557. IN BOOLEAN IsAnsi
  558. );
  559. //
  560. // from mofapi.c
  561. //
  562. void WmipProcessLanguageAddRemoveEvent(
  563. IN PWNODE_SINGLE_INSTANCE WnodeSI,
  564. IN NOTIFICATIONCALLBACK Callback,
  565. IN ULONG_PTR DeliveryContext,
  566. IN BOOLEAN IsAnsi
  567. );
  568. void WmipProcessMofAddRemoveEvent(
  569. IN PWNODE_SINGLE_INSTANCE WnodeSI,
  570. IN NOTIFICATIONCALLBACK Callback,
  571. IN ULONG_PTR DeliveryContext,
  572. IN BOOLEAN IsAnsi
  573. );
  574. //
  575. // from notify.c
  576. extern ULONG WmipNotificationSinkIndex;
  577. #ifndef MEMPHIS
  578. ULONG WmipProcessUMRequest(
  579. PWMI_LOGGER_INFORMATION LoggerInfo,
  580. PVOID DeliveryContext,
  581. ULONG ReplyIndex
  582. );
  583. #endif
  584. ULONG WmipAddHandleToEventPump(
  585. LPGUID Guid,
  586. PVOID DeliveryInfo,
  587. ULONG_PTR DeliveryContext,
  588. ULONG NotificationFlags,
  589. HANDLE GuidHandle
  590. );
  591. void WmipMakeEventCallbacks(
  592. IN PWNODE_HEADER Wnode,
  593. IN NOTIFICATIONCALLBACK Callback,
  594. IN ULONG_PTR DeliveryContext,
  595. IN BOOLEAN IsAnsi
  596. );
  597. ULONG
  598. WmipReceiveNotifications(
  599. IN ULONG HandleCount,
  600. IN HANDLE *HandleList,
  601. IN NOTIFICATIONCALLBACK Callback,
  602. IN ULONG_PTR DeliveryContext,
  603. IN BOOLEAN IsAnsi,
  604. IN ULONG Action,
  605. IN PUSER_THREAD_START_ROUTINE UserModeCallback,
  606. IN HANDLE ProcessHandle
  607. );
  608. ULONG WmipEventPump(
  609. PVOID Param
  610. );
  611. //
  612. // from main.c
  613. VOID
  614. WmipCreateHeap(
  615. VOID
  616. );
  617. #ifndef IsEqualGUID
  618. #define IsEqualGUID(guid1, guid2) \
  619. (!memcmp((guid1), (guid2), sizeof(GUID)))
  620. #endif
  621. //
  622. // These define the dll and mof resource name for all of the builtin mof
  623. // resources
  624. #define WMICOREDLLNAME L"wmicore.dll"
  625. #define WMICOREMOFRESOURCENAME L"MofResource"
  626. //
  627. // This defines the registry key under which security descriptors associated
  628. // with the guids are stored.
  629. #ifndef MEMPHIS
  630. #define WMISECURITYREGISTRYKEY TEXT("System\\CurrentControlSet\\Control\\Wmi\\Security")
  631. #endif
  632. //
  633. // This defines the initial value of the buffer passed to each data provider
  634. // to retrieve the registration information
  635. #if DBG
  636. #define INITIALREGINFOSIZE sizeof(WNODE_TOO_SMALL)
  637. #else
  638. #define INITIALREGINFOSIZE 8192
  639. #endif
  640. //
  641. // Chunk Management definitions
  642. // All structures that rely upon the chunk allocator must be defined so that
  643. // their members match that of ENTRYHEADER. These include DATASOURCE,
  644. // GUIDENTRY, INSTANCESET, DCENTRY, NOTIFICATIONENTRY, MOFCLASS, MOFRESOURCE
  645. // Also ENTRYHEADER reserves 0x80000000 for its own flag.
  646. struct _CHUNKINFO;
  647. struct _ENTRYHEADER;
  648. typedef void (*ENTRYCLEANUP)(
  649. struct _CHUNKINFO *,
  650. struct _ENTRYHEADER *
  651. );
  652. typedef struct _CHUNKINFO
  653. {
  654. LIST_ENTRY ChunkHead; // Head of list of chunks
  655. ULONG EntrySize; // Size of a single entry
  656. ULONG EntriesPerChunk; // Number of entries per chunk allocation
  657. ENTRYCLEANUP EntryCleanup; // Entry cleanup routine
  658. ULONG InitialFlags; // Initial flags for all entries
  659. ULONG Signature;
  660. #if DBG
  661. ULONG AllocCount;
  662. ULONG FreeCount;
  663. #endif
  664. } CHUNKINFO, *PCHUNKINFO;
  665. typedef struct
  666. {
  667. LIST_ENTRY ChunkList; // Node in list of chunks
  668. LIST_ENTRY FreeEntryHead; // Head of list of free entries in chunk
  669. ULONG EntriesInUse; // Count of entries being used
  670. } CHUNKHEADER, *PCHUNKHEADER;
  671. typedef struct _ENTRYHEADER
  672. {
  673. union
  674. {
  675. LIST_ENTRY FreeEntryList; // Node in list of free entries
  676. LIST_ENTRY InUseEntryList; // Node in list ofin use entries
  677. };
  678. PCHUNKHEADER Chunk; // Chunk in which entry is located
  679. ULONG Flags; // Flags
  680. ULONG RefCount; // Reference Count
  681. ULONG Signature;
  682. } ENTRYHEADER, *PENTRYHEADER;
  683. // Set if the entry is free
  684. #define FLAG_ENTRY_ON_FREE_LIST 0x80000000
  685. #define FLAG_ENTRY_ON_INUSE_LIST 0x40000000
  686. #define FLAG_ENTRY_INVALID 0x20000000
  687. #define FLAG_ENTRY_REMOVE_LIST 0x10000000
  688. #define WmipReferenceEntry(Entry) \
  689. InterlockedIncrement(&((PENTRYHEADER)(Entry))->RefCount)
  690. // chunk.c
  691. #ifndef MEMPHIS
  692. ULONG WmipBuildGuidObjectAttributes(
  693. IN LPGUID Guid,
  694. OUT POBJECT_ATTRIBUTES ObjectAttributes,
  695. OUT PUNICODE_STRING GuidString,
  696. OUT PWCHAR GuidObjectName
  697. );
  698. #endif
  699. ULONG WmipUnreferenceEntry(
  700. PCHUNKINFO ChunkInfo,
  701. PENTRYHEADER Entry);
  702. PENTRYHEADER WmipAllocEntry(
  703. PCHUNKINFO ChunkInfo
  704. );
  705. void WmipFreeEntry(
  706. PCHUNKINFO ChunkInfo,
  707. PENTRYHEADER Entry
  708. );
  709. //
  710. // This is the guid that denotes non event notifications. WMICore
  711. // automatically registers anyone opening a guid to
  712. extern GUID RegChangeNotificationGuid;
  713. extern CHUNKINFO DSChunkInfo;
  714. extern CHUNKINFO GEChunkInfo;
  715. extern CHUNKINFO ISChunkInfo;
  716. extern CHUNKINFO DCChunkInfo;
  717. extern CHUNKINFO NEChunkInfo;
  718. extern CHUNKINFO MRChunkInfo;
  719. struct tagGUIDENTRY;
  720. typedef struct tagGUIDENTRY GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
  721. struct tagDATASOURCE;
  722. //
  723. // An INSTANCESET contains the information a set of instances that is provided
  724. // by a single data source. An instance set is part of two lists. One list is
  725. // the set of instance sets for a particular guid. The other list is the list
  726. // of instance sets supported by a data source.
  727. //
  728. //
  729. // Instance names for an instance set registered with a base name and count
  730. // are stored in a ISBASENAME structure. This structure is tracked by
  731. // PDFISBASENAME in wmicore.idl.
  732. typedef struct
  733. {
  734. ULONG BaseIndex; // First index to append to base name
  735. WCHAR BaseName[1]; // Actual base name
  736. } ISBASENAME, *PISBASENAME, *PBISBASENAME;
  737. //
  738. // This defines the maximum number of characters that can be part of a suffix
  739. // to a basename. The current value of 6 will allow up to 999999 instances
  740. // of a guid with a static base name
  741. #define MAXBASENAMESUFFIXSIZE 6
  742. //
  743. // Instance names for an instance set registerd with a set of static names
  744. // are kept in a ISSTATICNAMES structure. This structure is tracked by
  745. // PDFISSTATICNAMES defined in wmicore.idl
  746. typedef struct
  747. {
  748. PWCHAR StaticNamePtr[1]; // pointers to static names
  749. // WCHAR StaticNames[1];
  750. } ISSTATICENAMES, *PISSTATICNAMES, *PBISSTATICNAMES;
  751. typedef struct tagInstanceSet
  752. {
  753. union
  754. {
  755. // Entry in list of instances within a guid
  756. LIST_ENTRY GuidISList;
  757. // Entry in main list of free instances
  758. LIST_ENTRY FreeISList;
  759. };
  760. PCHUNKHEADER Chunk; // Chunk in which entry is located
  761. ULONG Flags;
  762. // Reference count of number of guids using this instance set
  763. ULONG RefCount;
  764. // Signature to identify entry
  765. ULONG Signature;
  766. // Entry in list of instances within a data source
  767. LIST_ENTRY DSISList;
  768. // Back link to guid that this instance set is a member
  769. PBGUIDENTRY GuidEntry;
  770. // Back link to data source that this instance set is a member
  771. struct tagDATASOURCE *DataSource;
  772. // Count of instances in instance set
  773. ULONG Count;
  774. //
  775. // If IS_INSTANCE_BASENAME is set then IsBaseName pointe at instance base
  776. // name structure. Else if IS_INSTANCE_STATICNAME is set then
  777. // IsStaticNames points to static instance name list. If
  778. union
  779. {
  780. PBISBASENAME IsBaseName;
  781. PBISSTATICNAMES IsStaticNames;
  782. };
  783. } INSTANCESET, *PINSTANCESET, *PBINSTANCESET;
  784. #define IS_SIGNATURE 'nalA'
  785. //
  786. // Guid Map Entry List maintains the list of Guid and their maps.
  787. // Only those Guids that are Unregistered while a logger session is in
  788. // progress is kept in this list.
  789. // It is also used as a placeholder for InstanceIds. Trace Guid Registration
  790. // calls return a handle to a GUIDMAPENTRY which maintains the map and the
  791. // Instance Ids.
  792. //
  793. typedef struct tagTRACE_REG_INFO
  794. {
  795. ULONG RegistrationCookie;
  796. HANDLE InProgressEvent; // Registration is in Progress Event
  797. BOOLEAN EnabledState; // Indicates if this GUID is Enabled or not.
  798. PVOID NotifyRoutine;
  799. PVOID TraceCtxHandle;
  800. } TRACE_REG_INFO, *PTRACE_REG_INFO;
  801. typedef struct
  802. {
  803. LIST_ENTRY Entry;
  804. TRACEGUIDMAP GuidMap;
  805. ULONG InstanceId;
  806. ULONG64 LoggerContext;
  807. PTRACE_REG_INFO pControlGuidData;
  808. } GUIDMAPENTRY, *PGUIDMAPENTRY;
  809. #define IS_INSTANCE_BASENAME 0x00000001
  810. #define IS_INSTANCE_STATICNAMES 0x00000002
  811. #define IS_EXPENSIVE 0x00000004 // set if collection must be enabled
  812. #define IS_COLLECTING 0x00000008 // set when collecting
  813. #define IS_KM_PROVIDER 0x00000080 // KM data provider
  814. #define IS_SM_PROVIDER 0x00000100 // Shared memory provider
  815. #define IS_UM_PROVIDER 0x00000200 // User mode provider
  816. #define IS_NEWLY_REGISTERED 0x00000800 // set if IS is registering
  817. //
  818. // Any traced guids are used for trace logging and not querying
  819. #define IS_TRACED 0x00001000
  820. // Set when events are enabled for instance set
  821. #define IS_ENABLE_EVENT 0x00002000
  822. // Set when events are enabled for instance set
  823. #define IS_ENABLE_COLLECTION 0x00004000
  824. // Set if guid is used only for firing events and not querying
  825. #define IS_EVENT_ONLY 0x00008000
  826. // Set if data provider for instance set is expecting ansi instsance names
  827. #define IS_ANSI_INSTANCENAMES 0x00010000
  828. // Set if instance names are originated from a PDO
  829. #define IS_PDO_INSTANCENAME 0x00020000
  830. // If set the data provider for the InstanceSet is internal to wmi.dll
  831. #define IS_INTERNAL_PROVIDER 0x00040000
  832. // Set if a Traced Guid is also a Trace Control Guid
  833. #define IS_CONTROL_GUID 0x00080000
  834. #define IS_ON_FREE_LIST 0x80000000
  835. typedef struct tagGUIDENTRY
  836. {
  837. union
  838. {
  839. // Entry in list of all guids registered with WMI
  840. LIST_ENTRY MainGEList;
  841. // Entry in list of free guid entry blocks
  842. LIST_ENTRY FreeGEList;
  843. };
  844. PCHUNKHEADER Chunk; // Chunk in which entry is located
  845. ULONG Flags;
  846. // Count of number of data sources using this guid
  847. ULONG RefCount;
  848. // Signature to identify entry
  849. ULONG Signature;
  850. // Count of InstanceSets headed by this guid
  851. ULONG ISCount;
  852. // Head of list of all instances for guid
  853. LIST_ENTRY ISHead;
  854. // Guid that represents data block
  855. GUID Guid;
  856. } GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
  857. #define GE_SIGNATURE 'diuG'
  858. #define GE_ON_FREE_LIST 0x80000000
  859. //
  860. // When set this guid is an internally defined guid that has no data source
  861. // attached to it.
  862. #define GE_FLAG_INTERNAL 0x00000001
  863. typedef struct
  864. {
  865. union
  866. {
  867. // Entry in list of all DS
  868. LIST_ENTRY MainMRList;
  869. // Entry in list of free DS
  870. LIST_ENTRY FreeMRList;
  871. };
  872. PCHUNKHEADER Chunk; // Chunk in which entry is located
  873. ULONG Flags;
  874. ULONG RefCount;
  875. // Signature to identify entry
  876. ULONG Signature;
  877. PWCHAR MofImagePath; // Path to image file with resource
  878. PWCHAR MofResourceName; // Name of resource containing mof data
  879. #ifdef WMI_USER_MODE
  880. LIST_ENTRY MRMCHead;
  881. #endif
  882. } MOFRESOURCE, *PMOFRESOURCE;
  883. #define MR_SIGNATURE 'yhsA'
  884. #if DBG
  885. #define AVGMOFRESOURCECOUNT 1
  886. #else
  887. #define AVGMOFRESOURCECOUNT 4
  888. #endif
  889. typedef struct tagDATASOURCE
  890. {
  891. union
  892. {
  893. // Entry in list of all DS
  894. LIST_ENTRY MainDSList;
  895. // Entry in list of free DS
  896. LIST_ENTRY FreeDSList;
  897. };
  898. PCHUNKHEADER Chunk; // Chunk in which entry is located
  899. ULONG Flags;
  900. ULONG RefCount;
  901. ULONG Signature;
  902. // Head of list of instances for this DS
  903. LIST_ENTRY ISHead;
  904. // Binding string and callback address for DS rpc server
  905. PTCHAR BindingString;
  906. RPC_BINDING_HANDLE RpcBindingHandle;
  907. ULONG RequestAddress;
  908. ULONG RequestContext;
  909. // Provider id of kernel mode driver
  910. ULONG_PTR ProviderId;
  911. // Path to registry holding ACLs
  912. PTCHAR RegistryPath;
  913. // Head of list of MofResources attached to data source
  914. ULONG MofResourceCount;
  915. PMOFRESOURCE *MofResources;
  916. PMOFRESOURCE StaticMofResources[AVGMOFRESOURCECOUNT];
  917. };
  918. #define DS_SIGNATURE ' naD'
  919. #define VERIFY_DPCTXHANDLE(DsCtxHandle) \
  920. ( ((DsCtxHandle) == NULL) || \
  921. (((PBDATASOURCE)(DsCtxHandle))->Signature == DS_SIGNATURE) )
  922. typedef struct tagDATASOURCE DATASOURCE, *PDATASOURCE, *PBDATASOURCE;
  923. #define DS_ALLOW_ALL_ACCESS 0x00000001
  924. #define DS_KERNEL_MODE 0x00000002
  925. //
  926. // Set in the Internal WMI data source
  927. #define DS_INTERNAL 0x00000004
  928. #define DS_ON_FREE_LIST 0x80000000
  929. //
  930. // A list of enabled notifications is maintained by the wmi service to mange
  931. // delivering events and to know when to send enable and disable event
  932. // wmi requests to the data providers. Each NOTIFICATIONENTRY has an array of
  933. // DCREF which is a reference to the data consumer who is interested in the
  934. // event.
  935. #define RPCOUTSTANDINGCALLLIMIT 128
  936. typedef struct
  937. {
  938. LIST_ENTRY MainDCList; // Node on global data consumer list
  939. PCHUNKHEADER Chunk; // Chunk in which entry is located
  940. ULONG Flags;
  941. ULONG RefCount;
  942. ULONG Signature;
  943. // Actual RPC binding handle
  944. RPC_BINDING_HANDLE RpcBindingHandle;
  945. PUCHAR EventData; // Buffer to hold events to be sent
  946. ULONG LastEventOffset; // Offset in EventData to previous event
  947. ULONG NextEventOffset; // Offset in EventData to write next event
  948. ULONG EventDataSizeLeft; // Number of bytes left to use in EventData
  949. ULONG RpcCallsOutstanding; // Number of rpc calls outstanding
  950. #if DBG
  951. PTCHAR BindingString; // Binding string for consumer
  952. #endif
  953. } DCENTRY, *PDCENTRY;
  954. #define DC_SIGNATURE 'cirE'
  955. // If the data consumer has had its context rundown routine then this flag
  956. // is set. This indicates that the data consumer has gone away and no more
  957. // events should be sent to him.
  958. #define DC_FLAG_RUNDOWN 0x00000001
  959. #define VERIFY_DCCTXHANDLE(DcCtxHandle) \
  960. ( ((DcCtxHandle) == NULL) || \
  961. (((PDCENTRY)(DcCtxHandle))->Signature == DC_SIGNATURE) )
  962. typedef struct
  963. {
  964. PDCENTRY DcEntry; // points at data consumer interested in notification
  965. // Number of times collect has been enabled by
  966. // this DC.
  967. ULONG CollectRefCount;
  968. // Number of times collect has been enabled by
  969. // this DC.
  970. ULONG EventRefCount;
  971. ULONG Flags; // Flags
  972. ULONG LostEventCount;
  973. } DCREF, *PDCREF;
  974. //
  975. // _ENABLED flag set if DP already called to enable notification or collection
  976. #define DCREF_FLAG_NOTIFICATION_ENABLED 0x00000001
  977. #define DCREF_FLAG_COLLECTION_ENABLED 0x00000002
  978. // if DCREF_FLAG_NO_EXTRA_THREAD set then WMI will not create a special thread
  979. // to do the direct notification callback.
  980. #define DCREF_FLAG_NO_EXTRA_THREAD 0x00000008
  981. // If this flag is set then the notification callback is expecting an ANSI
  982. // instance names.
  983. #define DCREF_FLAG_ANSI 0x00000010
  984. // NOTE: Other notification flags in wmium.h are:
  985. // NOTIFICATION_TRACE_FLAG 0x00010000
  986. //
  987. // NOTIFICATION_FLAG_CALLBACK_DIRECT is set when NotifyAddress specifies
  988. // a direct callback address for delivering the event.
  989. //
  990. // NOTIFICATION_FLAG_CALLBACK_DIRECT is set when NotifyAddress specifies
  991. // a direct callback address for delivering the event.
  992. //
  993. #define NOTIFICATION_FLAG_CALLBACK_DIRECT 0x00020000
  994. #define NOTIFICATION_FLAG_CALLBACK_QUEUED 0x00040000
  995. #define NOTIFICATION_FLAG_WINDOW 0x00080000
  996. #define NOTIFICATION_FLAG_BATCHED 0x00100000
  997. //
  998. // This flag is set for those guid handles that may be duplicated in
  999. // the list. All Notifyee slots that have this flag are considered in a
  1000. // group and only one handle needs to be put on the list
  1001. //
  1002. #define NOTIFICATION_FLAG_GROUPED_EVENT 0x00200000
  1003. //
  1004. // This flag is set for those guid handles that are pending closure.
  1005. // Only the pump thread is allowed to close a handle; the main threads
  1006. // will set this flag to indicate that the handle should no longer be
  1007. // used. When the pump thread builds the list of handles and notices
  1008. // the flag it will close the handle.
  1009. //
  1010. #define NOTIFICATION_FLAG_PENDING_CLOSE 0x00400000
  1011. #define WmipIsNotifyeePendingClose(Notifyee) \
  1012. (((Notifyee)->Flags & NOTIFICATION_FLAG_PENDING_CLOSE) == NOTIFICATION_FLAG_PENDING_CLOSE)
  1013. //
  1014. // These are the flags contained in DcRef->Flags that pertain to Notifications
  1015. #define NOTIFICATION_MASK_EVENT_FLAGS \
  1016. (NOTIFICATION_FLAG_CALLBACK_DIRECT | \
  1017. NOTIFICATION_FLAG_CALLBACK_QUEUED | \
  1018. NOTIFICATION_FLAG_WINDOW | \
  1019. DCREF_FLAG_NO_EXTRA_THREAD | \
  1020. DCREF_FLAG_ANSI)
  1021. //
  1022. // This defines the number of DC references a NOTIFICATIONENTRY can have
  1023. // in a single entry
  1024. // CONSIDER: Merging NOTIFICATIONENTRY with GUIDENTRY
  1025. #define DCREFPERNOTIFICATION 16
  1026. typedef struct _notificationentry
  1027. {
  1028. LIST_ENTRY MainNotificationList; // Node in main notifications list
  1029. PCHUNKHEADER Chunk; // Chunk in which entry is located
  1030. ULONG Flags; // flags
  1031. ULONG RefCount;
  1032. // Signature to identify entry
  1033. ULONG Signature;
  1034. GUID Guid; // guid representing notification
  1035. // If > DCREFPERNOTIFICATION DC have
  1036. // enabled this event then this points
  1037. // to another NOTIFICATIONENTRY which
  1038. // has another DCREF array
  1039. struct _notificationentry *Continuation;
  1040. ULONG EventRefCount; // Global count of event enables
  1041. ULONG CollectRefCount; // Global count of collection enables
  1042. ULONG64 LoggerContext; // Logger context handle
  1043. HANDLE CollectInProgress; // Event set when all collect complete
  1044. DCREF DcRef[DCREFPERNOTIFICATION]; // DC that have enabled this event
  1045. } NOTIFICATIONENTRY, *PNOTIFICATIONENTRY;
  1046. #define NE_SIGNATURE 'eluJ'
  1047. // Set when a notification request is being processed by the data providers
  1048. #define NE_FLAG_NOTIFICATION_IN_PROGRESS 0x00000001
  1049. // Set when a collection request is being processed by the data providers
  1050. #define NE_FLAG_COLLECTION_IN_PROGRESS 0x00000002
  1051. // Set when a trace disable is being processed by a worker thread
  1052. #define NE_FLAG_TRACEDISABLE_IN_PROGRESS 0x00000004
  1053. #ifdef WMI_USER_MODE
  1054. //
  1055. // Valid MOF data types for qualifiers and properties (data items)
  1056. typedef enum
  1057. {
  1058. MOFInt32 = 0, // 32bit integer
  1059. MOFUInt32 = 1, // 32bit unsigned integer
  1060. MOFInt64 = 2, // 64bit integer
  1061. MOFUInt64 = 3, // 32bit unsigned integer
  1062. MOFInt16 = 4, // 16bit integer
  1063. MOFUInt16 = 5, // 16bit unsigned integer
  1064. MOFChar = 6, // 8bit integer
  1065. MOFByte = 7, // 8bit unsigned integer
  1066. MOFWChar = 8, // Wide (16bit) character
  1067. MOFDate = 9, // Date field
  1068. MOFBoolean = 10, // 8bit Boolean value
  1069. MOFEmbedded = 11, // Embedded class
  1070. MOFString = 12, // Counted String type
  1071. MOFZTString = 13, // NULL terminated unicode string
  1072. MOFAnsiString = 14, // NULL terminated ansi string
  1073. MOFUnknown = 0xffffffff // Data type is not known
  1074. } MOFDATATYPE, *PMOFDATATYPE;
  1075. // Data items that are of type MOFString are stored in the data block as a
  1076. // counted unicode string. The text of the string is always preceeded by
  1077. // a USHORT which contains the count of bytes following that composes the
  1078. // string. The string may be NULL terminated and in that case the count must
  1079. // include the null termination bytes.
  1080. // Data items that are of type MOFDate are fixed length Unicode strings and
  1081. // not preceeded by a count value. It is in the following fixed format:
  1082. //
  1083. // yyyymmddhhmmss.mmmmmmsutc
  1084. //
  1085. // Where yyyy is a 4 digit year, mm is the month, dd is the day, hh is
  1086. // the hour (24-hour clock), mm is the minute, ss is the second, the
  1087. // mmmmmm is the number of microseconds (typically all zeros) and s is a
  1088. // "+" or "-" indicating the sign of the UTC (correction field, and utc
  1089. // is the offset from UTC in minutes (using the sign indicated by s).
  1090. // For example, Wednesday, May 25, 1994, at 1:30:15 PM EDT would be
  1091. // represented as:
  1092. //
  1093. // 19940525133015.0000000-300
  1094. //
  1095. // Values MUST be zero-padded so that the entire string is always the
  1096. // same 25-character length. Fields which are not significant MUST be
  1097. // replaced with asterisk characters. Similarly, intervals use the
  1098. // same format, except that the interpretation of the fields is based
  1099. // on elapsed time. For example, an elapsed time of 1 day, 13 hours,
  1100. // 23 minutes, and 12 seconds would be:
  1101. //
  1102. // 00000001132312.000000+000
  1103. //
  1104. // A UTC offset of zero is always used for interval properties.
  1105. struct _MOFCLASSINFOW;
  1106. struct _MOFCLASSINFOA;
  1107. //
  1108. // Each class has one or more data items that are described by a MOFDATAITEM
  1109. // structure.
  1110. typedef struct
  1111. {
  1112. #ifdef MIDL_PASS
  1113. [string] PDFWCHAR
  1114. #else
  1115. LPWSTR
  1116. #endif
  1117. Name; // Text name of data item
  1118. #ifdef MIDL_PASS
  1119. [string] PDFWCHAR
  1120. #else
  1121. LPWSTR
  1122. #endif
  1123. Description; // Text description of data item
  1124. MOFDATATYPE DataType; // MOF data type
  1125. ULONG Version; // Version that this MOF is part of
  1126. ULONG SizeInBytes; // Size of data item in Blob
  1127. ULONG Flags; // Flags, See MOFDI_FLAG_*
  1128. GUID EmbeddedClassGuid; // Guid of data item's embedded class
  1129. ULONG FixedArrayElements; // Number of elements in fixed sized array
  1130. // Used when MOF_FLAG_FIXED_ARRAY is set
  1131. ULONG VariableArraySizeId; // MOF_FLAG_VARIABLE_ARRAY, Data id of
  1132. // variable containing number of elements
  1133. // in array
  1134. PVOID VarArrayTempPtr;
  1135. PVOID EcTempPtr;
  1136. ULONG_PTR PropertyQualifierHandle;
  1137. ULONG MethodId;
  1138. LPWSTR HeaderName;// Name of structure in generated header
  1139. struct _MOFCLASSINFOW *MethodClassInfo;
  1140. ULONG MaxLen;
  1141. } MOFDATAITEMW, *PMOFDATAITEMW;
  1142. typedef struct
  1143. {
  1144. LPSTR
  1145. Name; // Text name of data item
  1146. LPSTR
  1147. Description; // Text description of data item
  1148. MOFDATATYPE DataType; // MOF data type
  1149. ULONG Version; // Version that this MOF is part of
  1150. ULONG SizeInBytes; // Size of data item in Blob
  1151. ULONG Flags; // Flags, See MOFDI_FLAG_*
  1152. GUID EmbeddedClassGuid; // Guid of data item's embedded class
  1153. ULONG FixedArrayElements; // Number of elements in fixed sized array
  1154. // Used when MOF_FLAG_FIXED_ARRAY is set
  1155. ULONG VariableArraySizeId; // MOF_FLAG_VARIABLE_ARRAY, Data id of
  1156. // variable containing number of elements
  1157. // in array
  1158. PVOID VarArrayTempPtr;
  1159. PVOID EcTempPtr;
  1160. ULONG_PTR PropertyQualifierHandle;
  1161. ULONG MethodId;
  1162. LPSTR HeaderName; // Name of structure in generated header
  1163. struct _MOFCLASSINFOA *MethodClassInfo;
  1164. ULONG MaxLen;
  1165. } MOFDATAITEMA, *PMOFDATAITEMA;
  1166. #ifdef UNICODE
  1167. typedef MOFDATAITEMW MOFDATAITEM;
  1168. typedef PMOFDATAITEMW PMOFDATAITEM;
  1169. #else
  1170. typedef MOFDATAITEMA MOFDATAITEM;
  1171. typedef PMOFDATAITEMA PMOFDATAITEM;
  1172. #endif
  1173. // Data item is actually a fixed sized array
  1174. #define MOFDI_FLAG_FIXED_ARRAY 0x00000001
  1175. // Data item is actually a variable length array
  1176. #define MOFDI_FLAG_VARIABLE_ARRAY 0x00000002
  1177. // Data item is actually an embedded class
  1178. #define MOFDI_FLAG_EMBEDDED_CLASS 0x00000004
  1179. // Data item is readable
  1180. #define MOFDI_FLAG_READABLE 0x00000008
  1181. // Data item is writable
  1182. #define MOFDI_FLAG_WRITEABLE 0x00000010
  1183. // Data item is an event
  1184. #define MOFDI_FLAG_EVENT 0x00000020
  1185. // Embedded class Guid is not set
  1186. #define MOFDI_FLAG_EC_GUID_NOT_SET 0x00000040
  1187. // Data item is really a method
  1188. #define MOFDI_FLAG_METHOD 0x00000080
  1189. // Data item is an input method parameter
  1190. #define MOFDI_FLAG_INPUT_METHOD 0x00000100
  1191. // Data item is an output method parameter
  1192. #define MOFDI_FLAG_OUTPUT_METHOD 0x00000200
  1193. //
  1194. // The MOFCLASSINFO structure describes the format of a data block
  1195. typedef struct _MOFCLASSINFOW
  1196. {
  1197. GUID Guid; // Guid that represents class
  1198. #ifdef MIDL_PASS
  1199. [string] PDFWCHAR
  1200. #else
  1201. LPWSTR
  1202. #endif
  1203. Name; // Text name of class
  1204. #ifdef MIDL_PASS
  1205. [string] PDFWCHAR
  1206. #else
  1207. LPWSTR
  1208. #endif
  1209. Description;// Text description of class
  1210. #ifdef MIDL_PASS
  1211. [string] PDFWCHAR
  1212. #else
  1213. LPWSTR
  1214. #endif
  1215. HeaderName;// Name of structure in generated header
  1216. #ifdef MIDL_PASS
  1217. [string] PDFWCHAR
  1218. #else
  1219. LPWSTR
  1220. #endif
  1221. GuidName1;// Name of Guid in generated header
  1222. #ifdef MIDL_PASS
  1223. [string] PDFWCHAR
  1224. #else
  1225. LPWSTR
  1226. #endif
  1227. GuidName2;// Name of Guid in generated header
  1228. USHORT Language; // Language of MOF
  1229. USHORT Reserved;
  1230. ULONG Flags; // Flags, see MOFGI_FLAG_*
  1231. ULONG Version; // Version of Guid
  1232. ULONG DataItemCount; // Number of wmi data items (properties)
  1233. ULONG MethodCount; // Number of wmi data items (properties)
  1234. // Array of Property info
  1235. #ifdef MIDL_PASS
  1236. [size_is(DataItemCount)]
  1237. #endif
  1238. MOFDATAITEMW *DataItems;
  1239. #ifndef MIDL_PASS
  1240. UCHAR Tail[1];
  1241. #endif
  1242. } MOFCLASSINFOW, *PMOFCLASSINFOW;
  1243. typedef struct _MOFCLASSINFOA
  1244. {
  1245. GUID Guid; // Guid that represents class
  1246. LPSTR
  1247. Name; // Text name of class
  1248. LPSTR
  1249. Description;// Text description of class
  1250. LPSTR
  1251. HeaderName;// Name of structure in generated header
  1252. LPSTR
  1253. GuidName1;// Name of Guid in generated header
  1254. LPSTR
  1255. GuidName2;// Name of Guid in generated header
  1256. USHORT Language; // Language of MOF
  1257. USHORT Reserved;
  1258. ULONG Flags; // Flags, see MOFGI_FLAG_*
  1259. ULONG Version; // Version of Guid
  1260. ULONG DataItemCount; // Number of wmi data items (properties)
  1261. ULONG MethodCount; // Number of wmi data items (properties)
  1262. // Array of Property info
  1263. MOFDATAITEMA *DataItems;
  1264. UCHAR Tail[1];
  1265. } MOFCLASSINFOA, *PMOFCLASSINFOA;
  1266. #ifdef UNICODE
  1267. typedef MOFCLASSINFOW MOFCLASSINFO;
  1268. typedef PMOFCLASSINFOW PMOFCLASSINFO;
  1269. #else
  1270. typedef MOFCLASSINFOA MOFCLASSINFO;
  1271. typedef PMOFCLASSINFOA PMOFCLASSINFO;
  1272. #endif
  1273. // 0x00000001 to 0x00000004 are not available
  1274. #define MOFCI_FLAG_EVENT 0x10000000
  1275. #define MOFCI_FLAG_EMBEDDED_CLASS 0x20000000
  1276. #define MOFCI_FLAG_READONLY 0x40000000
  1277. #define MOFCI_FLAG_METHOD_PARAMS 0x80000000
  1278. typedef struct
  1279. {
  1280. union
  1281. {
  1282. // Entry in list of all DS
  1283. LIST_ENTRY MainMCList;
  1284. // Entry in list of free DS
  1285. LIST_ENTRY FreeMCList;
  1286. };
  1287. PCHUNKHEADER Chunk; // Chunk in which entry is located
  1288. ULONG Flags;
  1289. ULONG RefCount;
  1290. PMOFCLASSINFOW MofClassInfo; // Actual class info data
  1291. LIST_ENTRY MCMRList; // Entry in list of MCs in a MR
  1292. LIST_ENTRY MCVersionList; // Head or entry in list of MCs with
  1293. // same guid, but possibly different versions
  1294. ULONG_PTR ClassObjectHandle; // CBMOFObj, BMOF class object ptr
  1295. PMOFRESOURCE MofResource; // Resource holding class info
  1296. } MOFCLASS, *PMOFCLASS;
  1297. // If this is set then the MOF class can never be replaced with a later version
  1298. #define MC_FLAG_NEVER_REPLACE 0x00000001
  1299. #endif
  1300. //
  1301. // AVGGUIDSPERDS defines a guess as to the number of guids that get registered
  1302. // by any data provider. It is used to allocate the buffer used to deliver
  1303. // registration change notifications.
  1304. #if DBG
  1305. #define AVGGUIDSPERDS 2
  1306. #else
  1307. #define AVGGUIDSPERDS 256
  1308. #endif
  1309. #define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)(Base) + (Offset)))
  1310. //
  1311. // Guid and InstanceSet cache
  1312. #if DBG
  1313. #define PTRCACHEGROWSIZE 2
  1314. #else
  1315. #define PTRCACHEGROWSIZE 64
  1316. #endif
  1317. typedef struct
  1318. {
  1319. LPGUID Guid;
  1320. PBINSTANCESET InstanceSet;
  1321. } PTRCACHE;
  1322. //
  1323. // Registration data structures
  1324. //
  1325. #ifdef MEMPHIS
  1326. extern HANDLE SMMutex;
  1327. #define WmipEnterSMCritSection() WaitForSingleObject(SMMutex, INFINITE)
  1328. #define WmipLeaveSMCritSection() ReleaseMutex(SMMutex)
  1329. #else
  1330. extern RTL_CRITICAL_SECTION SMCritSect;
  1331. #if DBG
  1332. #ifdef CRITSECTTRACE
  1333. #define WmipEnterSMCritSection() { \
  1334. WmipDebugPrint(("WMI: %d Enter SM Crit %s %d\n", GetCurrentThreadId(), __FILE__, __LINE__)); \
  1335. RtlEnterCriticalSection(&SMCritSect); }
  1336. #define WmipLeaveSMCritSection() { \
  1337. WmipDebugPrint(("WMI: %d Leave SM Crit %s %d\n", GetCurrentThreadId(), __FILE__, __LINE__)); \
  1338. RtlLeaveCriticalSection(&SMCritSect); }
  1339. #else
  1340. #define WmipEnterSMCritSection() \
  1341. WmipAssert(NT_SUCCESS(RtlEnterCriticalSection(&SMCritSect)));
  1342. #define WmipLeaveSMCritSection() { \
  1343. WmipAssert(SMCritSect.LockCount >= 0); \
  1344. WmipAssert(NT_SUCCESS(RtlLeaveCriticalSection(&SMCritSect))); }
  1345. #endif // CRITSECTTRACE
  1346. #else
  1347. #define WmipEnterSMCritSection() RtlEnterCriticalSection(&SMCritSect)
  1348. #define WmipLeaveSMCritSection() RtlLeaveCriticalSection(&SMCritSect)
  1349. #endif // DBG
  1350. #endif // MEMPHIS
  1351. #ifndef IsEqualGUID
  1352. #define IsEqualGUID(guid1, guid2) \
  1353. (!memcmp((guid1), (guid2), sizeof(GUID)))
  1354. #endif
  1355. //
  1356. // WMI MOF result codes. Since they are never given to the caller they are
  1357. // defined in here
  1358. #define ERROR_WMIMOF_INCORRECT_DATA_TYPE -1 /* 0xffffffff */
  1359. #define ERROR_WMIMOF_NO_DATA -2 /* 0xfffffffe */
  1360. #define ERROR_WMIMOF_NOT_FOUND -3 /* 0xfffffffd */
  1361. #define ERROR_WMIMOF_UNUSED -4 /* 0xfffffffc */
  1362. // Property %ws in class %ws has no embedded class name
  1363. #define ERROR_WMIMOF_NO_EMBEDDED_CLASS_NAME -5 /* 0xfffffffb */
  1364. // Property %ws in class %ws has an unknown data type
  1365. #define ERROR_WMIMOF_UNKNOWN_DATA_TYPE -6 /* 0xfffffffa */
  1366. // Property %ws in class %ws has no syntax qualifier
  1367. #define ERROR_WMIMOF_NO_SYNTAX_QUALIFIER -7 /* 0xfffffff9 */
  1368. #define ERROR_WMIMOF_NO_CLASS_NAME -8 /* 0xfffffff8 */
  1369. #define ERROR_WMIMOF_BAD_DATA_FORMAT -9 /* 0xfffffff7 */
  1370. // Property %ws in class %ws has the same WmiDataId %d as property %ws
  1371. #define ERROR_WMIMOF_DUPLICATE_ID -10 /* 0xfffffff6 */
  1372. // Property %ws in class %ws has a WmiDataId of %d which is out of range
  1373. #define ERROR_WMIMOF_BAD_DATAITEM_ID -11 /* 0xfffffff5 */
  1374. #define ERROR_WMIMOF_MISSING_DATAITEM -12 /* 0xfffffff4 */
  1375. // Property for WmiDataId %d is not defined in class %ws
  1376. #define ERROR_WMIMOF_DATAITEM_NOT_FOUND -13 /* 0xfffffff3 */
  1377. // Embedded class %ws not defined for Property %ws in Class %ws
  1378. #define ERROR_WMIMOF_EMBEDDED_CLASS_NOT_FOUND -14 /* 0xfffffff2 */
  1379. // Property %ws in class %ws has an incorrect [WmiVersion] qualifier
  1380. #define ERROR_WMIMOF_INCONSISTENT_VERSIONING -15 /* 0xfffffff1 */
  1381. #define ERROR_WMIMOF_NO_PROPERTY_QUALIFERS -16 /* 0xfffffff0 */
  1382. // Class %ws has a badly formed or missing [guid] qualifier
  1383. #define ERROR_WMIMOF_BAD_OR_MISSING_GUID -17 /* 0xffffffef */
  1384. // Could not find property %ws which is the array size for property %ws in class %ws
  1385. #define ERROR_WMIMOF_VL_ARRAY_SIZE_NOT_FOUND -18 /* 0xffffffee */
  1386. // A class could not be parsed properly
  1387. #define ERROR_WMIMOF_CLASS_NOT_PARSED -19 /* 0xffffffed */
  1388. // Wmi class %ws requires the qualifiers [Dynamic, Provider("WmiProv")]
  1389. #define ERROR_WMIMOF_MISSING_HMOM_QUALIFIERS -20 /* 0xffffffec */
  1390. // Error accessing binary mof file %s
  1391. #define ERROR_WMIMOF_CANT_ACCESS_FILE -21 /* 0xffffffeb */
  1392. // Property InstanceName in class %ws must be type string and not %ws
  1393. #define ERROR_WMIMOF_INSTANCENAME_BAD_TYPE -22 /* 0xffffffea */
  1394. // Property Active in class %ws must be type bool and not %ws
  1395. #define ERROR_WMIMOF_ACTIVE_BAD_TYPE -23 /* 0xffffffe9 */
  1396. // Property %ws in class %ws does not have [WmiDataId()] qualifier
  1397. #define ERROR_WMIMOF_NO_WMIDATAID -24 /* 0xffffffe8 */
  1398. // Property InstanceName in class %ws must have [key] qualifier
  1399. #define ERROR_WMIMOF_INSTANCENAME_NOT_KEY -25 /* 0xffffffe7 */
  1400. // Class %ws does not have an InstanceName qualifier
  1401. #define ERROR_WMIMOF_NO_INSTANCENAME -26 /* 0xffffffe6 */
  1402. // Class %ws does not have an Active qualifier
  1403. #define ERROR_WMIMOF_NO_ACTIVE -27 /* 0xffffffe5 */
  1404. // Property %ws in class %ws is an array, but doesn't specify a dimension
  1405. #define ERROR_WMIMOF_MUST_DIM_ARRAY -28 /* 0xffffffe4 */
  1406. // The element count property %ws for the variable length array %ws in class %ws is not an integral type
  1407. #define ERROR_WMIMOF_BAD_VL_ARRAY_SIZE_TYPE -29 /* 0xdddddde4 */
  1408. // Property %ws in class %ws is both a fixed and variable length array
  1409. #define ERROR_WMIMOF_BOTH_FIXED_AND_VARIABLE_ARRAY -30 /* 0xffffffe3 */
  1410. // Embedded class %ws should not have InstaneName or Active properties
  1411. #define ERROR_WMIMOF_EMBEDDED_CLASS -31 /* 0xffffffe2 */
  1412. #define ERROR_WMIMOF_IMPLEMENTED_REQUIRED -32 /* 0xffffffe1 */
  1413. // TEXT("WmiMethodId for method %ws in class %ws must be unique")
  1414. #define ERROR_WMIMOF_DUPLICATE_METHODID -33 /* 0xffffffe0 */
  1415. // TEXT("WmiMethodId for method %ws in class %ws must be specified")
  1416. #define ERROR_WMIMOF_MISSING_METHODID -34 /* 0xffffffdf */
  1417. // TEXT("WmiMethodId for method %ws in class %ws must not be 0")
  1418. #define ERROR_WMIMOF_METHODID_ZERO -35 /* 0xffffffde */
  1419. // TEXT("Class %ws is derived from WmiEvent and may not be [abstract]")
  1420. #define ERROR_WMIMOF_WMIEVENT_ABSTRACT -36 /* 0xffffffdd */
  1421. // TEXT("The element count property for the variable length array
  1422. // %ws in class %ws is not a property of the class"),
  1423. #define ERROR_WMIMOF_VL_ARRAY_NOT_FOUND -37 /* 0xffffffdc */
  1424. // TEXT("An error occured resolving the variable length array
  1425. // property %ws in class %ws to element count property")
  1426. #define ERROR_WMIMOF_VL_ARRAY_NOT_RESOLVED -38 /* 0xffffffdb */
  1427. // TEXT("Method %ws in class %ws must return void\n")
  1428. #define ERROR_WMIMOF_METHOD_RETURN_NOT_VOID -39 /* 0xffffffda */
  1429. #define ERROR_WMIMOF_COUNT 39
  1430. // This file is not a valid binary mof file
  1431. // ERROR_WMI_INVALID_MOF
  1432. // There was not enough memory to complete an operation
  1433. // ERROR_NOT_ENOUGH_MEMORY
  1434. //
  1435. // Function prototypes for private functions
  1436. //
  1437. // sharemem.c
  1438. ULONG WmipEstablishSharedMemory(
  1439. PBDATASOURCE DataSource,
  1440. LPCTSTR SectionName,
  1441. ULONG SectionSize
  1442. );
  1443. //
  1444. // validate.c
  1445. BOOLEAN WmipValidateCountedString(
  1446. WCHAR *String
  1447. );
  1448. BOOLEAN WmipValidateGuid(
  1449. LPGUID Guid
  1450. );
  1451. BOOLEAN WmipProbeForRead(
  1452. PUCHAR Buffer,
  1453. ULONG BufferSize
  1454. );
  1455. //
  1456. // alloc.c
  1457. extern LIST_ENTRY GEHead;
  1458. extern PLIST_ENTRY GEHeadPtr;
  1459. extern CHUNKINFO GEChunkInfo;
  1460. extern LIST_ENTRY NEHead;
  1461. extern PLIST_ENTRY NEHeadPtr;
  1462. extern CHUNKINFO NEChunkInfo;
  1463. extern LIST_ENTRY DSHead;
  1464. extern PLIST_ENTRY DSHeadPtr;
  1465. extern CHUNKINFO DSChunkInfo;
  1466. extern LIST_ENTRY DCHead;
  1467. extern PLIST_ENTRY DCHeadPtr;
  1468. extern CHUNKINFO DCChunkInfo;
  1469. extern LIST_ENTRY MRHead;
  1470. extern PLIST_ENTRY MRHeadPtr;
  1471. extern CHUNKINFO MRChunkInfo;
  1472. extern CHUNKINFO ISChunkInfo;
  1473. extern LIST_ENTRY GMHead;
  1474. extern PLIST_ENTRY GMHeadPtr;
  1475. #ifdef WMI_USER_MODE
  1476. extern LIST_ENTRY MCHead;
  1477. extern PLIST_ENTRY MCHeadPtr;
  1478. extern CHUNKINFO MCChunkInfo;
  1479. #endif
  1480. #ifdef TRACK_REFERNECES
  1481. #define WmipUnreferenceDS(DataSource) \
  1482. { \
  1483. WmipDebugPrint(("WMI: Unref DS %x at %s %d\n", DataSource, __FILE__, __LINE__)); \
  1484. WmipUnreferenceEntry(&DSChunkInfo, (PENTRYHEADER)DataSource); \
  1485. }
  1486. #define WmipReferenceDS(DataSource) \
  1487. { \
  1488. WmipDebugPrint(("WMI: Ref DS %x at %s %d\n", DataSource, __FILE__, __LINE__)); \
  1489. WmipReferenceEntry((PENTRYHEADER)DataSource); \
  1490. }
  1491. #define WmipUnreferenceGE(GuidEntry) \
  1492. { \
  1493. WmipDebugPrint(("WMI: Unref GE %x at %s %d\n", GuidEntry, __FILE__, __LINE__)); \
  1494. WmipUnreferenceEntry(&GEChunkInfo, (PENTRYHEADER)GuidEntry); \
  1495. }
  1496. #define WmipReferenceGE(GuidEntry) \
  1497. { \
  1498. WmipDebugPrint(("WMI: Ref GE %x at %s %d\n", GuidEntry, __FILE__, __LINE__)); \
  1499. WmipReferenceEntry((PENTRYHEADER)GuidEntry); \
  1500. }
  1501. #define WmipUnreferenceIS(InstanceSet) \
  1502. { \
  1503. WmipDebugPrint(("WMI: Unref IS %x at %s %d\n", InstanceSet, __FILE__, __LINE__)); \
  1504. WmipUnreferenceEntry(&ISChunkInfo, (PENTRYHEADER)InstanceSet); \
  1505. }
  1506. #define WmipReferenceIS(InstanceSet) \
  1507. { \
  1508. WmipDebugPrint(("WMI: Ref IS %x at %s %d\n", InstanceSet, __FILE__, __LINE__)); \
  1509. WmipReferenceEntry((PENTRYHEADER)InstanceSet); \
  1510. }
  1511. #define WmipUnreferenceDC(DataConsumer) \
  1512. { \
  1513. WmipDebugPrint(("WMI: Unref DC %x at %s %d\n", DataConsumer, __FILE__, __LINE__)); \
  1514. WmipUnreferenceEntry(&DCChunkInfo, (PENTRYHEADER)DataConsumer); \
  1515. }
  1516. #define WmipReferenceDC(DataConsumer) \
  1517. { \
  1518. WmipDebugPrint(("WMI: Ref DC %x at %s %d\n", DataConsumer, __FILE__, __LINE__)); \
  1519. WmipReferenceEntry((PENTRYHEADER)DataConsumer); \
  1520. }
  1521. #define WmipUnreferenceNE(NotificationEntry) \
  1522. { \
  1523. WmipDebugPrint(("WMI: Unref NE %x at %s %d\n", NotificationEntry, __FILE__, __LINE__)); \
  1524. WmipUnreferenceEntry(&NEChunkInfo, (PENTRYHEADER)NotificationEntry); \
  1525. }
  1526. #define WmipReferenceNE(NotificationEntry) \
  1527. { \
  1528. WmipDebugPrint(("WMI: Ref NE %x at %s %d\n", NotificationEntry, __FILE__, __LINE__)); \
  1529. WmipReferenceEntry((PENTRYHEADER)NotificationEntry); \
  1530. }
  1531. #define WmipUnreferenceMR(MofResource) \
  1532. { \
  1533. WmipDebugPrint(("WMI: Unref MR %x at %s %d\n", MofResource, __FILE__, __LINE__)); \
  1534. WmipUnreferenceEntry(&MRChunkInfo, (PENTRYHEADER)MofResource); \
  1535. }
  1536. #define WmipReferenceMR(MofResource) \
  1537. { \
  1538. WmipDebugPrint(("WMI: Ref MR %x at %s %d\n", MofResource, __FILE__, __LINE__)); \
  1539. WmipReferenceEntry((PENTRYHEADER)MofResource); \
  1540. }
  1541. #ifdef WMI_USER_MODE
  1542. #define WmipUnreferenceMC(MofClass) \
  1543. { \
  1544. WmipDebugPrint(("WMI: Unref MC %x at %s %d\n", MofClass, __FILE__, __LINE__)); \
  1545. WmipUnreferenceEntry(&MCChunkInfo, (PENTRYHEADER)MofClass); \
  1546. }
  1547. #define WmipReferenceMC(MofClass) \
  1548. { \
  1549. WmipDebugPrint(("WMI: Ref MC %x at %s %d\n", MofClass, __FILE__, __LINE__)); \
  1550. WmipReferenceEntry((PENTRYHEADER)MofClass); \
  1551. }
  1552. #endif
  1553. #else
  1554. #define WmipUnreferenceDS(DataSource) \
  1555. WmipUnreferenceEntry(&DSChunkInfo, (PENTRYHEADER)DataSource)
  1556. #define WmipReferenceDS(DataSource) \
  1557. WmipReferenceEntry((PENTRYHEADER)DataSource)
  1558. #define WmipUnreferenceGE(GuidEntry) \
  1559. WmipUnreferenceEntry(&GEChunkInfo, (PENTRYHEADER)GuidEntry)
  1560. #define WmipReferenceGE(GuidEntry) \
  1561. WmipReferenceEntry((PENTRYHEADER)GuidEntry)
  1562. #define WmipUnreferenceIS(InstanceSet) \
  1563. WmipUnreferenceEntry(&ISChunkInfo, (PENTRYHEADER)InstanceSet)
  1564. #define WmipReferenceIS(InstanceSet) \
  1565. WmipReferenceEntry((PENTRYHEADER)InstanceSet)
  1566. #define WmipUnreferenceDC(DataConsumer) \
  1567. WmipUnreferenceEntry(&DCChunkInfo, (PENTRYHEADER)DataConsumer)
  1568. #define WmipReferenceDC(DataConsumer) \
  1569. WmipReferenceEntry((PENTRYHEADER)DataConsumer)
  1570. #define WmipUnreferenceNE(NotificationEntry) \
  1571. WmipUnreferenceEntry(&NEChunkInfo, (PENTRYHEADER)NotificationEntry)
  1572. #define WmipReferenceNE(NotificationEntry) \
  1573. WmipReferenceEntry((PENTRYHEADER)NotificationEntry)
  1574. #define WmipUnreferenceMR(MofResource) \
  1575. WmipUnreferenceEntry(&MRChunkInfo, (PENTRYHEADER)MofResource)
  1576. #define WmipReferenceMR(MofResource) \
  1577. WmipReferenceEntry((PENTRYHEADER)MofResource)
  1578. #ifdef WMI_USER_MODE
  1579. #define WmipUnreferenceMC(MofClass) \
  1580. WmipUnreferenceEntry(&MCChunkInfo, (PENTRYHEADER)MofClass)
  1581. #define WmipReferenceMC(MofClass) \
  1582. WmipReferenceEntry((PENTRYHEADER)MofClass)
  1583. #endif
  1584. #endif
  1585. PBDATASOURCE WmipAllocDataSource(
  1586. void
  1587. );
  1588. PBGUIDENTRY WmipAllocGuidEntry(
  1589. void
  1590. );
  1591. #define WmipAllocInstanceSet() ((PBINSTANCESET)WmipAllocEntry(&ISChunkInfo))
  1592. #define WmipAllocDataConsumer() ((PDCENTRY)WmipAllocEntry(&DCChunkInfo))
  1593. #define WmipAllocNotificationEntry() ((PNOTIFICATIONENTRY)WmipAllocEntry(&NEChunkInfo))
  1594. #define WmipAllocMofResource() ((PMOFRESOURCE)WmipAllocEntry(&MRChunkInfo))
  1595. #ifdef WMI_USER_MODE
  1596. #define WmipAllocMofClass() ((PMOFCLASS)WmipAllocEntry(&MCChunkInfo))
  1597. #endif
  1598. #define WmipAllocString(Size) \
  1599. WmipAlloc((Size)*sizeof(WCHAR))
  1600. #define WmipFreeString(Ptr) \
  1601. WmipFree(Ptr)
  1602. #ifdef MEMPHIS
  1603. #define WmipAlloc(Size) \
  1604. malloc(Size)
  1605. #define WmipFree(Ptr) \
  1606. free(Ptr)
  1607. #define WmipInitProcessHeap()
  1608. #else
  1609. //
  1610. // Reserve 1MB for WMI.DLL, but only commit 16K initially
  1611. #define DLLRESERVEDHEAPSIZE 1024 * 1024
  1612. #define DLLCOMMITHEAPSIZE 0 * 1024
  1613. //
  1614. // Reserve 1MB for WMI service, but only commit 16K initially
  1615. #define CORERESERVEDHEAPSIZE 1024 * 1024
  1616. #define CORECOMMITHEAPSIZE 16 * 1024
  1617. extern PVOID WmipProcessHeap;
  1618. #define WmipInitProcessHeap() \
  1619. { \
  1620. if (WmipProcessHeap == NULL) \
  1621. { \
  1622. WmipCreateHeap(); \
  1623. } \
  1624. }
  1625. #ifdef HEAPVALIDATION
  1626. PVOID WmipAlloc(
  1627. ULONG Size
  1628. );
  1629. void WmipFree(
  1630. PVOID p
  1631. );
  1632. #else
  1633. #if DBG
  1634. _inline PVOID WmipAlloc(ULONG Size)
  1635. {
  1636. WmipAssert(WmipProcessHeap != NULL);
  1637. return(RtlAllocateHeap(WmipProcessHeap, 0, Size));
  1638. }
  1639. _inline void WmipFree(PVOID Ptr)
  1640. {
  1641. RtlFreeHeap(WmipProcessHeap, 0, Ptr);
  1642. }
  1643. #else
  1644. #define WmipAlloc(Size) \
  1645. RtlAllocateHeap(WmipProcessHeap, 0, Size)
  1646. #define WmipFree(Ptr) \
  1647. RtlFreeHeap(WmipProcessHeap, 0, Ptr)
  1648. #endif
  1649. #endif
  1650. #endif
  1651. BOOLEAN WmipRealloc(
  1652. PVOID *Buffer,
  1653. ULONG CurrentSize,
  1654. ULONG NewSize,
  1655. BOOLEAN FreeOriginalBuffer
  1656. );
  1657. //
  1658. // datastr.c
  1659. extern GUID WmipBinaryMofGuid;
  1660. void WmipGenerateBinaryMofNotification(
  1661. PBINSTANCESET BianryMofInstanceSet,
  1662. LPCGUID Guid
  1663. );
  1664. BOOLEAN WmipEstablishInstanceSetRef(
  1665. PBDATASOURCE DataSourceRef,
  1666. LPGUID Guid,
  1667. PBINSTANCESET InstanceSet
  1668. );
  1669. ULONG WmipAddDataSource(
  1670. PTCHAR QueryBinding,
  1671. ULONG RequestAddress,
  1672. ULONG RequestContext,
  1673. LPCTSTR ImagePath,
  1674. PWMIREGINFOW RegistrationInfo,
  1675. ULONG RegistrationInfoSize,
  1676. ULONG_PTR *ProviderId,
  1677. BOOLEAN IsAnsi
  1678. );
  1679. ULONG WmipUpdateAddGuid(
  1680. PBDATASOURCE DataSource,
  1681. PWMIREGGUID RegGuid,
  1682. PWMIREGINFO RegistrationInfo,
  1683. PBINSTANCESET *AddModInstanceSet
  1684. );
  1685. ULONG WmipUpdateModifyGuid(
  1686. PBDATASOURCE DataSource,
  1687. PWMIREGGUID RegGuid,
  1688. PWMIREGINFO RegistrationInfo,
  1689. PBINSTANCESET *AddModInstanceSet
  1690. );
  1691. BOOLEAN WmipUpdateRemoveGuid(
  1692. PBDATASOURCE DataSource,
  1693. PWMIREGGUID RegGuid,
  1694. PBINSTANCESET *AddModInstanceSet
  1695. );
  1696. void WmipUpdateDataSource(
  1697. ULONG_PTR ProviderId,
  1698. PWMIREGINFOW RegistrationInfo,
  1699. ULONG RetSize
  1700. );
  1701. void WmipRemoveDataSource(
  1702. ULONG_PTR ProviderId
  1703. );
  1704. void WmipRemoveDataSourceByDS(
  1705. PBDATASOURCE DataSource
  1706. );
  1707. ULONG WmipRegisterInternalDataSource(
  1708. void
  1709. );
  1710. PBGUIDENTRY WmipFindGEByGuid(
  1711. LPGUID Guid,
  1712. BOOLEAN MakeTopOfList
  1713. );
  1714. PBINSTANCESET WmipFindISInDSByGuid(
  1715. PBDATASOURCE DataSource,
  1716. LPGUID Guid
  1717. );
  1718. PNOTIFICATIONENTRY WmipFindNEByGuid(
  1719. GUID UNALIGNED *Guid,
  1720. BOOLEAN MakeTopOfList
  1721. );
  1722. PDCREF WmipFindExistingAndFreeDCRefInNE(
  1723. PNOTIFICATIONENTRY NotificationEntry,
  1724. PDCENTRY DataConsumer,
  1725. PDCREF *FreeDcRef
  1726. );
  1727. PDCREF WmipFindDCRefInNE(
  1728. PNOTIFICATIONENTRY NotificationEntry,
  1729. PDCENTRY DataConsumer
  1730. );
  1731. PBDATASOURCE WmipFindDSByProviderId(
  1732. ULONG_PTR ProviderId
  1733. );
  1734. PBINSTANCESET WmipFindISByGuid(
  1735. PBDATASOURCE DataSource,
  1736. GUID UNALIGNED *Guid
  1737. );
  1738. PMOFRESOURCE WmipFindMRByNames(
  1739. LPCWSTR ImagePath,
  1740. LPCWSTR MofResourceName
  1741. );
  1742. #ifdef WMI_USER_MODE
  1743. PMOFCLASS WmipFindMCByGuid(
  1744. LPGUID Guid
  1745. );
  1746. PMOFCLASS WmipFindMCByGuidAndBestLanguage(
  1747. LPGUID Guid,
  1748. WORD Language
  1749. );
  1750. PMOFCLASS WmipFindMCByGuidAndLanguage(
  1751. LPGUID Guid,
  1752. WORD Language
  1753. );
  1754. #endif
  1755. PBINSTANCESET WmipFindISinGEbyName(
  1756. PBGUIDENTRY GuidEntry,
  1757. PWCHAR InstanceName,
  1758. PULONG InstanceIndex
  1759. );
  1760. PWNODE_HEADER WmipGenerateRegistrationNotification(
  1761. PBDATASOURCE DataSource,
  1762. PWNODE_HEADER Wnode,
  1763. ULONG GuidMax,
  1764. ULONG NotificationCode
  1765. );
  1766. BOOLEAN
  1767. WmipIsControlGuid(
  1768. PBGUIDENTRY GuidEntry
  1769. );
  1770. void WmipGenerateMofResourceNotification(
  1771. LPWSTR ImagePath,
  1772. LPWSTR ResourceName,
  1773. LPCGUID Guid
  1774. );
  1775. //
  1776. // wbem.c
  1777. ULONG WmipBuildMofClassInfo(
  1778. PBDATASOURCE DataSource,
  1779. LPWSTR ImagePath,
  1780. LPWSTR MofResourceName,
  1781. PBOOLEAN NewMofResource
  1782. );
  1783. ULONG WmipReadBuiltinMof(
  1784. void
  1785. );
  1786. //
  1787. // from krnlmode.c
  1788. ULONG WmipInitializeKM(
  1789. HANDLE *WmiKMHandle
  1790. );
  1791. void WmipKMNonEventNotification(
  1792. HANDLE WmiKMHandle,
  1793. PWNODE_HEADER Wnode
  1794. );
  1795. //
  1796. // main.c
  1797. extern HANDLE WmipRestrictedToken;
  1798. void WmipGetRegistryValue(
  1799. TCHAR *ValueName,
  1800. PULONG Value
  1801. );
  1802. ULONG WmiRunService(
  1803. ULONG Context
  1804. #ifdef MEMPHIS
  1805. , HINSTANCE InstanceHandle
  1806. #endif
  1807. );
  1808. ULONG WmipInitializeAccess(
  1809. PTCHAR *RpcStringBinding
  1810. );
  1811. void WmiTerminateService(
  1812. void
  1813. );
  1814. ULONG WmiInitializeService(
  1815. void
  1816. );
  1817. void WmiDeinitializeService(
  1818. void
  1819. );
  1820. void WmipEventNotification(
  1821. PWNODE_HEADER Wnode,
  1822. BOOLEAN SingleEvent,
  1823. ULONG EventSizeGuess
  1824. );
  1825. #define WmipBuildRegistrationNotification(Wnode, WnodeSize, NotificationCode, GuidCount) { \
  1826. memset(Wnode, 0, sizeof(WNODE_HEADER)); \
  1827. memcpy(&Wnode->Guid, &RegChangeNotificationGuid, sizeof(GUID)); \
  1828. Wnode->BufferSize = WnodeSize; \
  1829. Wnode->Linkage = NotificationCode; \
  1830. Wnode->Version = GuidCount; \
  1831. Wnode->Flags = WNODE_FLAG_INTERNAL; \
  1832. }
  1833. void WmipSendQueuedEvents(
  1834. void
  1835. );
  1836. ULONG WmipCleanupDataConsumer(
  1837. PDCENTRY DataConsumer
  1838. #if DBG
  1839. ,BOOLEAN *NotificationsEnabled,
  1840. BOOLEAN *CollectionsEnabled
  1841. #endif
  1842. );
  1843. //
  1844. // This defines the maximum number of replacement strings over all of the
  1845. // event messages.
  1846. #define MAX_MESSAGE_STRINGS 2
  1847. void __cdecl WmipReportEventLog(
  1848. ULONG MessageCode,
  1849. WORD MessageType,
  1850. WORD MessageCategory,
  1851. DWORD RawDataSize,
  1852. PVOID RawData,
  1853. WORD StringCount,
  1854. ...
  1855. );
  1856. #ifdef MEMPHIS
  1857. long WINAPI
  1858. DeviceNotificationWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
  1859. void WmipDestroyDeviceNotificationWindow(
  1860. HINSTANCE InstanceHandle,
  1861. HWND WindowHandle
  1862. );
  1863. ULONG WmipCreateDeviceNotificationWindow(
  1864. HINSTANCE InstanceHandle,
  1865. HWND *DeviceNotificationWindow
  1866. );
  1867. #endif
  1868. //
  1869. // server.c
  1870. void WmipRpcServerDeinitialize(
  1871. void
  1872. );
  1873. ULONG WmipRpcServerInitialize(
  1874. void
  1875. );
  1876. ULONG WmipDeliverWnodeToDS(
  1877. ULONG ActionCode,
  1878. PBDATASOURCE DataSource,
  1879. PWNODE_HEADER Wnode
  1880. );
  1881. ULONG WmipDoDisableRequest(
  1882. PNOTIFICATIONENTRY NotificationEntry,
  1883. PBGUIDENTRY GuidEntry,
  1884. BOOLEAN IsEvent,
  1885. BOOLEAN IsTraceLog,
  1886. ULONG64 LoggerContext,
  1887. ULONG InProgressFlag
  1888. );
  1889. ULONG CollectOrEventWorker(
  1890. PDCENTRY DataConsumer,
  1891. LPGUID Guid,
  1892. BOOLEAN Enable,
  1893. BOOLEAN IsEvent,
  1894. ULONG *NotificationCookie,
  1895. ULONG64 LoggerContext,
  1896. ULONG NotificationFlags
  1897. );
  1898. ULONG WmipCreateRestrictedToken(
  1899. HANDLE *RestrictedToken
  1900. );
  1901. void WmipShowPrivs(
  1902. HANDLE TokenHandle
  1903. );
  1904. #ifdef MEMPHIS
  1905. #define WmipRestrictToken(Token) (ERROR_SUCCESS)
  1906. #define WmipUnrestrictToken() (ERROR_SUCCESS)
  1907. #else
  1908. ULONG WmipRestrictToken(
  1909. HANDLE RestrictedToken
  1910. );
  1911. ULONG WmipUnrestrictToken(
  1912. void
  1913. );
  1914. ULONG WmipServiceDisableTraceProviders(
  1915. PWNODE_HEADER Wnode
  1916. );
  1917. #endif
  1918. void WmipReleaseCollectionEnabled(
  1919. PNOTIFICATIONENTRY NotificationEntry
  1920. );
  1921. //
  1922. // chunk.c
  1923. ULONG UnicodeToAnsi(
  1924. LPCWSTR pszW,
  1925. LPSTR * ppszA,
  1926. ULONG *AnsiSizeInBytes OPTIONAL
  1927. );
  1928. ULONG AnsiToUnicode(
  1929. LPCSTR pszA,
  1930. LPWSTR * ppszW
  1931. );
  1932. ULONG AnsiSizeForUnicodeString(
  1933. PWCHAR UnicodeString,
  1934. ULONG *AnsiSizeInBytes
  1935. );
  1936. ULONG UnicodeSizeForAnsiString(
  1937. LPCSTR AnsiString,
  1938. ULONG *UnicodeSizeInBytes
  1939. );
  1940. //
  1941. // debug.c
  1942. #if DBG
  1943. void WmipDumpIS(
  1944. PBINSTANCESET IS,
  1945. BOOLEAN RecurseGE,
  1946. BOOLEAN RecurseDS
  1947. );
  1948. void WmipDumpGE(
  1949. PBGUIDENTRY GE,
  1950. BOOLEAN RecurseIS
  1951. );
  1952. void WmipDumpDS(
  1953. PBDATASOURCE DS,
  1954. BOOLEAN RecurseIS
  1955. );
  1956. void WmipDumpAllDS(
  1957. void
  1958. );
  1959. #endif
  1960. #ifndef MEMPHIS
  1961. typedef enum
  1962. {
  1963. TRACELOG_START = 0,
  1964. TRACELOG_STOP = 1,
  1965. TRACELOG_QUERY = 2,
  1966. TRACELOG_QUERYALL = 3,
  1967. TRACELOG_QUERYENABLED = 4,
  1968. TRACELOG_UPDATE = 5,
  1969. TRACELOG_FLUSH = 6
  1970. } TRACEREQUESTCODE;
  1971. typedef struct _WMI_REF_CLOCK {
  1972. LARGE_INTEGER StartTime;
  1973. LARGE_INTEGER StartPerfClock;
  1974. } WMI_REF_CLOCK, *PWMI_REF_CLOCK;
  1975. //
  1976. // logsup.c
  1977. ULONG
  1978. WmiUnregisterGuids(
  1979. IN WMIHANDLE WMIHandle,
  1980. IN LPGUID Guid,
  1981. OUT ULONG64 *LoggerContext
  1982. );
  1983. void
  1984. WmipGenericTraceEnable(
  1985. IN ULONG RequestCode,
  1986. IN PVOID Buffer,
  1987. IN OUT PVOID *RequestAddress
  1988. );
  1989. ULONG
  1990. WmipAddLogHeaderToLogFile(
  1991. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo,
  1992. IN PWMI_REF_CLOCK RefClock,
  1993. IN ULONG Update
  1994. );
  1995. ULONG
  1996. WmipStartLogger(
  1997. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  1998. );
  1999. ULONG
  2000. WmipStopLogger(
  2001. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  2002. );
  2003. ULONG
  2004. WmipQueryLogger(
  2005. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo,
  2006. IN ULONG Update
  2007. );
  2008. ULONG
  2009. WmipFlushLogger(
  2010. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  2011. );
  2012. VOID
  2013. WmipInitString(
  2014. IN PVOID Destination,
  2015. IN PVOID Buffer,
  2016. IN ULONG Size
  2017. );
  2018. ULONG
  2019. WmipGetTraceRegKeys(
  2020. );
  2021. ULONG
  2022. WmipFinalizeLogFileHeader(
  2023. IN PWMI_LOGGER_INFORMATION LoggerInfo
  2024. );
  2025. ULONG
  2026. WmipRelogHeaderToLogFile(
  2027. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo ,
  2028. IN PSYSTEM_TRACE_HEADER RelogProp
  2029. );
  2030. //
  2031. // umlog.c
  2032. BOOLEAN
  2033. FASTCALL
  2034. WmipIsPrivateLoggerOn();
  2035. ULONG
  2036. WmipFlushUmLoggerBuffer();
  2037. ULONG
  2038. WmipSendUmLogRequest(
  2039. IN WMITRACECODE RequestCode,
  2040. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  2041. );
  2042. ULONG
  2043. FASTCALL
  2044. WmiTraceUmEvent(
  2045. IN PWNODE_HEADER Wnode
  2046. );
  2047. #endif