|
|
/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
bmofio.cpp
Abstract:
Binary mof Win32 subparser for Loc Studio
Author:
16-Jan-1997 AlanWar
Revision History:
--*/
#if DEBUG_HEAP
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#endif
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <wbemcli.h>
#include "dllcalls.h"
#include "bmfmisc.h"
#include "mrcicode.h"
#include "bmof.h"
ULONG GenerateMofForObj( PMOFFILETARGET MofFileTarget, CBMOFObj *Obj );
//
// Each class has one or more data items that are described by a MOFDATAITEM
// structure.
typedef struct { PWCHAR Name; PWCHAR DataType; // Method return type
ULONG Flags; // Flags, See MOFDI_FLAG_*
CBMOFQualList * QualifierList; } METHODPARAMETER, *PMETHODPARAMETER;
// Data item is actually a fixed sized array
#define MOFDI_FLAG_ARRAY 0x00000001
// 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 { PWCHAR ReturnDataType; ULONG ParamCount; // Number of wmi data items (properties)
// Array of Property info
METHODPARAMETER Parameters[1]; } METHODPARAMLIST, *PMETHODPARAMLIST;
//
// Definitions for WmipAlloc/WmipFree. On debug builds we use our own
// heap. Be aware that heap creation is not serialized.
//
#if 0
#if DEBUG_HEAP
PVOID WmiPrivateHeap;
PVOID _stdcall WmipAlloc(ULONG size) { PVOID p = NULL; if (WmiPrivateHeap == NULL) { WmiPrivateHeap = RtlCreateHeap(HEAP_GROWABLE | HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_DISABLE_COALESCE_ON_FREE, NULL, 0, 0, NULL, NULL); } if (WmiPrivateHeap != NULL) { p = RtlAllocateHeap(WmiPrivateHeap, 0, size); if (p != NULL) { memset(p, 0, size); } } return(p); }
void _stdcall WmipFree(PVOID p) { RtlFreeHeap(WmiPrivateHeap, 0, p); } #else
PVOID _stdcall WmipAlloc(ULONG size) { return(LocalAlloc(LPTR, size)); }
void _stdcall WmipFree(PVOID p) { LocalFree(p); } #endif
#endif
#define WmipAlloc malloc
#define WmipFree free
//
// Definitions for WmipAssert
//
#if DBG
#define WmipAssert(x) if (! (x) ) { \
WmipDebugPrint(("BMOFLocParser Assertion: "#x" at %s %d\n", __FILE__, __LINE__)); \ DebugBreak(); } #else
#define WmipAssert(x)
#endif
//
// WmipDebugPrint definitions
//
#if DBG
#define WmipDebugPrint(x) WmiDebugPrint x
VOID WmiDebugPrint( PCHAR DebugMessage, ... ) /*++
Routine Description:
Debug print for properties pages - stolen from classpnp\class.c
Arguments:
Debug print level between 0 and 3, with 3 being the most verbose.
Return Value:
None
--*/
{ #define DEBUG_BUFFER_LENGTH 512
static CHAR WmiBuffer[DEBUG_BUFFER_LENGTH];
va_list ap;
va_start(ap, DebugMessage);
_vsnprintf(WmiBuffer, DEBUG_BUFFER_LENGTH, DebugMessage, ap);
OutputDebugStringA(WmiBuffer);
va_end(ap);
} // end WmiDebugPrint()
#else
#define WmipDebugPrint(x)
#endif
ULONG AnsiToUnicode( LPCSTR pszA, LPWSTR *ppszW ) /*++
Routine Description:
Convert Ansi string into its Unicode equivalent
Arguments:
pszA is ansi string to convert
*ppszW on entry has a pointer to a unicode string into which the answer is written. If NULL on entry then a buffer is allocated and returned in it.
Return Value:
Error code
--*/ { ULONG cCharacters; ULONG Status; ULONG cbUnicodeUsed;
//
// If input is null then just return the same.
if (pszA == NULL) { *ppszW = NULL; return(ERROR_SUCCESS); }
//
// Determine the count of characters needed for Unicode string
cCharacters = MultiByteToWideChar(CP_ACP, 0, pszA, -1, NULL, 0);
if (cCharacters == 0) { *ppszW = NULL; return(GetLastError()); }
// Convert to Unicode
cbUnicodeUsed = MultiByteToWideChar(CP_ACP, 0, pszA, -1, *ppszW, cCharacters); if (0 == cbUnicodeUsed) { Status = GetLastError(); return(Status); }
return(ERROR_SUCCESS); }
ULONG AppendFileToFile( TCHAR *DestFile, TCHAR *SrcFile ) { #define READ_BLOCK_SIZE 0x8000
HANDLE DestHandle, SrcHandle; ULONG BytesRead, BytesWritten; PUCHAR Buffer; BOOL b; ULONG Status = ERROR_SUCCESS;
Buffer = (PUCHAR)WmipAlloc(READ_BLOCK_SIZE); if (Buffer != NULL) { DestHandle = CreateFile(DestFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (DestHandle != INVALID_HANDLE_VALUE) { SrcHandle = CreateFile(SrcFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (SrcHandle != INVALID_HANDLE_VALUE) { b = SetFilePointer(DestHandle, 0, NULL, FILE_END); if (b) { do { b = ReadFile(SrcHandle, Buffer, READ_BLOCK_SIZE, &BytesRead, NULL); if (b) { b = WriteFile(DestHandle, Buffer, BytesRead, &BytesWritten, NULL); if (!b) { Status = GetLastError(); break; } else if (BytesWritten != BytesRead) { Status = ERROR_BAD_LENGTH; break; } } else { Status = GetLastError(); break; } } while (BytesRead == READ_BLOCK_SIZE); } else { Status = GetLastError(); } CloseHandle(SrcHandle); } else { Status = GetLastError(); } CloseHandle(DestHandle); } else { Status = GetLastError(); } WmipFree(Buffer); } else { Status = ERROR_NOT_ENOUGH_MEMORY; } return(Status); }
BOOLEAN ConvertMofToBmf( TCHAR *MofFile, TCHAR *EnglishMofFile, TCHAR *BmfFile ) { WBEM_COMPILE_STATUS_INFO info; SCODE sc; LONG OptionFlags, ClassFlags, InstanceFlags; PWCHAR NameSpace; WCHAR MofFileStatic[MAX_PATH]; WCHAR BmfFileStatic[MAX_PATH]; PWCHAR BmfFileW, MofFileW; BOOLEAN Success; ULONG Status;
if (*EnglishMofFile != 0) { Status = AppendFileToFile(MofFile, EnglishMofFile); if (Status != ERROR_SUCCESS) { return(FALSE); } } #if 0
OutputDebugString(MofFile); OutputDebugString("\n"); DebugBreak(); #endif
NameSpace = L""; OptionFlags = 0; ClassFlags = 0; InstanceFlags = 0;
MofFileW = MofFileStatic; Status = AnsiToUnicode(MofFile, &MofFileW);
if ((Status == ERROR_SUCCESS) && (MofFileW != NULL)) { BmfFileW = BmfFileStatic; Status = AnsiToUnicode(BmfFile, &BmfFileW);
if ((Status == ERROR_SUCCESS) && (BmfFileW != NULL)) { sc = CreateBMOFViaDLL( MofFileW, BmfFileW, NameSpace, OptionFlags, ClassFlags, InstanceFlags, &info); Success = (sc == S_OK); } else { Success = FALSE; } } else { Success = FALSE; } return(Success); }
ULONG FilePrintVaList( HANDLE FileHandle, WCHAR *Format, va_list pArg ) { PWCHAR Buffer; ULONG Size, Written; ULONG Status;
Buffer = (PWCHAR)WmipAlloc(8192 * sizeof(WCHAR)); if (Buffer != NULL) { Size = _vsnwprintf(Buffer, 8192, Format, pArg); Buffer[8191] = 0; if (WriteFile(FileHandle, Buffer, Size * sizeof(WCHAR), &Written, NULL)) { Status = ERROR_SUCCESS; } else { Status = GetLastError(); } WmipFree(Buffer); } else { Status = ERROR_NOT_ENOUGH_MEMORY; }
return(Status); }
ULONG FilePrint( PMOFFILETARGET MofFileTarget, WCHAR *Format, ... ) { ULONG Status; va_list pArg;
va_start(pArg, Format); Status = FilePrintVaList(MofFileTarget->MofHandle, Format, pArg);
if ((MofFileTarget->WriteToEnglish) && (Status == ERROR_SUCCESS) && (MofFileTarget->EnglishMofHandle != NULL)) { Status = FilePrintVaList(MofFileTarget->EnglishMofHandle, Format, pArg); } return(Status); }
ULONG FilePrintToHandle( HANDLE FileHandle, WCHAR *Format, ... ) { ULONG Status; va_list pArg;
va_start(pArg, Format); Status = FilePrintVaList(FileHandle, Format, pArg);
return(Status); }
ULONG WmipDecompressBuffer( IN PUCHAR CompressedBuffer, OUT PUCHAR *UncompressedBuffer, OUT ULONG *UncompressedSize ) /*++
Routine Description:
This routine will decompress a compressed MOF blob into a buffer that can be used to interpert the blob.
Arguments:
CompressedBuffer points at the compressed MOF blob
*UncompressedBuffer returns with a pointer to the uncompressed MOF blob
Return Value:
ERROR_SUCCESS or an error code
--*/ { PBMOFCOMPRESSEDHEADER CompressedHeader = (PBMOFCOMPRESSEDHEADER)CompressedBuffer; BYTE *Buffer; ULONG Status;
if ((CompressedHeader->Signature != BMOF_SIG) || (CompressedHeader->CompressionType != 1)) { // TODO: LocStudio message
WmipDebugPrint(("WMI: Invalid compressed mof header\n")); Status = ERROR_INVALID_PARAMETER; } else { Buffer = (BYTE *)WmipAlloc(CompressedHeader->UncompressedSize); if (Buffer == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { *UncompressedSize = Mrci1Decompress(&CompressedHeader->Buffer[0], CompressedHeader->CompressedSize, Buffer, CompressedHeader->UncompressedSize);
if (*UncompressedSize != CompressedHeader->UncompressedSize) { // TODO: LocStudioMessage
WmipDebugPrint(("WMI: Invalid compressed mof buffer\n")); WmipFree(Buffer); Status = ERROR_INVALID_PARAMETER; } else { *UncompressedBuffer = Buffer; Status = ERROR_SUCCESS; } } } return(Status); }
ULONG WmipFindMofQualifier( CBMOFQualList *QualifierList, LPCWSTR QualifierName, DWORD *QualifierType, DWORD *NumberElements, PVOID QualifierValueBuffer ) /*++
Routine Description:
This routine will find a MOF qualifier within the qualifier list passed, ensure that its type matches the type requested and return the qualifier's value
Arguments:
QualifierList is the MOF qualifier list
QualifierName is the name of the qualifier to search for
*QualifierType on entry has the qualifier type being searched for. On exit it has the actual qualifier type for the qualifier value. If on entry *QualifierType is 0xffffffff then any qualifier type is acceptable
*NumberElements returns the number of elements in the array if the result of the qualifier is an array
QualifierValueBuffer points to a buffer that returns the value of the qualifier. If the qualifier is a simple type (int or int64) then the value is returned in the buffer. If qualifier value is a string then a pointer to the string is returned in the buffer
Return Value:
ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
--*/ { CBMOFDataItem MofDataItem; ULONG Status; PUCHAR List, ListPtr; ULONG BaseTypeSize; LONG ElementCount; LONG i;
if (QualifierList == NULL) { return(ERROR_FILE_NOT_FOUND); } if (FindQual(QualifierList, (PWCHAR)QualifierName, &MofDataItem)) { if ((*QualifierType != 0xffffffff) && (MofDataItem.m_dwType != *QualifierType)) { Status = ERROR_INVALID_PARAMETER; }
if (MofDataItem.m_dwType & VT_ARRAY) { if (MofDataItem.m_dwType == (VT_BSTR | VT_ARRAY)) { BaseTypeSize = sizeof(PWCHAR); } else { BaseTypeSize = iTypeSize(MofDataItem.m_dwType); }
ElementCount = GetNumElements(&MofDataItem, 0); if (NumberElements != NULL) { *NumberElements = ElementCount; }
if (ElementCount != -1) { List = (PUCHAR)WmipAlloc(ElementCount * BaseTypeSize); if (List != NULL) { ListPtr = List; for (i = 0; i < ElementCount; i++) { if ((GetData(&MofDataItem, (BYTE *)ListPtr, &i)) == 0) { WmipFree(List); Status = ERROR_INVALID_PARAMETER; return(Status); } ListPtr += BaseTypeSize; } Status = ERROR_SUCCESS; *QualifierType = MofDataItem.m_dwType; *((PVOID *)QualifierValueBuffer) = List; } else { Status = ERROR_NOT_ENOUGH_MEMORY; } } } else { if (GetData(&MofDataItem, (BYTE *)QualifierValueBuffer, 0) == 0) { Status = ERROR_INVALID_PARAMETER; } else { *QualifierType = MofDataItem.m_dwType; Status = ERROR_SUCCESS; } } } else { Status = ERROR_FILE_NOT_FOUND; } return(Status); }
ULONG WmipFindProperty( CBMOFObj * ClassObject, WCHAR * PropertyName, CBMOFDataItem *MofPropertyData, DWORD *ValueType, PVOID ValueBuffer ) /*++
Routine Description:
This routine will find a named property within a class object
Arguments:
ClassObject is the class object in which to search
PropertyName is the name of the property to search for
MofPropertyData returns with the property data
*ValueType on entry has the property data type being searched for. On exit it has the actual qualifier type for the qualifier value. If on entry *ValueType is 0xffffffff then any data type is acceptable
ValueBuffer points to a buffer that returns the value of the property. If the property is a simple type (int or int64) then the value is returned in the buffer. If qualifier value is a string then a pointer to the string is returned in the buffer
Return Value:
ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
--*/ { ULONG Status; LONG i;
if (FindProp(ClassObject, PropertyName, MofPropertyData)) { if ((*ValueType != 0xffffffff) && (MofPropertyData->m_dwType != *ValueType)) { Status = ERROR_INVALID_PARAMETER; }
i = 0; if (GetData(MofPropertyData, (BYTE *)ValueBuffer, &i) == 0) { Status = ERROR_INVALID_PARAMETER; } else { *ValueType = MofPropertyData->m_dwType; Status = ERROR_SUCCESS; } } else { Status = ERROR_FILE_NOT_FOUND; } return(Status); }
PWCHAR AddSlashesToString( PWCHAR SlashedNamespace, PWCHAR Namespace ) { PWCHAR Return = SlashedNamespace; //
// MOF likes the namespace paths to be C-style, that is to have a
// '\\' instad of a '\'. So whereever we see a '\', we insert a
// second one
//
while (*Namespace != 0) { if (*Namespace == L'\\') { *SlashedNamespace++ = L'\\'; } *SlashedNamespace++ = *Namespace++; } *SlashedNamespace = 0; return(Return); }
ULONG GenerateDataValueFromVariant( PMOFFILETARGET MofFileTarget, VARIANT *var, BOOLEAN PrintEqual ) { SCODE sc; VARIANT vTemp; ULONG Status; PWCHAR String;
//
// Uninitialized data will have a VT_NULL type.
//
if (var->vt == VT_NULL) { return(ERROR_SUCCESS); }
if (PrintEqual) { Status = FilePrint(MofFileTarget, L" = "); } //
// String types can just be dumped.
//
if (var->vt == VT_BSTR) { String = (PWCHAR)WmipAlloc(((wcslen(var->bstrVal)) * sizeof(WCHAR) * 2) + sizeof(WCHAR)); if (String != NULL) { Status = FilePrint(MofFileTarget, L"\"%ws\"", AddSlashesToString(String, var->bstrVal)); WmipFree(String); } else { Status = ERROR_NOT_ENOUGH_MEMORY; } return(Status); }
//
// References need to be maintained
//
if (var->vt == (VT_BSTR | VT_BYREF)) { String = (PWCHAR)WmipAlloc(((wcslen(var->bstrVal)) * sizeof(WCHAR) * 2) + sizeof(WCHAR)); if (String != NULL) { Status = FilePrint(MofFileTarget, L"$%ws", AddSlashesToString(String, var->bstrVal)); WmipFree(String); } else { Status = ERROR_NOT_ENOUGH_MEMORY; } return(Status); }
//
// Embedded classes, so recurse in to display the contents of it
//
if (var->vt == VT_UNKNOWN) { CBMOFObj * pObj; WmipDebugPrint(("BMOFLocParser: Data is an embeeded object %p\n", var)); pObj = (CBMOFObj *)var->bstrVal; Status = GenerateMofForObj(MofFileTarget, pObj); return(Status); }
if (var->vt == VT_BOOL) { if (var->boolVal) { Status = FilePrint(MofFileTarget, L"%ws", L"TRUE"); } else { Status = FilePrint(MofFileTarget, L"%ws", L"FALSE"); } return(Status); } //
// For non string data, convert the infomation to a bstr and display it.
//
VariantInit(&vTemp); sc = VariantChangeTypeEx(&vTemp, var,0,0, VT_BSTR); if (sc == S_OK) { Status = FilePrint(MofFileTarget, L"%ws", vTemp.bstrVal); VariantClear(&vTemp); } else { Status = sc; } return(Status); }
ULONG GenerateDataValue( PMOFFILETARGET MofFileTarget, CBMOFDataItem *Item, BOOLEAN PrintEqual ) { DWORD Type, SimpleType; long NumDim, i; long FirstDim; VARIANT var; BOOLEAN FirstIndex; ULONG Status = ERROR_SUCCESS;
//
// Determine the data type and clear out the variant
//
Type = Item->m_dwType; SimpleType = Type & ~VT_ARRAY; memset((void *)&var.lVal, 0, 8);
NumDim = GetNumDimensions(Item); if (NumDim == 0) { //
// handle the simple scalar case. Note that uninitialized properties
// will not have data.
//
if(GetData(Item, (BYTE *)&(var.lVal), NULL)) { var.vt = (VARTYPE)SimpleType; Status = GenerateDataValueFromVariant(MofFileTarget, &var, PrintEqual);
if (var.vt == VT_BSTR) { BMOFFree(var.bstrVal); } } } else if (NumDim == 1) { //
// For the array case, just loop getting each element.
// Start by getting the number of elements
//
FirstDim = GetNumElements(Item, 0); Status = ERROR_SUCCESS;
FirstIndex = TRUE; for (i = 0; (i < FirstDim) && (Status == ERROR_SUCCESS); i++) { if (! FirstIndex) { FilePrint(MofFileTarget, L", "); } else { FirstIndex = FALSE; } if (GetData(Item, (BYTE *)&(var.lVal), &i)) { var.vt = (VARTYPE)SimpleType; Status = GenerateDataValueFromVariant(MofFileTarget, &var, PrintEqual);
if(var.vt == VT_BSTR) { BMOFFree(var.bstrVal); } } } } else { //
// Currently undefined and multidimension arrays are not
// supported.
//
WmipDebugPrint(("BMOFLocParser: Multi dimensional arrays not supported\n")); WmipAssert(FALSE); Status = ERROR_INVALID_PARAMETER; }
return(Status); }
#define MAX_FLAVOR_TEXT_SIZE MAX_PATH
WCHAR *FlavorToText( WCHAR *ClassFlagsText, ULONG ClassFlags ) { PWCHAR CommaText;
//
// TODO: FInd any undocumented flavors
//
CommaText = L""; *ClassFlagsText = 0;
if (ClassFlags & FlavorAmended) { //
// since this is the first if, we can assume that a , would
// never be needed
//
wcscat(ClassFlagsText, L"amended"); CommaText = L","; }
if (ClassFlags & FlavorDisableOverride) { wcscat(ClassFlagsText, CommaText); wcscat(ClassFlagsText, L"DisableOverride"); CommaText = L","; }
if (ClassFlags & FlavorToSubclass) { wcscat(ClassFlagsText, CommaText); wcscat(ClassFlagsText, L"ToSubclass"); CommaText = L","; }
if (ClassFlags & FlavorToInstance) { wcscat(ClassFlagsText, CommaText); wcscat(ClassFlagsText, L"ToInstance"); CommaText = L","; }
WmipAssert(*ClassFlagsText != 0);
WmipDebugPrint(("BmofLocParser: Flavor : %ws\n", ClassFlagsText));
return(ClassFlagsText); }
ULONG GenerateQualifierList( PMOFFILETARGET MofFileTarget, CBMOFQualList * QualifierList, BOOLEAN SkipId ) { WCHAR *Name = NULL; CBMOFDataItem Item; BOOLEAN FirstQualifier; WCHAR OpenChar, CloseChar; ULONG Status = ERROR_SUCCESS; ULONG Flavor = 0; WCHAR s[MAX_FLAVOR_TEXT_SIZE];
FirstQualifier = TRUE; ResetQualList(QualifierList);
while ((Status == ERROR_SUCCESS) && (NextQualEx(QualifierList, &Name, &Item, &Flavor, MofFileTarget->UncompressedBlob))) { //
// TODO: if this is a mofcomp generated qualifier then we want
// to ignore it
//
if (_wcsicmp(Name, L"CIMTYPE") == 0) { // must skip CIMTYPE qualifier
continue; }
if ((SkipId) && _wcsicmp(Name, L"ID") == 0) { // If we want to skip the ID qualifier then do so
continue; } if (FirstQualifier) { Status = FilePrint(MofFileTarget, L"["); FirstQualifier = FALSE; } else { Status = FilePrint(MofFileTarget, L",\r\n "); }
if (Status == ERROR_SUCCESS) { //
// Arrays use {} to enclose the value of the qualifier
// while scalers use ()
//
if (Item.m_dwType & VT_ARRAY) { OpenChar = L'{'; CloseChar = L'}'; } else { OpenChar = L'('; CloseChar = L')'; }
Status = FilePrint(MofFileTarget, L"%ws%wc", Name, OpenChar);
if (Status == ERROR_SUCCESS) { Status = GenerateDataValue(MofFileTarget, &Item, FALSE);
if (Status == ERROR_SUCCESS) { Status = FilePrint(MofFileTarget, L"%wc", CloseChar); if ((Status == ERROR_SUCCESS) && (Flavor != 0)) { Status = FilePrint(MofFileTarget, L": %ws", FlavorToText(s, Flavor)); } } } } BMOFFree(Name); Flavor = 0; }
if ((Status == ERROR_SUCCESS) && ! FirstQualifier) { //
// if we had generated qualifiers then we need a closing ]
//
Status = FilePrint(MofFileTarget, L"]\r\n"); } return(Status); }
PWCHAR GeneratePropertyName( PWCHAR StringPtr ) { #define ObjectTextLen ( ((sizeof(L"object:") / sizeof(WCHAR)) - 1) )
PWCHAR PropertyType; //
// If CIMTYPE begins with object: then it is an embedded object
// and we need to skip the object: in the MOF generation
//
if (_wcsnicmp(StringPtr, L"object:", ObjectTextLen) == 0) { PropertyType = StringPtr + ObjectTextLen; } else { PropertyType = StringPtr; } return(PropertyType); }
ULONG GenerateProperty( PMOFFILETARGET MofFileTarget, PWCHAR PropertyName, BOOLEAN IsInstance, CBMOFQualList * QualifierList, CBMOFDataItem *Property ) { DWORD QualifierType; WCHAR *StringPtr; ULONG Status; PWCHAR ArraySuffix; PWCHAR PropertyType; PWCHAR ArrayText; BOOLEAN PrintEqual;
QualifierType = VT_BSTR; Status = WmipFindMofQualifier(QualifierList, L"CIMTYPE", &QualifierType, NULL, (PVOID)&StringPtr);
if (IsInstance) { //
// Property is within an instance definition
//
Status = FilePrint(MofFileTarget, L"%ws", PropertyName); PrintEqual = TRUE; if (Status == ERROR_SUCCESS) { if (Property->m_dwType & VT_ARRAY) { //
// use {} around arrays
//
Status = FilePrint(MofFileTarget, L" = { "); ArrayText = L"};"; PrintEqual = FALSE; } else if (Property->m_dwType == VT_UNKNOWN) { ArrayText = L""; } else { ArrayText = L";"; } if (Status == ERROR_SUCCESS) { Status = GenerateDataValue(MofFileTarget, Property, PrintEqual); if (Status == ERROR_SUCCESS) { Status = FilePrint(MofFileTarget, L"%ws\r\n", ArrayText); } } } } else { //
// Property is within a class definition, so just worry about
// defining it.
//
if (Status == ERROR_SUCCESS) { PropertyType = GeneratePropertyName(StringPtr); if (Property->m_dwType & VT_ARRAY) { ArraySuffix = L"[]"; } else { ArraySuffix = L""; }
WmipDebugPrint(("BmofLocParser: %ws %ws%ws\n", PropertyType, PropertyName, ArraySuffix)); Status = FilePrint(MofFileTarget, L"%ws %ws%ws;\r\n", PropertyType, PropertyName, ArraySuffix); BMOFFree(StringPtr); } }
return(Status); }
ULONG GetDataItemCount( CBMOFObj * ClassObject, PWCHAR QualifierToFind ) /*++
Routine Description:
This routine will count the number of WMI data items in the class and the total number of properties in the class.
Arguments:
ClassObject is class for which we count the number of data items
*TotalCount returns the total number of properties
Return Value:
Count of methods
--*/ { CBMOFQualList *PropQualifierList; CBMOFDataItem MofPropertyData; DWORD QualifierType; ULONG Counter = 0; WCHAR *PropertyName; ULONG Status; ULONG Index;
ResetObj(ClassObject); while (NextProp(ClassObject, &PropertyName, &MofPropertyData)) { PropQualifierList = GetPropQualList(ClassObject, PropertyName); if (PropQualifierList != NULL) { //
// Get the id of the property so we know it order in class
QualifierType = VT_I4; Status = WmipFindMofQualifier(PropQualifierList, QualifierToFind, &QualifierType, NULL, (PVOID)&Index); if (Status == ERROR_SUCCESS) { Counter++; } BMOFFree(PropQualifierList); } BMOFFree(PropertyName); }
return(Counter); }
ULONG ParseMethodInOutObject( CBMOFObj *ClassObject, PMETHODPARAMLIST ParamList, ULONG DataItemCount ) /*++
Routine Description:
This routine will parse a class object that is either the in or out parameters for a method.
Arguments:
ClassObject is the in or out parameter class object to parse
ClassInfo returns updated with information from ClassObject
DataItemCount is the number of data items in the ClassInfo
Return Value:
ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
--*/ { ULONG Status = ERROR_INVALID_PARAMETER; CBMOFDataItem MofPropertyData; PWCHAR PropertyName = NULL; ULONG Index; PMETHODPARAMETER MethodParam; CBMOFQualList *QualifierList = NULL; DWORD QualifierType; short BooleanValue; PWCHAR StringPtr;
ResetObj(ClassObject); while (NextProp(ClassObject, &PropertyName, &MofPropertyData)) { QualifierList = GetPropQualList(ClassObject, PropertyName); if (QualifierList != NULL) {
//
// Get the id of the property so we know its order in class
//
QualifierType = VT_I4; Status = WmipFindMofQualifier(QualifierList, L"Id", &QualifierType, NULL, (PVOID)&Index); if (Status == ERROR_SUCCESS) { //
// Method ids are 0 based
//
if (Index < DataItemCount) { //
// Valid data item id, make sure it already isn't
// in use. Note that we could have the same property
// be in both the in and the out class objects
//
MethodParam = &ParamList->Parameters[Index];
//
// If there is already an existing qualifier list
// attached then we free it and tag the new
// qualifier list to the parameter. Both lists
// should have all of the non [in] / [out]
// qualifiers
//
if (MethodParam->QualifierList != NULL) { BMOFFree(MethodParam->QualifierList); } MethodParam->QualifierList = QualifierList;
//
// See if this is an input, output or both
//
QualifierType = VT_BOOL; Status = WmipFindMofQualifier(QualifierList, L"in", &QualifierType, NULL, (PVOID)&BooleanValue); if ((Status == ERROR_SUCCESS) && BooleanValue) { MethodParam->Flags |= MOFDI_FLAG_INPUT_METHOD; }
QualifierType = VT_BOOL; Status = WmipFindMofQualifier(QualifierList, L"out", &QualifierType, NULL, (PVOID)&BooleanValue); if ((Status == ERROR_SUCCESS) && BooleanValue) { MethodParam->Flags |= MOFDI_FLAG_OUTPUT_METHOD; }
//
// If there is already a name and its the same as
// ours then free the old name and use the new one.
// If the names are different then we have a binary
// mof error
//
if (MethodParam->Name != NULL) { if (wcscmp(MethodParam->Name, PropertyName) != 0) { //
// id already in use, but a different name
//
BMOFFree(PropertyName); Status = ERROR_FILE_NOT_FOUND; goto done; } else { //
// This is a duplicate so just free up the
// memory used and decrement the total
// count of parameters in the list. The
// data obtained the last time should still
// be valid
//
ParamList->ParamCount--; BMOFFree(PropertyName); continue; } }
MethodParam->Name = PropertyName;
//
// Now figure out the data type for the parameter
// and the array status
//
if (MofPropertyData.m_dwType & VT_ARRAY) { MethodParam->Flags |= MOFDI_FLAG_ARRAY; }
QualifierType = VT_BSTR; Status = WmipFindMofQualifier(QualifierList, L"CIMTYPE", &QualifierType, NULL, (PVOID)&StringPtr);
if (Status == ERROR_SUCCESS) { MethodParam->DataType = StringPtr; } } else { //
// Method ID qualifier is out of range
//
BMOFFree(QualifierList); Status = ERROR_FILE_NOT_FOUND; goto done; } } else { //
// Check if this is the special ReturnValue parameter
// on the output parameter object. If so extract the
// return type, otherwise flag an error in the binary
// mof
//
if (_wcsicmp(L"ReturnValue", PropertyName) == 0) { QualifierType = VT_BSTR; Status = WmipFindMofQualifier(QualifierList, L"CIMTYPE", &QualifierType, NULL, (PVOID)&StringPtr);
if (Status == ERROR_SUCCESS) { BMOFFree(ParamList->ReturnDataType); ParamList->ReturnDataType = StringPtr; } } else { Status = ERROR_FILE_NOT_FOUND; goto done; } BMOFFree(PropertyName); BMOFFree(QualifierList); } } else { BMOFFree(PropertyName); } }
done:
return(Status); }
ULONG ParseMethodParameterObjects( IN CBMOFObj *InObject, IN CBMOFObj *OutObject, OUT PMETHODPARAMLIST *MethodParamList ) /*++
Routine Description:
This routine will parse the in and out method parameter obejcts to create a MOFCLASSINFO that describes the method call.
Arguments:
InObject is the object with the input parameters
OutObject is the object with the output parameters
*ClassInfo returns with the class info for the method call
Return Value:
ERROR_SUCCESS or a WMI Mof error code (see wmiump.h)
--*/ { PMETHODPARAMLIST ParamList; ULONG Status; ULONG DataItemCount; ULONG InItemCount, OutItemCount; ULONG Size; PMETHODPARAMETER MethodParameter; PWCHAR StringPtr;
Status = ERROR_SUCCESS; if (InObject != NULL) { ResetObj(InObject); InItemCount = GetDataItemCount(InObject, L"Id"); } else { InItemCount = 0; }
if (OutObject != NULL) { ResetObj(OutObject); OutItemCount = GetDataItemCount(OutObject, L"Id"); } else { OutItemCount = 0; }
DataItemCount = InItemCount + OutItemCount;
Size = sizeof(METHODPARAMLIST) + DataItemCount * sizeof(METHODPARAMETER); ParamList = (PMETHODPARAMLIST)WmipAlloc(Size); if (ParamList == NULL) { return(ERROR_NOT_ENOUGH_MEMORY); }
//
// Get the essential information to fill in the parameter list
memset(ParamList, 0, Size); ParamList->ParamCount = DataItemCount;
StringPtr = (PWCHAR)BMOFAlloc( sizeof(L"void") + sizeof(WCHAR) ); if (StringPtr != NULL) { wcscpy(StringPtr, L"void"); ParamList->ReturnDataType = StringPtr; } else { BMOFFree(ParamList); return(ERROR_NOT_ENOUGH_MEMORY); } //
// Parse the input parameter class object
//
if (InObject != NULL) { Status = ParseMethodInOutObject(InObject, ParamList, DataItemCount); } else { Status = ERROR_SUCCESS; } if (Status == ERROR_SUCCESS) { if (OutObject != NULL) { //
// Parse the output parameter class object
//
Status = ParseMethodInOutObject(OutObject, ParamList, DataItemCount); } }
*MethodParamList = ParamList;
return(Status); }
ULONG ParseMethodParameters( CBMOFDataItem *MofMethodData, PMETHODPARAMLIST *MethodParamList ) { ULONG Status = ERROR_SUCCESS; CBMOFObj *InObject; CBMOFObj *OutObject; LONG i; ULONG NumberDimensions; ULONG NumberElements; VARIANT InVar, OutVar; DWORD SimpleType;
*MethodParamList = NULL; SimpleType = MofMethodData->m_dwType & ~VT_ARRAY & ~VT_BYREF;
NumberDimensions = GetNumDimensions(MofMethodData); if (NumberDimensions > 0) { NumberElements = GetNumElements(MofMethodData, 0); WmipAssert(NumberDimensions == 1); WmipAssert((NumberElements == 1) || (NumberElements == 2));
i = 0; memset((void *)&InVar.lVal, 0, 8);
if (GetData(MofMethodData, (BYTE *)&(InVar.lVal), &i)) { InObject = (CBMOFObj *)InVar.bstrVal; InVar.vt = (VARTYPE)SimpleType; WmipAssert(InVar.vt == VT_UNKNOWN);
if (NumberElements == 2) { i = 1; memset((void *)&OutVar.lVal, 0, 8); if (GetData(MofMethodData, (BYTE *)&(OutVar.lVal), &i)) { OutVar.vt = (VARTYPE)SimpleType; WmipAssert(OutVar.vt == VT_UNKNOWN); OutObject = (CBMOFObj *)OutVar.bstrVal; } else { Status = ERROR_FILE_NOT_FOUND; } } else { OutObject = NULL; } } else { Status = ERROR_FILE_NOT_FOUND; } } else { InObject = NULL; OutObject = NULL; }
if (Status == ERROR_SUCCESS) { Status = ParseMethodParameterObjects(InObject, OutObject, MethodParamList); }
return(Status); }
ULONG GenerateMethod( PMOFFILETARGET MofFileTarget, PWCHAR MethodName, BOOLEAN IsInstance, CBMOFQualList * QualifierList, CBMOFDataItem *Method ) { ULONG Status; PMETHODPARAMLIST MethodList; ULONG i; PWCHAR ArraySuffix; PMETHODPARAMETER MethodParam; Status = ParseMethodParameters(Method, &MethodList);
if (Status == ERROR_SUCCESS) { Status = FilePrint(MofFileTarget, L"%ws %ws( ", GeneratePropertyName(MethodList->ReturnDataType), MethodName);
if (Status == ERROR_SUCCESS) { for (i = 0; ((Status == ERROR_SUCCESS) && (i < MethodList->ParamCount)); i++) { if (i != 0) { Status = FilePrint(MofFileTarget, L"\r\n,"); }
if (Status == ERROR_SUCCESS) { MethodParam = &MethodList->Parameters[i]; Status = GenerateQualifierList(MofFileTarget, MethodParam->QualifierList, TRUE); if (Status == ERROR_SUCCESS) { if (MethodParam->Flags & MOFDI_FLAG_ARRAY) { ArraySuffix = L"[]"; } else { ArraySuffix = L""; } Status = FilePrint(MofFileTarget, L"%ws %ws%ws", GeneratePropertyName(MethodParam->DataType), MethodParam->Name, ArraySuffix); } } } }
if (Status == ERROR_SUCCESS) { Status = FilePrint(MofFileTarget, L");\r\n"); } }
//
// Free all memory used to build method parameter list
//
if (MethodList != NULL) { for (i = 0; i < MethodList->ParamCount; i++) { MethodParam = &MethodList->Parameters[i]; if (MethodParam->QualifierList != NULL) { BMOFFree(MethodParam->QualifierList); }
if (MethodParam->Name != NULL) { BMOFFree(MethodParam->Name); } if (MethodParam->DataType != NULL) { BMOFFree(MethodParam->DataType); } } if (MethodList->ReturnDataType != NULL) { BMOFFree(MethodList->ReturnDataType); } WmipFree(MethodList); } return(Status); }
ULONG GenerateMofForObj( PMOFFILETARGET MofFileTarget, CBMOFObj *Obj ) { CBMOFQualList * QualifierList; CBMOFDataItem Property, Method; WCHAR *Name = NULL; ULONG Status; BOOLEAN IsInstance; DWORD ObjType; PWCHAR Text; CBMOFDataItem MofPropertyData; PWCHAR SuperClass, Separator; PWCHAR EmptyString = L""; ULONG DataType; PWCHAR Alias, AliasSeparator; //
// First display the class qualifier list
//
QualifierList = GetQualList(Obj); if(QualifierList != NULL) { Status = GenerateQualifierList(MofFileTarget, QualifierList, FALSE); BMOFFree(QualifierList);
if (Status != ERROR_SUCCESS) { return(Status); } } //
// Now determine if this is a class or instance and display the class name
//
ObjType = GetType(Obj); switch (ObjType) { case MofObjectTypeClass: { IsInstance = FALSE; Text = L"class"; break; }
case MofObjectTypeInstance: { IsInstance = TRUE; Text = L"instance of"; break; }
default: { WmipDebugPrint(("BMOFLocParser: Unknown class object type 0x%x\n", ObjType)); WmipAssert(FALSE); return(ERROR_INVALID_PARAMETER); } }
//
// See if there is a superclass, that is if this class was derrived
// from another
//
DataType = VT_BSTR; Status = WmipFindProperty(Obj, L"__SUPERCLASS", &MofPropertyData, &DataType, (PVOID)&SuperClass); switch (Status) { case ERROR_SUCCESS: { //
// This class is derrived from another
//
Separator = L":"; break; }
case ERROR_FILE_NOT_FOUND: { //
// This class is not derrived from another
//
SuperClass = EmptyString; Separator = EmptyString; break; }
default: { //
// Something is wrong, return an error
//
return(Status); } }
//
// See if there is an alias defined for this class
//
DataType = VT_BSTR; Status = WmipFindProperty(Obj, L"__ALIAS", &MofPropertyData, &DataType, (PVOID)&Alias); switch (Status) { case ERROR_SUCCESS: { //
// This class is derrived from another
//
AliasSeparator = L" as $"; break; }
case ERROR_FILE_NOT_FOUND: { //
// This class is not derrived from another
//
Alias = EmptyString; AliasSeparator = EmptyString; break; }
default: { //
// Something is wrong, return an error
//
return(Status); } } if (GetName(Obj, &Name)) { WmipDebugPrint(("BmofLocParser: Parsing -> %ws %ws %ws %ws\n", Text, Name, Separator, SuperClass)); Status = FilePrint(MofFileTarget, L"%ws %ws %ws %ws%ws%ws\r\n{\r\n", Text, Name, Separator, SuperClass, AliasSeparator, Alias); BMOFFree(Name); } else { Status = ERROR_INVALID_PARAMETER; }
if (SuperClass != EmptyString) { BMOFFree(SuperClass); } //
// Now generate each property and its qualifiers
//
ResetObj(Obj); while ((Status == ERROR_SUCCESS) && (NextProp(Obj, &Name, &Property))) { //
// Ignore any system property, that is, all those that begin
// with __
//
if ( (Name[0] == L'_') && (Name[1] == L'_') ) { WmipDebugPrint(("BmofLocParser: Skipping system property %ws\n", Name)); BMOFFree(Name); continue; } QualifierList = GetPropQualList(Obj, Name); if (QualifierList != NULL) { Status = GenerateQualifierList(MofFileTarget, QualifierList, FALSE); } if (Status == ERROR_SUCCESS) { WmipDebugPrint(("BmofLocParser: Parsing property %ws\n", Name)); Status = GenerateProperty(MofFileTarget, Name, IsInstance, QualifierList, &Property); }
if (QualifierList != NULL) { BMOFFree(QualifierList); }
BMOFFree(Name); } //
// Next we generate all of the methods and their qualifiers
//
while ((Status == ERROR_SUCCESS) && (NextMeth(Obj, &Name, &Method))) { QualifierList = GetMethQualList(Obj, Name); if (QualifierList != NULL) { Status = GenerateQualifierList(MofFileTarget, QualifierList, FALSE); }
if (Status == ERROR_SUCCESS) { WmipDebugPrint(("BmofLocParser: Parsing method %ws\n", Name)); Status = GenerateMethod(MofFileTarget, Name, IsInstance, QualifierList, &Method); }
if (QualifierList != NULL) { BMOFFree(QualifierList); }
BMOFFree(Name); }
if (Status == ERROR_SUCCESS) { //
// Closing brace for class definition
//
Status = FilePrint(MofFileTarget, L"};\r\n\r\n"); }
return(Status); }
PWCHAR MakeClassInstanceFlagsText( PWCHAR ClassFlagsText, ULONG ClassFlags ) { PWCHAR CommaText;
//
// TODO: FInd any undocumented flags
//
CommaText = L""; *ClassFlagsText = 0;
if (ClassFlags & 1) { //
// since this is the first if, we can assume that a , would
// never be needed
//
wcscat(ClassFlagsText, L"\"updateonly\""); CommaText = L","; }
if (ClassFlags & 2) { wcscat(ClassFlagsText, CommaText); wcscat(ClassFlagsText, L"\"createonly\""); CommaText = L","; }
if (ClassFlags & 32) { wcscat(ClassFlagsText, CommaText); wcscat(ClassFlagsText, L"\"safeupdate\""); CommaText = L","; }
if (ClassFlags & 64) { wcscat(ClassFlagsText, CommaText); wcscat(ClassFlagsText, L"\"forceupdate\""); CommaText = L","; }
WmipAssert(*ClassFlagsText != 0); return(ClassFlagsText); }
ULONG WatchClassInstanceFlags( PMOFFILETARGET MofFileTarget, CBMOFObj *Obj, PWCHAR ClassName, PWCHAR PragmaName, LONG *Flags ) { ULONG Status; LONG NewFlags; WCHAR FlagsText[MAX_PATH]; ULONG DataType; CBMOFDataItem Property; DataType = VT_I4; Status = WmipFindProperty(Obj, ClassName, &Property, &DataType, &NewFlags); if (Status == ERROR_SUCCESS) { if (*Flags != NewFlags) { //
// Flags have just appeared or
// changed so spit out a #pragma
//
WmipDebugPrint(("BmofLocParser: %ws changed to %ws\n", PragmaName, MakeClassInstanceFlagsText(FlagsText, NewFlags))); Status = FilePrint(MofFileTarget, L"\r\n#pragma %ws(%ws)\r\n\r\n", PragmaName, MakeClassInstanceFlagsText(FlagsText, NewFlags)); *Flags = NewFlags; } } else if (Status == ERROR_FILE_NOT_FOUND) { Status = ERROR_SUCCESS; } return(Status); }
ULONG WatchForEnglishMof( PMOFFILETARGET MofFileTarget, PWCHAR Namespace, ULONG ClassFlags, CBMOFObj *Obj ) { WCHAR *Name = NULL; WCHAR *NamespaceName = NULL; ULONG DataType; CBMOFDataItem MofPropertyData; ULONG Status; WCHAR s[MAX_PATH]; //
// We are looking for an instance of __namespace
//
if (GetName(Obj, &Name)) { if ( (GetType(Obj) == MofObjectTypeInstance) && (_wcsicmp(Name, L"__namespace") == 0) ) { //
// Now if we are dropping down to a namespace that ends in
// ms_409 then that means we have an english amendment and
// want to make a copy of it. Otherwise we want to stop
// making copies. We determine the namespace we are
// creating by looking at the value of the name property.
//
DataType = VT_BSTR; Status = WmipFindProperty(Obj, L"name", &MofPropertyData, &DataType, (PVOID)&NamespaceName); if (Status == ERROR_SUCCESS) { if (_wcsicmp(NamespaceName, L"ms_409") == 0) { //
// moving to the english locale, so start writing
// english
//
MofFileTarget->WriteToEnglish = TRUE; Status = FilePrintToHandle(MofFileTarget->EnglishMofHandle, L"\r\n\r\n" L"#pragma classflags(%d)\r\n" L"#pragma namespace(\"%ws\")\r\n", ClassFlags, AddSlashesToString(s, Namespace)); } else { //
// moving to a different locale, so stop writing
// english
//
MofFileTarget->WriteToEnglish = FALSE; } BMOFFree(NamespaceName); } else if (Status == ERROR_FILE_NOT_FOUND) { //
// Did not find the property we wanted. Not a good
// thing, but not fatal.
//
Status = ERROR_SUCCESS; } } else { Status = ERROR_SUCCESS; } BMOFFree(Name); } else { Status = ERROR_SUCCESS; } return(Status); }
BOOLEAN ConvertBmfToMof( PUCHAR BinaryMofData, TCHAR *MofFile, TCHAR *EnglishMofFile ) { HANDLE FileHandle; ULONG Status; CBMOFObjList *ObjList; CBMOFObj *Obj; PUCHAR UncompressedBmof; ULONG UncompressedBmofSize; WCHAR Namespace[MAX_PATH]; PWCHAR NewNamespace; ULONG DataType; CBMOFDataItem Property; LONG ClassFlags, InstanceFlags; WCHAR w; MOFFILETARGET MofFileTarget; //
// First thing is to try to create the output files in which we will
// generate the unicode MOF text
//
FileHandle = CreateFile(MofFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (FileHandle != INVALID_HANDLE_VALUE) { //
// Now open english mof file
//
if (*EnglishMofFile != 0) { MofFileTarget.EnglishMofHandle = CreateFile(EnglishMofFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } else { MofFileTarget.EnglishMofHandle = NULL; }
if (MofFileTarget.EnglishMofHandle != INVALID_HANDLE_VALUE) { //
// Initialize the mof file target information
//
MofFileTarget.MofHandle = FileHandle; MofFileTarget.WriteToEnglish = FALSE; //
// Write magic header that signifies that this is a unicode
// file
//
w = 0xfeff; Status = FilePrintToHandle(FileHandle, L"%wc", w); if (Status == ERROR_SUCCESS) { //
// Uncompress the binary mof data so that we can work with it
//
Status = WmipDecompressBuffer(BinaryMofData, &UncompressedBmof, &UncompressedBmofSize); if (Status == ERROR_SUCCESS) { WmipDebugPrint(("BmofLocParser: %s uncompressed to %d bytes\n", MofFile, UncompressedBmofSize)); WmipAssert(UncompressedBmof != NULL); MofFileTarget.UncompressedBlob = UncompressedBmof; //
// We start in the root\default namespace by default
//
wcscpy(Namespace, L"root\\default"); ClassFlags = 0; InstanceFlags = 0; //
// Create the binary mof object list and related structures
// so that we can later enumerate over them and
// reconstitute them back into unicode text
//
ObjList = CreateObjList(UncompressedBmof); if(ObjList != NULL) { ResetObjList(ObjList); while ((Obj = NextObj(ObjList)) && (Status == ERROR_SUCCESS)) {
//
// Watch for a new namespace instance and
// see if we are create an instance for
// "\\\\.\\root\\wmi\\ms_409". If so then
// turn on writing to the english mof,
// otherwise turn it off
//
if (MofFileTarget.EnglishMofHandle != NULL) { Status = WatchForEnglishMof(&MofFileTarget, Namespace, ClassFlags, Obj); }
if (Status == ERROR_SUCCESS) { //
// Watch for change in namespace and if so then
// spit out a #pragma namespace to track it
//
DataType = VT_BSTR; Status = WmipFindProperty(Obj, L"__NAMESPACE", &Property, &DataType, (PVOID)&NewNamespace); } if (Status == ERROR_SUCCESS) { if (_wcsicmp(Namespace, NewNamespace) != 0) { //
// Namespace has changed, spit out a
// #pragma
//
WmipDebugPrint(("BmofLocParser: Switching from namespace %ws to %ws\n", Namespace, NewNamespace)); Status = FilePrint(&MofFileTarget, L"\r\n#pragma namespace(\"%ws\")\r\n\r\n", AddSlashesToString(Namespace, NewNamespace)); wcscpy(Namespace, NewNamespace); } BMOFFree(NewNamespace); } else if (Status == ERROR_FILE_NOT_FOUND) { Status = ERROR_SUCCESS; } //
// Watch for change in classflags
//
if (Status == ERROR_SUCCESS) { Status = WatchClassInstanceFlags(&MofFileTarget, Obj, L"__ClassFlags", L"Classflags", &ClassFlags); } //
// Watch for change in instance flags
//
if (Status == ERROR_SUCCESS) { Status = WatchClassInstanceFlags(&MofFileTarget, Obj, L"__InstanceFlags", L"Instanceflags", &InstanceFlags); } //
// Generate mof for this object
//
if (Status == ERROR_SUCCESS) { Status = GenerateMofForObj(&MofFileTarget, Obj); } BMOFFree(Obj); } BMOFFree(ObjList); } else { // TODO: LocStudio message
Status = ERROR_INVALID_PARAMETER; } WmipFree(UncompressedBmof); } } CloseHandle(FileHandle); if (MofFileTarget.EnglishMofHandle != NULL) { CloseHandle(MofFileTarget.EnglishMofHandle); } if (Status != ERROR_SUCCESS) { //
// There was some error generating the MOF text and we are
// going to return a failure. Make sure to clean up any
// temporary file created
//
WmipDebugPrint(("BmofLocParser: BMF parsing returns error %d\n", Status)); #if 0
DebugBreak(); #endif
DeleteFile(MofFile); DeleteFile(EnglishMofFile); }
} else { CloseHandle(FileHandle); DeleteFile(MofFile); Status = GetLastError(); } } else { Status = GetLastError(); } return((Status == ERROR_SUCCESS) ? TRUE : FALSE); }
|