Leaked source code of windows server 2003
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.
 
 
 
 
 
 

924 lines
27 KiB

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
MOFDATA.CPP
Abstract:
Entry points for the WBEM MOF compiler.
History:
a-davj 12-April-97 Added WMI support.
--*/
#include "precomp.h"
#include <cominit.h>
#include "mofout.h"
#include "mofdata.h"
#include "typehelp.h"
#include "bmof.h"
#include "cbmofout.h"
#include "trace.h"
#include "strings.h"
#include "arrtempl.h"
#include <genutils.h>
#define TEMP_BUF 128
WCHAR * Macro_CloneStr(LPCWSTR pFr)
{
if(pFr == NULL)
return NULL;
DWORD dwLen = wcslen(pFr) + 1;
WCHAR * pTo = new WCHAR[dwLen];
if(pTo)
{
StringCchCopyW(pTo, dwLen, pFr);
return pTo;
}
return NULL;
}
HRESULT MofdSetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority, LPWSTR pUser,
LPWSTR pPassword)
{
SCODE sc;
BOOL bUseAuthInfo = FALSE;
DWORD dwQueryAuthnLevel, dwQueryImpLevel, dwQueryCapabilities;
DWORD dwAuthnSvc = RPC_C_AUTHN_GSS_NEGOTIATE;
WCHAR * pwCSPBPrincipal = NULL;
HRESULT hr = CoQueryProxyBlanket(
pInterface, //Location for the proxy to query
&dwAuthnSvc, //Location for the current authentication service
NULL, //Location for the current authorization service
NULL, //Location for the current principal name
&dwQueryAuthnLevel, //Location for the current authentication level
&dwQueryImpLevel, //Location for the current impersonation level
NULL,
&dwQueryCapabilities //Location for flags indicating further capabilities of the proxy
);
if(SUCCEEDED(hr) && dwAuthnSvc != RPC_C_AUTHN_WINNT)
{
pwCSPBPrincipal = COLE_DEFAULT_PRINCIPAL;
}
else
{
dwAuthnSvc = RPC_C_AUTHN_WINNT;
pwCSPBPrincipal = NULL;
}
// If we are doing trivial case, just pass in a null authenication structure which is used
// if the current logged in user's credentials are OK.
if((pAuthority == NULL || wcslen(pAuthority) < 1) &&
(pUser == NULL || wcslen(pUser) < 1) &&
(pPassword == NULL || wcslen(pPassword) < 1))
{
return WbemSetProxyBlanket(pInterface, dwAuthnSvc, RPC_C_AUTHZ_NONE,
pwCSPBPrincipal,
RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_STATIC_CLOAKING);
}
// If user, or Authority was passed in, the we need to create an authority argument for the login
COAUTHIDENTITY authident;
BSTR AuthArg = NULL, UserArg = NULL, PrincipalArg = NULL;
sc = DetermineLoginTypeEx(AuthArg, UserArg, PrincipalArg, pAuthority, pUser);
if(sc != S_OK)
return sc;
CSysFreeMe fm1(UserArg), fm2(AuthArg), fm3(PrincipalArg);
memset((void *)&authident,0,sizeof(COAUTHIDENTITY));
if(UserArg)
{
authident.UserLength = wcslen(UserArg);
authident.User = (LPWSTR)UserArg;
bUseAuthInfo = TRUE;
}
if(AuthArg)
{
authident.DomainLength = wcslen(AuthArg);
authident.Domain = (LPWSTR)AuthArg;
bUseAuthInfo = TRUE;
}
if(pPassword)
{
authident.PasswordLength = wcslen(pPassword);
authident.Password = (LPWSTR)pPassword;
bUseAuthInfo = TRUE;
}
authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
sc = WbemSetProxyBlanket(pInterface,
(PrincipalArg) ? RPC_C_AUTHN_GSS_KERBEROS : dwAuthnSvc,
RPC_C_AUTHZ_NONE,
(PrincipalArg) ? PrincipalArg : pwCSPBPrincipal,
RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
(bUseAuthInfo) ? &authident : NULL,
(bUseAuthInfo) ? 0 : EOAC_STATIC_CLOAKING
);
return sc;
}
CNamespaceCache::CNamespaceRecord::CNamespaceRecord(
COPY LPCWSTR wszName,
ADDREF IWbemServices* pNamespace)
{
m_wszName = Macro_CloneStr(wszName);
m_pNamespace = pNamespace;
m_pNamespace->AddRef();
}
CNamespaceCache::CNamespaceRecord::~CNamespaceRecord()
{
delete [] m_wszName;
if(m_pNamespace) m_pNamespace->Release();
}
//*****************************************************************************
CNamespaceCache::CNamespaceCache(ADDREF IWbemLocator* pLocator)
{
if(pLocator)
pLocator->AddRef();
m_pLocator = pLocator;
}
CNamespaceCache::~CNamespaceCache()
{
if(m_pLocator) m_pLocator->Release();
for(int i = 0; i < m_aRecords.GetSize(); i++)
{
delete (CNamespaceRecord*)m_aRecords[i];
}
}
RELEASE_ME IWbemServices* CNamespaceCache::GetNamespace(COPY LPCWSTR wszName, SCODE & scRet,
WCHAR * pUserName, WCHAR * pPassword , WCHAR * pAuthority,
IWbemContext * pCtx, GUID LocatorGUID, LONG fConnectFlags)
{
// Check if it is the cache
// ========================
scRet = S_OK;
for(int i = 0; i < m_aRecords.GetSize(); i++)
{
CNamespaceRecord* pRecord = (CNamespaceRecord*)m_aRecords[i];
if(!wbem_wcsicmp(pRecord->m_wszName, wszName))
{
// Found it
// ========
pRecord->m_pNamespace->AddRef();
return pRecord->m_pNamespace;
}
}
// Not found --- open it
// =====================
IWbemServices* pNamespace;
if(wszName == NULL)
return NULL;
LPOLESTR pwszName;
pwszName = SysAllocString(wszName);
if(pwszName == NULL)
return NULL;
CSysFreeMe fm0(pwszName);
LPOLESTR bstrPassword = NULL;
LPOLESTR bstrUserName = NULL;
LPOLESTR bstrAuthority = NULL;
if(pUserName && wcslen(pUserName) > 0)
{
bstrUserName = SysAllocString(pUserName);
if(bstrUserName == NULL)
return NULL;
}
CSysFreeMe fm1(bstrUserName);
if(pPassword)
{
bstrPassword = SysAllocString(pPassword);
if(bstrPassword == NULL)
return NULL;
}
CSysFreeMe fm2(bstrPassword);
if(pAuthority && wcslen(pAuthority) > 0)
{
bstrAuthority = SysAllocString(pAuthority);
if(bstrAuthority == NULL)
return NULL;
}
CSysFreeMe fm3(bstrAuthority);
// Determine if the connection is to the regular locator, or to one of the special inproc ones
// used for autocompile. If it is inproc, then remote connections are not valid.
bool bInProc = false;
if(LocatorGUID != CLSID_WbemLocator)
bInProc = true;
if(bInProc)
{
WCHAR * pMachine = ExtractMachineName(pwszName);
if(pMachine)
{
BOOL bLocal = bAreWeLocal(pMachine);
delete pMachine;
if(!bLocal)
{
scRet = WBEM_E_INVALID_NAMESPACE;
ERRORTRACE((LOG_MOFCOMP,"Error, tried to do a remote connect during autocomp\n"));
}
}
}
// Connect up to namespace. //TODO, PASS AUTHORITY IN THE CONTEXT
if(scRet == S_OK)
scRet = m_pLocator->ConnectServer((LPWSTR)pwszName,
bstrUserName, bstrPassword,
NULL, fConnectFlags,
pAuthority, pCtx, &pNamespace);
if(scRet == S_OK && !bInProc)
{
// Set the impersonation level up so that puts to providers can be done
DWORD dwAuthLevel, dwImpLevel;
SCODE sc = GetAuthImp( pNamespace, &dwAuthLevel, &dwImpLevel);
if(sc != S_OK || dwAuthLevel != RPC_C_AUTHN_LEVEL_NONE)
sc = MofdSetInterfaceSecurity(pNamespace, bstrAuthority, bstrUserName, bstrPassword);
}
if(FAILED(scRet)) return NULL;
// Add it to the cache
// ===================
CNamespaceRecord * pNew = new CNamespaceRecord(wszName, pNamespace);
if(pNew)
m_aRecords.Add(pNew); // AddRef'ed
return pNamespace;
}
//*****************************************************************************
//*****************************************************************************
void CMofData::SetQualifierDefault(ACQUIRE CMoQualifier* pDefault)
{
// Search for this qualifier in the defaults list
// ==============================================
for(int i = 0; i < m_aQualDefaults.GetSize(); i++)
{
CMoQualifier* pOrig = (CMoQualifier*)m_aQualDefaults[i];
if(wbem_wcsicmp(pOrig->GetName(), pDefault->GetName()) == 0)
{
// Found it. Replace
// =================
delete pOrig;
m_aQualDefaults[i] = (void*)pDefault;
return;
}
}
// Not found. Add
// ==============
m_aQualDefaults.Add((void*)pDefault);
}
HRESULT CMofData::SetDefaultFlavor(MODIFY CMoQualifier& Qual, bool bTopLevel, QUALSCOPE qs, PARSESTATE ps)
{
HRESULT hr;
// Search for this qualifier in the defaults list
// ==============================================
for(int i = 0; i < m_aQualDefaults.GetSize(); i++)
{
CMoQualifier* pOrig = (CMoQualifier*)m_aQualDefaults[i];
if(wbem_wcsicmp(pOrig->GetName(), Qual.GetName()) == 0)
{
// Found it. SetFlavor
// ===================
if(pOrig->IsCimDefault())
{
// dont bother if the parse state is the initial scan
if(ps == INITIAL)
continue;
if(Qual.IsUsingDefaultValue())
{
// see if the scope matches what we have here
DWORD dwScope = pOrig->GetScope();
bool bInScope = false;
if((dwScope & SCOPE_CLASS) || (dwScope & SCOPE_INSTANCE))
if(qs == CLASSINST_SCOPE)
bInScope = true;
if(dwScope & SCOPE_PROPERTY)
if(qs == PROPMETH_SCOPE)
bInScope = true;
if(bInScope)
{
CMoValue& Src = pOrig->AccessValue();
CMoValue& Dest = Qual.AccessValue();
Dest.SetType(Src.GetType());
VARIANT & varSrc = Src.AccessVariant();
VARIANT & varDest = Dest.AccessVariant();
hr = VariantCopy(&varDest, &varSrc);
if(FAILED(hr))
return hr;
Qual.SetFlavor(pOrig->GetFlavor());
Qual.SetAmended(pOrig->IsAmended());
}
}
}
else
{
Qual.SetFlavor(pOrig->GetFlavor());
Qual.SetAmended(pOrig->IsAmended());
}
return S_OK;
}
}
return S_OK;
}
BOOL CMofData::IsAliasInUse(READ_ONLY LPWSTR wszAlias)
{
for(int i = 0; i < m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
if(pObject->GetAlias() && !wbem_wcsicmp(pObject->GetAlias(), wszAlias))
{
return TRUE;
}
}
return FALSE;
}
BOOL IsGuid(LPWSTR pTest)
{
int i;
int iSoFar = 0;
#define HEXCHECK(n) \
for (i = 0; i < n; i++) \
if (!iswxdigit(*pTest++)) \
return FALSE;
#define HYPHENCHECK() \
if (*pTest++ != L'-') \
return FALSE;
if(*pTest++ != L'{')
return FALSE;
HEXCHECK(8);
HYPHENCHECK();
HEXCHECK(4);
HYPHENCHECK();
HEXCHECK(4);
HYPHENCHECK();
HEXCHECK(4);
HYPHENCHECK();
HEXCHECK(12);
if(*pTest++ != L'}')
return FALSE;
return TRUE;
}
INTERNAL LPCWSTR CMofData::FindAliasee(READ_ONLY LPWSTR wszAlias)
{
for(int i = 0; i < m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
if(pObject->GetAlias() && !wbem_wcsicmp(pObject->GetAlias(), wszAlias))
{
IWbemClassObject * pTemp;
pTemp = pObject->GetWbemObject();
// check for unresolved aliases in keys
if(pTemp && pObject->IsDone() == FALSE)
{
SCODE sc = pTemp->BeginEnumeration(WBEM_FLAG_KEYS_ONLY | WBEM_FLAG_REFS_ONLY);
if(sc != S_OK)
return NULL;
VARIANT var;
VariantInit(&var);
while ((sc = pTemp->Next(0, NULL, &var, NULL, NULL)) == S_OK)
{
if(var.vt == VT_BSTR && IsGuid(var.bstrVal))
{
VariantClear(&var);
return NULL;
}
VariantClear(&var);
}
}
return pObject->GetFullPath();
}
}
return NULL;
}
HRESULT CMofData::Store(CMofParser & Parser, OLE_MODIFY IWbemLocator* pLocator,IWbemServices *pOverride,BOOL bRollbackable,
WCHAR * pUserName, WCHAR * pPassword, WCHAR * pAuthority,
IWbemContext * pCtx, GUID LocatorGUID, WBEM_COMPILE_STATUS_INFO *pInfo,
BOOL bClassOwnerUpdate,
BOOL bInstanceOwnerUpdate,
LONG fConnectFlags)
{
HRESULT hres = WBEM_E_FAILED;
int i;
CNamespaceCache Cache(pLocator);
BOOL bMakingProgress = TRUE;
long lClassFlags = 0;
long lInstanceFlags = 0;
while(bMakingProgress)
{
bMakingProgress = FALSE;
for(i = 0; i< m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
if(pObject->IsDone())
continue;
lClassFlags = pObject->GetClassFlags();
lInstanceFlags = pObject->GetInstanceFlags();
if(bClassOwnerUpdate)
{
lClassFlags |= WBEM_FLAG_OWNER_UPDATE;
}
if(bInstanceOwnerUpdate)
{
lInstanceFlags |= WBEM_FLAG_OWNER_UPDATE;
}
// Get a namespace pointer for this object.
SCODE scRet;
IWbemServices* pNamespace = NULL;
if(pOverride && !wbem_wcsicmp(L"root\\default", pObject->GetNamespace()))
{
// AddRef() the namespace pointer, since we will be Releasing
// it below
pOverride->AddRef();
pNamespace = pOverride;
}
else
{
// This will return an AddRef'd pointer
pNamespace = Cache.GetNamespace(pObject->GetNamespace(), scRet,
pUserName, pPassword ,pAuthority, pCtx,
LocatorGUID, fConnectFlags);
}
if(pNamespace == NULL)
{
int iMsg = (GotLineNumber(i)) ? ERROR_OPENING : ERROR_OPENING_NO_LINES;
PrintError(i, iMsg, scRet, pInfo);
return scRet;
}
// Ensures we release the namespace pointer when we go out of scope
CReleaseMe rmns( pNamespace );
// If there isnt a wbem object, try to get one. This will fail if this is a
// instance for which the class hasn't been saved just yet.
if(pObject->GetWbemObject() == NULL)
{
IWbemClassObject* pWbemObject = NULL;
hres = pObject->CreateWbemObject(pNamespace, &pWbemObject,pCtx);
if(hres != S_OK)
if(pObject->IsInstance())
continue;
else
{
PrintError(i,
(GotLineNumber(i)) ? ERROR_CREATING : ERROR_CREATING_NO_LINES,
hres, pInfo);
return WBEM_E_FAILED;
}
bMakingProgress = TRUE;
pObject->Reflate(Parser);
pObject->SetWbemObject(pWbemObject);
if(!pObject->ApplyToWbemObject(pWbemObject, pNamespace,pCtx))
{
hres = m_pDbg->hresError;
PrintError(i,
(GotLineNumber(i)) ? ERROR_CREATING : ERROR_CREATING_NO_LINES,
hres, pInfo);
return WBEM_E_FAILED;
}
}
// If there are no unresolved aliases, save it!
if(pObject->GetNumAliasedValues() == 0 ||
S_OK == pObject->ResolveAliasesInWbemObject(pObject->GetWbemObject(),
(CMofAliasCollection*)this))
{
// Save this into WinMgmt
// ==================
hres = pObject->StoreWbemObject(pObject->GetWbemObject(), lClassFlags, lInstanceFlags,
pNamespace, pCtx, pUserName, pPassword ,pAuthority);
if(hres != S_OK)
{
PrintError(i,
(GotLineNumber(i)) ? ERROR_STORING : ERROR_STORING_NO_LINES,
hres, pInfo);
return WBEM_E_FAILED;
}
pObject->FreeWbemObjectIfPossible();
pObject->Deflate(false);
pObject->SetDone();
bMakingProgress = TRUE;
}
}
}
// If there is one or more objects that cant be resolved, print and bail
for(i = 0; i < m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
if(pObject && !pObject->IsDone())
{
PrintError(i,
(GotLineNumber(i)) ? ERROR_RESOLVING : ERROR_RESOLVING_NO_LINES,
hres, pInfo);
return WBEM_E_FAILED;
}
}
return S_OK;
}
HRESULT CMofData::RollBack(int nObjects)
{
return WBEM_E_FAILED;
}
BOOL CMofData::GotLineNumber(int nIndex)
{
CMObject* pObject = (CMObject*)m_aObjects[nIndex];
if(pObject == NULL || (pObject->GetFirstLine() == 0 && pObject->GetLastLine() == 0))
return FALSE;
else
return TRUE;
}
void CMofData::PrintError(int nIndex, long lMsgNum, HRESULT hres, WBEM_COMPILE_STATUS_INFO *pInfo)
{
CMObject* pObject = (CMObject*)m_aObjects[nIndex];
TCHAR szMsg[500];
bool bErrorFound = false;
if(pInfo)
pInfo->ObjectNum = nIndex+1;
if(!GotLineNumber(nIndex))
Trace(true, m_pDbg, lMsgNum, nIndex+1);
else
{
Trace(true, m_pDbg, lMsgNum, nIndex+1, pObject->GetFirstLine(),
pObject->GetLastLine(), pObject->GetFileName());
if(pInfo)
{
pInfo->FirstLine = pObject->GetFirstLine();
pInfo->LastLine = pObject->GetLastLine();
}
}
if(hres)
{
// A few error messages are retrived from the local resources. This is so that the name can be
// injected into the name.
if(hres == WBEM_E_NOT_FOUND || hres == WBEM_E_TYPE_MISMATCH || hres == WBEM_E_OVERRIDE_NOT_ALLOWED ||
hres == WBEM_E_PROPAGATED_QUALIFIER || hres == WBEM_E_VALUE_OUT_OF_RANGE)
{
Trace(true, m_pDbg, ERROR_FORMAT, hres);
Trace(true, m_pDbg, hres, m_pDbg->GetString());
bErrorFound = true;
}
else
{
// Get the error from the standard error facility
IWbemStatusCodeText * pStatus = NULL;
SCODE sc = CoCreateInstance(CLSID_WbemStatusCodeText, 0, CLSCTX_INPROC_SERVER,
IID_IWbemStatusCodeText, (LPVOID *) &pStatus);
if(sc == S_OK)
{
BSTR bstrError = 0;
BSTR bstrFacility = 0;
sc = pStatus->GetErrorCodeText(hres, 0, 0, &bstrError);
if(sc == S_OK)
{
sc = pStatus->GetFacilityCodeText(hres, 0, 0, &bstrFacility);
if(sc == S_OK)
{
IntString is(ERROR_FORMAT_LONG);
StringCchPrintfW(szMsg, 500, is, hres, bstrFacility, bstrError);
bErrorFound = true;
SysFreeString(bstrFacility);
}
SysFreeString(bstrError);
}
pStatus->Release();
}
// if all else fails, just use the generic error message
if(!bErrorFound)
{
IntString is(ERROR_FORMATEX);
StringCchPrintfW(szMsg, 500 ,is, hres);
}
// Print the error message
if(m_pDbg->m_bPrint)
printf("%S", szMsg);
ERRORTRACE((LOG_MOFCOMP,"%S", szMsg));
} // ELSE get error from standard facility
} // IF hres
}
//***************************************************************************
//
// GetFileNames
//
// DESCRIPTION:
//
// The amendment local, the localized and neutral file names are passed
// in using the BMOF string. These values are separated by commas and
// a single letter which indicates what follows. An example string
// would be ",aMS_409,nNEUTRAL.MOF,lLocalMof" Notice that the amendment
// substring starts with an 'a', the neutral starts with 'n', and the
// locale starts with 'l'.
//
// While the neutral name is required, the locale version isnt. If not
// supplied, it will be created. The two character inputs are ASSUMED to
// point to preallocated buffers of MAX_PATH size!
//
//***************************************************************************
HRESULT GetFileNames(TCHAR * pcNeutral, TCHAR * pcLocale, LPWSTR pwszBMOF)
{
WCHAR * pNeutral=NULL;
WCHAR * pLocale=NULL;
if(pwszBMOF == NULL)
return WBEM_E_INVALID_PARAMETER;
// make a copy of the string
DWORD dwLen = wcslen(pwszBMOF)+1;
WCHAR *pTemp = new WCHAR[dwLen];
if(pTemp == NULL)
return WBEM_E_OUT_OF_MEMORY;
CDeleteMe<WCHAR> dm1(pTemp);
StringCchCopyW(pTemp, dwLen, pwszBMOF);
// use wcstok to do a seach
WCHAR * token = wcstok( pTemp, L"," );
while( token != NULL )
{
if(token[0] == L'n')
{
pNeutral = token+1;
CopyOrConvert(pcNeutral, pNeutral, MAX_PATH);
}
else if(token[0] == L'l')
{
pLocale = token+1;
CopyOrConvert(pcLocale, pLocale, MAX_PATH);
}
token = wcstok( NULL, L"," );
}
// If the neutral name was not specified, that is an error
if(pNeutral == NULL)
return WBEM_E_INVALID_PARAMETER;
// If the local name was not specified, create it and make it the
// same as the neutral name except for changing the mfl extension
if(pLocale == NULL)
{
TCHAR * pFr = pcNeutral,* pTo = pcLocale;
for(; *pFr && *pFr != '.'; pTo++, pFr++)
*pTo = *pFr;
*pTo=0;
StringCchCatW(pcLocale, MAX_PATH, TEXT(".mfl"));
}
// make sure that the locale and neutral names are not the same
if(!lstrcmpi(pcLocale, pcNeutral))
return WBEM_E_INVALID_PARAMETER;
return S_OK;
}
//***************************************************************************
//
// GetLocale
//
// DESCRIPTION:
//
// Converts the amendment string to a local number. An example string
// would be "MS_409"
//
//***************************************************************************
HRESULT GetLocale(long * plLocale, WCHAR * pwszAmendment)
{
if(pwszAmendment == NULL || wcslen(pwszAmendment) != 6)
return WBEM_E_INVALID_PARAMETER;
*plLocale = 0;
swscanf(pwszAmendment+3,L"%x", plLocale);
return (*plLocale != 0) ? S_OK : WBEM_E_INVALID_PARAMETER;
}
//***************************************************************************
//
// RecursiveSetAmended
//
// DESCRIPTION:
//
// Sets the boolean indicating that an object is to be amended and all of
// its parents
//
//***************************************************************************
void CMofData::RecursiveSetAmended(CMObject * pObj)
{
// If the object is already amended, then its parents are already set.
// In that case, our job is done here!
if(pObj->IsAmended())
return;
// If the object hasnt been set yet, set it and also set its parents
pObj->SetAmended(true);
// Look for the parent and do the same
if(pObj->IsInstance() || pObj->IsDelete())
return; // run away now if this is a instance!
CMoClass * pClass = (CMoClass *)pObj;
const WCHAR *pClassName = pClass->GetParentName();
if(pClassName == NULL)
return;
// Find the parent and recursively set it!
for(int i = 0; i< m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
if(pObject && pObject->GetClassName() &&
!wbem_wcsicmp(pClassName, pObject->GetClassName()))
{
RecursiveSetAmended(pObject);
}
}
}
//***************************************************************************
//
// CMofData::Split
//
// DESCRIPTION:
//
// Creates a neutral and locale specific mof.
//
// Parameters:
// pwszBMOF See the GetFileNames() comments
// pInfo usual error info
// bUnicode if true, then the orignal file was unicode and so the
// new files will also be unicode
// bAutoRecovery Need to add this pragma if true
// pwszAmendment See the GetLocale() comments
//
//***************************************************************************
HRESULT CMofData::Split(CMofParser & Parser, LPWSTR pwszBMOF, WBEM_COMPILE_STATUS_INFO *pInfo, BOOL bUnicode,
BOOL bAutoRecovery, LPWSTR pwszAmendment)
{
int i;
TCHAR cNeutral[MAX_PATH];
TCHAR cLocale[MAX_PATH];
// Determine the file names and locale
HRESULT hRes = GetFileNames(cNeutral, cLocale, pwszBMOF);
if(hRes != S_OK)
return S_OK;
long lLocale;
hRes = GetLocale(&lLocale, pwszAmendment);
if(hRes != S_OK)
return S_OK;
// Create the output objects
COutput Neutral(cNeutral, NEUTRAL, bUnicode, bAutoRecovery, lLocale);
COutput Local(cLocale, LOCALIZED, bUnicode, bAutoRecovery, lLocale);
if(!Neutral.IsOK() || !Local.IsOK())
return WBEM_E_INVALID_PARAMETER;
// Start by determining what is amended
for(i = 0; i< m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
pObject->Reflate(Parser);
if(pObject->CheckIfAmended())
{
RecursiveSetAmended(pObject);
}
}
// Create the neutral output and the localized output.
// These two loops could have been combined, but are
// separate for debugging purposes
for(i = 0; i< m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
pObject->Split(Neutral);
}
for(i = 0; i< m_aObjects.GetSize(); i++)
{
CMObject* pObject = (CMObject*)m_aObjects[i];
pObject->Split(Local);
}
return S_OK;
}