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.
2428 lines
69 KiB
2428 lines
69 KiB
/*++
|
|
|
|
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);
|
|
}
|
|
|
|
|