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.
670 lines
17 KiB
670 lines
17 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mofgen.cpp
|
|
|
|
Abstract:
|
|
|
|
This file contains the implementation of the CMofGen class
|
|
|
|
Author:
|
|
|
|
Mohit Srivastava 28-Nov-00
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "iisprov.h"
|
|
#include "mofgen.h"
|
|
#include "MultiSzData.h"
|
|
|
|
#include <initguid.h>
|
|
// {041FFF3F-EB8F-4d51-9736-A26E91E3A3CA}
|
|
DEFINE_GUID(IisWmiMofgenGuid,
|
|
0x41fff3f, 0xeb8f, 0x4d51, 0x97, 0x36, 0xa2, 0x6e, 0x91, 0xe3, 0xa3, 0xca);
|
|
|
|
//
|
|
// Debugging Stuff
|
|
//
|
|
#include "pudebug.h"
|
|
DECLARE_DEBUG_PRINTS_OBJECT()
|
|
|
|
extern CDynSchema* g_pDynSch; // Initialized to NULL in schemadynamic.cpp
|
|
|
|
void ConstructFlatContainerList(METABASE_KEYTYPE*, bool*);
|
|
|
|
bool CMofGen::ParseCmdLine (int argc, wchar_t **argv)
|
|
{
|
|
for (int i=1; i<argc; ++i)
|
|
{
|
|
static wchar_t * wszOUT = L"/out:";
|
|
static wchar_t * wszHEADER = L"/header:";
|
|
static wchar_t * wszFOOTER = L"/footer:";
|
|
|
|
if (wcsncmp (argv[i], wszOUT, wcslen(wszOUT)) == 0)
|
|
{
|
|
if (m_wszOutFileName != 0)
|
|
{
|
|
// duplicate parameter
|
|
return false;
|
|
}
|
|
m_wszOutFileName = new WCHAR [wcslen (argv[i]) - wcslen (wszOUT) + 1];
|
|
if (m_wszOutFileName == 0)
|
|
{
|
|
return false;
|
|
}
|
|
wcscpy (m_wszOutFileName, argv[i] + wcslen(wszOUT));
|
|
}
|
|
else if (wcsncmp (argv[i], wszHEADER, wcslen (wszHEADER)) == 0)
|
|
{
|
|
if (m_wszHeaderFileName != 0)
|
|
{
|
|
// duplicate parameter
|
|
return false;
|
|
}
|
|
m_wszHeaderFileName = new WCHAR [wcslen (argv[i]) - wcslen (wszHEADER) + 1];
|
|
if (m_wszHeaderFileName == 0)
|
|
{
|
|
return false;
|
|
}
|
|
wcscpy (m_wszHeaderFileName, argv[i] + wcslen(wszHEADER));
|
|
}
|
|
else if (wcsncmp (argv[i], wszFOOTER, wcslen (wszFOOTER)) == 0)
|
|
{
|
|
if (m_wszFooterFileName != 0)
|
|
{
|
|
// duplicate parameter
|
|
return false;
|
|
}
|
|
m_wszFooterFileName = new WCHAR [wcslen (argv[i]) - wcslen (wszFOOTER) + 1];
|
|
if (m_wszFooterFileName == 0)
|
|
{
|
|
return false;
|
|
}
|
|
wcscpy (m_wszFooterFileName, argv[i] + wcslen(wszFOOTER));
|
|
}
|
|
else
|
|
{
|
|
wprintf (L"Unknown parameter: %s\n", argv[i]);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// verify that we have the required parameters
|
|
|
|
if (m_wszOutFileName == 0)
|
|
{
|
|
printf ("You need to specify an output file name\n");
|
|
return false;
|
|
}
|
|
|
|
if (m_wszHeaderFileName == 0)
|
|
{
|
|
printf ("You need to specify a header file name\n");
|
|
return false;
|
|
}
|
|
|
|
if (m_wszFooterFileName == 0)
|
|
{
|
|
printf ("You need to specify a footer file name\n");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void CMofGen::PrintUsage (wchar_t **argv)
|
|
{
|
|
DBG_ASSERT(argv != NULL);
|
|
wprintf (L"Usage:\n%s /out:<filename> /header:<filename> /footer:<filename>\n", argv[0]);
|
|
}
|
|
|
|
|
|
HRESULT CMofGen::PushMethods(WMI_CLASS* i_pElement)
|
|
{
|
|
DBG_ASSERT(i_pElement != NULL);
|
|
DBG_ASSERT(m_pFile != NULL);
|
|
|
|
WMI_METHOD* pMethCurrent;
|
|
|
|
LPCWSTR wszRetType = NULL;
|
|
LPWSTR wszDescription = NULL;
|
|
LPWSTR wszParamType = NULL;
|
|
LPWSTR wszParamTypeSuffix = NULL;
|
|
LPWSTR wszParamInOut = NULL;
|
|
|
|
int iError = 0;
|
|
|
|
if(i_pElement->ppMethod == NULL)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
for(ULONG i = 0; i_pElement->ppMethod[i] != NULL; i++)
|
|
{
|
|
pMethCurrent = i_pElement->ppMethod[i];
|
|
|
|
if(pMethCurrent->typeRetVal == NULL)
|
|
{
|
|
wszRetType = L"void";
|
|
}
|
|
else
|
|
{
|
|
CimTypeStringMapping* pCimType =
|
|
CMofGenUtils::LookupCimType(pMethCurrent->typeRetVal);
|
|
DBG_ASSERT(pCimType != NULL);
|
|
if (!pCimType) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
wszRetType = pCimType->wszString;
|
|
}
|
|
wszDescription = pMethCurrent->pszDescription;
|
|
|
|
iError = fwprintf(m_pFile, L"\t[Implemented,bypass_getobject");
|
|
if(iError < 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
if(wszDescription)
|
|
{
|
|
iError = fwprintf(m_pFile, L",Description(\"%s\")", wszDescription);
|
|
}
|
|
iError = fwprintf(m_pFile, L"] %s %s(", wszRetType, pMethCurrent->pszMethodName);
|
|
if(iError < 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
ULONG j = 0;
|
|
if(pMethCurrent->ppParams != NULL)
|
|
{
|
|
for(j = 0; pMethCurrent->ppParams[j] != NULL; j++)
|
|
{
|
|
wszParamType = L"";
|
|
wszParamTypeSuffix = L"";
|
|
wszParamInOut = L"";
|
|
if(j != 0)
|
|
{
|
|
iError = fwprintf(m_pFile, L", ");
|
|
if(iError < 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
switch(pMethCurrent->ppParams[j]->type)
|
|
{
|
|
case CIM_STRING:
|
|
wszParamType = L"string";
|
|
break;
|
|
case CIM_SINT32:
|
|
wszParamType = L"sint32";
|
|
break;
|
|
case VT_ARRAY | CIM_STRING:
|
|
wszParamType = L"string";
|
|
wszParamTypeSuffix = L"[]";
|
|
break;
|
|
case VT_ARRAY | VT_UNKNOWN:
|
|
wszParamType = L"ServerBinding";
|
|
wszParamTypeSuffix = L"[]";
|
|
break;
|
|
case CIM_BOOLEAN:
|
|
wszParamType = L"boolean";
|
|
break;
|
|
case CIM_DATETIME:
|
|
wszParamType = L"datetime";
|
|
break;
|
|
default:
|
|
wprintf(L"Warning: Type of Param: %s in Method: %s unknown. Not outputting type.\n",
|
|
pMethCurrent->ppParams[j]->pszParamName,
|
|
pMethCurrent->pszMethodName);
|
|
break;
|
|
}
|
|
switch(pMethCurrent->ppParams[j]->iInOut)
|
|
{
|
|
case PARAM_IN:
|
|
wszParamInOut = L"[IN]";
|
|
break;
|
|
case PARAM_OUT:
|
|
wszParamInOut = L"[OUT]";
|
|
break;
|
|
case PARAM_INOUT:
|
|
wszParamInOut = L"[IN,OUT]";
|
|
break;
|
|
default:
|
|
wprintf(L"Warning: Unsure if Param: %s in Method: %s is IN or OUT param. Not outputting IN/OUT qualifier\n",
|
|
pMethCurrent->ppParams[j]->pszParamName,
|
|
pMethCurrent->pszMethodName);
|
|
break;
|
|
}
|
|
|
|
// CreateNewSite has an optional param
|
|
if (!wcscmp(pMethCurrent->pszMethodName, L"CreateNewSite") &&
|
|
!wcscmp(pMethCurrent->ppParams[j]->pszParamName, L"ServerId")) {
|
|
wszParamInOut = L"[IN,OPTIONAL]";
|
|
}
|
|
|
|
iError = fwprintf(m_pFile, L"%s %s %s%s",
|
|
wszParamInOut, wszParamType, pMethCurrent->ppParams[j]->pszParamName, wszParamTypeSuffix);
|
|
if(iError < 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
}
|
|
|
|
iError = fwprintf(m_pFile, L");\n");
|
|
if(iError < 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMofGen::GenerateEscapedString(LPCWSTR i_wsz)
|
|
{
|
|
DBG_ASSERT(i_wsz != NULL);
|
|
|
|
ULONG cchOld = 0;
|
|
ULONG cchNew = 0;
|
|
LPWSTR wsz;
|
|
|
|
for(ULONG i = 0; i_wsz[i] != L'\0'; i++)
|
|
{
|
|
if(i_wsz[i] == L'\\' || i_wsz[i] == L'\"')
|
|
{
|
|
cchNew += 2;
|
|
}
|
|
else
|
|
{
|
|
cchNew++;
|
|
}
|
|
cchOld++;
|
|
}
|
|
|
|
if(cchNew > m_cchTemp || m_wszTemp == NULL)
|
|
{
|
|
delete [] m_wszTemp;
|
|
m_wszTemp = new WCHAR[1+cchNew*2];
|
|
if(m_wszTemp == NULL)
|
|
{
|
|
m_cchTemp = 0;
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
m_cchTemp = cchNew*2;
|
|
}
|
|
|
|
ULONG j = 0;
|
|
for(ULONG i = 0; i < cchOld; i++)
|
|
{
|
|
if(i_wsz[i] == L'\\' || i_wsz[i] == L'\"')
|
|
{
|
|
m_wszTemp[j] = L'\\';
|
|
m_wszTemp[j+1] = i_wsz[i];
|
|
j+=2;
|
|
}
|
|
else
|
|
{
|
|
m_wszTemp[j] = i_wsz[i];
|
|
j++;
|
|
}
|
|
}
|
|
DBG_ASSERT(m_wszTemp != NULL);
|
|
m_wszTemp[j] = L'\0';
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMofGen::PushProperties(WMI_CLASS* i_pElement)
|
|
{
|
|
DBG_ASSERT(i_pElement != NULL);
|
|
DBG_ASSERT(m_pFile != NULL);
|
|
|
|
HRESULT hr = S_OK;
|
|
METABASE_PROPERTY* pPropCurrent;
|
|
|
|
LPWSTR wszType = NULL;
|
|
LPWSTR wszTypeSuffix = NULL;
|
|
LPWSTR wszQual = NULL;
|
|
LPWSTR wszDefault = NULL;
|
|
LPWSTR wszQuote = L"";
|
|
|
|
int iError = 0;
|
|
|
|
if(i_pElement->ppmbp == NULL)
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
for(ULONG i = 0; i_pElement->ppmbp[i] != NULL; i++)
|
|
{
|
|
wszQual = wszTypeSuffix = wszType = wszQuote = L"";
|
|
wszDefault = NULL;
|
|
WCHAR wszBuf[20];
|
|
|
|
pPropCurrent= i_pElement->ppmbp[i];
|
|
switch(pPropCurrent->dwMDDataType)
|
|
{
|
|
case DWORD_METADATA:
|
|
if(pPropCurrent->dwMDMask != 0)
|
|
{
|
|
wszType = L"boolean";
|
|
if(pPropCurrent->pDefaultValue)
|
|
{
|
|
if(*((int *)(pPropCurrent->pDefaultValue)) == 0)
|
|
{
|
|
//wcscpy(wszBuf, L"false");
|
|
//wszDefault = wszBuf;
|
|
}
|
|
else
|
|
{
|
|
//wcscpy(wszBuf, L"true");
|
|
//wszDefault = wszBuf;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wszType = L"sint32";
|
|
if(pPropCurrent->pDefaultValue)
|
|
{
|
|
//swprintf(wszBuf, L"%d", *((int *)(pPropCurrent->pDefaultValue)));
|
|
//wszDefault = wszBuf;
|
|
}
|
|
}
|
|
break;
|
|
case STRING_METADATA:
|
|
case EXPANDSZ_METADATA:
|
|
wszType = L"string";
|
|
wszQuote = L"\"";
|
|
/*if(pPropCurrent->pDefaultValue != NULL)
|
|
{
|
|
//
|
|
// Sets m_wszTemp
|
|
//
|
|
hr = GenerateEscapedString((LPWSTR)pPropCurrent->pDefaultValue);
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
wszDefault = m_wszTemp;;
|
|
}*/
|
|
break;
|
|
case MULTISZ_METADATA:
|
|
{
|
|
wszType = L"string";
|
|
TFormattedMultiSz* pFormattedMultiSz =
|
|
TFormattedMultiSzData::Find(pPropCurrent->dwMDIdentifier);
|
|
if(pFormattedMultiSz)
|
|
{
|
|
wszType = pFormattedMultiSz->wszWmiClassName;
|
|
}
|
|
wszTypeSuffix = L"[]";
|
|
break;
|
|
}
|
|
case BINARY_METADATA:
|
|
wszType = L"uint8";
|
|
wszTypeSuffix = L"[]";
|
|
break;
|
|
default:
|
|
wprintf(L"Warning: Cannot determine type of Prop: %s in Class: %s. Ignoring property.\n", pPropCurrent->pszPropName, i_pElement->pszClassName);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// qualifier for read-only
|
|
//
|
|
if(pPropCurrent->fReadOnly)
|
|
{
|
|
wszQual = L"[read, write(FALSE)]";
|
|
}
|
|
else
|
|
{
|
|
wszQual = L"[read, write]";
|
|
}
|
|
|
|
if(wszDefault)
|
|
{
|
|
iError = fwprintf(m_pFile, L"\t%s %s %s%s = %s%s%s;\n",
|
|
wszQual, wszType, pPropCurrent->pszPropName, wszTypeSuffix,
|
|
wszQuote, wszDefault, wszQuote);
|
|
}
|
|
else
|
|
{
|
|
iError = fwprintf(m_pFile, L"\t%s %s %s%s;\n",
|
|
wszQual, wszType, pPropCurrent->pszPropName, wszTypeSuffix);
|
|
}
|
|
if(iError < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMofGen::PushAssociationComponent(LPWSTR i_wszComp,
|
|
LPWSTR i_wszClass)
|
|
{
|
|
DBG_ASSERT(i_wszComp != NULL);
|
|
DBG_ASSERT(i_wszClass != NULL);
|
|
DBG_ASSERT(m_pFile != NULL);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
int iError = fwprintf(m_pFile, L"\t[key] %s ref %s = NULL;\n", i_wszClass, i_wszComp);
|
|
if(iError < 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMofGen::PushFormattedMultiSz()
|
|
{
|
|
DBG_ASSERT(m_pFile != NULL);
|
|
|
|
HRESULT hr = S_OK;
|
|
int iError = 0;
|
|
TFormattedMultiSz** apFormattedMultiSz = TFormattedMultiSzData::apFormattedMultiSz;
|
|
|
|
if(apFormattedMultiSz == NULL)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
for(ULONG i = 0; apFormattedMultiSz[i] != NULL; i++)
|
|
{
|
|
iError = fwprintf(m_pFile, L"[provider(\"%s\"),Locale(1033)", g_wszIIsProvider);
|
|
if(iError < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
iError = fwprintf(m_pFile, L"]\n");
|
|
if(iError < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
iError = fwprintf(m_pFile, L"class %s : IIsStructuredDataClass\n", apFormattedMultiSz[i]->wszWmiClassName);
|
|
if(iError < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
iError = fwprintf(m_pFile, L"{\n");
|
|
if(iError < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
LPCWSTR* awszFields = apFormattedMultiSz[i]->awszFields;
|
|
if(awszFields != NULL)
|
|
{
|
|
for(ULONG j = 0; awszFields[j] != NULL; j++)
|
|
{
|
|
iError = fwprintf(m_pFile, L"\t[key, read, write] string %s;\n", awszFields[j]);
|
|
if(iError < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
iError = fwprintf(m_pFile, L"};\n\n");
|
|
if(iError < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMofGen::PushFile (LPWSTR i_wszFile)
|
|
{
|
|
DBG_ASSERT(i_wszFile != NULL);
|
|
DBG_ASSERT(m_pFile != NULL);
|
|
|
|
FILE *pFile = _wfopen (i_wszFile, L"r");
|
|
if (pFile == NULL)
|
|
{
|
|
wprintf(L"Could not open %s for reading\n", i_wszFile);
|
|
return RETURNCODETOHRESULT(ERROR_OPEN_FAILED);
|
|
}
|
|
|
|
WCHAR wszBuffer[512];
|
|
|
|
while (fgetws (wszBuffer, 512, pFile) != 0)
|
|
{
|
|
fputws (wszBuffer, m_pFile);
|
|
}
|
|
|
|
fclose (pFile);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMofGen::Push()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_pFile == NULL)
|
|
{
|
|
m_pFile = _wfopen(m_wszOutFileName, L"w+");
|
|
if(m_pFile == NULL)
|
|
{
|
|
wprintf(L"Could not open %s for writing\n", m_wszOutFileName);
|
|
hr = RETURNCODETOHRESULT(ERROR_OPEN_FAILED);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
hr = PushFile(m_wszHeaderFileName);
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
if(fwprintf(m_pFile, L"\n\n") < 0)
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
hr = PushFormattedMultiSz();
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
hr = PushClasses(g_pDynSch->GetHashClasses(), false);
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
hr = PushClasses(g_pDynSch->GetHashAssociations(), true);
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
hr = PushFile(m_wszFooterFileName);
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
return hr;
|
|
}
|
|
|
|
int __cdecl wmain(int argc, wchar_t* argv[])
|
|
{
|
|
#ifndef _NO_TRACING_
|
|
// CREATE_DEBUG_PRINT_OBJECT("Mofgen.exe", IisWmiMofgenGuid);
|
|
CREATE_DEBUG_PRINT_OBJECT("Mofgen.exe");
|
|
#else
|
|
CREATE_DEBUG_PRINT_OBJECT("Mofgen.exe");
|
|
#endif
|
|
|
|
HRESULT hr = S_OK;
|
|
CMofGen mofgen;
|
|
CSchemaExtensions catalog;
|
|
|
|
g_pDynSch = new CDynSchema();
|
|
if(g_pDynSch == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
hr = g_pDynSch->Initialize();
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = g_pDynSch->RunRules(&catalog, false);
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
if(!mofgen.ParseCmdLine(argc, argv))
|
|
{
|
|
mofgen.PrintUsage(argv);
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
hr = mofgen.Push();
|
|
if(FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
delete g_pDynSch;
|
|
g_pDynSch = NULL;
|
|
DELETE_DEBUG_PRINT_OBJECT();
|
|
if(FAILED(hr))
|
|
{
|
|
printf("MofGen failed, code: 0x%x\n", hr);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
wprintf(L"MofGen successful! %s created.\n", mofgen.GetOutFileName());
|
|
return 0;
|
|
}
|
|
}
|