windows-nt/Source/XPSP1/NT/base/ntos/wmi/wmiumds.h
2020-09-26 16:20:57 +08:00

688 lines
18 KiB
C

/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
wmikmp.h
Abstract:
Private header for WMI kernel mode component
Author:
AlanWar
Environment:
Revision History:
--*/
#ifndef _WMIUMDS_
#define _WMIUMDS_
//
// Define this to track reference counts
//#define TRACK_REFERNECES
#include <wchar.h>
extern const GUID WmipBinaryMofGuid;
extern const GUID RegChangeNotificationGuid;
//
// 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 WmipReferenceEntry(Entry) \
InterlockedIncrement(&((PENTRYHEADER)(Entry))->RefCount)
// chunk.c
ULONG WmipUnreferenceEntry(
PCHUNKINFO ChunkInfo,
PENTRYHEADER Entry);
PENTRYHEADER WmipAllocEntry(
PCHUNKINFO ChunkInfo
);
void WmipFreeEntry(
PCHUNKINFO ChunkInfo,
PENTRYHEADER Entry
);
PWCHAR WmipCountedToSz(
PWCHAR Counted
);
struct tagGUIDENTRY;
typedef struct tagGUIDENTRY GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
//
// 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;
// Size needed to place all instance names in a WNODE_ALL_DATA
ULONG WADInstanceNameSize;
// ProviderId for the DS associated with this IS
ULONG ProviderId;
// Count of Trace Transaction Guids for this Instance
ULONG TransGuidCount;
// Pointer to Trace Transaction Guids
PTRACEGUIDMAP TraceGuidMap;
//
// 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 'SImW'
//
// 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
{
ULONG RegistrationCookie;
HANDLE InProgressEvent; // Registration is in Progress Event
BOOLEAN EnabledState; // Indicates if this GUID is Enabled or not.
PVOID NotifyRoutine;
PVOID TraceCtxHandle;
} TRACE_REG_INFO, *PTRACE_REG_INFO;
typedef struct
{
LIST_ENTRY Entry;
TRACEGUIDMAP GuidMap;
ULONG InstanceId;
ULONG64 LoggerContext;
PTRACE_REG_INFO pControlGuidData;
} GUIDMAPENTRY, *PGUIDMAPENTRY;
//
// These flags are also by the WMIINSTANCEINFO structure in wmicore.idl
#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
// 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;
// Head of list of open objects to this guid
LIST_ENTRY ObjectHead;
// 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;
ULONG EventRefCount; // Global count of event enables
ULONG CollectRefCount; // Global count of collection enables
ULONG64 LoggerContext; // Logger context handle
PWMI_LOGGER_INFORMATION LoggerInfo; // LoggerInfo. Used in case of Ntdll tracing
PKEVENT CollectInProgress; // Event set when all collect complete
} GUIDENTRY, *PGUIDENTRY, *PBGUIDENTRY;
#define GE_SIGNATURE 'EGmW'
#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
// Set when a notification request is being processed by the data providers
#define GE_FLAG_NOTIFICATION_IN_PROGRESS 0x00000002
// Set when a collection request is being processed by the data providers
#define GE_FLAG_COLLECTION_IN_PROGRESS 0x00000004
// Set when a trace disable is being processed by a worker thread
#define GE_FLAG_TRACEDISABLE_IN_PROGRESS 0x00000008
// Set when there is a wait in progress for collect/event enable/disable
#define GE_FLAG_WAIT_ENABLED 0x00000010
// Set when the guid has had an enable collection sent to it
#define GE_FLAG_COLLECTION_ENABLED 0x00000020
// Set when the guid has had an enable notifications sent to it
#define GE_FLAG_NOTIFICATIONS_ENABLED 0x00000040
#define GE_NOTIFICATION_TRACE_FLAG 0x00000080
// Set when an enabled guid receives another enable notification
#define GE_NOTIFICATION_TRACE_UPDATE 0x00000100
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 RegistryPath; // Path to image file with resource
PWCHAR MofResourceName; // Name of resource containing mof data
} MOFRESOURCE, *PMOFRESOURCE;
#define MR_SIGNATURE 'RMmW'
//
// This is a user mode resource so the RegistryPath is really an image path
#define MR_FLAG_USER_MODE 0x00000001
#if DBG
#define AVGMOFRESOURCECOUNT 1
#else
#define AVGMOFRESOURCECOUNT 4
#endif
struct _WMIGUIDOBJECT;
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;
// Provider id of kernel mode driver
ULONG ProviderId;
// Path to registry holding ACLs
PTCHAR RegistryPath;
// Head of list of MofResources attached to data source
ULONG MofResourceCount;
PMOFRESOURCE *MofResources;
PMOFRESOURCE StaticMofResources[AVGMOFRESOURCECOUNT];
// Guid object if this is a UM provider
struct _WMIGUIDOBJECT *RequestObject;
};
#define DS_SIGNATURE 'SDmW'
#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
#define DS_USER_MODE 0x00000008
#define DS_ON_FREE_LIST 0x80000000
//
// 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
//
// Guid and InstanceSet cache
#if DBG
#define PTRCACHEGROWSIZE 2
#else
#define PTRCACHEGROWSIZE 64
#endif
typedef struct
{
LPGUID Guid;
PBINSTANCESET InstanceSet;
} PTRCACHE;
typedef struct
{
ULONG ProviderId;
ULONG Flags;
ULONG InstanceCount;
ULONG InstanceNameSize;
PWCHAR **StaticNamePtr;
ULONG BaseIndex;
PWCHAR BaseName;
} WMIINSTANCEINFO, *PWMIINSTANCEINFO;
// TODO: Since these were copied from wmium.h, we actually need to mov
// them someplace else so they aren't copied
//extern GUID GUID_REGISTRATION_CHANGE_NOTIFICATION;
//extern GUID_MOF_RESOURCE_ADDED_NOTIFICATION;
//extern GUID_MOF_RESOURCE_REMOVED_NOTIFICATION;
//
// Location of built in MOF for the system
//
#define WMICOREIMAGEPATH L"advapi32.dll"
#define WMICORERESOURCENAME L"MofResourceName"
void WmipGenerateBinaryMofNotification(
PBINSTANCESET BinaryMofInstanceSet,
LPCGUID Guid
);
void WmipGenerateMofResourceNotification(
LPWSTR ImagePath,
LPWSTR ResourceName,
LPCGUID Guid,
ULONG ActionCode
);
//
// alloc.c
extern LIST_ENTRY WmipGEHead;
extern PLIST_ENTRY WmipGEHeadPtr;
extern CHUNKINFO WmipGEChunkInfo;
extern LIST_ENTRY WmipDSHead;
extern PLIST_ENTRY WmipDSHeadPtr;
extern CHUNKINFO WmipDSChunkInfo;
extern LIST_ENTRY WmipMRHead;
extern PLIST_ENTRY WmipMRHeadPtr;
extern CHUNKINFO WmipMRChunkInfo;
extern CHUNKINFO WmipISChunkInfo;
extern LIST_ENTRY WmipGMHead;
extern PLIST_ENTRY WmipGMHeadPtr;
#ifdef TRACK_REFERNECES
#define WmipUnreferenceDS(DataSource) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Unref DS %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), DataSource, DataSource->RefCount, __FILE__, __LINE__)); \
WmipUnreferenceEntry(&WmipDSChunkInfo, (PENTRYHEADER)DataSource); \
}
#define WmipReferenceDS(DataSource) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Ref DS %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), DataSource, DataSource->RefCount, __FILE__, __LINE__)); \
WmipReferenceEntry((PENTRYHEADER)DataSource); \
}
#define WmipUnreferenceGE(GuidEntry) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Unref GE %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), GuidEntry, GuidEntry->RefCount, __FILE__, __LINE__)); \
WmipUnreferenceEntry(&WmipGEChunkInfo, (PENTRYHEADER)GuidEntry); \
}
#define WmipReferenceGE(GuidEntry) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Ref GE %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), GuidEntry, GuidEntry->RefCount, __FILE__, __LINE__)); \
WmipReferenceEntry((PENTRYHEADER)GuidEntry); \
}
#define WmipUnreferenceIS(InstanceSet) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Unref IS %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), InstanceSet, InstanceSet->RefCount, __FILE__, __LINE__)); \
WmipUnreferenceEntry(&WmipISChunkInfo, (PENTRYHEADER)InstanceSet); \
}
#define WmipReferenceIS(InstanceSet) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Ref IS %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), InstanceSet, InstanceSet->RefCount, __FILE__, __LINE__)); \
WmipReferenceEntry((PENTRYHEADER)InstanceSet); \
}
#define WmipUnreferenceMR(MofResource) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Unref MR %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), MofResource, MofResource->RefCount, __FILE__, __LINE__)); \
WmipUnreferenceEntry(&WmipMRChunkInfo, (PENTRYHEADER)MofResource); \
}
#define WmipReferenceMR(MofResource) \
{ \
WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL, "WMI: %p.%p Ref MR %x (%x) at %s %d\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), MofResource, MofResource->RefCount, __FILE__, __LINE__)); \
WmipReferenceEntry((PENTRYHEADER)MofResource); \
}
#else
#define WmipUnreferenceDS(DataSource) \
WmipUnreferenceEntry(&WmipDSChunkInfo, (PENTRYHEADER)DataSource)
#define WmipReferenceDS(DataSource) \
WmipReferenceEntry((PENTRYHEADER)DataSource)
#define WmipUnreferenceGE(GuidEntry) \
WmipUnreferenceEntry(&WmipGEChunkInfo, (PENTRYHEADER)GuidEntry)
#define WmipReferenceGE(GuidEntry) \
WmipReferenceEntry((PENTRYHEADER)GuidEntry)
#define WmipUnreferenceIS(InstanceSet) \
WmipUnreferenceEntry(&WmipISChunkInfo, (PENTRYHEADER)InstanceSet)
#define WmipReferenceIS(InstanceSet) \
WmipReferenceEntry((PENTRYHEADER)InstanceSet)
#define WmipUnreferenceDC(DataConsumer) \
WmipUnreferenceEntry(&WmipDCChunkInfo, (PENTRYHEADER)DataConsumer)
#define WmipReferenceDC(DataConsumer) \
WmipReferenceEntry((PENTRYHEADER)DataConsumer)
#define WmipUnreferenceMR(MofResource) \
WmipUnreferenceEntry(&WmipMRChunkInfo, (PENTRYHEADER)MofResource)
#define WmipReferenceMR(MofResource) \
WmipReferenceEntry((PENTRYHEADER)MofResource)
#endif
PBDATASOURCE WmipAllocDataSource(
void
);
PBGUIDENTRY WmipAllocGuidEntry(
void
);
#define WmipAllocInstanceSet() ((PBINSTANCESET)WmipAllocEntry(&WmipISChunkInfo))
#define WmipAllocMofResource() ((PMOFRESOURCE)WmipAllocEntry(&WmipMRChunkInfo))
#define WmipAllocString(Size) \
WmipAlloc((Size)*sizeof(WCHAR))
#define WmipFreeString(Ptr) \
WmipFree(Ptr)
BOOLEAN WmipIsNumber(
LPCWSTR String
);
#ifdef HEAPVALIDATION
PVOID WmipAlloc(
ULONG Size
);
PVOID WmipAllocWithTag(
ULONG Size,
ULONG Tag
);
void WmipFree(
PVOID p
);
#else
#define WmipAlloc(Size) \
ExAllocatePoolWithTag(PagedPool, Size, 'pimW')
#define WmipAllocWithTag(Size, Tag) \
ExAllocatePoolWithTag(PagedPool, Size, Tag)
#define WmipFree(Ptr) \
ExFreePool(Ptr)
#endif
#define WmipAllocNP(Size) \
ExAllocatePoolWithTag(NonPagedPool, Size, 'pimW')
#define WmipAllocNPWithTag(Size, Tag) \
ExAllocatePoolWithTag(NonPagedPool, Size, Tag)
BOOLEAN WmipRealloc(
PVOID *Buffer,
ULONG CurrentSize,
ULONG NewSize,
BOOLEAN FreeOriginalBuffer
);
PBGUIDENTRY WmipFindGEByGuid(
LPGUID Guid,
BOOLEAN MakeTopOfList
);
PBDATASOURCE WmipFindDSByProviderId(
ULONG_PTR ProviderId
);
PBINSTANCESET WmipFindISByGuid(
PBDATASOURCE DataSource,
GUID UNALIGNED *Guid
);
PMOFRESOURCE WmipFindMRByNames(
LPCWSTR ImagePath,
LPCWSTR MofResourceName
);
PBINSTANCESET WmipFindISinGEbyName(
PBGUIDENTRY GuidEntry,
PWCHAR InstanceName,
PULONG InstanceIndex
);
// TODO: Implement this
#define WmipReportEventLog(a,b,c,d,e,f,g)
#endif