503 lines
12 KiB
C
503 lines
12 KiB
C
//***************************************************************************
|
||
//
|
||
// (c) 1997 by Microsoft Corporation
|
||
//
|
||
// test.c
|
||
//
|
||
// a-davj 14-April-97 Created.
|
||
//
|
||
// Demonstration program for dumping out Binary Managed Object Format (BMOF)
|
||
// data.
|
||
//
|
||
//***************************************************************************
|
||
|
||
#include <windows.h>
|
||
#include <ole2.h>
|
||
#include <oleauto.h>
|
||
#include <stdio.h>
|
||
#include <io.h>
|
||
#include <fcntl.h>
|
||
#include <stdio.h>
|
||
#include <sys/stat.h>
|
||
#include <stdlib.h>
|
||
|
||
#include "bmof.h"
|
||
#include "mrcicode.h"
|
||
|
||
void DisplayObject(CBMOFObj * po);
|
||
|
||
//***************************************************************************
|
||
//
|
||
// void * BMOFAlloc
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Provides allocation service for BMOF.C. This allows users to choose
|
||
// the allocation method that is used.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// Size Input. Size of allocation in bytes.
|
||
//
|
||
// RETURN VALUE:
|
||
//
|
||
// pointer to new data. NULL if allocation failed.
|
||
//
|
||
//***************************************************************************
|
||
|
||
void * BMOFAlloc(size_t Size)
|
||
{
|
||
return malloc(Size);
|
||
}
|
||
|
||
//***************************************************************************
|
||
//
|
||
// void BMOFFree
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Provides allocation service for BMOF.C. This frees what ever was
|
||
// allocated via BMOFAlloc.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// pointer to memory to be freed.
|
||
//
|
||
//***************************************************************************
|
||
|
||
void BMOFFree(void * pFree)
|
||
{
|
||
free(pFree);
|
||
}
|
||
|
||
//***************************************************************************
|
||
//
|
||
// void DisplayVariant
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Displays VARIANT data. Note that this is only done in this sample for
|
||
// convienence, and using OLE is NOT necessary.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// pvar Input. Pointer to VARIANT which is to be displayed.
|
||
// It is assumed that the variant type is simple, I.E.
|
||
// neither the VT_ARRAY or VT_BYREF bits are set.
|
||
//
|
||
//***************************************************************************
|
||
|
||
void DisplayVariant(VARIANT * pvar)
|
||
{
|
||
SCODE sc;
|
||
VARIANT vTemp;
|
||
|
||
// Uninitialized data will have a VT_NULL type.
|
||
|
||
if(pvar->vt == VT_NULL)
|
||
{
|
||
printf(" data is NULL");
|
||
return;
|
||
}
|
||
|
||
// String types can just be dumped.
|
||
|
||
if(pvar->vt == VT_BSTR)
|
||
{
|
||
printf("value is %S",pvar->bstrVal);
|
||
return;
|
||
}
|
||
else if(pvar->vt == VT_UNKNOWN)
|
||
{
|
||
CBMOFObj * pObj;
|
||
printf(" got an embedded object");
|
||
pObj = (CBMOFObj *)pvar->bstrVal;
|
||
DisplayObject(pObj);
|
||
return;
|
||
}
|
||
|
||
// For non string data, convert the infomation to a bstr and display it.
|
||
|
||
VariantInit(&vTemp);
|
||
sc = VariantChangeTypeEx(&vTemp, pvar,0,0, VT_BSTR);
|
||
if(sc == S_OK)
|
||
{
|
||
printf("value is %S",vTemp.bstrVal);
|
||
}
|
||
else
|
||
printf(" Couldnt convert type 0x%x, error code 0x%x", pvar->vt, sc);
|
||
VariantClear(&vTemp);
|
||
}
|
||
|
||
//***************************************************************************
|
||
//
|
||
// void DisplayData
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Displays the data held in a data item. Note that Ole is use just for
|
||
// ease of use and is optional.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// pItem Input. Item to be displayed.
|
||
//
|
||
//***************************************************************************
|
||
|
||
void DisplayData(CBMOFDataItem * pItem)
|
||
{
|
||
DWORD dwType, dwSimpleType;
|
||
long lNumDim, lCnt;
|
||
long lFirstDim;
|
||
VARIANT var;
|
||
|
||
// Determine the data type and clear out the variant
|
||
|
||
dwType = pItem->m_dwType;
|
||
printf("\nData type is 0x%x ", dwType);
|
||
dwSimpleType = dwType & ~VT_ARRAY & ~VT_BYREF;
|
||
memset((void *)&var.lVal, 0, 8);
|
||
|
||
lNumDim = GetNumDimensions(pItem);
|
||
|
||
if(lNumDim == 0)
|
||
{
|
||
// handle the simple scalar case. Note that uninitialized properties
|
||
// will not have data.
|
||
|
||
if(GetData(pItem, (BYTE *)&(var.lVal), NULL))
|
||
{
|
||
var.vt = (VARTYPE)dwSimpleType;
|
||
DisplayVariant(&var);
|
||
|
||
// Note the GetData does not use OLE to allocate BSTRs
|
||
// and so we need to use our own freeing routine here.
|
||
|
||
if(var.vt == VT_BSTR)
|
||
BMOFFree(var.bstrVal);
|
||
}
|
||
else
|
||
printf(" NULL ");
|
||
}
|
||
else if(lNumDim == 1)
|
||
{
|
||
// For the array case, just loop getting each element.
|
||
// Start by getting the number of elements
|
||
|
||
lFirstDim = GetNumElements(pItem, 0);
|
||
if(lFirstDim < 1)
|
||
{
|
||
printf("\n CANT DISPLAY, BOGUS DIMENSION");
|
||
return;
|
||
}
|
||
printf("\n");
|
||
for(lCnt = 0; lCnt < lFirstDim; lCnt++)
|
||
{
|
||
if(GetData(pItem, (BYTE *)&(var.lVal), &lCnt))
|
||
{
|
||
var.vt = (VARTYPE)dwSimpleType;
|
||
DisplayVariant(&var);
|
||
|
||
// Note the GetData does not use OLE to allocate BSTRs
|
||
// and so we need to use our own freeing routine here.
|
||
|
||
if(var.vt == VT_BSTR)
|
||
BMOFFree(var.bstrVal);
|
||
printf("\n");
|
||
}
|
||
else
|
||
printf(" NULL ");
|
||
}
|
||
}
|
||
else if(lNumDim == -1)
|
||
{
|
||
printf("\n Undefined array");
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
// Currently multidimension arrays are not supported.
|
||
|
||
printf("\n CANT DISPLAY, TOO MANY DIMEMSIONS");
|
||
return;
|
||
}
|
||
|
||
|
||
return;
|
||
}
|
||
|
||
//***************************************************************************
|
||
//
|
||
// void DisplayQualList
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Helper routine for displaying a qualifier list.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// pql Input. Pointer to structure which wraps the
|
||
// qualifier list.
|
||
//
|
||
//***************************************************************************
|
||
|
||
void DisplayQualList(CBMOFQualList * pql)
|
||
{
|
||
WCHAR * pName = NULL;
|
||
CBMOFDataItem Item;
|
||
ResetQualList(pql);
|
||
printf("\nDisplaying qual list");
|
||
|
||
|
||
while(NextQual(pql, &pName, &Item))
|
||
{
|
||
printf("\nQualifier name is -%S- ",pName);
|
||
DisplayData(&Item);
|
||
BMOFFree(pName);
|
||
}
|
||
}
|
||
|
||
|
||
//***************************************************************************
|
||
//
|
||
// void DisplayObject
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Helper routine for displaying a class or instance.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// po Input. Pointer to structure that wraps the object.
|
||
//
|
||
//***************************************************************************
|
||
|
||
void DisplayObject(CBMOFObj * po)
|
||
{
|
||
CBMOFQualList * pql;
|
||
CBMOFDataItem Item;
|
||
WCHAR * pName = NULL;
|
||
BOOL bfirstmethod = TRUE;
|
||
|
||
// Display the objects name, its type (Is it a class or instance), and
|
||
// display the qualifier set which is attached to the object.
|
||
|
||
if(GetName(po, &pName))
|
||
{
|
||
printf("\n\nLooking at object %S",pName);
|
||
BMOFFree(pName);
|
||
}
|
||
printf("\nThe objects type is 0x%x", GetType(po));
|
||
pql = GetQualList(po);
|
||
if(pql)
|
||
{
|
||
DisplayQualList(pql);
|
||
BMOFFree(pql);
|
||
pql = NULL;
|
||
}
|
||
|
||
// Display each property and it associated qualifier list
|
||
|
||
ResetObj(po);
|
||
printf("\nDisplaying prop list");
|
||
|
||
while(NextProp(po, &pName, &Item))
|
||
{
|
||
printf("\n\nProperty name is -%S- type is 0x%x",pName, Item.m_dwType);
|
||
DisplayData(&Item);
|
||
pql = GetPropQualList(po, pName);
|
||
if(pql)
|
||
{
|
||
DisplayQualList(pql);
|
||
BMOFFree(pql);
|
||
pql = NULL;
|
||
}
|
||
|
||
BMOFFree(pName);
|
||
}
|
||
|
||
while(NextMeth(po, &pName, &Item))
|
||
{
|
||
|
||
if(bfirstmethod)
|
||
printf("\nDisplaying method list");
|
||
bfirstmethod = FALSE;
|
||
|
||
printf("\n\nMethod name is -%S- type is 0x%x",pName, Item.m_dwType);
|
||
DisplayData(&Item);
|
||
pql = GetMethQualList(po, pName);
|
||
if(pql)
|
||
{
|
||
DisplayQualList(pql);
|
||
BMOFFree(pql);
|
||
pql = NULL;
|
||
}
|
||
|
||
BMOFFree(pName);
|
||
}
|
||
|
||
}
|
||
|
||
//***************************************************************************
|
||
//
|
||
// BYTE * ReadBMOFFile
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Opens and decompresses the binary mof file
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// pFileName Input. Pointer to structure that wraps the object.
|
||
//
|
||
// RETURN VALUE:
|
||
//
|
||
// pointer to the binary mof data. This should be freed using "free". Note that
|
||
// NULL is returned for all errors.
|
||
//
|
||
//***************************************************************************
|
||
|
||
BYTE * ReadBMOFFile(char * pFileName)
|
||
{
|
||
int fh1 = -1;
|
||
int iRet;
|
||
DWORD dwCompType, dwCompressedSize, dwExpandedSize, dwSig, dwResSize;
|
||
BYTE * pCompressed = NULL;
|
||
BYTE * pExpanded = NULL;
|
||
|
||
fh1 = _open(pFileName, _O_BINARY | _O_RDONLY);
|
||
if(fh1 == -1)
|
||
{
|
||
printf("\nCould not open the file %s", pFileName);
|
||
return NULL;
|
||
}
|
||
|
||
// get the signature, compression type, and the sizes
|
||
|
||
iRet = _read(fh1, &dwSig, sizeof(DWORD));
|
||
if((DWORD)iRet != sizeof(DWORD))
|
||
{
|
||
printf("\nError reading file");
|
||
_close(fh1);
|
||
return NULL;
|
||
}
|
||
|
||
iRet = _read(fh1, &dwCompType, sizeof(DWORD));
|
||
iRet = _read(fh1, &dwCompressedSize, sizeof(DWORD));
|
||
iRet = _read(fh1, &dwExpandedSize, sizeof(DWORD));
|
||
|
||
// make sure the signature is valid and that the compression type is one
|
||
// we understand!
|
||
|
||
if(dwSig != BMOF_SIG ||dwCompType != 1)
|
||
{
|
||
_close(fh1);
|
||
return NULL;
|
||
}
|
||
|
||
// Allocate storage for the compressed data and
|
||
// expanded data
|
||
|
||
pCompressed = malloc(dwCompressedSize);
|
||
pExpanded = malloc(dwExpandedSize);
|
||
if(pCompressed == NULL || pExpanded == NULL)
|
||
{
|
||
_close(fh1);
|
||
return NULL;
|
||
}
|
||
|
||
// Read the compressed data.
|
||
|
||
iRet = _read(fh1, pCompressed, dwCompressedSize);
|
||
if((DWORD)iRet != dwCompressedSize)
|
||
{
|
||
printf("\nError reading data");
|
||
free(pExpanded);
|
||
free(pCompressed);
|
||
return NULL;
|
||
}
|
||
|
||
_close(fh1);
|
||
|
||
// Decompress the data
|
||
|
||
dwResSize = Mrci1Decompress(pCompressed, dwCompressedSize, pExpanded, dwExpandedSize);
|
||
free(pCompressed);
|
||
|
||
if(dwResSize != dwExpandedSize)
|
||
{
|
||
printf("\nError expanding data!!!");
|
||
free(pExpanded);
|
||
return NULL;
|
||
}
|
||
return pExpanded;
|
||
}
|
||
|
||
//***************************************************************************
|
||
//
|
||
// int main
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Entry point.
|
||
//
|
||
// COMMAND LINE ARGUMENT:
|
||
//
|
||
// This program should be launced with a single argument which is the
|
||
// name of the file which contains the BMOF.
|
||
//
|
||
// RETURN VALUE:
|
||
//
|
||
// 0 if OK, 1 if error.
|
||
//
|
||
//***************************************************************************
|
||
|
||
int _cdecl main(int argc, char ** argv)
|
||
{
|
||
BYTE * pTest;
|
||
CBMOFObjList * pol;
|
||
CBMOFObj * po;
|
||
|
||
// check the command line
|
||
|
||
if(argc < 2)
|
||
{
|
||
printf("\nusage: test BMOFFILE\nwhere BMOFFILE is the binary mof file to dump");
|
||
return 1;
|
||
}
|
||
|
||
pTest = ReadBMOFFile(argv[1]);
|
||
|
||
if(pTest == NULL)
|
||
{
|
||
printf("\nterminating abnormally, could not read binary mof");
|
||
return 1;
|
||
}
|
||
|
||
// Now use the helper functions to dump out the file. Create an object
|
||
// list structure and use it to enumerate the objects.
|
||
|
||
pol = CreateObjList(pTest);
|
||
if(pol == NULL)
|
||
{
|
||
return 1;
|
||
}
|
||
printf("\nThe number of objects is %d",pol->m_pol->dwNumberOfObjects);
|
||
|
||
ResetObjList (pol);
|
||
while(po = NextObj(pol))
|
||
{
|
||
DisplayObject(po);
|
||
BMOFFree(po);
|
||
}
|
||
|
||
BMOFFree(pol);
|
||
|
||
free(pTest);
|
||
printf("\nTerminating normally\n");
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|