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.
2600 lines
70 KiB
2600 lines
70 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
wmiump.h
|
|
|
|
Abstract:
|
|
|
|
Private headers for WMI user mode
|
|
|
|
Author:
|
|
|
|
16-Jan-1997 AlanWar
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define _WMI_SOURCE_
|
|
|
|
//
|
|
// Define this to track reference counts
|
|
//#define TRACK_REFERNECES
|
|
|
|
//
|
|
// Define this to get extra checks on heap validation
|
|
//#define HEAPVALIDATION
|
|
|
|
//
|
|
// Define this to get a trace of critical section
|
|
//#define CRITSECTTRACE
|
|
|
|
//
|
|
// Define this to compile WMI to run as a service under NT
|
|
#define RUN_AS_SERVICE
|
|
|
|
//
|
|
// Define this to include WMI user mode functionality. Note that if you enable
|
|
// this then you also need to fix the files: wmi\dll\sources and wmi\makefil0.
|
|
//#define WMI_USER_MODE
|
|
|
|
//
|
|
// Define this to track memory leaks
|
|
//#define TRACK_MEMORY_LEAKS
|
|
|
|
#ifndef MEMPHIS
|
|
#define UNICODE
|
|
#define _UNICODE
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#endif
|
|
|
|
#include <windows.h>
|
|
#include <ole2.h>
|
|
#include <tchar.h>
|
|
#include <stdio.h>
|
|
|
|
#ifndef MEMPHIS
|
|
#include "svcs.h"
|
|
#endif
|
|
|
|
#include <netevent.h>
|
|
|
|
#ifdef MEMPHIS
|
|
//
|
|
// CONSIDER: Is there a better place to get this stuff on MEMPHIS
|
|
//
|
|
// Doubly-linked list manipulation routines. Implemented as macros
|
|
// but logically these are procedures.
|
|
//
|
|
|
|
//
|
|
// VOID
|
|
// InitializeListHead(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define InitializeListHead(ListHead) (\
|
|
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
|
|
|
|
//
|
|
// BOOLEAN
|
|
// IsListEmpty(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define IsListEmpty(ListHead) \
|
|
((ListHead)->Flink == (ListHead))
|
|
|
|
//
|
|
// PLIST_ENTRY
|
|
// RemoveHeadList(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define RemoveHeadList(ListHead) \
|
|
(ListHead)->Flink;\
|
|
{RemoveEntryList((ListHead)->Flink)}
|
|
|
|
//
|
|
// PLIST_ENTRY
|
|
// RemoveTailList(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define RemoveTailList(ListHead) \
|
|
(ListHead)->Blink;\
|
|
{RemoveEntryList((ListHead)->Blink)}
|
|
|
|
//
|
|
// VOID
|
|
// RemoveEntryList(
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define RemoveEntryList(Entry) {\
|
|
PLIST_ENTRY _EX_Blink;\
|
|
PLIST_ENTRY _EX_Flink;\
|
|
_EX_Flink = (Entry)->Flink;\
|
|
_EX_Blink = (Entry)->Blink;\
|
|
_EX_Blink->Flink = _EX_Flink;\
|
|
_EX_Flink->Blink = _EX_Blink;\
|
|
}
|
|
|
|
//
|
|
// VOID
|
|
// InsertTailList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define InsertTailList(ListHead,Entry) {\
|
|
PLIST_ENTRY _EX_Blink;\
|
|
PLIST_ENTRY _EX_ListHead;\
|
|
_EX_ListHead = (ListHead);\
|
|
_EX_Blink = _EX_ListHead->Blink;\
|
|
(Entry)->Flink = _EX_ListHead;\
|
|
(Entry)->Blink = _EX_Blink;\
|
|
_EX_Blink->Flink = (Entry);\
|
|
_EX_ListHead->Blink = (Entry);\
|
|
}
|
|
|
|
//
|
|
// VOID
|
|
// InsertHeadList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define InsertHeadList(ListHead,Entry) {\
|
|
PLIST_ENTRY _EX_Flink;\
|
|
PLIST_ENTRY _EX_ListHead;\
|
|
_EX_ListHead = (ListHead);\
|
|
_EX_Flink = _EX_ListHead->Flink;\
|
|
(Entry)->Flink = _EX_Flink;\
|
|
(Entry)->Blink = _EX_ListHead;\
|
|
_EX_Flink->Blink = (Entry);\
|
|
_EX_ListHead->Flink = (Entry);\
|
|
}
|
|
|
|
//
|
|
//
|
|
// PSINGLE_LIST_ENTRY
|
|
// PopEntryList(
|
|
// PSINGLE_LIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define PopEntryList(ListHead) \
|
|
(ListHead)->Next;\
|
|
{\
|
|
PSINGLE_LIST_ENTRY FirstEntry;\
|
|
FirstEntry = (ListHead)->Next;\
|
|
if (FirstEntry != NULL) { \
|
|
(ListHead)->Next = FirstEntry->Next;\
|
|
} \
|
|
}
|
|
|
|
|
|
//
|
|
// VOID
|
|
// PushEntryList(
|
|
// PSINGLE_LIST_ENTRY ListHead,
|
|
// PSINGLE_LIST_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define PushEntryList(ListHead,Entry) \
|
|
(Entry)->Next = (ListHead)->Next; \
|
|
(ListHead)->Next = (Entry)
|
|
|
|
//
|
|
// Define the various device type values. Note that values used by Microsoft
|
|
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
|
|
// by customers.
|
|
//
|
|
|
|
#define DEVICE_TYPE ULONG
|
|
|
|
#define FILE_DEVICE_BEEP 0x00000001
|
|
#define FILE_DEVICE_CD_ROM 0x00000002
|
|
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
|
|
#define FILE_DEVICE_CONTROLLER 0x00000004
|
|
#define FILE_DEVICE_DATALINK 0x00000005
|
|
#define FILE_DEVICE_DFS 0x00000006
|
|
#define FILE_DEVICE_DISK 0x00000007
|
|
#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
|
|
#define FILE_DEVICE_FILE_SYSTEM 0x00000009
|
|
#define FILE_DEVICE_INPORT_PORT 0x0000000a
|
|
#define FILE_DEVICE_KEYBOARD 0x0000000b
|
|
#define FILE_DEVICE_MAILSLOT 0x0000000c
|
|
#define FILE_DEVICE_MIDI_IN 0x0000000d
|
|
#define FILE_DEVICE_MIDI_OUT 0x0000000e
|
|
#define FILE_DEVICE_MOUSE 0x0000000f
|
|
#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
|
|
#define FILE_DEVICE_NAMED_PIPE 0x00000011
|
|
#define FILE_DEVICE_NETWORK 0x00000012
|
|
#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
|
|
#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
|
|
#define FILE_DEVICE_NULL 0x00000015
|
|
#define FILE_DEVICE_PARALLEL_PORT 0x00000016
|
|
#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
|
|
#define FILE_DEVICE_PRINTER 0x00000018
|
|
#define FILE_DEVICE_SCANNER 0x00000019
|
|
#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
|
|
#define FILE_DEVICE_SERIAL_PORT 0x0000001b
|
|
#define FILE_DEVICE_SCREEN 0x0000001c
|
|
#define FILE_DEVICE_SOUND 0x0000001d
|
|
#define FILE_DEVICE_STREAMS 0x0000001e
|
|
#define FILE_DEVICE_TAPE 0x0000001f
|
|
#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
|
|
#define FILE_DEVICE_TRANSPORT 0x00000021
|
|
#define FILE_DEVICE_UNKNOWN 0x00000022
|
|
#define FILE_DEVICE_VIDEO 0x00000023
|
|
#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
|
|
#define FILE_DEVICE_WAVE_IN 0x00000025
|
|
#define FILE_DEVICE_WAVE_OUT 0x00000026
|
|
#define FILE_DEVICE_8042_PORT 0x00000027
|
|
#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
|
|
#define FILE_DEVICE_BATTERY 0x00000029
|
|
#define FILE_DEVICE_BUS_EXTENDER 0x0000002a
|
|
#define FILE_DEVICE_MODEM 0x0000002b
|
|
#define FILE_DEVICE_VDM 0x0000002c
|
|
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
|
|
#define FILE_DEVICE_SMB 0x0000002e
|
|
#define FILE_DEVICE_KS 0x0000002f
|
|
#define FILE_DEVICE_CHANGER 0x00000030
|
|
#define FILE_DEVICE_SMARTCARD 0x00000031
|
|
#define FILE_DEVICE_ACPI 0x00000032
|
|
#define FILE_DEVICE_DVD 0x00000033
|
|
|
|
//
|
|
// Macro definition for defining IOCTL and FSCTL function control codes. Note
|
|
// that function codes 0-2047 are reserved for Microsoft Corporation, and
|
|
// 2048-4095 are reserved for customers.
|
|
//
|
|
|
|
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
|
|
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
|
|
)
|
|
|
|
//
|
|
// Define the method codes for how buffers are passed for I/O and FS controls
|
|
//
|
|
|
|
#define METHOD_BUFFERED 0
|
|
#define METHOD_IN_DIRECT 1
|
|
#define METHOD_OUT_DIRECT 2
|
|
#define METHOD_NEITHER 3
|
|
|
|
//
|
|
// Define the access check value for any access
|
|
//
|
|
//
|
|
// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
|
|
// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
|
|
// constants *MUST* always be in sync.
|
|
//
|
|
|
|
|
|
#define FILE_ANY_ACCESS 0
|
|
#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
|
|
#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
|
|
|
|
typedef LONG NTSTATUS;
|
|
typedef NTSTATUS (*PUSER_THREAD_START_ROUTINE)(
|
|
PVOID ThreadParameter
|
|
);
|
|
|
|
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#include "wmium.h"
|
|
#include "wmiumkm.h"
|
|
#include "ntwmi.h"
|
|
#include "wmiguid.h"
|
|
|
|
#if DBG
|
|
#if defined(_NTDLLBUILD_)
|
|
#define EtwpAssert(x) if (! (x) ) { \
|
|
BOOLEAN OldLoggingEnabled = EtwpLoggingEnabled; \
|
|
EtwpLoggingEnabled = TRUE; \
|
|
EtwpDbgPrint(("WMI Assertion: "#x" at %s %d\n", __FILE__, __LINE__)); \
|
|
EtwpLoggingEnabled = OldLoggingEnabled; \
|
|
DbgBreakPoint(); }
|
|
#else
|
|
#define EtwpAssert(x) if (! (x) ) { \
|
|
BOOLEAN OldLoggingEnabled = EtwpLoggingEnabled; \
|
|
EtwpLoggingEnabled = TRUE; \
|
|
EtwpDbgPrint(("WMI Assertion: "#x" at %s %d\n", __FILE__, __LINE__)); \
|
|
EtwpLoggingEnabled = OldLoggingEnabled; \
|
|
DebugBreak(); }
|
|
#endif
|
|
#else
|
|
#define EtwpAssert(x)
|
|
#endif
|
|
|
|
#if DBG
|
|
extern BOOLEAN EtwpLoggingEnabled;
|
|
#ifdef MEMPHIS
|
|
void __cdecl DebugOut(char *Format, ...);
|
|
#define EtwpDebugPrint(_x_) { if (EtwpLoggingEnabled) DebugOut _x_; }
|
|
#define EtwpDbgPrint(_x_) { if (EtwpLoggingEnabled) DebugOut _x_; }
|
|
#else
|
|
#define EtwpDebugPrint(_x_) { if (EtwpLoggingEnabled) DbgPrint _x_; }
|
|
#define EtwpDbgPrint(_x_) { if (EtwpLoggingEnabled) DbgPrint _x_; }
|
|
#endif
|
|
#else
|
|
#define EtwpDebugPrint(_x_)
|
|
#define EtwpDbgPrint(_x_)
|
|
#endif
|
|
|
|
#define NULL_GUID {0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
|
|
|
//
|
|
// Registry based config options. Only available on checked builds
|
|
//
|
|
#define WmiRegKeyText TEXT("\\Registry\\Machine\\System\\CurrentControlSet\\Control\\WMI")
|
|
#define PumpTimeoutRegValueText TEXT("NotificationPumpTimeout")
|
|
#define LoggingEnableValueText TEXT("LoggingEnabled")
|
|
|
|
#define DEFAULT_ALLOC_SIZE 4096
|
|
|
|
|
|
|
|
|
|
//
|
|
// WMI RPC related definitions
|
|
typedef struct
|
|
{
|
|
WNODE_HEADER WnodeHeader;
|
|
BYTE Data[1];
|
|
} WNODE_INTERNAL, *PWNODE_INTERNAL;
|
|
|
|
#define INTERNAL_PROVIDER_ID 1
|
|
|
|
//
|
|
// Size of initial buffer used to read notifications from kernel mode
|
|
#define STARTNOTIFICATIONBUFFERSIZE 4096
|
|
|
|
#ifdef MEMPHIS
|
|
#define WmiRpcProtocolSequence TEXT("ncalrpc")
|
|
|
|
#define WmiServiceRpcProtocolSequence TEXT("ncalrpc")
|
|
#define WmiServiceRpcEndpoint TEXT("WmiRpcEndpoint")
|
|
#else
|
|
//#define WmiRpcProtocolSequence TEXT("ncalrpc")
|
|
//#define WmiRpcEndpointPrefix TEXT("NT")
|
|
|
|
#define WmiRpcProtocolSequence TEXT("ncacn_np")
|
|
#define WmiRpcEndpointPrefix TEXT("\\pipe\\")
|
|
|
|
#define WmiServiceRpcProtocolSequence TEXT("ncacn_np")
|
|
#define WmiServiceRpcEndpoint SVCS_RPC_PIPE
|
|
#endif
|
|
|
|
#define MinRpcCalls 1
|
|
#define MaxRpcCalls RPC_C_PROTSEQ_MAX_REQS_DEFAULT
|
|
|
|
//
|
|
// Time to wait between retrying an RPC call that was too busy to complete
|
|
#define RPC_BUSY_WAIT_TIMER 500
|
|
|
|
//
|
|
// Number of times to retry an RPC call that was too busy to complete
|
|
#define RPC_BUSY_WAIT_RETRIES 5
|
|
|
|
//
|
|
// WMI RPC interface principle name
|
|
#define WMI_RPC_PRINC_NAME TEXT("WMI_RPC_PRINC_NAME")
|
|
|
|
//
|
|
// This macro will break CountedString into a pointer to the actual string
|
|
// and the actual length of the string excluding any trailing nul characters
|
|
#define EtwpBreakCountedString(CountedString, CountedStringLen) { \
|
|
CountedStringLen = *CountedString++; \
|
|
if (CountedString[(CountedStringLen-sizeof(WCHAR))/sizeof(WCHAR)] == UNICODE_NULL) \
|
|
{ \
|
|
CountedStringLen -= sizeof(WCHAR); \
|
|
} \
|
|
}
|
|
|
|
|
|
typedef struct
|
|
{
|
|
HANDLE GuidHandle;
|
|
PVOID DeliveryInfo;
|
|
ULONG_PTR DeliveryContext;
|
|
ULONG Flags;
|
|
} NOTIFYEE, *PNOTIFYEE;
|
|
|
|
#define STATIC_NOTIFYEE_COUNT 2
|
|
|
|
typedef struct
|
|
{
|
|
LIST_ENTRY GNList;
|
|
GUID Guid;
|
|
ULONG RefCount;
|
|
ULONG NotifyeeCount;
|
|
PNOTIFYEE Notifyee;
|
|
NOTIFYEE StaticNotifyee[STATIC_NOTIFYEE_COUNT];
|
|
BOOLEAN bInProgress;
|
|
} GUIDNOTIFICATION, *PGUIDNOTIFICATION;
|
|
|
|
#define EtwpAllocGNEntry() (PGUIDNOTIFICATION)EtwpAlloc(sizeof(GUIDNOTIFICATION))
|
|
#define EtwpFreeGNEntry(GNEntry) EtwpFree(GNEntry)
|
|
#define EtwpReferenceGNEntry(GNEntry) InterlockedIncrement(&GNEntry->RefCount);
|
|
|
|
|
|
//
|
|
// Notification Cookie data structures
|
|
//#if DBG
|
|
//#define NOTIFYCOOKIESPERCHUNK 2
|
|
//#else
|
|
//#define NOTIFYCOOKIESPERCHUNK 128
|
|
//#endif
|
|
/*
|
|
typedef struct
|
|
{
|
|
PVOID DeliveryContext;
|
|
PVOID DeliveryInfo;
|
|
GUID Guid;
|
|
BOOLEAN InUse;
|
|
} NOTIFYCOOKIE, *PNOTIFYCOOKIE;
|
|
|
|
typedef struct
|
|
{
|
|
LIST_ENTRY Next; // Next cookie chunk
|
|
ULONG BaseSlot; // Index of first slot number
|
|
USHORT FreeSlot; // Index to a free cookie
|
|
BOOLEAN Full; // TRUE if this chunk is full
|
|
NOTIFYCOOKIE Cookies[NOTIFYCOOKIESPERCHUNK];
|
|
} NOTIFYCOOKIECHUNK, *PNOTIFYCOOKIECHUNK;
|
|
*/
|
|
|
|
//
|
|
// Useful macro to establish a WNODE_HEADER quickly
|
|
#ifdef _WIN64
|
|
|
|
#define EtwpBuildWnodeHeader(Wnode, WnodeSize, FlagsUlong, Handle) { \
|
|
(Wnode)->Flags = FlagsUlong; \
|
|
(Wnode)->KernelHandle = Handle; \
|
|
(Wnode)->BufferSize = WnodeSize; \
|
|
(Wnode)->Linkage = 0; \
|
|
}
|
|
|
|
#else
|
|
|
|
#define EtwpBuildWnodeHeader(Wnode, WnodeSize, FlagsUlong, Handle) { \
|
|
(Wnode)->Flags = FlagsUlong; \
|
|
*((PULONG64)(&((Wnode)->TimeStamp))) = (ULONG64)(IntToPtr(PtrToInt(Handle))); \
|
|
(Wnode)->BufferSize = WnodeSize; \
|
|
(Wnode)->Linkage = 0; \
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef MEMPHIS
|
|
extern HANDLE PMMutex;
|
|
#define EtwpEnterPMCritSection() WaitForSingleObject(PMMutex, INFINITE)
|
|
|
|
#define EtwpLeavePMCritSection() ReleaseMutex(PMMutex)
|
|
|
|
#else
|
|
extern RTL_CRITICAL_SECTION PMCritSect;
|
|
extern HANDLE EtwpCBInProgressEvent;
|
|
#if DBG
|
|
#define EtwpEnterPMCritSection() \
|
|
EtwpAssert(NT_SUCCESS(RtlEnterCriticalSection(&PMCritSect)));
|
|
|
|
#define EtwpLeavePMCritSection() { \
|
|
EtwpAssert(PMCritSect.LockCount >= 0); \
|
|
EtwpAssert(NT_SUCCESS(RtlLeaveCriticalSection(&PMCritSect))); }
|
|
|
|
//
|
|
// Assumptions about EtwpLockCB and EtwpUnlockCB:
|
|
// 1. Called only by the Pump Thread
|
|
// 2. There can be only one callback in progress at any time with the
|
|
// Global event EtwpCBInProgressEvent unset and the corresponding GNEntry
|
|
// marked as InProgress.
|
|
// 3. Once the callback completes (successfully or not), the event is set
|
|
// and the GNEntry unlocked.
|
|
// 4. Unregistering threads remove the GNEntry first and then check to see
|
|
// whether to block for the PumpThread based on InProgressFlag.
|
|
// 5. No callbacks are permitted if the GNEntry is not found in the GNList.
|
|
//
|
|
|
|
|
|
#define EtwpLockCB(GNEntry) { \
|
|
EtwpDebugPrint(("WMI: Locking GNEntry 0x%x %s %d\n", GNEntry, __FILE__, __LINE__)); \
|
|
EtwpAssert( GNEntry->bInProgress == FALSE); \
|
|
GNEntry->bInProgress = TRUE; \
|
|
NtClearEvent (EtwpCBInProgressEvent); }
|
|
|
|
#define EtwpUnlockCB(GNEntry) { \
|
|
EtwpDebugPrint(("WMI: Unlocking GNEntry 0x%x %s %d\n", GNEntry, __FILE__, __LINE__)); \
|
|
EtwpAssert( GNEntry->bInProgress == TRUE); \
|
|
NtSetEvent(EtwpCBInProgressEvent, NULL); \
|
|
GNEntry->bInProgress = FALSE;}
|
|
|
|
#else
|
|
#define EtwpEnterPMCritSection() RtlEnterCriticalSection(&PMCritSect)
|
|
#define EtwpLeavePMCritSection() RtlLeaveCriticalSection(&PMCritSect)
|
|
|
|
#define EtwpLockCB(GNEntry) {\
|
|
GNEntry->bInProgress = TRUE; \
|
|
NtClearEvent (EtwpCBInProgressEvent);}
|
|
#define EtwpUnlockCB(GNEntry) { \
|
|
NtSetEvent(EtwpCBInProgressEvent, NULL); \
|
|
GNEntry->bInProgress = FALSE; }
|
|
|
|
#endif // DBG
|
|
|
|
#endif // MEMPHIS
|
|
|
|
|
|
typedef struct
|
|
{
|
|
NOTIFICATIONCALLBACK Callback;
|
|
ULONG_PTR Context;
|
|
PWNODE_HEADER Wnode;
|
|
BYTE WnodeBuffer[1];
|
|
} NOTIFDELIVERYCTX, *PNOTIFDELIVERYCTX;
|
|
|
|
|
|
// from handle.c
|
|
|
|
#define EtwpVerifyToken() \
|
|
{ \
|
|
ULONG VerifyStatus; \
|
|
VerifyStatus = EtwpCheckImpersonationTokenType(); \
|
|
if (VerifyStatus != ERROR_SUCCESS) \
|
|
{ \
|
|
SetLastError(VerifyStatus); \
|
|
return(VerifyStatus); \
|
|
} \
|
|
}
|
|
|
|
ULONG EtwpCheckImpersonationTokenType(
|
|
void
|
|
);
|
|
|
|
ULONG EtwpCopyStringToCountedUnicode(
|
|
LPCWSTR String,
|
|
PWCHAR CountedString,
|
|
ULONG *BytesUsed,
|
|
BOOLEAN ConvertFromAnsi
|
|
);
|
|
|
|
ULONG EtwpCountedAnsiToCountedUnicode(
|
|
PCHAR Ansi,
|
|
PWCHAR Unicode
|
|
);
|
|
|
|
ULONG EtwpCountedUnicodeToCountedAnsi(
|
|
PWCHAR Unicode,
|
|
PCHAR Ansi
|
|
);
|
|
|
|
#ifndef MEMPHIS
|
|
ULONG EtwpCheckGuidAccess(
|
|
LPGUID Guid,
|
|
ACCESS_MASK DesiredAccess
|
|
);
|
|
|
|
ULONG EtwpOpenKernelGuid(
|
|
LPGUID Guid,
|
|
ACCESS_MASK DesiredAccess,
|
|
PHANDLE Handle,
|
|
ULONG Ioctl
|
|
);
|
|
#endif
|
|
/*
|
|
ULONG EtwpAllocateCookie(
|
|
PVOID DeliveryInfo,
|
|
PVOID DeliveryContext,
|
|
LPGUID Guid
|
|
);
|
|
|
|
BOOLEAN EtwpLookupCookie(
|
|
ULONG CookieSlot,
|
|
LPGUID Guid,
|
|
PVOID *DeliveryInfo,
|
|
PVOID *DeliveryContext
|
|
);
|
|
|
|
void EtwpGetGuidInCookie(
|
|
ULONG CookieSlot,
|
|
LPGUID Guid
|
|
);
|
|
|
|
void EtwpFreeCookie(
|
|
ULONG CookieSlot
|
|
);
|
|
*/
|
|
|
|
PGUIDNOTIFICATION
|
|
EtwpFindAndLockGuidNotification(
|
|
LPGUID Guid,
|
|
BOOLEAN bLock
|
|
);
|
|
|
|
ULONG
|
|
EtwpAddToGNList(
|
|
LPGUID Guid,
|
|
PVOID DeliveryInfo,
|
|
ULONG_PTR DeliveryContext,
|
|
ULONG Flags,
|
|
HANDLE GuidHandle
|
|
);
|
|
|
|
ULONG
|
|
EtwpRemoveFromGNList(
|
|
LPGUID Guid,
|
|
PVOID DeliveryInfo
|
|
);
|
|
|
|
BOOLEAN
|
|
EtwpDereferenceGNEntry(
|
|
PGUIDNOTIFICATION GNEntry
|
|
);
|
|
|
|
//PTCHAR GuidToString(
|
|
// PTCHAR s,
|
|
// LPGUID piid
|
|
// );
|
|
|
|
PCHAR GuidToStringA(
|
|
PCHAR s,
|
|
ULONG szBuf,
|
|
LPGUID piid
|
|
);
|
|
|
|
|
|
// from request.c
|
|
ULONG EtwpSendWmiRequest(
|
|
ULONG ActionCode,
|
|
PWNODE_HEADER Wnode,
|
|
ULONG WnodeSize,
|
|
PVOID OutBuffer,
|
|
ULONG MaxBufferSize,
|
|
ULONG *RetSize
|
|
);
|
|
|
|
ULONG EtwpSendWmiKMRequest(
|
|
HANDLE Handle,
|
|
ULONG Ioctl,
|
|
PVOID InBuffer,
|
|
ULONG InBufferSize,
|
|
PVOID OutBuffer,
|
|
ULONG MaxBufferSize,
|
|
ULONG *ReturnSize,
|
|
LPOVERLAPPED Overlapped
|
|
);
|
|
|
|
ULONG EtwpSendRegisterKMRequest(
|
|
HANDLE DeviceHandle,
|
|
ULONG Ioctl,
|
|
PVOID InBuffer,
|
|
ULONG InBufferSize,
|
|
PVOID OutBuffer,
|
|
ULONG MaxBufferSize,
|
|
ULONG *ReturnSize,
|
|
LPOVERLAPPED Overlapped
|
|
);
|
|
|
|
ULONG EtwpConvertWADToAnsi(
|
|
PWNODE_ALL_DATA Wnode
|
|
);
|
|
|
|
ULONG EtwpConvertWADToUnicode(
|
|
PWNODE_ALL_DATA WnodeAllData,
|
|
ULONG *BufferSize
|
|
);
|
|
|
|
ULONG EtwpRegisterGuids(
|
|
IN LPGUID MasterGuid,
|
|
IN LPGUID ControlGuid,
|
|
IN LPCWSTR MofImagePath,
|
|
IN LPCWSTR MofResourceName,
|
|
OUT ULONG64 *LoggerContext,
|
|
OUT HANDLE *RegistrationHandle
|
|
);
|
|
|
|
//
|
|
// from intrnldp.c
|
|
ULONG EtwpInternalProvider(
|
|
ULONG ActionCode,
|
|
PWNODE_HEADER Wnode,
|
|
ULONG MaxWnodeSize,
|
|
PVOID OutBuffer,
|
|
ULONG *RetSize
|
|
);
|
|
|
|
ULONG
|
|
EtwpEnumRegGuids(
|
|
PWMIGUIDLISTINFO *pGuidInfo
|
|
);
|
|
|
|
//
|
|
// from dcapi.c
|
|
ULONG
|
|
EtwpNotificationRegistration(
|
|
IN LPGUID InGuid,
|
|
IN BOOLEAN Enable,
|
|
IN PVOID DeliveryInfo,
|
|
IN ULONG_PTR DeliveryContext,
|
|
IN ULONG64 LoggerContext,
|
|
IN ULONG Flags,
|
|
IN BOOLEAN IsAnsi
|
|
);
|
|
|
|
|
|
//
|
|
// from mofapi.c
|
|
//
|
|
void EtwpProcessLanguageAddRemoveEvent(
|
|
IN PWNODE_SINGLE_INSTANCE WnodeSI,
|
|
IN NOTIFICATIONCALLBACK Callback,
|
|
IN ULONG_PTR DeliveryContext,
|
|
IN BOOLEAN IsAnsi
|
|
);
|
|
|
|
void EtwpProcessMofAddRemoveEvent(
|
|
IN PWNODE_SINGLE_INSTANCE WnodeSI,
|
|
IN NOTIFICATIONCALLBACK Callback,
|
|
IN ULONG_PTR DeliveryContext,
|
|
IN BOOLEAN IsAnsi
|
|
);
|
|
|
|
|
|
//
|
|
// from notify.c
|
|
extern ULONG EtwpNotificationSinkIndex;
|
|
#ifndef MEMPHIS
|
|
|
|
ULONG EtwpProcessUMRequest(
|
|
PWMI_LOGGER_INFORMATION LoggerInfo,
|
|
PVOID DeliveryContext,
|
|
ULONG ReplyIndex
|
|
);
|
|
|
|
#endif
|
|
|
|
ULONG EtwpAddHandleToEventPump(
|
|
LPGUID Guid,
|
|
PVOID DeliveryInfo,
|
|
ULONG_PTR DeliveryContext,
|
|
ULONG NotificationFlags,
|
|
HANDLE GuidHandle
|
|
);
|
|
|
|
void EtwpMakeEventCallbacks(
|
|
IN PWNODE_HEADER Wnode,
|
|
IN NOTIFICATIONCALLBACK Callback,
|
|
IN ULONG_PTR DeliveryContext,
|
|
IN BOOLEAN IsAnsi
|
|
);
|
|
|
|
|
|
ULONG
|
|
EtwpReceiveNotifications(
|
|
IN ULONG HandleCount,
|
|
IN HANDLE *HandleList,
|
|
IN NOTIFICATIONCALLBACK Callback,
|
|
IN ULONG_PTR DeliveryContext,
|
|
IN BOOLEAN IsAnsi,
|
|
IN ULONG Action,
|
|
IN PUSER_THREAD_START_ROUTINE UserModeCallback,
|
|
IN HANDLE ProcessHandle
|
|
);
|
|
|
|
ULONG EtwpEventPump(
|
|
PVOID Param
|
|
);
|
|
|
|
void
|
|
EtwpEnableDisableGuid(
|
|
PWNODE_HEADER Wnode,
|
|
ULONG RequestCode,
|
|
BOOLEAN bDelayEnable
|
|
);
|
|
|
|
//
|
|
// from main.c
|
|
VOID
|
|
EtwpCreateHeap(
|
|
VOID
|
|
);
|
|
|
|
#ifndef IsEqualGUID
|
|
#define IsEqualGUID(guid1, guid2) \
|
|
(!memcmp((guid1), (guid2), sizeof(GUID)))
|
|
#endif
|
|
|
|
|
|
//
|
|
// These define the dll and mof resource name for all of the builtin mof
|
|
// resources
|
|
#define WMICOREDLLNAME L"wmicore.dll"
|
|
#define WMICOREMOFRESOURCENAME L"MofResource"
|
|
|
|
|
|
//
|
|
// This defines the registry key under which security descriptors associated
|
|
// with the guids are stored.
|
|
#ifndef MEMPHIS
|
|
#define WMISECURITYREGISTRYKEY TEXT("System\\CurrentControlSet\\Control\\Wmi\\Security")
|
|
#endif
|
|
|
|
|
|
//
|
|
// This defines the initial value of the buffer passed to each data provider
|
|
// to retrieve the registration information
|
|
#if DBG
|
|
#define INITIALREGINFOSIZE sizeof(WNODE_TOO_SMALL)
|
|
#else
|
|
#define INITIALREGINFOSIZE 8192
|
|
#endif
|
|
|
|
|
|
//
|
|
// Chunk Management definitions
|
|
// All structures that rely upon the chunk allocator must be defined so that
|
|
// their members match that of ENTRYHEADER. These include DATASOURCE,
|
|
// GUIDENTRY, INSTANCESET, DCENTRY, NOTIFICATIONENTRY, MOFCLASS, MOFRESOURCE
|
|
// Also ENTRYHEADER reserves 0x80000000 for its own flag.
|
|
|
|
struct _CHUNKINFO;
|
|
struct _ENTRYHEADER;
|
|
|
|
typedef void (*ENTRYCLEANUP)(
|
|
struct _CHUNKINFO *,
|
|
struct _ENTRYHEADER *
|
|
);
|
|
|
|
typedef struct _CHUNKINFO
|
|
{
|
|
LIST_ENTRY ChunkHead; // Head of list of chunks
|
|
ULONG EntrySize; // Size of a single entry
|
|
ULONG EntriesPerChunk; // Number of entries per chunk allocation
|
|
ENTRYCLEANUP EntryCleanup; // Entry cleanup routine
|
|
ULONG InitialFlags; // Initial flags for all entries
|
|
ULONG Signature;
|
|
#if DBG
|
|
ULONG AllocCount;
|
|
ULONG FreeCount;
|
|
#endif
|
|
} CHUNKINFO, *PCHUNKINFO;
|
|
|
|
typedef struct
|
|
{
|
|
LIST_ENTRY ChunkList; // Node in list of chunks
|
|
LIST_ENTRY FreeEntryHead; // Head of list of free entries in chunk
|
|
ULONG EntriesInUse; // Count of entries being used
|
|
} CHUNKHEADER, *PCHUNKHEADER;
|
|
|
|
typedef struct _ENTRYHEADER
|
|
{
|
|
union
|
|
{
|
|
LIST_ENTRY FreeEntryList; // Node in list of free entries
|
|
LIST_ENTRY InUseEntryList; // Node in list ofin use entries
|
|
};
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags; // Flags
|
|
ULONG RefCount; // Reference Count
|
|
ULONG Signature;
|
|
} ENTRYHEADER, *PENTRYHEADER;
|
|
|
|
// Set if the entry is free
|
|
#define FLAG_ENTRY_ON_FREE_LIST 0x80000000
|
|
#define FLAG_ENTRY_ON_INUSE_LIST 0x40000000
|
|
#define FLAG_ENTRY_INVALID 0x20000000
|
|
#define FLAG_ENTRY_REMOVE_LIST 0x10000000
|
|
|
|
|
|
#define EtwpReferenceEntry(Entry) \
|
|
InterlockedIncrement(&((PENTRYHEADER)(Entry))->RefCount)
|
|
|
|
// chunk.c
|
|
#ifndef MEMPHIS
|
|
ULONG EtwpBuildGuidObjectAttributes(
|
|
IN LPGUID Guid,
|
|
OUT POBJECT_ATTRIBUTES ObjectAttributes,
|
|
OUT PUNICODE_STRING GuidString,
|
|
OUT PWCHAR GuidObjectName
|
|
);
|
|
#endif
|
|
|
|
ULONG EtwpUnreferenceEntry(
|
|
PCHUNKINFO ChunkInfo,
|
|
PENTRYHEADER Entry);
|
|
|
|
PENTRYHEADER EtwpAllocEntry(
|
|
PCHUNKINFO ChunkInfo
|
|
);
|
|
|
|
void EtwpFreeEntry(
|
|
PCHUNKINFO ChunkInfo,
|
|
PENTRYHEADER Entry
|
|
);
|
|
|
|
//
|
|
// This is the guid that denotes non event notifications. WMICore
|
|
// automatically registers anyone opening a guid to
|
|
extern GUID RegChangeNotificationGuid;
|
|
|
|
extern CHUNKINFO DSChunkInfo;
|
|
extern CHUNKINFO GEChunkInfo;
|
|
extern CHUNKINFO ISChunkInfo;
|
|
extern CHUNKINFO DCChunkInfo;
|
|
extern CHUNKINFO NEChunkInfo;
|
|
extern CHUNKINFO MRChunkInfo;
|
|
|
|
struct tagGUIDENTRY;
|
|
typedef struct tagGUIDENTRY GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
|
|
|
|
struct tagDATASOURCE;
|
|
|
|
|
|
//
|
|
// An INSTANCESET contains the information a set of instances that is provided
|
|
// by a single data source. An instance set is part of two lists. One list is
|
|
// the set of instance sets for a particular guid. The other list is the list
|
|
// of instance sets supported by a data source.
|
|
//
|
|
|
|
//
|
|
// Instance names for an instance set registered with a base name and count
|
|
// are stored in a ISBASENAME structure. This structure is tracked by
|
|
// PDFISBASENAME in wmicore.idl.
|
|
typedef struct
|
|
{
|
|
ULONG BaseIndex; // First index to append to base name
|
|
WCHAR BaseName[1]; // Actual base name
|
|
} ISBASENAME, *PISBASENAME, *PBISBASENAME;
|
|
|
|
//
|
|
// This defines the maximum number of characters that can be part of a suffix
|
|
// to a basename. The current value of 6 will allow up to 999999 instances
|
|
// of a guid with a static base name
|
|
#define MAXBASENAMESUFFIXSIZE 6
|
|
|
|
//
|
|
// Instance names for an instance set registerd with a set of static names
|
|
// are kept in a ISSTATICNAMES structure. This structure is tracked by
|
|
// PDFISSTATICNAMES defined in wmicore.idl
|
|
typedef struct
|
|
{
|
|
PWCHAR StaticNamePtr[1]; // pointers to static names
|
|
// WCHAR StaticNames[1];
|
|
} ISSTATICENAMES, *PISSTATICNAMES, *PBISSTATICNAMES;
|
|
|
|
typedef struct tagInstanceSet
|
|
{
|
|
union
|
|
{
|
|
// Entry in list of instances within a guid
|
|
LIST_ENTRY GuidISList;
|
|
|
|
// Entry in main list of free instances
|
|
LIST_ENTRY FreeISList;
|
|
};
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags;
|
|
|
|
// Reference count of number of guids using this instance set
|
|
ULONG RefCount;
|
|
|
|
// Signature to identify entry
|
|
ULONG Signature;
|
|
|
|
// Entry in list of instances within a data source
|
|
LIST_ENTRY DSISList;
|
|
|
|
// Back link to guid that this instance set is a member
|
|
PBGUIDENTRY GuidEntry;
|
|
|
|
// Back link to data source that this instance set is a member
|
|
struct tagDATASOURCE *DataSource;
|
|
|
|
// Count of instances in instance set
|
|
ULONG Count;
|
|
|
|
//
|
|
// If IS_INSTANCE_BASENAME is set then IsBaseName pointe at instance base
|
|
// name structure. Else if IS_INSTANCE_STATICNAME is set then
|
|
// IsStaticNames points to static instance name list. If
|
|
union
|
|
{
|
|
PBISBASENAME IsBaseName;
|
|
PBISSTATICNAMES IsStaticNames;
|
|
};
|
|
|
|
} INSTANCESET, *PINSTANCESET, *PBINSTANCESET;
|
|
|
|
#define IS_SIGNATURE 'nalA'
|
|
|
|
//
|
|
// Guid Map Entry List maintains the list of Guid and their maps.
|
|
// Only those Guids that are Unregistered while a logger session is in
|
|
// progress is kept in this list.
|
|
// It is also used as a placeholder for InstanceIds. Trace Guid Registration
|
|
// calls return a handle to a GUIDMAPENTRY which maintains the map and the
|
|
// Instance Ids.
|
|
//
|
|
|
|
typedef struct tagTRACE_REG_INFO
|
|
{
|
|
BOOLEAN EnabledState; // Indicates if this GUID is Enabled or not.
|
|
PVOID NotifyRoutine;
|
|
PVOID TraceCtxHandle;
|
|
PVOID NotifyContext;
|
|
ULONG64 LoggerContext;
|
|
} TRACE_REG_INFO, *PTRACE_REG_INFO;
|
|
|
|
typedef struct
|
|
{
|
|
ULONG InstanceId;
|
|
ULONG Reserved;
|
|
GUID Guid;
|
|
} GUIDMAPENTRY, *PGUIDMAPENTRY;
|
|
|
|
|
|
#define IS_INSTANCE_BASENAME 0x00000001
|
|
#define IS_INSTANCE_STATICNAMES 0x00000002
|
|
#define IS_EXPENSIVE 0x00000004 // set if collection must be enabled
|
|
#define IS_COLLECTING 0x00000008 // set when collecting
|
|
|
|
#define IS_KM_PROVIDER 0x00000080 // KM data provider
|
|
#define IS_SM_PROVIDER 0x00000100 // Shared memory provider
|
|
#define IS_UM_PROVIDER 0x00000200 // User mode provider
|
|
#define IS_NEWLY_REGISTERED 0x00000800 // set if IS is registering
|
|
|
|
//
|
|
// Any traced guids are used for trace logging and not querying
|
|
#define IS_TRACED 0x00001000
|
|
|
|
// Set when events are enabled for instance set
|
|
#define IS_ENABLE_EVENT 0x00002000
|
|
|
|
// Set when events are enabled for instance set
|
|
#define IS_ENABLE_COLLECTION 0x00004000
|
|
|
|
// Set if guid is used only for firing events and not querying
|
|
#define IS_EVENT_ONLY 0x00008000
|
|
|
|
// Set if data provider for instance set is expecting ansi instsance names
|
|
#define IS_ANSI_INSTANCENAMES 0x00010000
|
|
|
|
// Set if instance names are originated from a PDO
|
|
#define IS_PDO_INSTANCENAME 0x00020000
|
|
|
|
// If set the data provider for the InstanceSet is internal to wmi.dll
|
|
#define IS_INTERNAL_PROVIDER 0x00040000
|
|
|
|
// Set if a Traced Guid is also a Trace Control Guid
|
|
#define IS_CONTROL_GUID 0x00080000
|
|
|
|
#define IS_ON_FREE_LIST 0x80000000
|
|
|
|
typedef struct tagGUIDENTRY
|
|
{
|
|
union
|
|
{
|
|
// Entry in list of all guids registered with WMI
|
|
LIST_ENTRY MainGEList;
|
|
|
|
// Entry in list of free guid entry blocks
|
|
LIST_ENTRY FreeGEList;
|
|
};
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags;
|
|
|
|
// Count of number of data sources using this guid
|
|
ULONG RefCount;
|
|
|
|
// Signature to identify entry
|
|
ULONG Signature;
|
|
|
|
// Count of InstanceSets headed by this guid
|
|
ULONG ISCount;
|
|
|
|
// Head of list of all instances for guid
|
|
LIST_ENTRY ISHead;
|
|
|
|
// Guid that represents data block
|
|
GUID Guid;
|
|
|
|
} GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
|
|
|
|
#define GE_SIGNATURE 'diuG'
|
|
|
|
#define GE_ON_FREE_LIST 0x80000000
|
|
|
|
//
|
|
// When set this guid is an internally defined guid that has no data source
|
|
// attached to it.
|
|
#define GE_FLAG_INTERNAL 0x00000001
|
|
|
|
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
// Entry in list of all DS
|
|
LIST_ENTRY MainMRList;
|
|
|
|
// Entry in list of free DS
|
|
LIST_ENTRY FreeMRList;
|
|
};
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags;
|
|
|
|
ULONG RefCount;
|
|
|
|
// Signature to identify entry
|
|
ULONG Signature;
|
|
|
|
PWCHAR MofImagePath; // Path to image file with resource
|
|
PWCHAR MofResourceName; // Name of resource containing mof data
|
|
#ifdef WMI_USER_MODE
|
|
LIST_ENTRY MRMCHead;
|
|
#endif
|
|
|
|
} MOFRESOURCE, *PMOFRESOURCE;
|
|
|
|
#define MR_SIGNATURE 'yhsA'
|
|
|
|
|
|
#if DBG
|
|
#define AVGMOFRESOURCECOUNT 1
|
|
#else
|
|
#define AVGMOFRESOURCECOUNT 4
|
|
#endif
|
|
|
|
typedef struct tagDATASOURCE
|
|
{
|
|
union
|
|
{
|
|
// Entry in list of all DS
|
|
LIST_ENTRY MainDSList;
|
|
|
|
// Entry in list of free DS
|
|
LIST_ENTRY FreeDSList;
|
|
};
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags;
|
|
|
|
ULONG RefCount;
|
|
|
|
ULONG Signature;
|
|
|
|
// Head of list of instances for this DS
|
|
LIST_ENTRY ISHead;
|
|
|
|
// Binding string and callback address for DS rpc server
|
|
PTCHAR BindingString;
|
|
RPC_BINDING_HANDLE RpcBindingHandle;
|
|
ULONG RequestAddress;
|
|
ULONG RequestContext;
|
|
|
|
// Provider id of kernel mode driver
|
|
ULONG_PTR ProviderId;
|
|
|
|
// Path to registry holding ACLs
|
|
PTCHAR RegistryPath;
|
|
|
|
// Head of list of MofResources attached to data source
|
|
ULONG MofResourceCount;
|
|
PMOFRESOURCE *MofResources;
|
|
PMOFRESOURCE StaticMofResources[AVGMOFRESOURCECOUNT];
|
|
};
|
|
|
|
#define DS_SIGNATURE ' naD'
|
|
|
|
#define VERIFY_DPCTXHANDLE(DsCtxHandle) \
|
|
( ((DsCtxHandle) == NULL) || \
|
|
(((PBDATASOURCE)(DsCtxHandle))->Signature == DS_SIGNATURE) )
|
|
|
|
typedef struct tagDATASOURCE DATASOURCE, *PDATASOURCE, *PBDATASOURCE;
|
|
|
|
#define DS_ALLOW_ALL_ACCESS 0x00000001
|
|
#define DS_KERNEL_MODE 0x00000002
|
|
|
|
//
|
|
// Set in the Internal WMI data source
|
|
#define DS_INTERNAL 0x00000004
|
|
|
|
#define DS_ON_FREE_LIST 0x80000000
|
|
|
|
|
|
//
|
|
// A list of enabled notifications is maintained by the wmi service to mange
|
|
// delivering events and to know when to send enable and disable event
|
|
// wmi requests to the data providers. Each NOTIFICATIONENTRY has an array of
|
|
// DCREF which is a reference to the data consumer who is interested in the
|
|
// event.
|
|
|
|
#define RPCOUTSTANDINGCALLLIMIT 128
|
|
|
|
typedef struct
|
|
{
|
|
LIST_ENTRY MainDCList; // Node on global data consumer list
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags;
|
|
ULONG RefCount;
|
|
|
|
ULONG Signature;
|
|
// Actual RPC binding handle
|
|
RPC_BINDING_HANDLE RpcBindingHandle;
|
|
|
|
PUCHAR EventData; // Buffer to hold events to be sent
|
|
ULONG LastEventOffset; // Offset in EventData to previous event
|
|
ULONG NextEventOffset; // Offset in EventData to write next event
|
|
ULONG EventDataSizeLeft; // Number of bytes left to use in EventData
|
|
|
|
ULONG RpcCallsOutstanding; // Number of rpc calls outstanding
|
|
#if DBG
|
|
PTCHAR BindingString; // Binding string for consumer
|
|
#endif
|
|
} DCENTRY, *PDCENTRY;
|
|
|
|
#define DC_SIGNATURE 'cirE'
|
|
|
|
// If the data consumer has had its context rundown routine then this flag
|
|
// is set. This indicates that the data consumer has gone away and no more
|
|
// events should be sent to him.
|
|
#define DC_FLAG_RUNDOWN 0x00000001
|
|
|
|
#define VERIFY_DCCTXHANDLE(DcCtxHandle) \
|
|
( ((DcCtxHandle) == NULL) || \
|
|
(((PDCENTRY)(DcCtxHandle))->Signature == DC_SIGNATURE) )
|
|
|
|
|
|
typedef struct
|
|
{
|
|
PDCENTRY DcEntry; // points at data consumer interested in notification
|
|
// Number of times collect has been enabled by
|
|
// this DC.
|
|
ULONG CollectRefCount;
|
|
|
|
// Number of times collect has been enabled by
|
|
// this DC.
|
|
ULONG EventRefCount;
|
|
|
|
ULONG Flags; // Flags
|
|
ULONG LostEventCount;
|
|
} DCREF, *PDCREF;
|
|
|
|
//
|
|
// _ENABLED flag set if DP already called to enable notification or collection
|
|
#define DCREF_FLAG_NOTIFICATION_ENABLED 0x00000001
|
|
#define DCREF_FLAG_COLLECTION_ENABLED 0x00000002
|
|
|
|
// if DCREF_FLAG_NO_EXTRA_THREAD set then WMI will not create a special thread
|
|
// to do the direct notification callback.
|
|
#define DCREF_FLAG_NO_EXTRA_THREAD 0x00000008
|
|
|
|
// If this flag is set then the notification callback is expecting an ANSI
|
|
// instance names.
|
|
#define DCREF_FLAG_ANSI 0x00000010
|
|
|
|
// NOTE: Other notification flags in wmium.h are:
|
|
// NOTIFICATION_TRACE_FLAG 0x00010000
|
|
//
|
|
// NOTIFICATION_FLAG_CALLBACK_DIRECT is set when NotifyAddress specifies
|
|
// a direct callback address for delivering the event.
|
|
//
|
|
// NOTIFICATION_FLAG_CALLBACK_DIRECT is set when NotifyAddress specifies
|
|
// a direct callback address for delivering the event.
|
|
//
|
|
#define NOTIFICATION_FLAG_CALLBACK_DIRECT 0x00020000
|
|
#define NOTIFICATION_FLAG_CALLBACK_QUEUED 0x00040000
|
|
#define NOTIFICATION_FLAG_WINDOW 0x00080000
|
|
#define NOTIFICATION_FLAG_BATCHED 0x00100000
|
|
|
|
//
|
|
// This flag is set for those guid handles that may be duplicated in
|
|
// the list. All Notifyee slots that have this flag are considered in a
|
|
// group and only one handle needs to be put on the list
|
|
//
|
|
#define NOTIFICATION_FLAG_GROUPED_EVENT 0x00200000
|
|
|
|
//
|
|
// This flag is set for those guid handles that are pending closure.
|
|
// Only the pump thread is allowed to close a handle; the main threads
|
|
// will set this flag to indicate that the handle should no longer be
|
|
// used. When the pump thread builds the list of handles and notices
|
|
// the flag it will close the handle.
|
|
//
|
|
#define NOTIFICATION_FLAG_PENDING_CLOSE 0x00400000
|
|
|
|
#define EtwpIsNotifyeePendingClose(Notifyee) \
|
|
(((Notifyee)->Flags & NOTIFICATION_FLAG_PENDING_CLOSE) == NOTIFICATION_FLAG_PENDING_CLOSE)
|
|
|
|
|
|
//
|
|
// These are the flags contained in DcRef->Flags that pertain to Notifications
|
|
#define NOTIFICATION_MASK_EVENT_FLAGS \
|
|
(NOTIFICATION_FLAG_CALLBACK_DIRECT | \
|
|
NOTIFICATION_FLAG_CALLBACK_QUEUED | \
|
|
NOTIFICATION_FLAG_WINDOW | \
|
|
DCREF_FLAG_NO_EXTRA_THREAD | \
|
|
DCREF_FLAG_ANSI)
|
|
|
|
|
|
//
|
|
// This defines the number of DC references a NOTIFICATIONENTRY can have
|
|
// in a single entry
|
|
|
|
// CONSIDER: Merging NOTIFICATIONENTRY with GUIDENTRY
|
|
#define DCREFPERNOTIFICATION 16
|
|
|
|
typedef struct _notificationentry
|
|
{
|
|
LIST_ENTRY MainNotificationList; // Node in main notifications list
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags; // flags
|
|
ULONG RefCount;
|
|
|
|
// Signature to identify entry
|
|
ULONG Signature;
|
|
|
|
GUID Guid; // guid representing notification
|
|
// If > DCREFPERNOTIFICATION DC have
|
|
// enabled this event then this points
|
|
// to another NOTIFICATIONENTRY which
|
|
// has another DCREF array
|
|
struct _notificationentry *Continuation;
|
|
ULONG EventRefCount; // Global count of event enables
|
|
ULONG CollectRefCount; // Global count of collection enables
|
|
ULONG64 LoggerContext; // Logger context handle
|
|
|
|
HANDLE CollectInProgress; // Event set when all collect complete
|
|
|
|
DCREF DcRef[DCREFPERNOTIFICATION]; // DC that have enabled this event
|
|
} NOTIFICATIONENTRY, *PNOTIFICATIONENTRY;
|
|
|
|
#define NE_SIGNATURE 'eluJ'
|
|
|
|
// Set when a notification request is being processed by the data providers
|
|
#define NE_FLAG_NOTIFICATION_IN_PROGRESS 0x00000001
|
|
|
|
// Set when a collection request is being processed by the data providers
|
|
#define NE_FLAG_COLLECTION_IN_PROGRESS 0x00000002
|
|
|
|
// Set when a trace disable is being processed by a worker thread
|
|
#define NE_FLAG_TRACEDISABLE_IN_PROGRESS 0x00000004
|
|
|
|
#ifdef WMI_USER_MODE
|
|
//
|
|
// Valid MOF data types for qualifiers and properties (data items)
|
|
typedef enum
|
|
{
|
|
MOFInt32 = 0, // 32bit integer
|
|
MOFUInt32 = 1, // 32bit unsigned integer
|
|
MOFInt64 = 2, // 64bit integer
|
|
MOFUInt64 = 3, // 32bit unsigned integer
|
|
MOFInt16 = 4, // 16bit integer
|
|
MOFUInt16 = 5, // 16bit unsigned integer
|
|
MOFChar = 6, // 8bit integer
|
|
MOFByte = 7, // 8bit unsigned integer
|
|
MOFWChar = 8, // Wide (16bit) character
|
|
MOFDate = 9, // Date field
|
|
MOFBoolean = 10, // 8bit Boolean value
|
|
MOFEmbedded = 11, // Embedded class
|
|
MOFString = 12, // Counted String type
|
|
MOFZTString = 13, // NULL terminated unicode string
|
|
MOFAnsiString = 14, // NULL terminated ansi string
|
|
MOFUnknown = 0xffffffff // Data type is not known
|
|
} MOFDATATYPE, *PMOFDATATYPE;
|
|
|
|
// Data items that are of type MOFString are stored in the data block as a
|
|
// counted unicode string. The text of the string is always preceeded by
|
|
// a USHORT which contains the count of bytes following that composes the
|
|
// string. The string may be NULL terminated and in that case the count must
|
|
// include the null termination bytes.
|
|
|
|
|
|
// Data items that are of type MOFDate are fixed length Unicode strings and
|
|
// not preceeded by a count value. It is in the following fixed format:
|
|
//
|
|
// yyyymmddhhmmss.mmmmmmsutc
|
|
//
|
|
// Where yyyy is a 4 digit year, mm is the month, dd is the day, hh is
|
|
// the hour (24-hour clock), mm is the minute, ss is the second, the
|
|
// mmmmmm is the number of microseconds (typically all zeros) and s is a
|
|
// "+" or "-" indicating the sign of the UTC (correction field, and utc
|
|
// is the offset from UTC in minutes (using the sign indicated by s).
|
|
// For example, Wednesday, May 25, 1994, at 1:30:15 PM EDT would be
|
|
// represented as:
|
|
//
|
|
// 19940525133015.0000000-300
|
|
//
|
|
// Values MUST be zero-padded so that the entire string is always the
|
|
// same 25-character length. Fields which are not significant MUST be
|
|
// replaced with asterisk characters. Similarly, intervals use the
|
|
// same format, except that the interpretation of the fields is based
|
|
// on elapsed time. For example, an elapsed time of 1 day, 13 hours,
|
|
// 23 minutes, and 12 seconds would be:
|
|
//
|
|
// 00000001132312.000000+000
|
|
//
|
|
// A UTC offset of zero is always used for interval properties.
|
|
|
|
struct _MOFCLASSINFOW;
|
|
struct _MOFCLASSINFOA;
|
|
|
|
//
|
|
// Each class has one or more data items that are described by a MOFDATAITEM
|
|
// structure.
|
|
typedef struct
|
|
{
|
|
#ifdef MIDL_PASS
|
|
[string] PDFWCHAR
|
|
#else
|
|
LPWSTR
|
|
#endif
|
|
Name; // Text name of data item
|
|
#ifdef MIDL_PASS
|
|
[string] PDFWCHAR
|
|
#else
|
|
LPWSTR
|
|
#endif
|
|
Description; // Text description of data item
|
|
MOFDATATYPE DataType; // MOF data type
|
|
ULONG Version; // Version that this MOF is part of
|
|
ULONG SizeInBytes; // Size of data item in Blob
|
|
ULONG Flags; // Flags, See MOFDI_FLAG_*
|
|
GUID EmbeddedClassGuid; // Guid of data item's embedded class
|
|
ULONG FixedArrayElements; // Number of elements in fixed sized array
|
|
// Used when MOF_FLAG_FIXED_ARRAY is set
|
|
|
|
ULONG VariableArraySizeId; // MOF_FLAG_VARIABLE_ARRAY, Data id of
|
|
// variable containing number of elements
|
|
// in array
|
|
|
|
PVOID VarArrayTempPtr;
|
|
PVOID EcTempPtr;
|
|
ULONG_PTR PropertyQualifierHandle;
|
|
ULONG MethodId;
|
|
LPWSTR HeaderName;// Name of structure in generated header
|
|
struct _MOFCLASSINFOW *MethodClassInfo;
|
|
ULONG MaxLen;
|
|
} MOFDATAITEMW, *PMOFDATAITEMW;
|
|
|
|
typedef struct
|
|
{
|
|
LPSTR
|
|
Name; // Text name of data item
|
|
LPSTR
|
|
Description; // Text description of data item
|
|
MOFDATATYPE DataType; // MOF data type
|
|
ULONG Version; // Version that this MOF is part of
|
|
ULONG SizeInBytes; // Size of data item in Blob
|
|
ULONG Flags; // Flags, See MOFDI_FLAG_*
|
|
GUID EmbeddedClassGuid; // Guid of data item's embedded class
|
|
ULONG FixedArrayElements; // Number of elements in fixed sized array
|
|
// Used when MOF_FLAG_FIXED_ARRAY is set
|
|
|
|
ULONG VariableArraySizeId; // MOF_FLAG_VARIABLE_ARRAY, Data id of
|
|
// variable containing number of elements
|
|
// in array
|
|
PVOID VarArrayTempPtr;
|
|
PVOID EcTempPtr;
|
|
ULONG_PTR PropertyQualifierHandle;
|
|
ULONG MethodId;
|
|
LPSTR HeaderName; // Name of structure in generated header
|
|
struct _MOFCLASSINFOA *MethodClassInfo;
|
|
ULONG MaxLen;
|
|
} MOFDATAITEMA, *PMOFDATAITEMA;
|
|
|
|
#ifdef UNICODE
|
|
typedef MOFDATAITEMW MOFDATAITEM;
|
|
typedef PMOFDATAITEMW PMOFDATAITEM;
|
|
#else
|
|
typedef MOFDATAITEMA MOFDATAITEM;
|
|
typedef PMOFDATAITEMA PMOFDATAITEM;
|
|
#endif
|
|
|
|
|
|
// Data item is actually a fixed sized array
|
|
#define MOFDI_FLAG_FIXED_ARRAY 0x00000001
|
|
|
|
// Data item is actually a variable length array
|
|
#define MOFDI_FLAG_VARIABLE_ARRAY 0x00000002
|
|
|
|
// Data item is actually an embedded class
|
|
#define MOFDI_FLAG_EMBEDDED_CLASS 0x00000004
|
|
|
|
// Data item is readable
|
|
#define MOFDI_FLAG_READABLE 0x00000008
|
|
|
|
// Data item is writable
|
|
#define MOFDI_FLAG_WRITEABLE 0x00000010
|
|
|
|
// Data item is an event
|
|
#define MOFDI_FLAG_EVENT 0x00000020
|
|
|
|
// Embedded class Guid is not set
|
|
#define MOFDI_FLAG_EC_GUID_NOT_SET 0x00000040
|
|
|
|
// Data item is really a method
|
|
#define MOFDI_FLAG_METHOD 0x00000080
|
|
|
|
// Data item is an input method parameter
|
|
#define MOFDI_FLAG_INPUT_METHOD 0x00000100
|
|
|
|
// Data item is an output method parameter
|
|
#define MOFDI_FLAG_OUTPUT_METHOD 0x00000200
|
|
|
|
//
|
|
// The MOFCLASSINFO structure describes the format of a data block
|
|
typedef struct _MOFCLASSINFOW
|
|
{
|
|
GUID Guid; // Guid that represents class
|
|
|
|
#ifdef MIDL_PASS
|
|
[string] PDFWCHAR
|
|
#else
|
|
LPWSTR
|
|
#endif
|
|
Name; // Text name of class
|
|
#ifdef MIDL_PASS
|
|
[string] PDFWCHAR
|
|
#else
|
|
LPWSTR
|
|
#endif
|
|
Description;// Text description of class
|
|
#ifdef MIDL_PASS
|
|
[string] PDFWCHAR
|
|
#else
|
|
LPWSTR
|
|
#endif
|
|
HeaderName;// Name of structure in generated header
|
|
#ifdef MIDL_PASS
|
|
[string] PDFWCHAR
|
|
#else
|
|
LPWSTR
|
|
#endif
|
|
GuidName1;// Name of Guid in generated header
|
|
#ifdef MIDL_PASS
|
|
[string] PDFWCHAR
|
|
#else
|
|
LPWSTR
|
|
#endif
|
|
GuidName2;// Name of Guid in generated header
|
|
USHORT Language; // Language of MOF
|
|
USHORT Reserved;
|
|
ULONG Flags; // Flags, see MOFGI_FLAG_*
|
|
ULONG Version; // Version of Guid
|
|
ULONG_PTR ClassQualifierHandle; // CBMOFObj, BMOF class qualifier ptr
|
|
ULONG DataItemCount; // Number of wmi data items (properties)
|
|
ULONG MethodCount; // Number of wmi data items (properties)
|
|
// Array of Property info
|
|
#ifdef MIDL_PASS
|
|
[size_is(DataItemCount)]
|
|
#endif
|
|
MOFDATAITEMW *DataItems;
|
|
#ifndef MIDL_PASS
|
|
UCHAR Tail[1];
|
|
#endif
|
|
} MOFCLASSINFOW, *PMOFCLASSINFOW;
|
|
|
|
typedef struct _MOFCLASSINFOA
|
|
{
|
|
GUID Guid; // Guid that represents class
|
|
|
|
LPSTR
|
|
Name; // Text name of class
|
|
LPSTR
|
|
Description;// Text description of class
|
|
LPSTR
|
|
HeaderName;// Name of structure in generated header
|
|
LPSTR
|
|
GuidName1;// Name of Guid in generated header
|
|
LPSTR
|
|
GuidName2;// Name of Guid in generated header
|
|
USHORT Language; // Language of MOF
|
|
USHORT Reserved;
|
|
ULONG Flags; // Flags, see MOFGI_FLAG_*
|
|
ULONG Version; // Version of Guid
|
|
ULONG_PTR ClassQualifierHandle; // CBMOFObj, BMOF class qualifier ptr
|
|
ULONG DataItemCount; // Number of wmi data items (properties)
|
|
ULONG MethodCount; // Number of wmi data items (properties)
|
|
// Array of Property info
|
|
MOFDATAITEMA *DataItems;
|
|
UCHAR Tail[1];
|
|
} MOFCLASSINFOA, *PMOFCLASSINFOA;
|
|
|
|
#ifdef UNICODE
|
|
typedef MOFCLASSINFOW MOFCLASSINFO;
|
|
typedef PMOFCLASSINFOW PMOFCLASSINFO;
|
|
#else
|
|
typedef MOFCLASSINFOA MOFCLASSINFO;
|
|
typedef PMOFCLASSINFOA PMOFCLASSINFO;
|
|
#endif
|
|
|
|
// 0x00000001 to 0x00000004 are not available
|
|
#define MOFCI_FLAG_EVENT 0x10000000
|
|
#define MOFCI_FLAG_EMBEDDED_CLASS 0x20000000
|
|
#define MOFCI_FLAG_READONLY 0x40000000
|
|
#define MOFCI_FLAG_METHOD_PARAMS 0x80000000
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
// Entry in list of all DS
|
|
LIST_ENTRY MainMCList;
|
|
|
|
// Entry in list of free DS
|
|
LIST_ENTRY FreeMCList;
|
|
};
|
|
PCHUNKHEADER Chunk; // Chunk in which entry is located
|
|
ULONG Flags;
|
|
|
|
ULONG RefCount;
|
|
|
|
PMOFCLASSINFOW MofClassInfo; // Actual class info data
|
|
|
|
LIST_ENTRY MCMRList; // Entry in list of MCs in a MR
|
|
|
|
LIST_ENTRY MCVersionList; // Head or entry in list of MCs with
|
|
// same guid, but possibly different versions
|
|
|
|
ULONG_PTR ClassObjectHandle; // CBMOFObj, BMOF class object ptr
|
|
PMOFRESOURCE MofResource; // Resource holding class info
|
|
|
|
} MOFCLASS, *PMOFCLASS;
|
|
|
|
// If this is set then the MOF class can never be replaced with a later version
|
|
#define MC_FLAG_NEVER_REPLACE 0x00000001
|
|
|
|
#endif
|
|
|
|
//
|
|
// AVGGUIDSPERDS defines a guess as to the number of guids that get registered
|
|
// by any data provider. It is used to allocate the buffer used to deliver
|
|
// registration change notifications.
|
|
#if DBG
|
|
#define AVGGUIDSPERDS 2
|
|
#else
|
|
#define AVGGUIDSPERDS 256
|
|
#endif
|
|
|
|
|
|
#define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)(Base) + (Offset)))
|
|
|
|
|
|
|
|
//
|
|
// Guid and InstanceSet cache
|
|
#if DBG
|
|
#define PTRCACHEGROWSIZE 2
|
|
#else
|
|
#define PTRCACHEGROWSIZE 64
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
LPGUID Guid;
|
|
PBINSTANCESET InstanceSet;
|
|
} PTRCACHE;
|
|
|
|
|
|
//
|
|
// Registration data structures
|
|
//
|
|
|
|
#ifdef MEMPHIS
|
|
|
|
extern HANDLE SMMutex;
|
|
#define EtwpEnterSMCritSection() WaitForSingleObject(SMMutex, INFINITE)
|
|
|
|
#define EtwpLeaveSMCritSection() ReleaseMutex(SMMutex)
|
|
|
|
#else
|
|
extern RTL_CRITICAL_SECTION SMCritSect;
|
|
#if DBG
|
|
#ifdef CRITSECTTRACE
|
|
#define EtwpEnterSMCritSection() { \
|
|
EtwpDebugPrint(("WMI: Enter SM Crit %s %d\n", __FILE__, __LINE__)); \
|
|
RtlEnterCriticalSection(&SMCritSect); }
|
|
|
|
#define EtwpLeaveSMCritSection() { \
|
|
EtwpDebugPrint(("WMI: Leave SM Crit %s %d\n", __FILE__, __LINE__)); \
|
|
RtlLeaveCriticalSection(&SMCritSect); }
|
|
#else
|
|
#define EtwpEnterSMCritSection() \
|
|
EtwpAssert(NT_SUCCESS(RtlEnterCriticalSection(&SMCritSect)));
|
|
#define EtwpLeaveSMCritSection() { \
|
|
EtwpAssert(SMCritSect.LockCount >= 0); \
|
|
EtwpAssert(NT_SUCCESS(RtlLeaveCriticalSection(&SMCritSect))); }
|
|
#endif // CRITSECTTRACE
|
|
|
|
#else
|
|
#define EtwpEnterSMCritSection() RtlEnterCriticalSection(&SMCritSect)
|
|
#define EtwpLeaveSMCritSection() RtlLeaveCriticalSection(&SMCritSect)
|
|
#endif // DBG
|
|
#endif // MEMPHIS
|
|
|
|
#ifndef IsEqualGUID
|
|
#define IsEqualGUID(guid1, guid2) \
|
|
(!memcmp((guid1), (guid2), sizeof(GUID)))
|
|
#endif
|
|
|
|
|
|
//
|
|
// WMI MOF result codes. Since they are never given to the caller they are
|
|
// defined in here
|
|
#define ERROR_WMIMOF_INCORRECT_DATA_TYPE -1 /* 0xffffffff */
|
|
#define ERROR_WMIMOF_NO_DATA -2 /* 0xfffffffe */
|
|
#define ERROR_WMIMOF_NOT_FOUND -3 /* 0xfffffffd */
|
|
#define ERROR_WMIMOF_UNUSED -4 /* 0xfffffffc */
|
|
// Property %ws in class %ws has no embedded class name
|
|
#define ERROR_WMIMOF_NO_EMBEDDED_CLASS_NAME -5 /* 0xfffffffb */
|
|
// Property %ws in class %ws has an unknown data type
|
|
#define ERROR_WMIMOF_UNKNOWN_DATA_TYPE -6 /* 0xfffffffa */
|
|
// Property %ws in class %ws has no syntax qualifier
|
|
#define ERROR_WMIMOF_NO_SYNTAX_QUALIFIER -7 /* 0xfffffff9 */
|
|
#define ERROR_WMIMOF_NO_CLASS_NAME -8 /* 0xfffffff8 */
|
|
#define ERROR_WMIMOF_BAD_DATA_FORMAT -9 /* 0xfffffff7 */
|
|
// Property %ws in class %ws has the same WmiDataId %d as property %ws
|
|
#define ERROR_WMIMOF_DUPLICATE_ID -10 /* 0xfffffff6 */
|
|
// Property %ws in class %ws has a WmiDataId of %d which is out of range
|
|
#define ERROR_WMIMOF_BAD_DATAITEM_ID -11 /* 0xfffffff5 */
|
|
#define ERROR_WMIMOF_MISSING_DATAITEM -12 /* 0xfffffff4 */
|
|
// Property for WmiDataId %d is not defined in class %ws
|
|
#define ERROR_WMIMOF_DATAITEM_NOT_FOUND -13 /* 0xfffffff3 */
|
|
// Embedded class %ws not defined for Property %ws in Class %ws
|
|
#define ERROR_WMIMOF_EMBEDDED_CLASS_NOT_FOUND -14 /* 0xfffffff2 */
|
|
// Property %ws in class %ws has an incorrect [WmiVersion] qualifier
|
|
#define ERROR_WMIMOF_INCONSISTENT_VERSIONING -15 /* 0xfffffff1 */
|
|
#define ERROR_WMIMOF_NO_PROPERTY_QUALIFERS -16 /* 0xfffffff0 */
|
|
// Class %ws has a badly formed or missing [guid] qualifier
|
|
#define ERROR_WMIMOF_BAD_OR_MISSING_GUID -17 /* 0xffffffef */
|
|
// Could not find property %ws which is the array size for property %ws in class %ws
|
|
#define ERROR_WMIMOF_VL_ARRAY_SIZE_NOT_FOUND -18 /* 0xffffffee */
|
|
// A class could not be parsed properly
|
|
#define ERROR_WMIMOF_CLASS_NOT_PARSED -19 /* 0xffffffed */
|
|
// Wmi class %ws requires the qualifiers [Dynamic, Provider("WmiProv")]
|
|
#define ERROR_WMIMOF_MISSING_HMOM_QUALIFIERS -20 /* 0xffffffec */
|
|
// Error accessing binary mof file %s
|
|
#define ERROR_WMIMOF_CANT_ACCESS_FILE -21 /* 0xffffffeb */
|
|
// Property InstanceName in class %ws must be type string and not %ws
|
|
#define ERROR_WMIMOF_INSTANCENAME_BAD_TYPE -22 /* 0xffffffea */
|
|
// Property Active in class %ws must be type bool and not %ws
|
|
#define ERROR_WMIMOF_ACTIVE_BAD_TYPE -23 /* 0xffffffe9 */
|
|
// Property %ws in class %ws does not have [WmiDataId()] qualifier
|
|
#define ERROR_WMIMOF_NO_WMIDATAID -24 /* 0xffffffe8 */
|
|
// Property InstanceName in class %ws must have [key] qualifier
|
|
#define ERROR_WMIMOF_INSTANCENAME_NOT_KEY -25 /* 0xffffffe7 */
|
|
// Class %ws does not have an InstanceName qualifier
|
|
#define ERROR_WMIMOF_NO_INSTANCENAME -26 /* 0xffffffe6 */
|
|
// Class %ws does not have an Active qualifier
|
|
#define ERROR_WMIMOF_NO_ACTIVE -27 /* 0xffffffe5 */
|
|
// Property %ws in class %ws is an array, but doesn't specify a dimension
|
|
#define ERROR_WMIMOF_MUST_DIM_ARRAY -28 /* 0xffffffe4 */
|
|
// The element count property %ws for the variable length array %ws in class %ws is not an integral type
|
|
#define ERROR_WMIMOF_BAD_VL_ARRAY_SIZE_TYPE -29 /* 0xdddddde4 */
|
|
// Property %ws in class %ws is both a fixed and variable length array
|
|
#define ERROR_WMIMOF_BOTH_FIXED_AND_VARIABLE_ARRAY -30 /* 0xffffffe3 */
|
|
// Embedded class %ws should not have InstaneName or Active properties
|
|
#define ERROR_WMIMOF_EMBEDDED_CLASS -31 /* 0xffffffe2 */
|
|
#define ERROR_WMIMOF_IMPLEMENTED_REQUIRED -32 /* 0xffffffe1 */
|
|
// TEXT("WmiMethodId for method %ws in class %ws must be unique")
|
|
#define ERROR_WMIMOF_DUPLICATE_METHODID -33 /* 0xffffffe0 */
|
|
// TEXT("WmiMethodId for method %ws in class %ws must be specified")
|
|
#define ERROR_WMIMOF_MISSING_METHODID -34 /* 0xffffffdf */
|
|
// TEXT("WmiMethodId for method %ws in class %ws must not be 0")
|
|
#define ERROR_WMIMOF_METHODID_ZERO -35 /* 0xffffffde */
|
|
// TEXT("Class %ws is derived from WmiEvent and may not be [abstract]")
|
|
#define ERROR_WMIMOF_WMIEVENT_ABSTRACT -36 /* 0xffffffdd */
|
|
// TEXT("The element count property for the variable length array
|
|
// %ws in class %ws is not a property of the class"),
|
|
#define ERROR_WMIMOF_VL_ARRAY_NOT_FOUND -37 /* 0xffffffdc */
|
|
// TEXT("An error occured resolving the variable length array
|
|
// property %ws in class %ws to element count property")
|
|
#define ERROR_WMIMOF_VL_ARRAY_NOT_RESOLVED -38 /* 0xffffffdb */
|
|
// TEXT("Method %ws in class %ws must return void\n")
|
|
#define ERROR_WMIMOF_METHOD_RETURN_NOT_VOID -39 /* 0xffffffda */
|
|
// TEXT("Embedded class %ws should not have any methods\n")
|
|
#define ERROR_WMIMOF_EMBEDDED_CLASS_HAS_METHODS -40 /* 0xffffffd9 */
|
|
|
|
#define ERROR_WMIMOF_COUNT 40
|
|
|
|
// This file is not a valid binary mof file
|
|
// ERROR_WMI_INVALID_MOF
|
|
|
|
// There was not enough memory to complete an operation
|
|
// ERROR_NOT_ENOUGH_MEMORY
|
|
|
|
//
|
|
// Function prototypes for private functions
|
|
|
|
//
|
|
// sharemem.c
|
|
ULONG EtwpEstablishSharedMemory(
|
|
PBDATASOURCE DataSource,
|
|
LPCTSTR SectionName,
|
|
ULONG SectionSize
|
|
);
|
|
|
|
//
|
|
// validate.c
|
|
BOOLEAN EtwpValidateCountedString(
|
|
WCHAR *String
|
|
);
|
|
|
|
BOOLEAN EtwpValidateGuid(
|
|
LPGUID Guid
|
|
);
|
|
|
|
BOOLEAN EtwpProbeForRead(
|
|
PUCHAR Buffer,
|
|
ULONG BufferSize
|
|
);
|
|
|
|
//
|
|
// alloc.c
|
|
|
|
extern LIST_ENTRY GEHead;
|
|
extern PLIST_ENTRY GEHeadPtr;
|
|
extern CHUNKINFO GEChunkInfo;
|
|
|
|
extern LIST_ENTRY NEHead;
|
|
extern PLIST_ENTRY NEHeadPtr;
|
|
extern CHUNKINFO NEChunkInfo;
|
|
|
|
extern LIST_ENTRY DSHead;
|
|
extern PLIST_ENTRY DSHeadPtr;
|
|
extern CHUNKINFO DSChunkInfo;
|
|
|
|
extern LIST_ENTRY DCHead;
|
|
extern PLIST_ENTRY DCHeadPtr;
|
|
extern CHUNKINFO DCChunkInfo;
|
|
|
|
extern LIST_ENTRY MRHead;
|
|
extern PLIST_ENTRY MRHeadPtr;
|
|
extern CHUNKINFO MRChunkInfo;
|
|
|
|
extern CHUNKINFO ISChunkInfo;
|
|
|
|
extern LIST_ENTRY GMHead;
|
|
extern PLIST_ENTRY GMHeadPtr;
|
|
|
|
#ifdef WMI_USER_MODE
|
|
extern LIST_ENTRY MCHead;
|
|
extern PLIST_ENTRY MCHeadPtr;
|
|
extern CHUNKINFO MCChunkInfo;
|
|
#endif
|
|
|
|
#ifdef TRACK_REFERNECES
|
|
#define EtwpUnreferenceDS(DataSource) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Unref DS %x at %s %d\n", DataSource, __FILE__, __LINE__)); \
|
|
EtwpUnreferenceEntry(&DSChunkInfo, (PENTRYHEADER)DataSource); \
|
|
}
|
|
|
|
#define EtwpReferenceDS(DataSource) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Ref DS %x at %s %d\n", DataSource, __FILE__, __LINE__)); \
|
|
EtwpReferenceEntry((PENTRYHEADER)DataSource); \
|
|
}
|
|
|
|
#define EtwpUnreferenceGE(GuidEntry) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Unref GE %x at %s %d\n", GuidEntry, __FILE__, __LINE__)); \
|
|
EtwpUnreferenceEntry(&GEChunkInfo, (PENTRYHEADER)GuidEntry); \
|
|
}
|
|
|
|
#define EtwpReferenceGE(GuidEntry) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Ref GE %x at %s %d\n", GuidEntry, __FILE__, __LINE__)); \
|
|
EtwpReferenceEntry((PENTRYHEADER)GuidEntry); \
|
|
}
|
|
|
|
#define EtwpUnreferenceIS(InstanceSet) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Unref IS %x at %s %d\n", InstanceSet, __FILE__, __LINE__)); \
|
|
EtwpUnreferenceEntry(&ISChunkInfo, (PENTRYHEADER)InstanceSet); \
|
|
}
|
|
|
|
#define EtwpReferenceIS(InstanceSet) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Ref IS %x at %s %d\n", InstanceSet, __FILE__, __LINE__)); \
|
|
EtwpReferenceEntry((PENTRYHEADER)InstanceSet); \
|
|
}
|
|
|
|
#define EtwpUnreferenceDC(DataConsumer) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Unref DC %x at %s %d\n", DataConsumer, __FILE__, __LINE__)); \
|
|
EtwpUnreferenceEntry(&DCChunkInfo, (PENTRYHEADER)DataConsumer); \
|
|
}
|
|
|
|
#define EtwpReferenceDC(DataConsumer) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Ref DC %x at %s %d\n", DataConsumer, __FILE__, __LINE__)); \
|
|
EtwpReferenceEntry((PENTRYHEADER)DataConsumer); \
|
|
}
|
|
|
|
#define EtwpUnreferenceNE(NotificationEntry) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Unref NE %x at %s %d\n", NotificationEntry, __FILE__, __LINE__)); \
|
|
EtwpUnreferenceEntry(&NEChunkInfo, (PENTRYHEADER)NotificationEntry); \
|
|
}
|
|
|
|
#define EtwpReferenceNE(NotificationEntry) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Ref NE %x at %s %d\n", NotificationEntry, __FILE__, __LINE__)); \
|
|
EtwpReferenceEntry((PENTRYHEADER)NotificationEntry); \
|
|
}
|
|
|
|
#define WmippUnreferenceMR(MofResource) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Unref MR %x at %s %d\n", MofResource, __FILE__, __LINE__)); \
|
|
EtwpUnreferenceEntry(&MRChunkInfo, (PENTRYHEADER)MofResource); \
|
|
}
|
|
|
|
#define WmipReferenceMR(MofResource) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Ref MR %x at %s %d\n", MofResource, __FILE__, __LINE__)); \
|
|
EtwpReferenceEntry((PENTRYHEADER)MofResource); \
|
|
}
|
|
|
|
#ifdef WMI_USER_MODE
|
|
#define EtwpUnreferenceMC(MofClass) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Unref MC %x at %s %d\n", MofClass, __FILE__, __LINE__)); \
|
|
EtwpUnreferenceEntry(&MCChunkInfo, (PENTRYHEADER)MofClass); \
|
|
}
|
|
|
|
#define EtwpReferenceMC(MofClass) \
|
|
{ \
|
|
EtwpDebugPrint(("WMI: Ref MC %x at %s %d\n", MofClass, __FILE__, __LINE__)); \
|
|
EtwpReferenceEntry((PENTRYHEADER)MofClass); \
|
|
}
|
|
#endif
|
|
#else
|
|
#define EtwpUnreferenceDS(DataSource) \
|
|
EtwpUnreferenceEntry(&DSChunkInfo, (PENTRYHEADER)DataSource)
|
|
|
|
#define EtwpReferenceDS(DataSource) \
|
|
EtwpReferenceEntry((PENTRYHEADER)DataSource)
|
|
|
|
#define EtwpUnreferenceGE(GuidEntry) \
|
|
EtwpUnreferenceEntry(&GEChunkInfo, (PENTRYHEADER)GuidEntry)
|
|
|
|
#define EtwpReferenceGE(GuidEntry) \
|
|
EtwpReferenceEntry((PENTRYHEADER)GuidEntry)
|
|
|
|
#define EtwpUnreferenceIS(InstanceSet) \
|
|
EtwpUnreferenceEntry(&ISChunkInfo, (PENTRYHEADER)InstanceSet)
|
|
|
|
#define EtwpReferenceIS(InstanceSet) \
|
|
EtwpReferenceEntry((PENTRYHEADER)InstanceSet)
|
|
|
|
#define EtwpUnreferenceDC(DataConsumer) \
|
|
EtwpUnreferenceEntry(&DCChunkInfo, (PENTRYHEADER)DataConsumer)
|
|
|
|
#define EtwpReferenceDC(DataConsumer) \
|
|
EtwpReferenceEntry((PENTRYHEADER)DataConsumer)
|
|
|
|
#define EtwpUnreferenceNE(NotificationEntry) \
|
|
EtwpUnreferenceEntry(&NEChunkInfo, (PENTRYHEADER)NotificationEntry)
|
|
|
|
#define EtwpReferenceNE(NotificationEntry) \
|
|
EtwpReferenceEntry((PENTRYHEADER)NotificationEntry)
|
|
|
|
#define WmipUnreferenceMR(MofResource) \
|
|
EtwpUnreferenceEntry(&MRChunkInfo, (PENTRYHEADER)MofResource)
|
|
|
|
#define WmipReferenceMR(MofResource) \
|
|
EtwpReferenceEntry((PENTRYHEADER)MofResource)
|
|
|
|
#ifdef WMI_USER_MODE
|
|
#define EtwpUnreferenceMC(MofClass) \
|
|
EtwpUnreferenceEntry(&MCChunkInfo, (PENTRYHEADER)MofClass)
|
|
|
|
#define EtwpReferenceMC(MofClass) \
|
|
EtwpReferenceEntry((PENTRYHEADER)MofClass)
|
|
#endif
|
|
#endif
|
|
|
|
PBDATASOURCE EtwpAllocDataSource(
|
|
void
|
|
);
|
|
|
|
PBGUIDENTRY EtwpAllocGuidEntry(
|
|
void
|
|
);
|
|
|
|
#define EtwpAllocInstanceSet() ((PBINSTANCESET)EtwpAllocEntry(&ISChunkInfo))
|
|
#define EtwpAllocDataConsumer() ((PDCENTRY)EtwpAllocEntry(&DCChunkInfo))
|
|
|
|
#define EtwpAllocNotificationEntry() ((PNOTIFICATIONENTRY)EtwpAllocEntry(&NEChunkInfo))
|
|
|
|
#define EtwpAllocMofResource() ((PMOFRESOURCE)EtwpAllocEntry(&MRChunkInfo))
|
|
|
|
#define WmipDebugPrint EtwpDebugPrint
|
|
#define WmipAlloc EtwpAlloc
|
|
#define WmipAssert EtwpAssert
|
|
#define WmipFree EtwpFree
|
|
|
|
#ifdef WMI_USER_MODE
|
|
#define EtwpAllocMofClass() ((PMOFCLASS)EtwpAllocEntry(&MCChunkInfo))
|
|
#endif
|
|
|
|
#define EtwpAllocString(Size) \
|
|
EtwpAlloc((Size)*sizeof(WCHAR))
|
|
|
|
#define EtwpFreeString(Ptr) \
|
|
EtwpFree(Ptr)
|
|
|
|
#ifdef MEMPHIS
|
|
#define EtwpAlloc(Size) \
|
|
malloc(Size)
|
|
|
|
#define EtwpFree(Ptr) \
|
|
free(Ptr)
|
|
|
|
#define EtwpInitProcessHeap()
|
|
#else
|
|
|
|
//
|
|
// Reserve 1MB for WMI.DLL, but only commit 16K initially
|
|
#define DLLRESERVEDHEAPSIZE 1024 * 1024
|
|
#define DLLCOMMITHEAPSIZE 0 * 1024
|
|
|
|
//
|
|
// Reserve 1MB for WMI service, but only commit 16K initially
|
|
#define CORERESERVEDHEAPSIZE 1024 * 1024
|
|
#define CORECOMMITHEAPSIZE 16 * 1024
|
|
|
|
|
|
extern PVOID EtwpProcessHeap;
|
|
|
|
#define EtwpInitProcessHeap() \
|
|
{ \
|
|
if (EtwpProcessHeap == NULL) \
|
|
{ \
|
|
EtwpCreateHeap(); \
|
|
} \
|
|
}
|
|
|
|
|
|
#ifdef HEAPVALIDATION
|
|
PVOID EtwpAlloc(
|
|
ULONG Size
|
|
);
|
|
|
|
void EtwpFree(
|
|
PVOID p
|
|
);
|
|
|
|
#else
|
|
#if DBG
|
|
_inline PVOID EtwpAlloc(ULONG Size)
|
|
{
|
|
EtwpAssert(EtwpProcessHeap != NULL);
|
|
return(RtlAllocateHeap(EtwpProcessHeap, 0, Size));
|
|
}
|
|
|
|
_inline void EtwpFree(PVOID Ptr)
|
|
{
|
|
RtlFreeHeap(EtwpProcessHeap, 0, Ptr);
|
|
}
|
|
|
|
#else
|
|
#define EtwpAlloc(Size) \
|
|
RtlAllocateHeap(EtwpProcessHeap, 0, Size)
|
|
|
|
#define EtwpFree(Ptr) \
|
|
RtlFreeHeap(EtwpProcessHeap, 0, Ptr)
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
BOOLEAN EtwpRealloc(
|
|
PVOID *Buffer,
|
|
ULONG CurrentSize,
|
|
ULONG NewSize,
|
|
BOOLEAN FreeOriginalBuffer
|
|
);
|
|
|
|
|
|
//
|
|
// datastr.c
|
|
extern GUID EtwpBinaryMofGuid;
|
|
|
|
void EtwpGenerateBinaryMofNotification(
|
|
PBINSTANCESET BianryMofInstanceSet,
|
|
LPCGUID Guid
|
|
);
|
|
|
|
BOOLEAN EtwpEstablishInstanceSetRef(
|
|
PBDATASOURCE DataSourceRef,
|
|
LPGUID Guid,
|
|
PBINSTANCESET InstanceSet
|
|
);
|
|
|
|
ULONG EtwpAddDataSource(
|
|
PTCHAR QueryBinding,
|
|
ULONG RequestAddress,
|
|
ULONG RequestContext,
|
|
LPCTSTR ImagePath,
|
|
PWMIREGINFOW RegistrationInfo,
|
|
ULONG RegistrationInfoSize,
|
|
ULONG_PTR *ProviderId,
|
|
BOOLEAN IsAnsi
|
|
);
|
|
|
|
ULONG EtwpUpdateAddGuid(
|
|
PBDATASOURCE DataSource,
|
|
PWMIREGGUID RegGuid,
|
|
PWMIREGINFO RegistrationInfo,
|
|
PBINSTANCESET *AddModInstanceSet
|
|
);
|
|
|
|
ULONG EtwpUpdateModifyGuid(
|
|
PBDATASOURCE DataSource,
|
|
PWMIREGGUID RegGuid,
|
|
PWMIREGINFO RegistrationInfo,
|
|
PBINSTANCESET *AddModInstanceSet
|
|
);
|
|
|
|
BOOLEAN EtwpUpdateRemoveGuid(
|
|
PBDATASOURCE DataSource,
|
|
PWMIREGGUID RegGuid,
|
|
PBINSTANCESET *AddModInstanceSet
|
|
);
|
|
|
|
void EtwpUpdateDataSource(
|
|
ULONG_PTR ProviderId,
|
|
PWMIREGINFOW RegistrationInfo,
|
|
ULONG RetSize
|
|
);
|
|
|
|
void EtwpRemoveDataSource(
|
|
ULONG_PTR ProviderId
|
|
);
|
|
|
|
void EtwpRemoveDataSourceByDS(
|
|
PBDATASOURCE DataSource
|
|
);
|
|
|
|
ULONG EtwpRegisterInternalDataSource(
|
|
void
|
|
);
|
|
|
|
PBGUIDENTRY EtwpFindGEByGuid(
|
|
LPGUID Guid,
|
|
BOOLEAN MakeTopOfList
|
|
);
|
|
|
|
PBINSTANCESET EtwpFindISInDSByGuid(
|
|
PBDATASOURCE DataSource,
|
|
LPGUID Guid
|
|
);
|
|
|
|
PNOTIFICATIONENTRY EtwpFindNEByGuid(
|
|
GUID UNALIGNED *Guid,
|
|
BOOLEAN MakeTopOfList
|
|
);
|
|
|
|
PDCREF EtwpFindExistingAndFreeDCRefInNE(
|
|
PNOTIFICATIONENTRY NotificationEntry,
|
|
PDCENTRY DataConsumer,
|
|
PDCREF *FreeDcRef
|
|
);
|
|
|
|
PDCREF EtwpFindDCRefInNE(
|
|
PNOTIFICATIONENTRY NotificationEntry,
|
|
PDCENTRY DataConsumer
|
|
);
|
|
|
|
PBDATASOURCE EtwpFindDSByProviderId(
|
|
ULONG_PTR ProviderId
|
|
);
|
|
|
|
PBINSTANCESET EtwpFindISByGuid(
|
|
PBDATASOURCE DataSource,
|
|
GUID UNALIGNED *Guid
|
|
);
|
|
|
|
PMOFRESOURCE EtwpFindMRByNames(
|
|
LPCWSTR ImagePath,
|
|
LPCWSTR MofResourceName
|
|
);
|
|
|
|
#ifdef WMI_USER_MODE
|
|
PMOFCLASS EtwpFindMCByGuid(
|
|
LPGUID Guid
|
|
);
|
|
|
|
PMOFCLASS EtwpFindMCByGuidAndBestLanguage(
|
|
LPGUID Guid,
|
|
WORD Language
|
|
);
|
|
|
|
PMOFCLASS EtwpFindMCByGuidAndLanguage(
|
|
LPGUID Guid,
|
|
WORD Language
|
|
);
|
|
#endif
|
|
|
|
PBINSTANCESET EtwpFindISinGEbyName(
|
|
PBGUIDENTRY GuidEntry,
|
|
PWCHAR InstanceName,
|
|
PULONG InstanceIndex
|
|
);
|
|
|
|
PWNODE_HEADER EtwpGenerateRegistrationNotification(
|
|
PBDATASOURCE DataSource,
|
|
PWNODE_HEADER Wnode,
|
|
ULONG GuidMax,
|
|
ULONG NotificationCode
|
|
);
|
|
|
|
BOOLEAN
|
|
EtwpIsControlGuid(
|
|
PBGUIDENTRY GuidEntry
|
|
);
|
|
|
|
void EtwpGenerateMofResourceNotification(
|
|
LPWSTR ImagePath,
|
|
LPWSTR ResourceName,
|
|
LPCGUID Guid
|
|
);
|
|
|
|
//
|
|
// wbem.c
|
|
ULONG EtwpBuildMofClassInfo(
|
|
PBDATASOURCE DataSource,
|
|
LPWSTR ImagePath,
|
|
LPWSTR MofResourceName,
|
|
PBOOLEAN NewMofResource
|
|
);
|
|
|
|
ULONG EtwpReadBuiltinMof(
|
|
void
|
|
);
|
|
|
|
|
|
//
|
|
// from krnlmode.c
|
|
ULONG EtwpInitializeKM(
|
|
HANDLE *WmiKMHandle
|
|
);
|
|
|
|
void EtwpKMNonEventNotification(
|
|
HANDLE WmiKMHandle,
|
|
PWNODE_HEADER Wnode
|
|
);
|
|
|
|
//
|
|
// main.c
|
|
|
|
extern HANDLE EtwpRestrictedToken;
|
|
|
|
|
|
NTSTATUS EtwpGetRegistryValue(
|
|
TCHAR *ValueName,
|
|
PULONG Value
|
|
);
|
|
|
|
ULONG WmiRunService(
|
|
ULONG Context
|
|
#ifdef MEMPHIS
|
|
, HINSTANCE InstanceHandle
|
|
#endif
|
|
);
|
|
|
|
ULONG EtwpInitializeAccess(
|
|
PTCHAR *RpcStringBinding
|
|
);
|
|
|
|
void WmiTerminateService(
|
|
void
|
|
);
|
|
|
|
ULONG WmiInitializeService(
|
|
void
|
|
);
|
|
|
|
void WmiDeinitializeService(
|
|
void
|
|
);
|
|
|
|
void EtwpEventNotification(
|
|
PWNODE_HEADER Wnode,
|
|
BOOLEAN SingleEvent,
|
|
ULONG EventSizeGuess
|
|
);
|
|
|
|
#define EtwpBuildRegistrationNotification(Wnode, WnodeSize, NotificationCode, GuidCount) { \
|
|
memset(Wnode, 0, sizeof(WNODE_HEADER)); \
|
|
memcpy(&Wnode->Guid, &RegChangeNotificationGuid, sizeof(GUID)); \
|
|
Wnode->BufferSize = WnodeSize; \
|
|
Wnode->Linkage = NotificationCode; \
|
|
Wnode->Version = GuidCount; \
|
|
Wnode->Flags = WNODE_FLAG_INTERNAL; \
|
|
}
|
|
|
|
void EtwpSendQueuedEvents(
|
|
void
|
|
);
|
|
|
|
ULONG EtwpCleanupDataConsumer(
|
|
PDCENTRY DataConsumer
|
|
#if DBG
|
|
,BOOLEAN *NotificationsEnabled,
|
|
BOOLEAN *CollectionsEnabled
|
|
#endif
|
|
);
|
|
//
|
|
// This defines the maximum number of replacement strings over all of the
|
|
// event messages.
|
|
#define MAX_MESSAGE_STRINGS 2
|
|
void __cdecl EtwpReportEventLog(
|
|
ULONG MessageCode,
|
|
WORD MessageType,
|
|
WORD MessageCategory,
|
|
DWORD RawDataSize,
|
|
PVOID RawData,
|
|
WORD StringCount,
|
|
...
|
|
);
|
|
|
|
#ifdef MEMPHIS
|
|
long WINAPI
|
|
DeviceNotificationWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
|
|
|
|
void EtwpDestroyDeviceNotificationWindow(
|
|
HINSTANCE InstanceHandle,
|
|
HWND WindowHandle
|
|
);
|
|
|
|
ULONG EtwpCreateDeviceNotificationWindow(
|
|
HINSTANCE InstanceHandle,
|
|
HWND *DeviceNotificationWindow
|
|
);
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// server.c
|
|
void EtwpRpcServerDeinitialize(
|
|
void
|
|
);
|
|
|
|
ULONG EtwpRpcServerInitialize(
|
|
void
|
|
);
|
|
|
|
ULONG EtwpDeliverWnodeToDS(
|
|
ULONG ActionCode,
|
|
PBDATASOURCE DataSource,
|
|
PWNODE_HEADER Wnode
|
|
);
|
|
|
|
ULONG EtwpDoDisableRequest(
|
|
PNOTIFICATIONENTRY NotificationEntry,
|
|
PBGUIDENTRY GuidEntry,
|
|
BOOLEAN IsEvent,
|
|
BOOLEAN IsTraceLog,
|
|
ULONG64 LoggerContext,
|
|
ULONG InProgressFlag
|
|
);
|
|
|
|
ULONG CollectOrEventWorker(
|
|
PDCENTRY DataConsumer,
|
|
LPGUID Guid,
|
|
BOOLEAN Enable,
|
|
BOOLEAN IsEvent,
|
|
ULONG *NotificationCookie,
|
|
ULONG64 LoggerContext,
|
|
ULONG NotificationFlags
|
|
);
|
|
|
|
ULONG EtwpCreateRestrictedToken(
|
|
HANDLE *RestrictedToken
|
|
);
|
|
|
|
void EtwpShowPrivs(
|
|
HANDLE TokenHandle
|
|
);
|
|
|
|
#ifdef MEMPHIS
|
|
#define EtwpRestrictToken(Token) (ERROR_SUCCESS)
|
|
#define EtwpUnrestrictToken() (ERROR_SUCCESS)
|
|
#else
|
|
ULONG EtwpRestrictToken(
|
|
HANDLE RestrictedToken
|
|
);
|
|
|
|
ULONG EtwpUnrestrictToken(
|
|
void
|
|
);
|
|
|
|
ULONG EtwpServiceDisableTraceProviders(
|
|
PWNODE_HEADER Wnode
|
|
);
|
|
|
|
#endif
|
|
|
|
void EtwpReleaseCollectionEnabled(
|
|
PNOTIFICATIONENTRY NotificationEntry
|
|
);
|
|
|
|
//
|
|
// chunk.c
|
|
ULONG UnicodeToAnsi(
|
|
LPCWSTR pszW,
|
|
LPSTR * ppszA,
|
|
ULONG *AnsiSizeInBytes OPTIONAL
|
|
);
|
|
|
|
ULONG AnsiToUnicode(
|
|
LPCSTR pszA,
|
|
LPWSTR * ppszW
|
|
);
|
|
|
|
ULONG AnsiSizeForUnicodeString(
|
|
PWCHAR UnicodeString,
|
|
ULONG *AnsiSizeInBytes
|
|
);
|
|
|
|
ULONG UnicodeSizeForAnsiString(
|
|
LPCSTR AnsiString,
|
|
ULONG *UnicodeSizeInBytes
|
|
);
|
|
|
|
//
|
|
// debug.c
|
|
#if DBG
|
|
void EtwpDumpIS(
|
|
PBINSTANCESET IS,
|
|
BOOLEAN RecurseGE,
|
|
BOOLEAN RecurseDS
|
|
);
|
|
|
|
void EtwpDumpGE(
|
|
PBGUIDENTRY GE,
|
|
BOOLEAN RecurseIS
|
|
);
|
|
|
|
void EtwpDumpDS(
|
|
PBDATASOURCE DS,
|
|
BOOLEAN RecurseIS
|
|
);
|
|
|
|
void EtwpDumpAllDS(
|
|
void
|
|
);
|
|
|
|
#endif
|
|
|
|
#ifndef MEMPHIS
|
|
|
|
typedef enum
|
|
{
|
|
TRACELOG_START = 0,
|
|
TRACELOG_STOP = 1,
|
|
TRACELOG_QUERY = 2,
|
|
TRACELOG_QUERYALL = 3,
|
|
TRACELOG_QUERYENABLED = 4,
|
|
TRACELOG_UPDATE = 5,
|
|
TRACELOG_FLUSH = 6
|
|
} TRACEREQUESTCODE;
|
|
|
|
typedef struct _WMI_REF_CLOCK {
|
|
LARGE_INTEGER StartTime;
|
|
LARGE_INTEGER StartPerfClock;
|
|
} WMI_REF_CLOCK, *PWMI_REF_CLOCK;
|
|
|
|
//
|
|
// logsup.c
|
|
|
|
ULONG
|
|
WmiUnregisterGuids(
|
|
IN WMIHANDLE WMIHandle,
|
|
IN LPGUID Guid,
|
|
OUT ULONG64 *LoggerContext
|
|
);
|
|
|
|
ULONG
|
|
EtwpAddLogHeaderToLogFile(
|
|
IN OUT PWMI_LOGGER_INFORMATION LoggerInfo,
|
|
IN PWMI_REF_CLOCK RefClock,
|
|
IN ULONG Update
|
|
);
|
|
|
|
ULONG
|
|
EtwpStartLogger(
|
|
IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
|
|
);
|
|
|
|
ULONG
|
|
EtwpStopLogger(
|
|
IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
|
|
);
|
|
|
|
ULONG
|
|
EtwpQueryLogger(
|
|
IN OUT PWMI_LOGGER_INFORMATION LoggerInfo,
|
|
IN ULONG Update
|
|
);
|
|
ULONG
|
|
EtwpFlushLogger(
|
|
IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
|
|
);
|
|
|
|
VOID
|
|
EtwpInitString(
|
|
IN PVOID Destination,
|
|
IN PVOID Buffer,
|
|
IN ULONG Size
|
|
);
|
|
|
|
ULONG
|
|
EtwpGetTraceRegKeys(
|
|
);
|
|
|
|
ULONG
|
|
EtwpFinalizeLogFileHeader(
|
|
IN PWMI_LOGGER_INFORMATION LoggerInfo
|
|
);
|
|
|
|
ULONG
|
|
EtwpRelogHeaderToLogFile(
|
|
IN OUT PWMI_LOGGER_INFORMATION LoggerInfo ,
|
|
IN PSYSTEM_TRACE_HEADER RelogProp
|
|
);
|
|
|
|
//
|
|
// umlog.c
|
|
BOOLEAN
|
|
FASTCALL
|
|
EtwpIsPrivateLoggerOn();
|
|
|
|
ULONG
|
|
EtwpSendUmLogRequest(
|
|
IN WMITRACECODE RequestCode,
|
|
IN OUT PWMI_LOGGER_INFORMATION LoggerInfo
|
|
);
|
|
|
|
ULONG
|
|
FASTCALL
|
|
EtwpTraceUmEvent(
|
|
IN PWNODE_HEADER Wnode
|
|
);
|
|
|
|
NTSTATUS
|
|
EtwpTraceUmMessage(
|
|
IN ULONG Size,
|
|
IN ULONG64 LoggerHandle,
|
|
IN ULONG MessageFlags,
|
|
IN LPGUID MessageGuid,
|
|
IN USHORT MessageNumber,
|
|
va_list MessageArgList
|
|
);
|
|
|
|
#endif
|