|
|
/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
mofapi.c
Abstract: WMI MOF access apis
Author:
16-Jan-1997 AlanWar
Revision History:
--*/
#include "wmiump.h"
#include "trcapi.h"
#include "common.h"
BOOLEAN EtwpCopyCountedString( PUCHAR Base, PULONG Offset, PULONG BufferRemaining, PWCHAR SourceString ) { PWCHAR w; ULONG BufferUsed; ULONG BytesUsed; BOOLEAN BufferNotFull; if (*BufferRemaining > 1) { w = (PWCHAR)OffsetToPtr(Base, *Offset); (*BufferRemaining)--; BufferNotFull = EtwpCopyMRString(w+1, *BufferRemaining, &BufferUsed, SourceString); if (BufferNotFull) { BytesUsed = BufferUsed * sizeof(WCHAR); *w = (USHORT)BytesUsed; (*BufferRemaining) -= BufferUsed; (*Offset) += BytesUsed + sizeof(USHORT); } } else { BufferNotFull = FALSE; } return(BufferNotFull); }
ULONG EtwpBuildMofAddRemoveEvent( IN PWNODE_SINGLE_INSTANCE WnodeSI, IN PWMIMOFLIST MofList, IN PWCHAR *LanguageList, IN ULONG LanguageCount, IN BOOLEAN IncludeNeutralLanguage, IN NOTIFICATIONCALLBACK Callback, IN ULONG_PTR DeliveryContext, IN BOOLEAN IsAnsi ) { PWNODE_ALL_DATA WnodeAD; ULONG BytesUsed, BufferUsed; BOOLEAN BufferNotFull; PWCHAR RegPath, ImagePath, ResourceName; ULONG SizeNeeded; ULONG InstanceCount, MaxInstanceCount; ULONG Status; ULONG Offset; POFFSETINSTANCEDATAANDLENGTH DataLenPtr; PWCHAR w; PULONG InstanceNamesOffsets; PWCHAR InstanceNames; ULONG BufferRemaining; ULONG i,j; PWMIMOFENTRY MofEntry; PWCHAR ImagePathStatic; EtwpAssert(WnodeSI->WnodeHeader.Flags & WNODE_FLAG_SINGLE_INSTANCE);
ImagePathStatic = EtwpAlloc(MAX_PATH * sizeof(WCHAR)); if (ImagePathStatic != NULL) { //
// Figure out how large the WNODE_ALL_DATA will need to be and
// guess at how much space to allocate for the image paths and
// resource names
//
if (IncludeNeutralLanguage) { MaxInstanceCount = (LanguageCount + 1); } else { MaxInstanceCount = LanguageCount; } MaxInstanceCount *= MofList->MofListCount;
#if DBG
SizeNeeded = sizeof(WNODE_ALL_DATA) + (MaxInstanceCount * (sizeof(ULONG) + // offset to instance name
sizeof(USHORT) + // instance name length
sizeof(OFFSETINSTANCEDATAANDLENGTH))) + 64; #else
SizeNeeded = sizeof(WNODE_ALL_DATA) + (MaxInstanceCount * (sizeof(ULONG) + // offset to instance name
sizeof(USHORT) + // instance name length
sizeof(OFFSETINSTANCEDATAANDLENGTH))) + 0x1000; #endif
WnodeAD = NULL; do { TryAgain: if (WnodeAD != NULL) { EtwpFree(WnodeAD); }
WnodeAD = EtwpAlloc(SizeNeeded); if (WnodeAD != NULL) { //
// Build up WNODE_ALL_DATA with all mof resources
//
memset(WnodeAD, 0, SizeNeeded);
WnodeAD->WnodeHeader = WnodeSI->WnodeHeader; WnodeAD->WnodeHeader.Flags = WNODE_FLAG_ALL_DATA | WNODE_FLAG_EVENT_ITEM; WnodeAD->WnodeHeader.BufferSize = SizeNeeded; WnodeAD->WnodeHeader.Linkage = 0;
//
// Establish pointer to the data offset and length
// structure and allocate space for all instances
//
Offset = FIELD_OFFSET(WNODE_ALL_DATA, OffsetInstanceDataAndLength); DataLenPtr = (POFFSETINSTANCEDATAANDLENGTH)OffsetToPtr(WnodeAD, Offset); Offset = (Offset + (MaxInstanceCount * sizeof(OFFSETINSTANCEDATAANDLENGTH)) + 7) & ~7;
//
// Establish the instance name offsets and fill in
// the empty instance names. Note we point them all
// to the same offset which is an empty instance
// name.
//
InstanceNamesOffsets = (PULONG)OffsetToPtr(WnodeAD, Offset);
WnodeAD->OffsetInstanceNameOffsets = Offset; Offset = Offset + (MaxInstanceCount * sizeof(ULONG)); InstanceNames = (PWCHAR)OffsetToPtr(WnodeAD, Offset); *InstanceNames = 0; for (i = 0; i < MaxInstanceCount; i++) { InstanceNamesOffsets[i] = Offset; }
//
// Establish a pointer to the data block for all of
// the instances
//
Offset = (Offset + (MaxInstanceCount * sizeof(USHORT)) + 7) & ~7; WnodeAD->DataBlockOffset = Offset;
BufferRemaining = (SizeNeeded - Offset) / sizeof(WCHAR);
InstanceCount = 0;
//
// Loop over all mof resources in list
//
for (j = 0; j < MofList->MofListCount; j++) { MofEntry = &MofList->MofEntry[j]; RegPath = (PWCHAR)OffsetToPtr(MofList, MofEntry->RegPathOffset);
//
// Convert regpath to image path if needed
//
if ((MofEntry->Flags & WMIMOFENTRY_FLAG_USERMODE) == 0) { ImagePath = EtwpRegistryToImagePath(ImagePathStatic, RegPath+1); } else { ImagePath = RegPath; }
if (ImagePath != NULL) { ResourceName = (PWCHAR)OffsetToPtr(MofList, MofEntry->ResourceOffset);
//
// Now lets go and build up the data for each
// instance. First fill in the language neutral mof
// if we are supposed to
//
if (IncludeNeutralLanguage) {
DataLenPtr[InstanceCount].OffsetInstanceData = Offset;
if ((! EtwpCopyCountedString((PUCHAR)WnodeAD, &Offset, &BufferRemaining, ImagePath)) || (! EtwpCopyCountedString((PUCHAR)WnodeAD, &Offset, &BufferRemaining, ResourceName))) { SizeNeeded *=2; goto TryAgain; }
DataLenPtr[InstanceCount].LengthInstanceData = Offset - DataLenPtr[InstanceCount].OffsetInstanceData;
InstanceCount++;
//
// We cheat here and do not align the offset on an
// 8 byte boundry for the next data block since we
// know the data type is a WCHAR and we know we are
// on a 2 byte boundry.
//
}
//
// Now loop over and build language specific mof
// resources
//
for (i = 0; i < LanguageCount; i++) { DataLenPtr[InstanceCount].OffsetInstanceData = Offset; if (BufferRemaining > 1) { w = (PWCHAR)OffsetToPtr(WnodeAD, Offset);
Status = EtwpBuildMUIPath(w+1, BufferRemaining - 1, &BufferUsed, ImagePath, LanguageList[i], &BufferNotFull); if (Status == ERROR_SUCCESS) { if (BufferNotFull) { BufferRemaining--; BytesUsed = BufferUsed * sizeof(WCHAR); *w = (USHORT)BytesUsed; BufferRemaining -= BufferUsed; Offset += (BytesUsed + sizeof(USHORT));
if (! EtwpCopyCountedString((PUCHAR)WnodeAD, &Offset, &BufferRemaining, ResourceName)) { SizeNeeded *=2; goto TryAgain; }
DataLenPtr[InstanceCount].LengthInstanceData = Offset - DataLenPtr[InstanceCount].OffsetInstanceData;
//
// We cheat here and do not align the offset on an
// 8 byte boundry for the next data block since we
// know the data type is a WCHAR and we know we are
// on a 2 byte boundry.
//
InstanceCount++; } else { SizeNeeded *=2; goto TryAgain; } } } else { SizeNeeded *=2; goto TryAgain; } } } } } else { Status = ERROR_NOT_ENOUGH_MEMORY; } } while (FALSE);
if (WnodeAD != NULL) { WnodeAD->InstanceCount = InstanceCount; EtwpMakeEventCallbacks((PWNODE_HEADER)WnodeAD, Callback, DeliveryContext, IsAnsi); EtwpFree(WnodeAD); Status = ERROR_SUCCESS; } EtwpFree(ImagePathStatic); } else { Status = ERROR_NOT_ENOUGH_MEMORY; } return(Status); }
void EtwpProcessMofAddRemoveEvent( IN PWNODE_SINGLE_INSTANCE WnodeSI, IN NOTIFICATIONCALLBACK Callback, IN ULONG_PTR DeliveryContext, IN BOOLEAN IsAnsi ) { PWCHAR RegPath, ResourceName; PWCHAR *LanguageList; ULONG LanguageCount; ULONG Status; PWMIMOFLIST MofList; ULONG i; PWMIMOFENTRY MofEntry; ULONG Offset; ULONG SizeNeeded; PWCHAR w; RegPath = (PWCHAR)OffsetToPtr(WnodeSI, WnodeSI->DataBlockOffset); EtwpAssert(*RegPath != 0);
ResourceName = (PWCHAR)OffsetToPtr(WnodeSI, WnodeSI->DataBlockOffset + sizeof(USHORT) + *RegPath++ + sizeof(USHORT)); SizeNeeded = sizeof(WMIMOFLIST) + ((wcslen(RegPath) + (wcslen(ResourceName) + 2)) * sizeof(WCHAR)); MofList = (PWMIMOFLIST)EtwpAlloc(SizeNeeded); if (MofList != NULL) { Status = EtwpGetLanguageList(&LanguageList, &LanguageCount);
if (Status == ERROR_SUCCESS) { MofList->MofListCount = 1; MofEntry = &MofList->MofEntry[0]; Offset = sizeof(WMIMOFLIST); MofEntry->RegPathOffset = Offset; w = (PWCHAR)OffsetToPtr(MofList, Offset); wcscpy(w, RegPath); Offset += (wcslen(RegPath) + 1) * sizeof(WCHAR); MofEntry->ResourceOffset = Offset; w = (PWCHAR)OffsetToPtr(MofList, Offset); wcscpy(w, ResourceName); if (WnodeSI->WnodeHeader.ProviderId == MOFEVENT_ACTION_REGISTRY_PATH) { MofEntry->Flags = 0; } else { MofEntry->Flags = WMIMOFENTRY_FLAG_USERMODE; } Status = EtwpBuildMofAddRemoveEvent(WnodeSI, MofList, LanguageList, LanguageCount, TRUE, Callback, DeliveryContext, IsAnsi); //
// Free up memory used to hold the language list
//
for (i = 0; i < LanguageCount; i++) { EtwpFree(LanguageList[i]); } EtwpFree(LanguageList); } EtwpFree(MofList); } else { Status = ERROR_NOT_ENOUGH_MEMORY; } if (Status != ERROR_SUCCESS) { //
// If the WNODE_ALL_DATA event wasn't fired then just fire the
// WNDOE_SINGLE_INSTANCE event so at least we get the language
// neutral mof
//
WnodeSI->WnodeHeader.Flags &= ~WNODE_FLAG_INTERNAL; EtwpMakeEventCallbacks((PWNODE_HEADER)WnodeSI, Callback, DeliveryContext, IsAnsi); } }
void EtwpProcessLanguageAddRemoveEvent( IN PWNODE_SINGLE_INSTANCE WnodeSI, IN NOTIFICATIONCALLBACK Callback, IN ULONG_PTR DeliveryContext, IN BOOLEAN IsAnsi ) { ULONG Status; PWMIMOFLIST MofList; PWCHAR Language; //
// Get list of mof resources and build an event with the list of
// resources for the language that is coming or going
//
Status = EtwpGetMofResourceList(&MofList);
if (Status == ERROR_SUCCESS) { Language = (PWCHAR)OffsetToPtr(WnodeSI, WnodeSI->DataBlockOffset + sizeof(USHORT)); Status = EtwpBuildMofAddRemoveEvent(WnodeSI, MofList, &Language, 1, FALSE, Callback, DeliveryContext, IsAnsi); } }
|