|
|
/*++
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
LONG AllocCount; LONG 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
LONG 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
#define MAXBASENAMESUFFIXVALUE 999999
#define BASENAMEFORMATSTRING L"%d"
//
// 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;
//
// 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 %p (%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 %p (%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 %p (%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 %p (%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 %p (%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 %p (%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 %p (%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 %p (%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 WmipAllocGuidEntryX( ULONG Line, PCHAR File );
#define WmipAllocGuidEntry() WmipAllocGuidEntryX(__LINE__, __FILE__)
#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
|