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.

2535 lines
65 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  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. DbgBreakPoint(); }
  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. WmipSetLastError(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. BOOLEAN ActuallyRemove
  487. );
  488. void
  489. WmipDereferenceGNEntry(
  490. PGUIDNOTIFICATION GNEntry
  491. );
  492. PTCHAR GuidToString(
  493. PTCHAR s,
  494. LPGUID piid
  495. );
  496. PCHAR GuidToStringA(
  497. PCHAR s,
  498. LPGUID piid
  499. );
  500. // from request.c
  501. ULONG WmipSendWmiRequest(
  502. ULONG ActionCode,
  503. PWNODE_HEADER Wnode,
  504. ULONG WnodeSize,
  505. PVOID OutBuffer,
  506. ULONG MaxBufferSize,
  507. ULONG *RetSize
  508. );
  509. ULONG WmipSendWmiKMRequest(
  510. HANDLE Handle,
  511. ULONG Ioctl,
  512. PVOID InBuffer,
  513. ULONG InBufferSize,
  514. PVOID OutBuffer,
  515. ULONG MaxBufferSize,
  516. ULONG *ReturnSize,
  517. LPOVERLAPPED Overlapped
  518. );
  519. ULONG WmipConvertWADToAnsi(
  520. PWNODE_ALL_DATA Wnode
  521. );
  522. ULONG WmipConvertWADToUnicode(
  523. PWNODE_ALL_DATA WnodeAllData,
  524. ULONG *BufferSize
  525. );
  526. /*ULONG WmipQueryPidEntry(
  527. IN GUID Guid,
  528. IN ULONG Pid,
  529. OUT BOOLEAN *PidEntry
  530. );*/
  531. ULONG WmipRegisterGuids(
  532. IN LPGUID MasterGuid,
  533. IN ULONG RegistrationCookie,
  534. IN PWMIREGINFOW RegInfo,
  535. IN ULONG GuidCount,
  536. OUT PTRACEGUIDMAP *GuidMapHandle,
  537. OUT ULONG64 *LoggerContext,
  538. OUT HANDLE *RegistrationHandle
  539. );
  540. //
  541. // from intrnldp.c
  542. ULONG WmipInternalProvider(
  543. ULONG ActionCode,
  544. PWNODE_HEADER Wnode,
  545. ULONG MaxWnodeSize,
  546. PVOID OutBuffer,
  547. ULONG *RetSize
  548. );
  549. ULONG
  550. WmipEnumRegGuids(
  551. PWMIGUIDLISTINFO *pGuidInfo
  552. );
  553. //
  554. // from dcapi.c
  555. ULONG
  556. WmipNotificationRegistration(
  557. IN LPGUID InGuid,
  558. IN BOOLEAN Enable,
  559. IN PVOID DeliveryInfo,
  560. IN ULONG_PTR DeliveryContext,
  561. IN ULONG64 LoggerContext,
  562. IN ULONG Flags,
  563. IN BOOLEAN IsAnsi
  564. );
  565. //
  566. // from mofapi.c
  567. //
  568. void WmipProcessLanguageAddRemoveEvent(
  569. IN PWNODE_SINGLE_INSTANCE WnodeSI,
  570. IN NOTIFICATIONCALLBACK Callback,
  571. IN ULONG_PTR DeliveryContext,
  572. IN BOOLEAN IsAnsi
  573. );
  574. void WmipProcessMofAddRemoveEvent(
  575. IN PWNODE_SINGLE_INSTANCE WnodeSI,
  576. IN NOTIFICATIONCALLBACK Callback,
  577. IN ULONG_PTR DeliveryContext,
  578. IN BOOLEAN IsAnsi
  579. );
  580. //
  581. // from notify.c
  582. extern ULONG WmipNotificationSinkIndex;
  583. #ifndef MEMPHIS
  584. ULONG WmipProcessUMRequest(
  585. PWMI_LOGGER_INFORMATION LoggerInfo,
  586. PVOID DeliveryContext,
  587. ULONG ReplyIndex
  588. );
  589. #endif
  590. ULONG WmipAddHandleToEventPump(
  591. LPGUID Guid,
  592. PVOID DeliveryInfo,
  593. ULONG_PTR DeliveryContext,
  594. ULONG NotificationFlags,
  595. HANDLE GuidHandle
  596. );
  597. void WmipMakeEventCallbacks(
  598. IN PWNODE_HEADER Wnode,
  599. IN NOTIFICATIONCALLBACK Callback,
  600. IN ULONG_PTR DeliveryContext,
  601. IN BOOLEAN IsAnsi
  602. );
  603. ULONG
  604. WmipReceiveNotifications(
  605. IN ULONG HandleCount,
  606. IN HANDLE *HandleList,
  607. IN NOTIFICATIONCALLBACK Callback,
  608. IN ULONG_PTR DeliveryContext,
  609. IN BOOLEAN IsAnsi,
  610. IN ULONG Action,
  611. IN PUSER_THREAD_START_ROUTINE UserModeCallback,
  612. IN HANDLE ProcessHandle
  613. );
  614. ULONG WmipEventPump(
  615. PVOID Param
  616. );
  617. //
  618. // from main.c
  619. VOID
  620. WmipCreateHeap(
  621. VOID
  622. );
  623. #ifndef IsEqualGUID
  624. #define IsEqualGUID(guid1, guid2) \
  625. (!memcmp((guid1), (guid2), sizeof(GUID)))
  626. #endif
  627. //
  628. // These define the dll and mof resource name for all of the builtin mof
  629. // resources
  630. #define WMICOREDLLNAME L"wmicore.dll"
  631. #define WMICOREMOFRESOURCENAME L"MofResource"
  632. //
  633. // This defines the registry key under which security descriptors associated
  634. // with the guids are stored.
  635. #ifndef MEMPHIS
  636. #define WMISECURITYREGISTRYKEY TEXT("System\\CurrentControlSet\\Control\\Wmi\\Security")
  637. #endif
  638. //
  639. // This defines the initial value of the buffer passed to each data provider
  640. // to retrieve the registration information
  641. #if DBG
  642. #define INITIALREGINFOSIZE sizeof(WNODE_TOO_SMALL)
  643. #else
  644. #define INITIALREGINFOSIZE 8192
  645. #endif
  646. //
  647. // Chunk Management definitions
  648. // All structures that rely upon the chunk allocator must be defined so that
  649. // their members match that of ENTRYHEADER. These include DATASOURCE,
  650. // GUIDENTRY, INSTANCESET, DCENTRY, NOTIFICATIONENTRY, MOFCLASS, MOFRESOURCE
  651. // Also ENTRYHEADER reserves 0x80000000 for its own flag.
  652. struct _CHUNKINFO;
  653. struct _ENTRYHEADER;
  654. typedef void (*ENTRYCLEANUP)(
  655. struct _CHUNKINFO *,
  656. struct _ENTRYHEADER *
  657. );
  658. typedef struct _CHUNKINFO
  659. {
  660. LIST_ENTRY ChunkHead; // Head of list of chunks
  661. ULONG EntrySize; // Size of a single entry
  662. ULONG EntriesPerChunk; // Number of entries per chunk allocation
  663. ENTRYCLEANUP EntryCleanup; // Entry cleanup routine
  664. ULONG InitialFlags; // Initial flags for all entries
  665. ULONG Signature;
  666. #if DBG
  667. ULONG AllocCount;
  668. ULONG FreeCount;
  669. #endif
  670. } CHUNKINFO, *PCHUNKINFO;
  671. typedef struct
  672. {
  673. LIST_ENTRY ChunkList; // Node in list of chunks
  674. LIST_ENTRY FreeEntryHead; // Head of list of free entries in chunk
  675. ULONG EntriesInUse; // Count of entries being used
  676. } CHUNKHEADER, *PCHUNKHEADER;
  677. typedef struct _ENTRYHEADER
  678. {
  679. union
  680. {
  681. LIST_ENTRY FreeEntryList; // Node in list of free entries
  682. LIST_ENTRY InUseEntryList; // Node in list ofin use entries
  683. };
  684. PCHUNKHEADER Chunk; // Chunk in which entry is located
  685. ULONG Flags; // Flags
  686. ULONG RefCount; // Reference Count
  687. ULONG Signature;
  688. } ENTRYHEADER, *PENTRYHEADER;
  689. // Set if the entry is free
  690. #define FLAG_ENTRY_ON_FREE_LIST 0x80000000
  691. #define FLAG_ENTRY_ON_INUSE_LIST 0x40000000
  692. #define FLAG_ENTRY_INVALID 0x20000000
  693. #define FLAG_ENTRY_REMOVE_LIST 0x10000000
  694. #define WmipReferenceEntry(Entry) \
  695. InterlockedIncrement(&((PENTRYHEADER)(Entry))->RefCount)
  696. // chunk.c
  697. #ifndef MEMPHIS
  698. ULONG WmipBuildGuidObjectAttributes(
  699. IN LPGUID Guid,
  700. OUT POBJECT_ATTRIBUTES ObjectAttributes,
  701. OUT PUNICODE_STRING GuidString,
  702. OUT PWCHAR GuidObjectName
  703. );
  704. #endif
  705. ULONG WmipUnreferenceEntry(
  706. PCHUNKINFO ChunkInfo,
  707. PENTRYHEADER Entry);
  708. PENTRYHEADER WmipAllocEntry(
  709. PCHUNKINFO ChunkInfo
  710. );
  711. void WmipFreeEntry(
  712. PCHUNKINFO ChunkInfo,
  713. PENTRYHEADER Entry
  714. );
  715. //
  716. // This is the guid that denotes non event notifications. WMICore
  717. // automatically registers anyone opening a guid to
  718. extern GUID RegChangeNotificationGuid;
  719. extern CHUNKINFO DSChunkInfo;
  720. extern CHUNKINFO GEChunkInfo;
  721. extern CHUNKINFO ISChunkInfo;
  722. extern CHUNKINFO DCChunkInfo;
  723. extern CHUNKINFO NEChunkInfo;
  724. extern CHUNKINFO MRChunkInfo;
  725. struct tagGUIDENTRY;
  726. typedef struct tagGUIDENTRY GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
  727. struct tagDATASOURCE;
  728. //
  729. // An INSTANCESET contains the information a set of instances that is provided
  730. // by a single data source. An instance set is part of two lists. One list is
  731. // the set of instance sets for a particular guid. The other list is the list
  732. // of instance sets supported by a data source.
  733. //
  734. //
  735. // Instance names for an instance set registered with a base name and count
  736. // are stored in a ISBASENAME structure. This structure is tracked by
  737. // PDFISBASENAME in wmicore.idl.
  738. typedef struct
  739. {
  740. ULONG BaseIndex; // First index to append to base name
  741. WCHAR BaseName[1]; // Actual base name
  742. } ISBASENAME, *PISBASENAME, *PBISBASENAME;
  743. //
  744. // This defines the maximum number of characters that can be part of a suffix
  745. // to a basename. The current value of 6 will allow up to 999999 instances
  746. // of a guid with a static base name
  747. #define MAXBASENAMESUFFIXSIZE 6
  748. //
  749. // Instance names for an instance set registerd with a set of static names
  750. // are kept in a ISSTATICNAMES structure. This structure is tracked by
  751. // PDFISSTATICNAMES defined in wmicore.idl
  752. typedef struct
  753. {
  754. PWCHAR StaticNamePtr[1]; // pointers to static names
  755. // WCHAR StaticNames[1];
  756. } ISSTATICENAMES, *PISSTATICNAMES, *PBISSTATICNAMES;
  757. typedef struct tagInstanceSet
  758. {
  759. union
  760. {
  761. // Entry in list of instances within a guid
  762. LIST_ENTRY GuidISList;
  763. // Entry in main list of free instances
  764. LIST_ENTRY FreeISList;
  765. };
  766. PCHUNKHEADER Chunk; // Chunk in which entry is located
  767. ULONG Flags;
  768. // Reference count of number of guids using this instance set
  769. ULONG RefCount;
  770. // Signature to identify entry
  771. ULONG Signature;
  772. // Entry in list of instances within a data source
  773. LIST_ENTRY DSISList;
  774. // Back link to guid that this instance set is a member
  775. PBGUIDENTRY GuidEntry;
  776. // Back link to data source that this instance set is a member
  777. struct tagDATASOURCE *DataSource;
  778. // Count of instances in instance set
  779. ULONG Count;
  780. //
  781. // If IS_INSTANCE_BASENAME is set then IsBaseName pointe at instance base
  782. // name structure. Else if IS_INSTANCE_STATICNAME is set then
  783. // IsStaticNames points to static instance name list. If
  784. union
  785. {
  786. PBISBASENAME IsBaseName;
  787. PBISSTATICNAMES IsStaticNames;
  788. };
  789. } INSTANCESET, *PINSTANCESET, *PBINSTANCESET;
  790. #define IS_SIGNATURE 'nalA'
  791. //
  792. // Guid Map Entry List maintains the list of Guid and their maps.
  793. // Only those Guids that are Unregistered while a logger session is in
  794. // progress is kept in this list.
  795. // It is also used as a placeholder for InstanceIds. Trace Guid Registration
  796. // calls return a handle to a GUIDMAPENTRY which maintains the map and the
  797. // Instance Ids.
  798. //
  799. typedef struct tagTRACE_REG_INFO
  800. {
  801. ULONG RegistrationCookie;
  802. HANDLE InProgressEvent; // Registration is in Progress Event
  803. BOOLEAN EnabledState; // Indicates if this GUID is Enabled or not.
  804. PVOID NotifyRoutine;
  805. PVOID TraceCtxHandle;
  806. } TRACE_REG_INFO, *PTRACE_REG_INFO;
  807. typedef struct
  808. {
  809. LIST_ENTRY Entry;
  810. TRACEGUIDMAP GuidMap;
  811. ULONG InstanceId;
  812. ULONG64 LoggerContext;
  813. PTRACE_REG_INFO pControlGuidData;
  814. } GUIDMAPENTRY, *PGUIDMAPENTRY;
  815. #define IS_INSTANCE_BASENAME 0x00000001
  816. #define IS_INSTANCE_STATICNAMES 0x00000002
  817. #define IS_EXPENSIVE 0x00000004 // set if collection must be enabled
  818. #define IS_COLLECTING 0x00000008 // set when collecting
  819. #define IS_KM_PROVIDER 0x00000080 // KM data provider
  820. #define IS_SM_PROVIDER 0x00000100 // Shared memory provider
  821. #define IS_UM_PROVIDER 0x00000200 // User mode provider
  822. #define IS_NEWLY_REGISTERED 0x00000800 // set if IS is registering
  823. //
  824. // Any traced guids are used for trace logging and not querying
  825. #define IS_TRACED 0x00001000
  826. // Set when events are enabled for instance set
  827. #define IS_ENABLE_EVENT 0x00002000
  828. // Set when events are enabled for instance set
  829. #define IS_ENABLE_COLLECTION 0x00004000
  830. // Set if guid is used only for firing events and not querying
  831. #define IS_EVENT_ONLY 0x00008000
  832. // Set if data provider for instance set is expecting ansi instsance names
  833. #define IS_ANSI_INSTANCENAMES 0x00010000
  834. // Set if instance names are originated from a PDO
  835. #define IS_PDO_INSTANCENAME 0x00020000
  836. // If set the data provider for the InstanceSet is internal to wmi.dll
  837. #define IS_INTERNAL_PROVIDER 0x00040000
  838. // Set if a Traced Guid is also a Trace Control Guid
  839. #define IS_CONTROL_GUID 0x00080000
  840. #define IS_ON_FREE_LIST 0x80000000
  841. typedef struct tagGUIDENTRY
  842. {
  843. union
  844. {
  845. // Entry in list of all guids registered with WMI
  846. LIST_ENTRY MainGEList;
  847. // Entry in list of free guid entry blocks
  848. LIST_ENTRY FreeGEList;
  849. };
  850. PCHUNKHEADER Chunk; // Chunk in which entry is located
  851. ULONG Flags;
  852. // Count of number of data sources using this guid
  853. ULONG RefCount;
  854. // Signature to identify entry
  855. ULONG Signature;
  856. // Count of InstanceSets headed by this guid
  857. ULONG ISCount;
  858. // Head of list of all instances for guid
  859. LIST_ENTRY ISHead;
  860. // Guid that represents data block
  861. GUID Guid;
  862. } GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
  863. #define GE_SIGNATURE 'diuG'
  864. #define GE_ON_FREE_LIST 0x80000000
  865. //
  866. // When set this guid is an internally defined guid that has no data source
  867. // attached to it.
  868. #define GE_FLAG_INTERNAL 0x00000001
  869. typedef struct
  870. {
  871. union
  872. {
  873. // Entry in list of all DS
  874. LIST_ENTRY MainMRList;
  875. // Entry in list of free DS
  876. LIST_ENTRY FreeMRList;
  877. };
  878. PCHUNKHEADER Chunk; // Chunk in which entry is located
  879. ULONG Flags;
  880. ULONG RefCount;
  881. // Signature to identify entry
  882. ULONG Signature;
  883. PWCHAR MofImagePath; // Path to image file with resource
  884. PWCHAR MofResourceName; // Name of resource containing mof data
  885. #ifdef WMI_USER_MODE
  886. LIST_ENTRY MRMCHead;
  887. #endif
  888. } MOFRESOURCE, *PMOFRESOURCE;
  889. #define MR_SIGNATURE 'yhsA'
  890. #if DBG
  891. #define AVGMOFRESOURCECOUNT 1
  892. #else
  893. #define AVGMOFRESOURCECOUNT 4
  894. #endif
  895. typedef struct tagDATASOURCE
  896. {
  897. union
  898. {
  899. // Entry in list of all DS
  900. LIST_ENTRY MainDSList;
  901. // Entry in list of free DS
  902. LIST_ENTRY FreeDSList;
  903. };
  904. PCHUNKHEADER Chunk; // Chunk in which entry is located
  905. ULONG Flags;
  906. ULONG RefCount;
  907. ULONG Signature;
  908. // Head of list of instances for this DS
  909. LIST_ENTRY ISHead;
  910. // Binding string and callback address for DS rpc server
  911. PTCHAR BindingString;
  912. RPC_BINDING_HANDLE RpcBindingHandle;
  913. ULONG RequestAddress;
  914. ULONG RequestContext;
  915. // Provider id of kernel mode driver
  916. ULONG_PTR ProviderId;
  917. // Path to registry holding ACLs
  918. PTCHAR RegistryPath;
  919. // Head of list of MofResources attached to data source
  920. ULONG MofResourceCount;
  921. PMOFRESOURCE *MofResources;
  922. PMOFRESOURCE StaticMofResources[AVGMOFRESOURCECOUNT];
  923. };
  924. #define DS_SIGNATURE ' naD'
  925. #define VERIFY_DPCTXHANDLE(DsCtxHandle) \
  926. ( ((DsCtxHandle) == NULL) || \
  927. (((PBDATASOURCE)(DsCtxHandle))->Signature == DS_SIGNATURE) )
  928. typedef struct tagDATASOURCE DATASOURCE, *PDATASOURCE, *PBDATASOURCE;
  929. #define DS_ALLOW_ALL_ACCESS 0x00000001
  930. #define DS_KERNEL_MODE 0x00000002
  931. //
  932. // Set in the Internal WMI data source
  933. #define DS_INTERNAL 0x00000004
  934. #define DS_ON_FREE_LIST 0x80000000
  935. //
  936. // A list of enabled notifications is maintained by the wmi service to mange
  937. // delivering events and to know when to send enable and disable event
  938. // wmi requests to the data providers. Each NOTIFICATIONENTRY has an array of
  939. // DCREF which is a reference to the data consumer who is interested in the
  940. // event.
  941. #define RPCOUTSTANDINGCALLLIMIT 128
  942. typedef struct
  943. {
  944. LIST_ENTRY MainDCList; // Node on global data consumer list
  945. PCHUNKHEADER Chunk; // Chunk in which entry is located
  946. ULONG Flags;
  947. ULONG RefCount;
  948. ULONG Signature;
  949. // Actual RPC binding handle
  950. RPC_BINDING_HANDLE RpcBindingHandle;
  951. PUCHAR EventData; // Buffer to hold events to be sent
  952. ULONG LastEventOffset; // Offset in EventData to previous event
  953. ULONG NextEventOffset; // Offset in EventData to write next event
  954. ULONG EventDataSizeLeft; // Number of bytes left to use in EventData
  955. ULONG RpcCallsOutstanding; // Number of rpc calls outstanding
  956. #if DBG
  957. PTCHAR BindingString; // Binding string for consumer
  958. #endif
  959. } DCENTRY, *PDCENTRY;
  960. #define DC_SIGNATURE 'cirE'
  961. // If the data consumer has had its context rundown routine then this flag
  962. // is set. This indicates that the data consumer has gone away and no more
  963. // events should be sent to him.
  964. #define DC_FLAG_RUNDOWN 0x00000001
  965. #define VERIFY_DCCTXHANDLE(DcCtxHandle) \
  966. ( ((DcCtxHandle) == NULL) || \
  967. (((PDCENTRY)(DcCtxHandle))->Signature == DC_SIGNATURE) )
  968. typedef struct
  969. {
  970. PDCENTRY DcEntry; // points at data consumer interested in notification
  971. // Number of times collect has been enabled by
  972. // this DC.
  973. ULONG CollectRefCount;
  974. // Number of times collect has been enabled by
  975. // this DC.
  976. ULONG EventRefCount;
  977. ULONG Flags; // Flags
  978. ULONG LostEventCount;
  979. } DCREF, *PDCREF;
  980. //
  981. // _ENABLED flag set if DP already called to enable notification or collection
  982. #define DCREF_FLAG_NOTIFICATION_ENABLED 0x00000001
  983. #define DCREF_FLAG_COLLECTION_ENABLED 0x00000002
  984. // if DCREF_FLAG_NO_EXTRA_THREAD set then WMI will not create a special thread
  985. // to do the direct notification callback.
  986. #define DCREF_FLAG_NO_EXTRA_THREAD 0x00000008
  987. // If this flag is set then the notification callback is expecting an ANSI
  988. // instance names.
  989. #define DCREF_FLAG_ANSI 0x00000010
  990. // NOTE: Other notification flags in wmium.h are:
  991. // NOTIFICATION_TRACE_FLAG 0x00010000
  992. //
  993. // NOTIFICATION_FLAG_CALLBACK_DIRECT is set when NotifyAddress specifies
  994. // a direct callback address for delivering the event.
  995. //
  996. // NOTIFICATION_FLAG_CALLBACK_DIRECT is set when NotifyAddress specifies
  997. // a direct callback address for delivering the event.
  998. //
  999. #define NOTIFICATION_FLAG_CALLBACK_DIRECT 0x00020000
  1000. #define NOTIFICATION_FLAG_CALLBACK_QUEUED 0x00040000
  1001. #define NOTIFICATION_FLAG_WINDOW 0x00080000
  1002. #define NOTIFICATION_FLAG_BATCHED 0x00100000
  1003. #define NOTIFICATION_FLAG_GROUPED_EVENT 0x00200000
  1004. //
  1005. // These are the flags contained in DcRef->Flags that pertain to Notifications
  1006. #define NOTIFICATION_MASK_EVENT_FLAGS \
  1007. (NOTIFICATION_FLAG_CALLBACK_DIRECT | \
  1008. NOTIFICATION_FLAG_CALLBACK_QUEUED | \
  1009. NOTIFICATION_FLAG_WINDOW | \
  1010. DCREF_FLAG_NO_EXTRA_THREAD | \
  1011. DCREF_FLAG_ANSI)
  1012. //
  1013. // This defines the number of DC references a NOTIFICATIONENTRY can have
  1014. // in a single entry
  1015. // CONSIDER: Merging NOTIFICATIONENTRY with GUIDENTRY
  1016. #define DCREFPERNOTIFICATION 16
  1017. typedef struct _notificationentry
  1018. {
  1019. LIST_ENTRY MainNotificationList; // Node in main notifications list
  1020. PCHUNKHEADER Chunk; // Chunk in which entry is located
  1021. ULONG Flags; // flags
  1022. ULONG RefCount;
  1023. // Signature to identify entry
  1024. ULONG Signature;
  1025. GUID Guid; // guid representing notification
  1026. // If > DCREFPERNOTIFICATION DC have
  1027. // enabled this event then this points
  1028. // to another NOTIFICATIONENTRY which
  1029. // has another DCREF array
  1030. struct _notificationentry *Continuation;
  1031. ULONG EventRefCount; // Global count of event enables
  1032. ULONG CollectRefCount; // Global count of collection enables
  1033. ULONG64 LoggerContext; // Logger context handle
  1034. HANDLE CollectInProgress; // Event set when all collect complete
  1035. DCREF DcRef[DCREFPERNOTIFICATION]; // DC that have enabled this event
  1036. } NOTIFICATIONENTRY, *PNOTIFICATIONENTRY;
  1037. #define NE_SIGNATURE 'eluJ'
  1038. // Set when a notification request is being processed by the data providers
  1039. #define NE_FLAG_NOTIFICATION_IN_PROGRESS 0x00000001
  1040. // Set when a collection request is being processed by the data providers
  1041. #define NE_FLAG_COLLECTION_IN_PROGRESS 0x00000002
  1042. // Set when a trace disable is being processed by a worker thread
  1043. #define NE_FLAG_TRACEDISABLE_IN_PROGRESS 0x00000004
  1044. #ifdef WMI_USER_MODE
  1045. //
  1046. // Valid MOF data types for qualifiers and properties (data items)
  1047. typedef enum
  1048. {
  1049. MOFInt32 = 0, // 32bit integer
  1050. MOFUInt32 = 1, // 32bit unsigned integer
  1051. MOFInt64 = 2, // 64bit integer
  1052. MOFUInt64 = 3, // 32bit unsigned integer
  1053. MOFInt16 = 4, // 16bit integer
  1054. MOFUInt16 = 5, // 16bit unsigned integer
  1055. MOFChar = 6, // 8bit integer
  1056. MOFByte = 7, // 8bit unsigned integer
  1057. MOFWChar = 8, // Wide (16bit) character
  1058. MOFDate = 9, // Date field
  1059. MOFBoolean = 10, // 8bit Boolean value
  1060. MOFEmbedded = 11, // Embedded class
  1061. MOFString = 12, // Counted String type
  1062. MOFZTString = 13, // NULL terminated unicode string
  1063. MOFAnsiString = 14, // NULL terminated ansi string
  1064. MOFUnknown = 0xffffffff // Data type is not known
  1065. } MOFDATATYPE, *PMOFDATATYPE;
  1066. // Data items that are of type MOFString are stored in the data block as a
  1067. // counted unicode string. The text of the string is always preceeded by
  1068. // a USHORT which contains the count of bytes following that composes the
  1069. // string. The string may be NULL terminated and in that case the count must
  1070. // include the null termination bytes.
  1071. // Data items that are of type MOFDate are fixed length Unicode strings and
  1072. // not preceeded by a count value. It is in the following fixed format:
  1073. //
  1074. // yyyymmddhhmmss.mmmmmmsutc
  1075. //
  1076. // Where yyyy is a 4 digit year, mm is the month, dd is the day, hh is
  1077. // the hour (24-hour clock), mm is the minute, ss is the second, the
  1078. // mmmmmm is the number of microseconds (typically all zeros) and s is a
  1079. // "+" or "-" indicating the sign of the UTC (correction field, and utc
  1080. // is the offset from UTC in minutes (using the sign indicated by s).
  1081. // For example, Wednesday, May 25, 1994, at 1:30:15 PM EDT would be
  1082. // represented as:
  1083. //
  1084. // 19940525133015.0000000-300
  1085. //
  1086. // Values MUST be zero-padded so that the entire string is always the
  1087. // same 25-character length. Fields which are not significant MUST be
  1088. // replaced with asterisk characters. Similarly, intervals use the
  1089. // same format, except that the interpretation of the fields is based
  1090. // on elapsed time. For example, an elapsed time of 1 day, 13 hours,
  1091. // 23 minutes, and 12 seconds would be:
  1092. //
  1093. // 00000001132312.000000+000
  1094. //
  1095. // A UTC offset of zero is always used for interval properties.
  1096. struct _MOFCLASSINFOW;
  1097. struct _MOFCLASSINFOA;
  1098. //
  1099. // Each class has one or more data items that are described by a MOFDATAITEM
  1100. // structure.
  1101. typedef struct
  1102. {
  1103. #ifdef MIDL_PASS
  1104. [string] PDFWCHAR
  1105. #else
  1106. LPWSTR
  1107. #endif
  1108. Name; // Text name of data item
  1109. #ifdef MIDL_PASS
  1110. [string] PDFWCHAR
  1111. #else
  1112. LPWSTR
  1113. #endif
  1114. Description; // Text description of data item
  1115. MOFDATATYPE DataType; // MOF data type
  1116. ULONG Version; // Version that this MOF is part of
  1117. ULONG SizeInBytes; // Size of data item in Blob
  1118. ULONG Flags; // Flags, See MOFDI_FLAG_*
  1119. GUID EmbeddedClassGuid; // Guid of data item's embedded class
  1120. ULONG FixedArrayElements; // Number of elements in fixed sized array
  1121. // Used when MOF_FLAG_FIXED_ARRAY is set
  1122. ULONG VariableArraySizeId; // MOF_FLAG_VARIABLE_ARRAY, Data id of
  1123. // variable containing number of elements
  1124. // in array
  1125. PVOID VarArrayTempPtr;
  1126. PVOID EcTempPtr;
  1127. ULONG_PTR PropertyQualifierHandle;
  1128. ULONG MethodId;
  1129. LPWSTR HeaderName;// Name of structure in generated header
  1130. struct _MOFCLASSINFOW *MethodClassInfo;
  1131. } MOFDATAITEMW, *PMOFDATAITEMW;
  1132. typedef struct
  1133. {
  1134. LPSTR
  1135. Name; // Text name of data item
  1136. LPSTR
  1137. Description; // Text description of data item
  1138. MOFDATATYPE DataType; // MOF data type
  1139. ULONG Version; // Version that this MOF is part of
  1140. ULONG SizeInBytes; // Size of data item in Blob
  1141. ULONG Flags; // Flags, See MOFDI_FLAG_*
  1142. GUID EmbeddedClassGuid; // Guid of data item's embedded class
  1143. ULONG FixedArrayElements; // Number of elements in fixed sized array
  1144. // Used when MOF_FLAG_FIXED_ARRAY is set
  1145. ULONG VariableArraySizeId; // MOF_FLAG_VARIABLE_ARRAY, Data id of
  1146. // variable containing number of elements
  1147. // in array
  1148. PVOID VarArrayTempPtr;
  1149. PVOID EcTempPtr;
  1150. ULONG_PTR PropertyQualifierHandle;
  1151. ULONG MethodId;
  1152. LPSTR HeaderName; // Name of structure in generated header
  1153. struct _MOFCLASSINFOA *MethodClassInfo;
  1154. } MOFDATAITEMA, *PMOFDATAITEMA;
  1155. #ifdef UNICODE
  1156. typedef MOFDATAITEMW MOFDATAITEM;
  1157. typedef PMOFDATAITEMW PMOFDATAITEM;
  1158. #else
  1159. typedef MOFDATAITEMA MOFDATAITEM;
  1160. typedef PMOFDATAITEMA PMOFDATAITEM;
  1161. #endif
  1162. // Data item is actually a fixed sized array
  1163. #define MOFDI_FLAG_FIXED_ARRAY 0x00000001
  1164. // Data item is actually a variable length array
  1165. #define MOFDI_FLAG_VARIABLE_ARRAY 0x00000002
  1166. // Data item is actually an embedded class
  1167. #define MOFDI_FLAG_EMBEDDED_CLASS 0x00000004
  1168. // Data item is readable
  1169. #define MOFDI_FLAG_READABLE 0x00000008
  1170. // Data item is writable
  1171. #define MOFDI_FLAG_WRITEABLE 0x00000010
  1172. // Data item is an event
  1173. #define MOFDI_FLAG_EVENT 0x00000020
  1174. // Embedded class Guid is not set
  1175. #define MOFDI_FLAG_EC_GUID_NOT_SET 0x00000040
  1176. // Data item is really a method
  1177. #define MOFDI_FLAG_METHOD 0x00000080
  1178. // Data item is an input method parameter
  1179. #define MOFDI_FLAG_INPUT_METHOD 0x00000100
  1180. // Data item is an output method parameter
  1181. #define MOFDI_FLAG_OUTPUT_METHOD 0x00000200
  1182. //
  1183. // The MOFCLASSINFO structure describes the format of a data block
  1184. typedef struct _MOFCLASSINFOW
  1185. {
  1186. GUID Guid; // Guid that represents class
  1187. #ifdef MIDL_PASS
  1188. [string] PDFWCHAR
  1189. #else
  1190. LPWSTR
  1191. #endif
  1192. Name; // Text name of class
  1193. #ifdef MIDL_PASS
  1194. [string] PDFWCHAR
  1195. #else
  1196. LPWSTR
  1197. #endif
  1198. Description;// Text description of class
  1199. #ifdef MIDL_PASS
  1200. [string] PDFWCHAR
  1201. #else
  1202. LPWSTR
  1203. #endif
  1204. HeaderName;// Name of structure in generated header
  1205. #ifdef MIDL_PASS
  1206. [string] PDFWCHAR
  1207. #else
  1208. LPWSTR
  1209. #endif
  1210. GuidName1;// Name of Guid in generated header
  1211. #ifdef MIDL_PASS
  1212. [string] PDFWCHAR
  1213. #else
  1214. LPWSTR
  1215. #endif
  1216. GuidName2;// Name of Guid in generated header
  1217. USHORT Language; // Language of MOF
  1218. USHORT Reserved;
  1219. ULONG Flags; // Flags, see MOFGI_FLAG_*
  1220. ULONG Version; // Version of Guid
  1221. ULONG DataItemCount; // Number of wmi data items (properties)
  1222. ULONG MethodCount; // Number of wmi data items (properties)
  1223. // Array of Property info
  1224. #ifdef MIDL_PASS
  1225. [size_is(DataItemCount)]
  1226. #endif
  1227. MOFDATAITEMW *DataItems;
  1228. #ifndef MIDL_PASS
  1229. UCHAR Tail[1];
  1230. #endif
  1231. } MOFCLASSINFOW, *PMOFCLASSINFOW;
  1232. typedef struct _MOFCLASSINFOA
  1233. {
  1234. GUID Guid; // Guid that represents class
  1235. LPSTR
  1236. Name; // Text name of class
  1237. LPSTR
  1238. Description;// Text description of class
  1239. LPSTR
  1240. HeaderName;// Name of structure in generated header
  1241. LPSTR
  1242. GuidName1;// Name of Guid in generated header
  1243. LPSTR
  1244. GuidName2;// Name of Guid in generated header
  1245. USHORT Language; // Language of MOF
  1246. USHORT Reserved;
  1247. ULONG Flags; // Flags, see MOFGI_FLAG_*
  1248. ULONG Version; // Version of Guid
  1249. ULONG DataItemCount; // Number of wmi data items (properties)
  1250. ULONG MethodCount; // Number of wmi data items (properties)
  1251. // Array of Property info
  1252. MOFDATAITEMA *DataItems;
  1253. UCHAR Tail[1];
  1254. } MOFCLASSINFOA, *PMOFCLASSINFOA;
  1255. #ifdef UNICODE
  1256. typedef MOFCLASSINFOW MOFCLASSINFO;
  1257. typedef PMOFCLASSINFOW PMOFCLASSINFO;
  1258. #else
  1259. typedef MOFCLASSINFOA MOFCLASSINFO;
  1260. typedef PMOFCLASSINFOA PMOFCLASSINFO;
  1261. #endif
  1262. // 0x00000001 to 0x00000004 are not available
  1263. #define MOFCI_FLAG_EVENT 0x10000000
  1264. #define MOFCI_FLAG_EMBEDDED_CLASS 0x20000000
  1265. #define MOFCI_FLAG_READONLY 0x40000000
  1266. #define MOFCI_FLAG_METHOD_PARAMS 0x80000000
  1267. typedef struct
  1268. {
  1269. union
  1270. {
  1271. // Entry in list of all DS
  1272. LIST_ENTRY MainMCList;
  1273. // Entry in list of free DS
  1274. LIST_ENTRY FreeMCList;
  1275. };
  1276. PCHUNKHEADER Chunk; // Chunk in which entry is located
  1277. ULONG Flags;
  1278. ULONG RefCount;
  1279. PMOFCLASSINFOW MofClassInfo; // Actual class info data
  1280. LIST_ENTRY MCMRList; // Entry in list of MCs in a MR
  1281. LIST_ENTRY MCVersionList; // Head or entry in list of MCs with
  1282. // same guid, but possibly different versions
  1283. ULONG_PTR ClassObjectHandle; // CBMOFObj, BMOF class object ptr
  1284. PMOFRESOURCE MofResource; // Resource holding class info
  1285. } MOFCLASS, *PMOFCLASS;
  1286. // If this is set then the MOF class can never be replaced with a later version
  1287. #define MC_FLAG_NEVER_REPLACE 0x00000001
  1288. #endif
  1289. //
  1290. // AVGGUIDSPERDS defines a guess as to the number of guids that get registered
  1291. // by any data provider. It is used to allocate the buffer used to deliver
  1292. // registration change notifications.
  1293. #if DBG
  1294. #define AVGGUIDSPERDS 2
  1295. #else
  1296. #define AVGGUIDSPERDS 256
  1297. #endif
  1298. #define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)(Base) + (Offset)))
  1299. //
  1300. // Guid and InstanceSet cache
  1301. #if DBG
  1302. #define PTRCACHEGROWSIZE 2
  1303. #else
  1304. #define PTRCACHEGROWSIZE 64
  1305. #endif
  1306. typedef struct
  1307. {
  1308. LPGUID Guid;
  1309. PBINSTANCESET InstanceSet;
  1310. } PTRCACHE;
  1311. //
  1312. // Registration data structures
  1313. //
  1314. #ifdef MEMPHIS
  1315. extern HANDLE SMMutex;
  1316. #define WmipEnterSMCritSection() WaitForSingleObject(SMMutex, INFINITE)
  1317. #define WmipLeaveSMCritSection() ReleaseMutex(SMMutex)
  1318. #else
  1319. extern RTL_CRITICAL_SECTION SMCritSect;
  1320. #if DBG
  1321. #ifdef CRITSECTTRACE
  1322. #define WmipEnterSMCritSection() { \
  1323. WmipDebugPrint(("WMI: %d Enter SM Crit %s %d\n", GetCurrentThreadId(), __FILE__, __LINE__)); \
  1324. RtlEnterCriticalSection(&SMCritSect); }
  1325. #define WmipLeaveSMCritSection() { \
  1326. WmipDebugPrint(("WMI: %d Leave SM Crit %s %d\n", GetCurrentThreadId(), __FILE__, __LINE__)); \
  1327. RtlLeaveCriticalSection(&SMCritSect); }
  1328. #else
  1329. #define WmipEnterSMCritSection() \
  1330. WmipAssert(NT_SUCCESS(RtlEnterCriticalSection(&SMCritSect)));
  1331. #define WmipLeaveSMCritSection() { \
  1332. WmipAssert(SMCritSect.LockCount >= 0); \
  1333. WmipAssert(NT_SUCCESS(RtlLeaveCriticalSection(&SMCritSect))); }
  1334. #endif // CRITSECTTRACE
  1335. #else
  1336. #define WmipEnterSMCritSection() RtlEnterCriticalSection(&SMCritSect)
  1337. #define WmipLeaveSMCritSection() RtlLeaveCriticalSection(&SMCritSect)
  1338. #endif // DBG
  1339. #endif // MEMPHIS
  1340. #ifndef IsEqualGUID
  1341. #define IsEqualGUID(guid1, guid2) \
  1342. (!memcmp((guid1), (guid2), sizeof(GUID)))
  1343. #endif
  1344. //
  1345. // WMI MOF result codes. Since they are never given to the caller they are
  1346. // defined in here
  1347. #define ERROR_WMIMOF_INCORRECT_DATA_TYPE -1 /* 0xffffffff */
  1348. #define ERROR_WMIMOF_NO_DATA -2 /* 0xfffffffe */
  1349. #define ERROR_WMIMOF_NOT_FOUND -3 /* 0xfffffffd */
  1350. #define ERROR_WMIMOF_UNUSED -4 /* 0xfffffffc */
  1351. // Property %ws in class %ws has no embedded class name
  1352. #define ERROR_WMIMOF_NO_EMBEDDED_CLASS_NAME -5 /* 0xfffffffb */
  1353. // Property %ws in class %ws has an unknown data type
  1354. #define ERROR_WMIMOF_UNKNOWN_DATA_TYPE -6 /* 0xfffffffa */
  1355. // Property %ws in class %ws has no syntax qualifier
  1356. #define ERROR_WMIMOF_NO_SYNTAX_QUALIFIER -7 /* 0xfffffff9 */
  1357. #define ERROR_WMIMOF_NO_CLASS_NAME -8 /* 0xfffffff8 */
  1358. #define ERROR_WMIMOF_BAD_DATA_FORMAT -9 /* 0xfffffff7 */
  1359. // Property %ws in class %ws has the same WmiDataId %d as property %ws
  1360. #define ERROR_WMIMOF_DUPLICATE_ID -10 /* 0xfffffff6 */
  1361. // Property %ws in class %ws has a WmiDataId of %d which is out of range
  1362. #define ERROR_WMIMOF_BAD_DATAITEM_ID -11 /* 0xfffffff5 */
  1363. #define ERROR_WMIMOF_MISSING_DATAITEM -12 /* 0xfffffff4 */
  1364. // Property for WmiDataId %d is not defined in class %ws
  1365. #define ERROR_WMIMOF_DATAITEM_NOT_FOUND -13 /* 0xfffffff3 */
  1366. // Embedded class %ws not defined for Property %ws in Class %ws
  1367. #define ERROR_WMIMOF_EMBEDDED_CLASS_NOT_FOUND -14 /* 0xfffffff2 */
  1368. // Property %ws in class %ws has an incorrect [WmiVersion] qualifier
  1369. #define ERROR_WMIMOF_INCONSISTENT_VERSIONING -15 /* 0xfffffff1 */
  1370. #define ERROR_WMIMOF_NO_PROPERTY_QUALIFERS -16 /* 0xfffffff0 */
  1371. // Class %ws has a badly formed or missing [guid] qualifier
  1372. #define ERROR_WMIMOF_BAD_OR_MISSING_GUID -17 /* 0xffffffef */
  1373. // Could not find property %ws which is the array size for property %ws in class %ws
  1374. #define ERROR_WMIMOF_VL_ARRAY_SIZE_NOT_FOUND -18 /* 0xffffffee */
  1375. // A class could not be parsed properly
  1376. #define ERROR_WMIMOF_CLASS_NOT_PARSED -19 /* 0xffffffed */
  1377. // Wmi class %ws requires the qualifiers [Dynamic, Provider("WmiProv")]
  1378. #define ERROR_WMIMOF_MISSING_HMOM_QUALIFIERS -20 /* 0xffffffec */
  1379. // Error accessing binary mof file %s
  1380. #define ERROR_WMIMOF_CANT_ACCESS_FILE -21 /* 0xffffffeb */
  1381. // Property InstanceName in class %ws must be type string and not %ws
  1382. #define ERROR_WMIMOF_INSTANCENAME_BAD_TYPE -22 /* 0xffffffea */
  1383. // Property Active in class %ws must be type bool and not %ws
  1384. #define ERROR_WMIMOF_ACTIVE_BAD_TYPE -23 /* 0xffffffe9 */
  1385. // Property %ws in class %ws does not have [WmiDataId()] qualifier
  1386. #define ERROR_WMIMOF_NO_WMIDATAID -24 /* 0xffffffe8 */
  1387. // Property InstanceName in class %ws must have [key] qualifier
  1388. #define ERROR_WMIMOF_INSTANCENAME_NOT_KEY -25 /* 0xffffffe7 */
  1389. // Class %ws does not have an InstanceName qualifier
  1390. #define ERROR_WMIMOF_NO_INSTANCENAME -26 /* 0xffffffe6 */
  1391. // Class %ws does not have an Active qualifier
  1392. #define ERROR_WMIMOF_NO_ACTIVE -27 /* 0xffffffe5 */
  1393. // Property %ws in class %ws is an array, but doesn't specify a dimension
  1394. #define ERROR_WMIMOF_MUST_DIM_ARRAY -28 /* 0xffffffe4 */
  1395. // The element count property %ws for the variable length array %ws in class %ws is not an integral type
  1396. #define ERROR_WMIMOF_BAD_VL_ARRAY_SIZE_TYPE -29 /* 0xdddddde4 */
  1397. // Property %ws in class %ws is both a fixed and variable length array
  1398. #define ERROR_WMIMOF_BOTH_FIXED_AND_VARIABLE_ARRAY -30 /* 0xffffffe3 */
  1399. // Embedded class %ws should not have InstaneName or Active properties
  1400. #define ERROR_WMIMOF_EMBEDDED_CLASS -31 /* 0xffffffe2 */
  1401. #define ERROR_WMIMOF_IMPLEMENTED_REQUIRED -32 /* 0xffffffe1 */
  1402. // TEXT("WmiMethodId for method %ws in class %ws must be unique")
  1403. #define ERROR_WMIMOF_DUPLICATE_METHODID -33 /* 0xffffffe0 */
  1404. // TEXT("WmiMethodId for method %ws in class %ws must be specified")
  1405. #define ERROR_WMIMOF_MISSING_METHODID -34 /* 0xffffffdf */
  1406. // TEXT("WmiMethodId for method %ws in class %ws must not be 0")
  1407. #define ERROR_WMIMOF_METHODID_ZERO -35 /* 0xffffffde */
  1408. // TEXT("Class %ws is derived from WmiEvent and may not be [abstract]")
  1409. #define ERROR_WMIMOF_WMIEVENT_ABSTRACT -36 /* 0xffffffdd */
  1410. #define ERROR_WMIMOF_COUNT 36
  1411. // This file is not a valid binary mof file
  1412. // ERROR_WMI_INVALID_MOF
  1413. // There was not enough memory to complete an operation
  1414. // ERROR_NOT_ENOUGH_MEMORY
  1415. //
  1416. // Function prototypes for private functions
  1417. //
  1418. // sharemem.c
  1419. ULONG WmipEstablishSharedMemory(
  1420. PBDATASOURCE DataSource,
  1421. LPCTSTR SectionName,
  1422. ULONG SectionSize
  1423. );
  1424. //
  1425. // validate.c
  1426. BOOLEAN WmipValidateCountedString(
  1427. WCHAR *String
  1428. );
  1429. BOOLEAN WmipValidateGuid(
  1430. LPGUID Guid
  1431. );
  1432. BOOLEAN WmipProbeForRead(
  1433. PUCHAR Buffer,
  1434. ULONG BufferSize
  1435. );
  1436. //
  1437. // alloc.c
  1438. extern LIST_ENTRY GEHead;
  1439. extern PLIST_ENTRY GEHeadPtr;
  1440. extern CHUNKINFO GEChunkInfo;
  1441. extern LIST_ENTRY NEHead;
  1442. extern PLIST_ENTRY NEHeadPtr;
  1443. extern CHUNKINFO NEChunkInfo;
  1444. extern LIST_ENTRY DSHead;
  1445. extern PLIST_ENTRY DSHeadPtr;
  1446. extern CHUNKINFO DSChunkInfo;
  1447. extern LIST_ENTRY DCHead;
  1448. extern PLIST_ENTRY DCHeadPtr;
  1449. extern CHUNKINFO DCChunkInfo;
  1450. extern LIST_ENTRY MRHead;
  1451. extern PLIST_ENTRY MRHeadPtr;
  1452. extern CHUNKINFO MRChunkInfo;
  1453. extern CHUNKINFO ISChunkInfo;
  1454. extern LIST_ENTRY GMHead;
  1455. extern PLIST_ENTRY GMHeadPtr;
  1456. #ifdef WMI_USER_MODE
  1457. extern LIST_ENTRY MCHead;
  1458. extern PLIST_ENTRY MCHeadPtr;
  1459. extern CHUNKINFO MCChunkInfo;
  1460. #endif
  1461. #ifdef TRACK_REFERNECES
  1462. #define WmipUnreferenceDS(DataSource) \
  1463. { \
  1464. WmipDebugPrint(("WMI: Unref DS %x at %s %d\n", DataSource, __FILE__, __LINE__)); \
  1465. WmipUnreferenceEntry(&DSChunkInfo, (PENTRYHEADER)DataSource); \
  1466. }
  1467. #define WmipReferenceDS(DataSource) \
  1468. { \
  1469. WmipDebugPrint(("WMI: Ref DS %x at %s %d\n", DataSource, __FILE__, __LINE__)); \
  1470. WmipReferenceEntry((PENTRYHEADER)DataSource); \
  1471. }
  1472. #define WmipUnreferenceGE(GuidEntry) \
  1473. { \
  1474. WmipDebugPrint(("WMI: Unref GE %x at %s %d\n", GuidEntry, __FILE__, __LINE__)); \
  1475. WmipUnreferenceEntry(&GEChunkInfo, (PENTRYHEADER)GuidEntry); \
  1476. }
  1477. #define WmipReferenceGE(GuidEntry) \
  1478. { \
  1479. WmipDebugPrint(("WMI: Ref GE %x at %s %d\n", GuidEntry, __FILE__, __LINE__)); \
  1480. WmipReferenceEntry((PENTRYHEADER)GuidEntry); \
  1481. }
  1482. #define WmipUnreferenceIS(InstanceSet) \
  1483. { \
  1484. WmipDebugPrint(("WMI: Unref IS %x at %s %d\n", InstanceSet, __FILE__, __LINE__)); \
  1485. WmipUnreferenceEntry(&ISChunkInfo, (PENTRYHEADER)InstanceSet); \
  1486. }
  1487. #define WmipReferenceIS(InstanceSet) \
  1488. { \
  1489. WmipDebugPrint(("WMI: Ref IS %x at %s %d\n", InstanceSet, __FILE__, __LINE__)); \
  1490. WmipReferenceEntry((PENTRYHEADER)InstanceSet); \
  1491. }
  1492. #define WmipUnreferenceDC(DataConsumer) \
  1493. { \
  1494. WmipDebugPrint(("WMI: Unref DC %x at %s %d\n", DataConsumer, __FILE__, __LINE__)); \
  1495. WmipUnreferenceEntry(&DCChunkInfo, (PENTRYHEADER)DataConsumer); \
  1496. }
  1497. #define WmipReferenceDC(DataConsumer) \
  1498. { \
  1499. WmipDebugPrint(("WMI: Ref DC %x at %s %d\n", DataConsumer, __FILE__, __LINE__)); \
  1500. WmipReferenceEntry((PENTRYHEADER)DataConsumer); \
  1501. }
  1502. #define WmipUnreferenceNE(NotificationEntry) \
  1503. { \
  1504. WmipDebugPrint(("WMI: Unref NE %x at %s %d\n", NotificationEntry, __FILE__, __LINE__)); \
  1505. WmipUnreferenceEntry(&NEChunkInfo, (PENTRYHEADER)NotificationEntry); \
  1506. }
  1507. #define WmipReferenceNE(NotificationEntry) \
  1508. { \
  1509. WmipDebugPrint(("WMI: Ref NE %x at %s %d\n", NotificationEntry, __FILE__, __LINE__)); \
  1510. WmipReferenceEntry((PENTRYHEADER)NotificationEntry); \
  1511. }
  1512. #define WmipUnreferenceMR(MofResource) \
  1513. { \
  1514. WmipDebugPrint(("WMI: Unref MR %x at %s %d\n", MofResource, __FILE__, __LINE__)); \
  1515. WmipUnreferenceEntry(&MRChunkInfo, (PENTRYHEADER)MofResource); \
  1516. }
  1517. #define WmipReferenceMR(MofResource) \
  1518. { \
  1519. WmipDebugPrint(("WMI: Ref MR %x at %s %d\n", MofResource, __FILE__, __LINE__)); \
  1520. WmipReferenceEntry((PENTRYHEADER)MofResource); \
  1521. }
  1522. #ifdef WMI_USER_MODE
  1523. #define WmipUnreferenceMC(MofClass) \
  1524. { \
  1525. WmipDebugPrint(("WMI: Unref MC %x at %s %d\n", MofClass, __FILE__, __LINE__)); \
  1526. WmipUnreferenceEntry(&MCChunkInfo, (PENTRYHEADER)MofClass); \
  1527. }
  1528. #define WmipReferenceMC(MofClass) \
  1529. { \
  1530. WmipDebugPrint(("WMI: Ref MC %x at %s %d\n", MofClass, __FILE__, __LINE__)); \
  1531. WmipReferenceEntry((PENTRYHEADER)MofClass); \
  1532. }
  1533. #endif
  1534. #else
  1535. #define WmipUnreferenceDS(DataSource) \
  1536. WmipUnreferenceEntry(&DSChunkInfo, (PENTRYHEADER)DataSource)
  1537. #define WmipReferenceDS(DataSource) \
  1538. WmipReferenceEntry((PENTRYHEADER)DataSource)
  1539. #define WmipUnreferenceGE(GuidEntry) \
  1540. WmipUnreferenceEntry(&GEChunkInfo, (PENTRYHEADER)GuidEntry)
  1541. #define WmipReferenceGE(GuidEntry) \
  1542. WmipReferenceEntry((PENTRYHEADER)GuidEntry)
  1543. #define WmipUnreferenceIS(InstanceSet) \
  1544. WmipUnreferenceEntry(&ISChunkInfo, (PENTRYHEADER)InstanceSet)
  1545. #define WmipReferenceIS(InstanceSet) \
  1546. WmipReferenceEntry((PENTRYHEADER)InstanceSet)
  1547. #define WmipUnreferenceDC(DataConsumer) \
  1548. WmipUnreferenceEntry(&DCChunkInfo, (PENTRYHEADER)DataConsumer)
  1549. #define WmipReferenceDC(DataConsumer) \
  1550. WmipReferenceEntry((PENTRYHEADER)DataConsumer)
  1551. #define WmipUnreferenceNE(NotificationEntry) \
  1552. WmipUnreferenceEntry(&NEChunkInfo, (PENTRYHEADER)NotificationEntry)
  1553. #define WmipReferenceNE(NotificationEntry) \
  1554. WmipReferenceEntry((PENTRYHEADER)NotificationEntry)
  1555. #define WmipUnreferenceMR(MofResource) \
  1556. WmipUnreferenceEntry(&MRChunkInfo, (PENTRYHEADER)MofResource)
  1557. #define WmipReferenceMR(MofResource) \
  1558. WmipReferenceEntry((PENTRYHEADER)MofResource)
  1559. #ifdef WMI_USER_MODE
  1560. #define WmipUnreferenceMC(MofClass) \
  1561. WmipUnreferenceEntry(&MCChunkInfo, (PENTRYHEADER)MofClass)
  1562. #define WmipReferenceMC(MofClass) \
  1563. WmipReferenceEntry((PENTRYHEADER)MofClass)
  1564. #endif
  1565. #endif
  1566. PBDATASOURCE WmipAllocDataSource(
  1567. void
  1568. );
  1569. PBGUIDENTRY WmipAllocGuidEntry(
  1570. void
  1571. );
  1572. #define WmipAllocInstanceSet() ((PBINSTANCESET)WmipAllocEntry(&ISChunkInfo))
  1573. #define WmipAllocDataConsumer() ((PDCENTRY)WmipAllocEntry(&DCChunkInfo))
  1574. #define WmipAllocNotificationEntry() ((PNOTIFICATIONENTRY)WmipAllocEntry(&NEChunkInfo))
  1575. #define WmipAllocMofResource() ((PMOFRESOURCE)WmipAllocEntry(&MRChunkInfo))
  1576. #ifdef WMI_USER_MODE
  1577. #define WmipAllocMofClass() ((PMOFCLASS)WmipAllocEntry(&MCChunkInfo))
  1578. #endif
  1579. #define WmipAllocString(Size) \
  1580. WmipAlloc((Size)*sizeof(WCHAR))
  1581. #define WmipFreeString(Ptr) \
  1582. WmipFree(Ptr)
  1583. #ifdef MEMPHIS
  1584. #define WmipAlloc(Size) \
  1585. malloc(Size)
  1586. #define WmipFree(Ptr) \
  1587. free(Ptr)
  1588. #define WmipInitProcessHeap()
  1589. #else
  1590. //
  1591. // Reserve 1MB for WMI.DLL, but only commit 16K initially
  1592. #define DLLRESERVEDHEAPSIZE 1024 * 1024
  1593. #define DLLCOMMITHEAPSIZE 0 * 1024
  1594. //
  1595. // Reserve 1MB for WMI service, but only commit 16K initially
  1596. #define CORERESERVEDHEAPSIZE 1024 * 1024
  1597. #define CORECOMMITHEAPSIZE 16 * 1024
  1598. extern PVOID WmipProcessHeap;
  1599. #define WmipInitProcessHeap() \
  1600. { \
  1601. if (WmipProcessHeap == NULL) \
  1602. { \
  1603. WmipCreateHeap(); \
  1604. } \
  1605. }
  1606. #ifdef HEAPVALIDATION
  1607. PVOID WmipAlloc(
  1608. ULONG Size
  1609. );
  1610. void WmipFree(
  1611. PVOID p
  1612. );
  1613. #else
  1614. #if DBG
  1615. _inline PVOID WmipAlloc(ULONG Size)
  1616. {
  1617. WmipAssert(WmipProcessHeap != NULL);
  1618. return(RtlAllocateHeap(WmipProcessHeap, 0, Size));
  1619. }
  1620. _inline void WmipFree(PVOID Ptr)
  1621. {
  1622. RtlFreeHeap(WmipProcessHeap, 0, Ptr);
  1623. }
  1624. #else
  1625. #define WmipAlloc(Size) \
  1626. RtlAllocateHeap(WmipProcessHeap, 0, Size)
  1627. #define WmipFree(Ptr) \
  1628. RtlFreeHeap(WmipProcessHeap, 0, Ptr)
  1629. #endif
  1630. #endif
  1631. #endif
  1632. BOOLEAN WmipRealloc(
  1633. PVOID *Buffer,
  1634. ULONG CurrentSize,
  1635. ULONG NewSize,
  1636. BOOLEAN FreeOriginalBuffer
  1637. );
  1638. //
  1639. // datastr.c
  1640. extern GUID WmipBinaryMofGuid;
  1641. void WmipGenerateBinaryMofNotification(
  1642. PBINSTANCESET BianryMofInstanceSet,
  1643. LPCGUID Guid
  1644. );
  1645. BOOLEAN WmipEstablishInstanceSetRef(
  1646. PBDATASOURCE DataSourceRef,
  1647. LPGUID Guid,
  1648. PBINSTANCESET InstanceSet
  1649. );
  1650. ULONG WmipAddDataSource(
  1651. PTCHAR QueryBinding,
  1652. ULONG RequestAddress,
  1653. ULONG RequestContext,
  1654. LPCTSTR ImagePath,
  1655. PWMIREGINFOW RegistrationInfo,
  1656. ULONG RegistrationInfoSize,
  1657. ULONG_PTR *ProviderId,
  1658. BOOLEAN IsAnsi
  1659. );
  1660. ULONG WmipUpdateAddGuid(
  1661. PBDATASOURCE DataSource,
  1662. PWMIREGGUID RegGuid,
  1663. PWMIREGINFO RegistrationInfo,
  1664. PBINSTANCESET *AddModInstanceSet
  1665. );
  1666. ULONG WmipUpdateModifyGuid(
  1667. PBDATASOURCE DataSource,
  1668. PWMIREGGUID RegGuid,
  1669. PWMIREGINFO RegistrationInfo,
  1670. PBINSTANCESET *AddModInstanceSet
  1671. );
  1672. BOOLEAN WmipUpdateRemoveGuid(
  1673. PBDATASOURCE DataSource,
  1674. PWMIREGGUID RegGuid,
  1675. PBINSTANCESET *AddModInstanceSet
  1676. );
  1677. void WmipUpdateDataSource(
  1678. ULONG_PTR ProviderId,
  1679. PWMIREGINFOW RegistrationInfo,
  1680. ULONG RetSize
  1681. );
  1682. void WmipRemoveDataSource(
  1683. ULONG_PTR ProviderId
  1684. );
  1685. void WmipRemoveDataSourceByDS(
  1686. PBDATASOURCE DataSource
  1687. );
  1688. ULONG WmipRegisterInternalDataSource(
  1689. void
  1690. );
  1691. PBGUIDENTRY WmipFindGEByGuid(
  1692. LPGUID Guid,
  1693. BOOLEAN MakeTopOfList
  1694. );
  1695. PBINSTANCESET WmipFindISInDSByGuid(
  1696. PBDATASOURCE DataSource,
  1697. LPGUID Guid
  1698. );
  1699. PNOTIFICATIONENTRY WmipFindNEByGuid(
  1700. GUID UNALIGNED *Guid,
  1701. BOOLEAN MakeTopOfList
  1702. );
  1703. PDCREF WmipFindExistingAndFreeDCRefInNE(
  1704. PNOTIFICATIONENTRY NotificationEntry,
  1705. PDCENTRY DataConsumer,
  1706. PDCREF *FreeDcRef
  1707. );
  1708. PDCREF WmipFindDCRefInNE(
  1709. PNOTIFICATIONENTRY NotificationEntry,
  1710. PDCENTRY DataConsumer
  1711. );
  1712. PBDATASOURCE WmipFindDSByProviderId(
  1713. ULONG_PTR ProviderId
  1714. );
  1715. PBINSTANCESET WmipFindISByGuid(
  1716. PBDATASOURCE DataSource,
  1717. GUID UNALIGNED *Guid
  1718. );
  1719. PMOFRESOURCE WmipFindMRByNames(
  1720. LPCWSTR ImagePath,
  1721. LPCWSTR MofResourceName
  1722. );
  1723. #ifdef WMI_USER_MODE
  1724. PMOFCLASS WmipFindMCByGuid(
  1725. LPGUID Guid
  1726. );
  1727. PMOFCLASS WmipFindMCByGuidAndBestLanguage(
  1728. LPGUID Guid,
  1729. WORD Language
  1730. );
  1731. PMOFCLASS WmipFindMCByGuidAndLanguage(
  1732. LPGUID Guid,
  1733. WORD Language
  1734. );
  1735. #endif
  1736. PBINSTANCESET WmipFindISinGEbyName(
  1737. PBGUIDENTRY GuidEntry,
  1738. PWCHAR InstanceName,
  1739. PULONG InstanceIndex
  1740. );
  1741. PWNODE_HEADER WmipGenerateRegistrationNotification(
  1742. PBDATASOURCE DataSource,
  1743. PWNODE_HEADER Wnode,
  1744. ULONG GuidMax,
  1745. ULONG NotificationCode
  1746. );
  1747. BOOLEAN
  1748. WmipIsControlGuid(
  1749. PBGUIDENTRY GuidEntry
  1750. );
  1751. void WmipGenerateMofResourceNotification(
  1752. LPWSTR ImagePath,
  1753. LPWSTR ResourceName,
  1754. LPCGUID Guid
  1755. );
  1756. //
  1757. // wbem.c
  1758. ULONG WmipBuildMofClassInfo(
  1759. PBDATASOURCE DataSource,
  1760. LPWSTR ImagePath,
  1761. LPWSTR MofResourceName,
  1762. PBOOLEAN NewMofResource
  1763. );
  1764. ULONG WmipReadBuiltinMof(
  1765. void
  1766. );
  1767. //
  1768. // from krnlmode.c
  1769. ULONG WmipInitializeKM(
  1770. HANDLE *WmiKMHandle
  1771. );
  1772. void WmipKMNonEventNotification(
  1773. HANDLE WmiKMHandle,
  1774. PWNODE_HEADER Wnode
  1775. );
  1776. //
  1777. // main.c
  1778. extern HANDLE WmipRestrictedToken;
  1779. void WmipGetRegistryValue(
  1780. TCHAR *ValueName,
  1781. PULONG Value
  1782. );
  1783. ULONG WmiRunService(
  1784. ULONG Context
  1785. #ifdef MEMPHIS
  1786. , HINSTANCE InstanceHandle
  1787. #endif
  1788. );
  1789. ULONG WmipInitializeAccess(
  1790. PTCHAR *RpcStringBinding
  1791. );
  1792. void WmiTerminateService(
  1793. void
  1794. );
  1795. ULONG WmiInitializeService(
  1796. void
  1797. );
  1798. void WmiDeinitializeService(
  1799. void
  1800. );
  1801. void WmipEventNotification(
  1802. PWNODE_HEADER Wnode,
  1803. BOOLEAN SingleEvent,
  1804. ULONG EventSizeGuess
  1805. );
  1806. #define WmipBuildRegistrationNotification(Wnode, WnodeSize, NotificationCode, GuidCount) { \
  1807. memset(Wnode, 0, sizeof(WNODE_HEADER)); \
  1808. memcpy(&Wnode->Guid, &RegChangeNotificationGuid, sizeof(GUID)); \
  1809. Wnode->BufferSize = WnodeSize; \
  1810. Wnode->Linkage = NotificationCode; \
  1811. Wnode->Version = GuidCount; \
  1812. Wnode->Flags = WNODE_FLAG_INTERNAL; \
  1813. }
  1814. void WmipSendQueuedEvents(
  1815. void
  1816. );
  1817. ULONG WmipCleanupDataConsumer(
  1818. PDCENTRY DataConsumer
  1819. #if DBG
  1820. ,BOOLEAN *NotificationsEnabled,
  1821. BOOLEAN *CollectionsEnabled
  1822. #endif
  1823. );
  1824. //
  1825. // This defines the maximum number of replacement strings over all of the
  1826. // event messages.
  1827. #define MAX_MESSAGE_STRINGS 2
  1828. void __cdecl WmipReportEventLog(
  1829. ULONG MessageCode,
  1830. WORD MessageType,
  1831. WORD MessageCategory,
  1832. DWORD RawDataSize,
  1833. PVOID RawData,
  1834. WORD StringCount,
  1835. ...
  1836. );
  1837. #ifdef MEMPHIS
  1838. long WINAPI
  1839. DeviceNotificationWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
  1840. void WmipDestroyDeviceNotificationWindow(
  1841. HINSTANCE InstanceHandle,
  1842. HWND WindowHandle
  1843. );
  1844. ULONG WmipCreateDeviceNotificationWindow(
  1845. HINSTANCE InstanceHandle,
  1846. HWND *DeviceNotificationWindow
  1847. );
  1848. #endif
  1849. //
  1850. // server.c
  1851. void WmipRpcServerDeinitialize(
  1852. void
  1853. );
  1854. ULONG WmipRpcServerInitialize(
  1855. void
  1856. );
  1857. ULONG WmipDeliverWnodeToDS(
  1858. ULONG ActionCode,
  1859. PBDATASOURCE DataSource,
  1860. PWNODE_HEADER Wnode
  1861. );
  1862. ULONG WmipDoDisableRequest(
  1863. PNOTIFICATIONENTRY NotificationEntry,
  1864. PBGUIDENTRY GuidEntry,
  1865. BOOLEAN IsEvent,
  1866. BOOLEAN IsTraceLog,
  1867. ULONG64 LoggerContext,
  1868. ULONG InProgressFlag
  1869. );
  1870. ULONG CollectOrEventWorker(
  1871. PDCENTRY DataConsumer,
  1872. LPGUID Guid,
  1873. BOOLEAN Enable,
  1874. BOOLEAN IsEvent,
  1875. ULONG *NotificationCookie,
  1876. ULONG64 LoggerContext,
  1877. ULONG NotificationFlags
  1878. );
  1879. ULONG WmipCreateRestrictedToken(
  1880. HANDLE *RestrictedToken
  1881. );
  1882. void WmipShowPrivs(
  1883. HANDLE TokenHandle
  1884. );
  1885. #ifdef MEMPHIS
  1886. #define WmipRestrictToken(Token) (ERROR_SUCCESS)
  1887. #define WmipUnrestrictToken() (ERROR_SUCCESS)
  1888. #else
  1889. ULONG WmipRestrictToken(
  1890. HANDLE RestrictedToken
  1891. );
  1892. ULONG WmipUnrestrictToken(
  1893. void
  1894. );
  1895. ULONG WmipServiceDisableTraceProviders(
  1896. PWNODE_HEADER Wnode
  1897. );
  1898. #endif
  1899. void WmipReleaseCollectionEnabled(
  1900. PNOTIFICATIONENTRY NotificationEntry
  1901. );
  1902. //
  1903. // chunk.c
  1904. ULONG UnicodeToAnsi(
  1905. LPCWSTR pszW,
  1906. LPSTR * ppszA,
  1907. ULONG *AnsiSizeInBytes OPTIONAL
  1908. );
  1909. ULONG AnsiToUnicode(
  1910. LPCSTR pszA,
  1911. LPWSTR * ppszW
  1912. );
  1913. ULONG AnsiSizeForUnicodeString(
  1914. PWCHAR UnicodeString,
  1915. ULONG *AnsiSizeInBytes
  1916. );
  1917. ULONG UnicodeSizeForAnsiString(
  1918. LPCSTR AnsiString,
  1919. ULONG *UnicodeSizeInBytes
  1920. );
  1921. //
  1922. // debug.c
  1923. #if DBG
  1924. void WmipDumpIS(
  1925. PBINSTANCESET IS,
  1926. BOOLEAN RecurseGE,
  1927. BOOLEAN RecurseDS
  1928. );
  1929. void WmipDumpGE(
  1930. PBGUIDENTRY GE,
  1931. BOOLEAN RecurseIS
  1932. );
  1933. void WmipDumpDS(
  1934. PBDATASOURCE DS,
  1935. BOOLEAN RecurseIS
  1936. );
  1937. void WmipDumpAllDS(
  1938. void
  1939. );
  1940. #endif
  1941. #ifndef MEMPHIS
  1942. typedef enum
  1943. {
  1944. TRACELOG_START = 0,
  1945. TRACELOG_STOP = 1,
  1946. TRACELOG_QUERY = 2,
  1947. TRACELOG_QUERYALL = 3,
  1948. TRACELOG_QUERYENABLED = 4,
  1949. TRACELOG_UPDATE = 5,
  1950. TRACELOG_FLUSH = 6
  1951. } TRACEREQUESTCODE;
  1952. typedef struct _WMI_REF_CLOCK {
  1953. LARGE_INTEGER StartTime;
  1954. LARGE_INTEGER StartPerfClock;
  1955. } WMI_REF_CLOCK, *PWMI_REF_CLOCK;
  1956. //
  1957. // logsup.c
  1958. ULONG
  1959. WmiUnregisterGuids(
  1960. IN WMIHANDLE WMIHandle,
  1961. IN LPGUID Guid,
  1962. OUT ULONG64 *LoggerContext
  1963. );
  1964. void
  1965. WmipGenericTraceEnable(
  1966. IN ULONG RequestCode,
  1967. IN PVOID Buffer,
  1968. IN OUT PVOID *RequestAddress
  1969. );
  1970. ULONG
  1971. WmipAddLogHeaderToLogFile(
  1972. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo,
  1973. IN PWMI_REF_CLOCK RefClock,
  1974. IN ULONG Update
  1975. );
  1976. ULONG
  1977. WmipStartLogger(
  1978. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  1979. );
  1980. ULONG
  1981. WmipStopLogger(
  1982. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  1983. );
  1984. ULONG
  1985. WmipQueryLogger(
  1986. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo,
  1987. IN ULONG Update
  1988. );
  1989. ULONG
  1990. WmipFlushLogger(
  1991. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  1992. );
  1993. VOID
  1994. WmipInitString(
  1995. IN PVOID Destination,
  1996. IN PVOID Buffer,
  1997. IN ULONG Size
  1998. );
  1999. ULONG
  2000. WmipGetTraceRegKeys(
  2001. );
  2002. ULONG
  2003. WmipFinalizeLogFileHeader(
  2004. IN PWMI_LOGGER_INFORMATION LoggerInfo
  2005. );
  2006. //
  2007. // umlog.c
  2008. BOOLEAN
  2009. FASTCALL
  2010. WmipIsPrivateLoggerOn();
  2011. ULONG
  2012. WmipFlushUmLoggerBuffer();
  2013. ULONG
  2014. WmipSendUmLogRequest(
  2015. IN WMITRACECODE RequestCode,
  2016. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  2017. );
  2018. ULONG
  2019. FASTCALL
  2020. WmiTraceUmEvent(
  2021. IN PWNODE_HEADER Wnode
  2022. );
  2023. ULONG
  2024. WmipStartUmLogger(
  2025. IN ULONG WnodeSize,
  2026. IN OUT ULONG *SizeUsed,
  2027. OUT ULONG *SizeNeeded,
  2028. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  2029. );
  2030. ULONG
  2031. WmipStopUmLogger(
  2032. IN ULONG WnodeSize,
  2033. IN OUT ULONG *SizeUsed,
  2034. OUT ULONG *SizeNeeded,
  2035. IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
  2036. );
  2037. PWMI_BUFFER_HEADER
  2038. FASTCALL
  2039. WmipGetFullFreeBuffer();
  2040. LONG
  2041. FASTCALL
  2042. WmipReleaseTraceBuffer(
  2043. IN PWMI_BUFFER_HEADER BufferResource
  2044. );
  2045. PWMI_BUFFER_HEADER
  2046. FASTCALL
  2047. WmipSwitchFullBuffer(
  2048. IN PWMI_BUFFER_HEADER OldBuffer
  2049. );
  2050. ULONG
  2051. WmipReleaseFullBuffer(
  2052. IN PWMI_BUFFER_HEADER Buffer
  2053. );
  2054. #endif