2259 lines
68 KiB
C++
2259 lines
68 KiB
C++
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// BINMOF.CPP
|
|
|
|
//
|
|
|
|
// Module:
|
|
|
|
// Purpose:
|
|
|
|
//
|
|
|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
#include "wmicom.h"
|
|
#include "wmimof.h"
|
|
#include <wchar.h>
|
|
#include <stdio.h>
|
|
#include "wdmshell.h"
|
|
#include <cregcls.h>
|
|
#include <bmof.h>
|
|
#include <mrcicode.h>
|
|
#include <mofcomp.h>
|
|
#include <crc32.h>
|
|
#include <TCHAR.h>
|
|
|
|
//#define DBG_PRINTFA( a ) { char pBuff[128]; sprintf a ; OutputDebugStringA(pBuff); }
|
|
#define WDM_REG_KEY L"Software\\Microsoft\\WBEM\\WDM"
|
|
#define WDM_DREDGE_KEY L"Software\\Microsoft\\WBEM\\WDM\\DREDGE"
|
|
#define DREDGE_KEY L"DREDGE"
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//***************************************************************************
|
|
//
|
|
// 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 ConvertStringToCTypeString( WCHAR * Out, WCHAR * In )
|
|
{
|
|
WCHAR * token = NULL;
|
|
|
|
if(In)
|
|
{
|
|
CAutoWChar tmpBuf(_MAX_PATH*2);
|
|
if( tmpBuf.Valid() )
|
|
{
|
|
wcscpy((WCHAR*)tmpBuf,In);
|
|
token = wcstok( (WCHAR*)tmpBuf, L"\\" );
|
|
if( !token )
|
|
{
|
|
wcscpy(Out,In);
|
|
}
|
|
else
|
|
{
|
|
BOOL fFirst = TRUE;
|
|
while( token != NULL )
|
|
{
|
|
if( fFirst )
|
|
{
|
|
wcscpy(Out,token);
|
|
fFirst = FALSE;
|
|
}
|
|
else
|
|
{
|
|
wcscat(Out,L"\\\\");
|
|
wcscat(Out,token);
|
|
}
|
|
token = wcstok( NULL, L"\\" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//*****************************************************************************************
|
|
// The binary mof class
|
|
//*****************************************************************************************
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
CWMIBinMof::CWMIBinMof()
|
|
{
|
|
m_pCompiler = NULL;
|
|
m_pWMI = NULL;
|
|
m_nInit = NOT_INITIALIZED;
|
|
m_pMofResourceInfo = NULL;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::InitializePtrs(CHandleMap * pList, IWbemServices __RPC_FAR * pServices,
|
|
IWbemObjectSink __RPC_FAR * pHandler, IWbemContext __RPC_FAR *pCtx)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
SAFE_DELETE_PTR(m_pWMI);
|
|
m_pWMI = new CWMIManagement;
|
|
if( m_pWMI )
|
|
{
|
|
m_pWMI->SetWMIPointers(pList, pServices, pHandler, pCtx);
|
|
m_nInit = FULLY_INITIALIZED;
|
|
hr = S_OK;
|
|
}
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::Initialize(CWMIManagement * p,BOOL fUpdateNamespace)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
if( p )
|
|
{
|
|
hr = InitializePtrs(p->HandleMap(),p->Services(),p->Handler(),p->Context());
|
|
}
|
|
else
|
|
{
|
|
m_nInit = PARTIALLY_INITIALIZED;
|
|
hr = S_OK;
|
|
}
|
|
m_fUpdateNamespace = fUpdateNamespace;
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::Initialize(CHandleMap * pList, BOOL fUpdateNamespace,ULONG uDesiredAccess,
|
|
IWbemServices __RPC_FAR * pServices, IWbemObjectSink __RPC_FAR * pHandler,
|
|
IWbemContext __RPC_FAR *pCtx)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
hr = InitializePtrs(pList,pServices,pHandler,pCtx);
|
|
m_fUpdateNamespace = fUpdateNamespace;
|
|
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
CWMIBinMof::~CWMIBinMof()
|
|
{
|
|
SAFE_RELEASE_PTR(m_pCompiler);
|
|
SAFE_DELETE_PTR(m_pWMI);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::OpenFileAndLookForItIfItDoesNotExist(TCHAR *& pFile, HANDLE & hFile )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//=========================================================================
|
|
// Ok, hopefully CreateFile will find it
|
|
//=========================================================================
|
|
hFile = CreateFile(pFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
hr = WBEM_E_FAILED;
|
|
//=====================================================================
|
|
// CreateFile DIDN'T find it, so look in the Windows dir
|
|
//=====================================================================
|
|
TCHAR pszSysDir[MAX_PATH+4];
|
|
|
|
UINT uSize = GetSystemDirectory(pszSysDir, MAX_PATH);
|
|
if( uSize > 0)
|
|
{
|
|
TCHAR * pTmp = pFile;
|
|
pFile = new TCHAR[MAX_PATH*2 + 4];
|
|
if( pFile )
|
|
{
|
|
_stprintf(pFile,L"%s\\%s",pszSysDir,pTmp);
|
|
//=============================================================
|
|
// Ok, now try to open again
|
|
//=============================================================
|
|
hFile = CreateFile(pFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
if( hFile != INVALID_HANDLE_VALUE )
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
SAFE_DELETE_ARRAY(pTmp);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::GetFileDateAndTime(ULONG & lLowDateTime,ULONG & lHighDateTime,WCHAR * wcsFileName)
|
|
{
|
|
HANDLE hFile = NULL;
|
|
FILETIME ftCreationTime, ftLastAccessTime, ftLastWriteTime,ftLocal;
|
|
BOOL fRc = FALSE;
|
|
TCHAR * pFile = NULL;
|
|
|
|
if( ExtractFileNameFromKey(pFile,wcsFileName) )
|
|
{
|
|
if( SUCCEEDED(OpenFileAndLookForItIfItDoesNotExist( pFile, hFile )))
|
|
{
|
|
if( GetFileTime( hFile, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime ))
|
|
{
|
|
//==========================================================
|
|
// Pick up the path of the file while we are here....
|
|
//==========================================================
|
|
TCHAR sFullPath[MAX_PATH * 4];
|
|
TCHAR *sFilename = NULL;
|
|
|
|
if (GetFullPathName(pFile, MAX_PATH * 4, sFullPath, &sFilename) != 0)
|
|
{
|
|
|
|
#ifndef UNICODE
|
|
CAnsiUnicode XLate;
|
|
WCHAR * pTmp = NULL;
|
|
if( SUCCEEDED(XLate.AllocateAndConvertAnsiToUnicode(sFullPath,pTmp)))
|
|
{
|
|
wcscpy(wcsFileName,pTmp);
|
|
SAFE_DELETE_ARRAY( pTmp );
|
|
}
|
|
#else
|
|
wcscpy(wcsFileName,sFullPath);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
|
|
DWORD dwTest = GetLastError();
|
|
ERRORTRACE((THISPROVIDER,"GetFullPathName FAILED for filename: \n"));
|
|
TranslateAndLog(wcsFileName);
|
|
ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
|
|
}
|
|
|
|
FileTimeToLocalFileTime( &ftLastWriteTime, &ftLocal);
|
|
|
|
lLowDateTime = (ULONG)ftLocal.dwLowDateTime;
|
|
lHighDateTime = (ULONG)ftLocal.dwHighDateTime;
|
|
|
|
fRc = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwTest = GetLastError();
|
|
ERRORTRACE((THISPROVIDER,"GetFileTime FAILED for filename:\n"));
|
|
TranslateAndLog(wcsFileName);
|
|
ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
}
|
|
else
|
|
{
|
|
DWORD dwTest = GetLastError();
|
|
ERRORTRACE((THISPROVIDER,"CreateFile FAILED for filename:\n"));
|
|
TranslateAndLog(wcsFileName);
|
|
ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
DWORD dwTest = GetLastError();
|
|
ERRORTRACE((THISPROVIDER,"Can't extract filename: \n"));
|
|
TranslateAndLog(wcsFileName);
|
|
ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
|
|
}
|
|
|
|
SAFE_DELETE_ARRAY( pFile )
|
|
return fRc;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::NeedToProcessThisMof( WCHAR * wcsFileName,ULONG & lLowDateTime, ULONG & lHighDateTime )
|
|
{
|
|
BOOL fNeedToProcessThisMof = TRUE;
|
|
HRESULT hr = WBEM_E_OUT_OF_MEMORY;
|
|
IWbemClassObject * pClass=NULL;
|
|
CAutoWChar wcsBuf(_MAX_PATH*4);
|
|
CAutoWChar wcsTmp(_MAX_PATH*4);
|
|
if( wcsTmp.Valid() && wcsBuf.Valid() )
|
|
{
|
|
|
|
//==================================================
|
|
// Change all \ to \\
|
|
//==================================================
|
|
ConvertStringToCTypeString( wcsTmp,wcsFileName );
|
|
swprintf(wcsBuf,L"WmiBinaryMofResource.HighDateTime=%lu,LowDateTime=%lu,Name=\"%s\"",lHighDateTime,lLowDateTime,wcsTmp);
|
|
|
|
//==================================================
|
|
// Get a pointer to a IWbemClassObject object
|
|
// Have we ever processed this mof before?
|
|
// if not, then return TRUE
|
|
//==================================================
|
|
|
|
if( m_fUpdateNamespace )
|
|
{
|
|
CBSTR cbstr(wcsBuf);
|
|
hr = SERVICES->GetObject(cbstr, 0,CONTEXT, &pClass, NULL);
|
|
if(WBEM_NO_ERROR == hr)
|
|
{
|
|
fNeedToProcessThisMof = FALSE;
|
|
CVARIANT vSuccess;
|
|
|
|
hr = pClass->Get(L"MofProcessed", 0, &vSuccess, 0, 0);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
//=========================================================================
|
|
// make sure it is added to the registry
|
|
//=========================================================================
|
|
AddThisMofToRegistryIfNeeded(WDM_REG_KEY,wcsFileName,lLowDateTime,lHighDateTime,vSuccess.GetBool());
|
|
}
|
|
SAFE_RELEASE_PTR( pClass);
|
|
}
|
|
//==============================================================================
|
|
// Delete any old instances that might be hanging around for this driver
|
|
//==============================================================================
|
|
IEnumWbemClassObject* pEnum = NULL;
|
|
CAutoWChar wcsQuery(MEMSIZETOALLOCATE);
|
|
if( wcsQuery.Valid() )
|
|
{
|
|
ULONG uReturned = 0;
|
|
swprintf(wcsQuery,L"select * from WMIBinaryMofResource where Name = \"%s\"",wcsTmp);
|
|
CBSTR bstrTemp = wcsQuery;
|
|
CBSTR strQryLang(L"WQL");
|
|
|
|
hr = SERVICES->ExecQuery(strQryLang, bstrTemp, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT,&pEnum);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
IWbemClassObject * pClass = NULL;
|
|
while( TRUE )
|
|
{
|
|
if( WBEM_NO_ERROR == (hr = pEnum->Next(2000, 1, &pClass, &uReturned)))
|
|
{
|
|
CVARIANT vPath, vDriver;
|
|
hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
if( _wcsicmp(vPath.GetStr(),wcsBuf) != 0 )
|
|
{
|
|
hr = SERVICES->DeleteInstance(vPath.GetStr(),WBEM_FLAG_OWNER_UPDATE,CONTEXT,NULL);
|
|
ERRORTRACE((THISPROVIDER,"We have been requested to delete this mof, :%ld\n",hr));
|
|
TranslateAndLog(vPath.GetStr());
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
//=====================================================
|
|
// Duplicate change in registry
|
|
//=====================================================
|
|
DeleteMofFromRegistry( vPath.GetStr() );
|
|
//==========================================================================
|
|
// Gets rid of the old classes for the old versions of this driver
|
|
//==========================================================================
|
|
hr = pClass->Get(L"Driver", 0, &vDriver, 0, 0);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
CNamespaceManagement Namespace(this);
|
|
Namespace.DeleteOldClasses(vDriver.GetStr(),CVARIANT((long)lLowDateTime),CVARIANT((long)lHighDateTime), TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR( pClass );
|
|
if( hr != WBEM_NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR(pEnum);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( ThisMofExistsInRegistry(WDM_DREDGE_KEY,wcsFileName, lLowDateTime, lHighDateTime, TRUE) )
|
|
{
|
|
fNeedToProcessThisMof = FALSE;
|
|
}
|
|
}
|
|
}
|
|
return fNeedToProcessThisMof;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::UpdateMofTimestampInHMOM(WCHAR * wcsKey,ULONG & lLowDateTime, ULONG & lHighDateTime, BOOL fSuccess )
|
|
{
|
|
BOOL fRc = FALSE;
|
|
IWbemClassObject * pNewInst = NULL;
|
|
IWbemClassObject * pIWbemClassObject = NULL;
|
|
//==================================================
|
|
// Get a pointer to a IWbemClassObject object
|
|
//==================================================
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
if( m_fUpdateNamespace )
|
|
{
|
|
CVARIANT cvarName;
|
|
cvarName.SetStr(L"WMIBinaryMofResource");
|
|
hr = SERVICES->GetObject(cvarName, 0,CONTEXT, &pIWbemClassObject, NULL);
|
|
if(WBEM_NO_ERROR == hr)
|
|
{
|
|
//=============================================================
|
|
// Spawn a new instance
|
|
//=============================================================
|
|
hr = pIWbemClassObject->SpawnInstance(0, &pNewInst);
|
|
SAFE_RELEASE_PTR(pIWbemClassObject);
|
|
if( WBEM_NO_ERROR == hr )
|
|
{
|
|
CVARIANT vLow, vHigh, vName, vSuccess;
|
|
|
|
vSuccess.SetBool(fSuccess);
|
|
vName.SetStr(wcsKey);
|
|
vLow.SetLONG(lLowDateTime);
|
|
vHigh.SetLONG(lHighDateTime);
|
|
|
|
hr = pNewInst->Put(L"Name", 0, &vName, NULL);
|
|
if( S_OK == hr )
|
|
{
|
|
hr = pNewInst->Put(L"LowDateTime", 0, &vLow, NULL);
|
|
if( S_OK == hr )
|
|
{
|
|
hr = pNewInst->Put(L"HighDateTime", 0, &vHigh, NULL);
|
|
if( S_OK == hr )
|
|
{
|
|
hr = pNewInst->Put(L"MofProcessed", 0, &vSuccess, NULL);
|
|
if( S_OK == hr )
|
|
{
|
|
CVARIANT vActive;
|
|
vActive.SetBool(TRUE);
|
|
pNewInst->Put(L"Active", 0, &vActive, NULL);
|
|
}
|
|
|
|
hr = SERVICES->PutInstance(pNewInst,WBEM_FLAG_OWNER_UPDATE,CONTEXT,NULL);
|
|
SAFE_RELEASE_PTR(pNewInst);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
//==========================================
|
|
// Make sure this really is in the registry
|
|
// too
|
|
//==========================================
|
|
if( WBEM_NO_ERROR == AddThisMofToRegistryIfNeeded(WDM_REG_KEY,wcsKey,lLowDateTime,lHighDateTime,fSuccess))
|
|
{
|
|
fRc = TRUE;
|
|
}
|
|
}
|
|
return fRc;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::GetNextSectionFromTheEnd(WCHAR * pwcsTempPath, WCHAR * pwcsEnd )
|
|
{
|
|
BOOL fReturn = FALSE;
|
|
WCHAR * pc = wcsrchr(pwcsTempPath,'\\');
|
|
if(pc)
|
|
{
|
|
//==================================================
|
|
// Copy what was there and set the end to NULL
|
|
//==================================================
|
|
pc++;
|
|
wcscpy( pwcsEnd, pc );
|
|
pc--;
|
|
*(pc) = NULL;
|
|
fReturn = TRUE;
|
|
}
|
|
return fReturn;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::UseDefaultLocaleId(WCHAR * wcsFile, WORD & wLocalId)
|
|
{
|
|
BOOL fLoadDefaultLocale = TRUE;
|
|
|
|
//=============================================================
|
|
// Parse paths - get the locale id from paths of this format:
|
|
//
|
|
// check for path beginning with %windir% and with MUI in second to last position
|
|
// if not found, check for fixed directory: %windir%\MUI\Fallback
|
|
// if not found - assume it is not MUI related and try it with FindResource
|
|
//
|
|
//=============================================================
|
|
TCHAR szWindowsDir[_MAX_PATH];
|
|
if ( GetWindowsDirectory ( szWindowsDir , sizeof ( szWindowsDir ) / sizeof(TCHAR)) )
|
|
{
|
|
//==========================================================
|
|
// if these are windows directories
|
|
//==========================================================
|
|
if( 0 == _wcsnicmp( szWindowsDir, wcsFile, wcslen(szWindowsDir)))
|
|
{
|
|
CAutoWChar wcsTempPath(_MAX_PATH);
|
|
CAutoWChar wcsBuffer(_MAX_PATH);
|
|
|
|
if( wcsTempPath.Valid() && wcsBuffer.Valid() )
|
|
{
|
|
//======================================================
|
|
// Find last \ in the string, and trim off filename
|
|
//======================================================
|
|
wcscpy(wcsTempPath,wcsFile);
|
|
|
|
if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
|
|
{
|
|
//==================================================
|
|
// Now, get the potential locale id
|
|
//==================================================
|
|
if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
|
|
{
|
|
wLocalId = (WORD) _wtoi(wcsBuffer);
|
|
//==============================================
|
|
// Now, get the next bit to see if it says MUI
|
|
// or Fallback
|
|
//==============================================
|
|
if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
|
|
{
|
|
if( 0 == _wcsicmp( L"MUI", wcsBuffer ))
|
|
{
|
|
fLoadDefaultLocale = FALSE;
|
|
}
|
|
else if( 0 == _wcsicmp( L"Fallback", wcsBuffer ) )
|
|
{
|
|
//==============================================
|
|
// If it says Fallback, then check to make
|
|
// sure the next bit says MUI
|
|
//==============================================
|
|
if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
|
|
{
|
|
if( 0 == _wcsicmp( L"MUI", wcsBuffer ) )
|
|
{
|
|
fLoadDefaultLocale = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return fLoadDefaultLocale;
|
|
}
|
|
///////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::GetPointerToBinaryResource(BYTE *& pRes,
|
|
DWORD & dwSize,
|
|
HGLOBAL & hResource,
|
|
HINSTANCE & hInst,
|
|
WCHAR * wcsResource,
|
|
WCHAR * wcsFile)
|
|
|
|
{
|
|
TCHAR * pResource = NULL;
|
|
BOOL fRc = FALSE;
|
|
CAnsiUnicode xLate;
|
|
DWORD dwError = 0;
|
|
|
|
TCHAR * pFile = NULL;
|
|
|
|
if( ExtractFileNameFromKey(pFile,wcsFile) ){
|
|
|
|
#ifndef UNICODE
|
|
xLate.UnicodeToAnsi(wcsResource,pResource);
|
|
#else
|
|
pResource = wcsResource;
|
|
#endif
|
|
if( pResource )
|
|
{
|
|
hInst = LoadLibraryEx(pFile,NULL,LOAD_LIBRARY_AS_DATAFILE);
|
|
if( hInst != NULL )
|
|
{
|
|
HRSRC hSrc = NULL;
|
|
WORD wLocaleId = 0;
|
|
if( UseDefaultLocaleId(wcsResource, wLocaleId ))
|
|
{
|
|
hSrc = FindResource(hInst,pResource, _T("MOFDATA"));
|
|
}
|
|
else
|
|
{
|
|
hSrc = FindResourceEx(hInst,pResource, _T("MOFDATA"),wLocaleId);
|
|
}
|
|
if( hSrc == NULL )
|
|
{
|
|
|
|
FreeLibrary(hInst);
|
|
dwError = GetLastError();
|
|
}
|
|
if( NULL != hSrc)
|
|
{
|
|
hResource = LoadResource( hInst,hSrc);
|
|
if( hResource )
|
|
{
|
|
pRes = (BYTE *)LockResource(hResource);
|
|
dwSize = SizeofResource(hInst,hSrc);
|
|
fRc = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#ifndef UNICODE
|
|
SAFE_DELETE_ARRAY(pResource );
|
|
#endif
|
|
SAFE_DELETE_ARRAY(pFile );
|
|
|
|
}
|
|
return fRc;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BYTE * CWMIBinMof::DecompressBinaryMof(BYTE * pRes)
|
|
{
|
|
|
|
DWORD dwCompType, dwCompressedSize, dwExpandedSize, dwSig, dwResSize;
|
|
BYTE * pExpanded = NULL;
|
|
|
|
//=========================================================
|
|
// get the signature, compression type, and the sizes
|
|
//=========================================================
|
|
memcpy(&dwSig,pRes,sizeof(DWORD));
|
|
pRes += sizeof( DWORD );
|
|
|
|
memcpy(&dwCompType,pRes,sizeof(DWORD));
|
|
pRes += sizeof( DWORD );
|
|
|
|
memcpy(&dwCompressedSize,pRes,sizeof(DWORD));
|
|
pRes += sizeof( DWORD );
|
|
|
|
memcpy(&dwExpandedSize,pRes,sizeof(DWORD));
|
|
pRes += sizeof( DWORD );
|
|
|
|
//=========================================================
|
|
// make sure the signature is valid and that the compression type is one
|
|
// we understand!
|
|
//=========================================================
|
|
if(dwSig != BMOF_SIG ||dwCompType != 1){
|
|
return NULL;
|
|
}
|
|
|
|
//=========================================================
|
|
// Allocate storage for the compressed data and
|
|
// expanded data
|
|
//=========================================================
|
|
try
|
|
{
|
|
pExpanded = (BYTE*)malloc(dwExpandedSize);
|
|
if( pExpanded == NULL)
|
|
{
|
|
goto ExitDecompression;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
throw;
|
|
}
|
|
|
|
//=========================================================
|
|
// Decompress the data
|
|
//=========================================================
|
|
CBaseMrciCompression * pMrci = new CBaseMrciCompression;
|
|
if( pMrci )
|
|
{
|
|
dwResSize = pMrci->Mrci1Decompress(pRes, dwCompressedSize, pExpanded, dwExpandedSize);
|
|
if(dwResSize != dwExpandedSize)
|
|
{
|
|
SAFE_DELETE_PTR(pMrci);
|
|
goto ExitDecompression;
|
|
}
|
|
SAFE_DELETE_PTR(pMrci);
|
|
}
|
|
|
|
|
|
//=========================================================
|
|
// Now, get out of here
|
|
//=========================================================
|
|
return pExpanded;
|
|
|
|
ExitDecompression:
|
|
if( pExpanded )
|
|
free(pExpanded);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::ExtractFileNameFromKey(TCHAR *& pKey,WCHAR * wcsKey)
|
|
{
|
|
WCHAR *wcsToken = NULL;
|
|
CAutoWChar wcsTmp(MAX_PATH * 4);
|
|
BOOL fRc = FALSE;
|
|
|
|
if( wcsTmp.Valid() )
|
|
{
|
|
if(wcsKey)
|
|
{
|
|
//======================================================
|
|
// Get a ptr to the first [ , if there isn't one, then
|
|
// just copy the whole thing.
|
|
//======================================================
|
|
wcscpy(wcsTmp,wcsKey);
|
|
wcsToken = wcstok(wcsTmp, L"[" );
|
|
if( wcsToken != NULL )
|
|
{
|
|
wcscpy(wcsTmp,wcsToken);
|
|
}
|
|
|
|
#ifndef UNICODE
|
|
CAnsiUnicode XLate;
|
|
|
|
if( SUCCEEDED(XLate.UnicodeToAnsi(wcsTmp,pKey)))
|
|
{
|
|
fRc = TRUE;
|
|
}
|
|
#else
|
|
pKey = new TCHAR[_tcslen(wcsTmp) + 1];
|
|
if(pKey)
|
|
{
|
|
_tcscpy(pKey,wcsTmp);
|
|
fRc = TRUE;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
return fRc;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CWMIBinMof::CreateKey(WCHAR * wcsFileName, WCHAR * wcsResource,WCHAR * wcsKey)
|
|
{
|
|
swprintf(wcsKey,L"%s[%s]",wcsFileName, wcsResource );
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::SendToMofComp(DWORD dwSize,BYTE * pRes,WCHAR * wcsKey)
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
if(m_pCompiler == NULL)
|
|
{
|
|
hr = CoCreateInstance(CLSID_WinmgmtMofCompiler, 0, CLSCTX_INPROC_SERVER,IID_IWinmgmtMofCompiler, (LPVOID *) &m_pCompiler);
|
|
}
|
|
if(hr == WBEM_NO_ERROR)
|
|
{
|
|
|
|
WBEM_COMPILE_STATUS_INFO Info;
|
|
memset(&Info,0,sizeof(WBEM_COMPILE_STATUS_INFO));
|
|
hr = m_pCompiler->WinmgmtCompileBuffer(dwSize, pRes, 0, 65536, 0,SERVICES,CONTEXT , &Info);
|
|
if( hr != WBEM_NO_ERROR )
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
ERRORTRACE((THISPROVIDER,"Mofcomp of binary mof failed for:\n"));
|
|
TranslateAndLog(wcsKey);
|
|
ERRORTRACE((THISPROVIDER,"WinmgmtCompileBuffer return value: %ld\n",hr));
|
|
ERRORTRACE((THISPROVIDER,"Size of Mof: %ld\n",dwSize));
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
ERRORTRACE((THISPROVIDER,"Binary mof succeeded for:\n"));
|
|
TranslateAndLog(wcsKey);
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::ExtractBinaryMofFromFile(WCHAR * wcsFile, WCHAR * wcsResource,WCHAR * wcsKey, BOOL & fMofHasChanged)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fSuccess = TRUE;
|
|
CAutoWChar wcsTmp(MAX_PATH*4);
|
|
|
|
if( wcsTmp.Valid() )
|
|
{
|
|
ULONG lLowDateTime=0,lHighDateTime=0;
|
|
//=====================================
|
|
// As long as we have a list, process
|
|
// one at a time
|
|
//=====================================
|
|
lLowDateTime = 0l;
|
|
lHighDateTime = 0L;
|
|
fMofHasChanged = FALSE;
|
|
//==============================================
|
|
// Compare the file date/timestamp the date/timestamp is different, change
|
|
// it.
|
|
//==============================================
|
|
wcscpy(wcsTmp,wcsFile);
|
|
if( GetFileDateAndTime(lLowDateTime,lHighDateTime,wcsTmp) )
|
|
{
|
|
CreateKey(wcsTmp,wcsResource,wcsKey);
|
|
|
|
|
|
// DBG_PRINTFA((pBuff,"Event:%S\n",wcsKey));
|
|
|
|
if( NeedToProcessThisMof(wcsKey,lLowDateTime,lHighDateTime) )
|
|
{
|
|
fMofHasChanged = TRUE;
|
|
|
|
if( m_fUpdateNamespace )
|
|
{
|
|
DWORD dwSize = 0;
|
|
BYTE * pRes = NULL;
|
|
HGLOBAL hResource = NULL;
|
|
HINSTANCE hInst = NULL;
|
|
|
|
if( GetPointerToBinaryResource(pRes,dwSize,hResource,hInst,wcsResource,wcsKey) )
|
|
{
|
|
hr = SendToMofComp(dwSize,pRes,wcsKey);
|
|
if(hr == WBEM_S_NO_ERROR )
|
|
{
|
|
if( UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime, TRUE) )
|
|
{
|
|
CNamespaceManagement Namespace(this);
|
|
Namespace.CreateClassAssociationsToDriver(wcsKey,pRes,lLowDateTime,lHighDateTime);
|
|
Namespace.DeleteOldClasses(wcsKey,CVARIANT((long)lLowDateTime),CVARIANT((long)lHighDateTime), TRUE);
|
|
fSuccess = TRUE;
|
|
}
|
|
else
|
|
{
|
|
UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
|
|
}
|
|
UnlockResource(hResource);
|
|
FreeResource(hResource);
|
|
FreeLibrary(hInst);
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
ERRORTRACE((THISPROVIDER,"Could not get pointer to binary resource for file:\n"));
|
|
TranslateAndLog(wcsKey);
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fSuccess = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwTest = GetLastError();
|
|
ERRORTRACE((THISPROVIDER,"Something FAILED for filename: %s\n",wcsFile));
|
|
ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
|
|
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
ERRORTRACE((THISPROVIDER,"Invalid File:\n"));
|
|
TranslateAndLog(wcsFile);
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
UpdateMofTimestampInHMOM(wcsFile,lLowDateTime,lHighDateTime,FALSE);
|
|
wcscpy(wcsKey, wcsFile);
|
|
|
|
}
|
|
}
|
|
return fSuccess;
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#define WDMPROV_REG_KEY L"Software\\Microsoft\\WBEM\\WDMProvider"
|
|
BOOL CWMIBinMof::UserConfiguredRegistryToProcessStrandedClassesDuringEveryInit(void)
|
|
{
|
|
DWORD dwProcess = 0;
|
|
CRegistry RegInfo ;
|
|
|
|
DWORD dwRet = RegInfo.Open (HKEY_LOCAL_MACHINE, WDMPROV_REG_KEY, KEY_READ) ;
|
|
if ( dwRet == ERROR_SUCCESS )
|
|
{
|
|
RegInfo.GetCurrentKeyValue ( L"ProcessStrandedClasses",dwProcess );
|
|
}
|
|
RegInfo.Close();
|
|
|
|
return (BOOL) dwProcess;
|
|
}
|
|
/////////// //////////////////////////////////////////////////////////
|
|
void CWMIBinMof::ProcessListOfWMIBinaryMofsFromWMI()
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
if( m_nInit == FULLY_INITIALIZED )
|
|
{
|
|
CAutoWChar wcsFileName(MAX_PATH*3);
|
|
CAutoWChar wcsResource(MAX_PATH*3);
|
|
|
|
if( wcsFileName.Valid() && wcsResource.Valid() )
|
|
{
|
|
KeyList ArrDriversInRegistry;
|
|
//============================================================
|
|
// Get list of what is currently in the registry
|
|
//============================================================
|
|
GetListOfDriversCurrentlyInRegistry(WDM_REG_KEY,ArrDriversInRegistry);
|
|
|
|
//======================================================================
|
|
// Initialize things
|
|
//======================================================================
|
|
BOOL fMofChanged = FALSE;
|
|
m_fUpdateNamespace = TRUE;
|
|
|
|
//======================================================================
|
|
// Allocate working classes
|
|
//======================================================================
|
|
CWMIStandardShell * pWMI = new CWMIStandardShell;
|
|
if( pWMI )
|
|
{
|
|
hr = pWMI->Initialize(NULL,FALSE,m_pWMI->HandleMap(),m_fUpdateNamespace, WMIGUID_QUERY, m_pWMI->Services(),m_pWMI->Handler(),m_pWMI->Context());
|
|
if( S_OK == hr )
|
|
{
|
|
|
|
CNamespaceManagement * pNamespace = new CNamespaceManagement(this);
|
|
if( pNamespace )
|
|
{
|
|
//=========================================
|
|
// Query the binary guid
|
|
//=========================================
|
|
pNamespace->InitQuery(L"select * from WMIBinaryMofResource where Name != ");
|
|
|
|
hr = pWMI->QueryAndProcessAllBinaryGuidInstances(*pNamespace, fMofChanged, &ArrDriversInRegistry);
|
|
//=========================================
|
|
// Get a list of binary mofs from WMI
|
|
//=========================================
|
|
GetListOfBinaryMofs();
|
|
ULONG nTmp=0;
|
|
CAutoWChar wcsTmpKey(MAX_PATH*3);
|
|
BOOL fProcessStrandedClasses = FALSE;
|
|
if( wcsTmpKey.Valid() )
|
|
{
|
|
if( m_uResourceCount > 0 )
|
|
{
|
|
//===============================================================
|
|
// Go through and get all the resources to process one by one
|
|
//===============================================================
|
|
while( GetBinaryMofFileNameAndResourceName(wcsFileName,wcsResource)){
|
|
|
|
//============================================================
|
|
// Process the binary mof
|
|
//============================================================
|
|
if( ExtractBinaryMofFromFile(wcsFileName,wcsResource,wcsTmpKey,fMofChanged))
|
|
{
|
|
pNamespace->UpdateQuery(L" and Name != ",wcsTmpKey);
|
|
}
|
|
if( fMofChanged )
|
|
{
|
|
fProcessStrandedClasses = TRUE;
|
|
}
|
|
|
|
ArrDriversInRegistry.Remove(wcsTmpKey);
|
|
}
|
|
}
|
|
}
|
|
pNamespace->DeleteOldDrivers(FALSE);
|
|
//===========================================================================
|
|
// If we are not supposed to process stranded classes, check the reg key
|
|
// to see if it wants us to anyway
|
|
//===========================================================================
|
|
if( !fProcessStrandedClasses )
|
|
{
|
|
fProcessStrandedClasses = UserConfiguredRegistryToProcessStrandedClassesDuringEveryInit();
|
|
}
|
|
if( fProcessStrandedClasses )
|
|
{
|
|
pNamespace->DeleteStrandedClasses();
|
|
}
|
|
DeleteOldDriversInRegistry(ArrDriversInRegistry);
|
|
SAFE_DELETE_PTR(pNamespace);
|
|
}
|
|
}
|
|
SAFE_DELETE_PTR(pWMI);
|
|
}
|
|
if( m_pMofResourceInfo )
|
|
{
|
|
WmiFreeBuffer( m_pMofResourceInfo );
|
|
}
|
|
}
|
|
}
|
|
ERRORTRACE((THISPROVIDER,"End of processing Binary MOFS***************\n"));
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
//=============================================================
|
|
// THE BINARY MOF GROUP
|
|
//=============================================================
|
|
BOOL CWMIBinMof::GetListOfBinaryMofs()
|
|
{
|
|
BOOL fRc = TRUE;
|
|
ULONG uRc;
|
|
m_uCurrentResource = 0;
|
|
|
|
m_pMofResourceInfo = NULL;
|
|
m_uResourceCount = 0;
|
|
|
|
try
|
|
{
|
|
uRc = WmiMofEnumerateResourcesW( 0, &m_uResourceCount, &m_pMofResourceInfo );
|
|
if( uRc != ERROR_SUCCESS )
|
|
{
|
|
fRc = FALSE;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
fRc = FALSE;
|
|
// don't throw
|
|
}
|
|
|
|
return fRc;
|
|
}
|
|
//=============================================================
|
|
BOOL CWMIBinMof::GetBinaryMofFileNameAndResourceName(WCHAR * pwcsFileName,WCHAR * pwcsResource)
|
|
{
|
|
BOOL fRc = FALSE;
|
|
|
|
//===================================================================
|
|
// There are a lot of tests in here, due to strange results from
|
|
// WDM Service under stress.
|
|
//===================================================================
|
|
if( m_uCurrentResource < m_uResourceCount ){
|
|
|
|
if( m_pMofResourceInfo ){
|
|
|
|
DWORD dwFileLen = wcslen(m_pMofResourceInfo[m_uCurrentResource].ImagePath);
|
|
DWORD dwResourceLen = wcslen(m_pMofResourceInfo[m_uCurrentResource].ResourceName);
|
|
|
|
if( dwFileLen <( MAX_PATH * 2) && dwResourceLen < (MAX_PATH * 2 )){
|
|
|
|
if( IsBadReadPtr( m_pMofResourceInfo[m_uCurrentResource].ImagePath,dwFileLen) == 0 ){
|
|
wcscpy( pwcsFileName, m_pMofResourceInfo[m_uCurrentResource].ImagePath );
|
|
|
|
if( IsBadReadPtr( m_pMofResourceInfo[m_uCurrentResource].ResourceName,dwResourceLen) == 0 ){
|
|
wcscpy( pwcsResource, m_pMofResourceInfo[m_uCurrentResource].ResourceName );
|
|
m_uCurrentResource++;
|
|
fRc = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return fRc;
|
|
}
|
|
////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::ExtractBinaryMofFromDataBlock(BYTE * pByte,ULONG uInstanceSize, WCHAR * wcsKey, BOOL & fMofHasChanged)
|
|
{
|
|
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
//===================================================
|
|
// Get the CRC of the data buffer
|
|
//===================================================
|
|
DWORD dwCRC = STARTING_CRC32_VALUE;
|
|
|
|
if( IsBadReadPtr( pByte,uInstanceSize) != 0 ){
|
|
return WBEM_E_INVALID_OBJECT;
|
|
}
|
|
|
|
dwCRC = UpdateCRC32(pByte,uInstanceSize, dwCRC);
|
|
FINALIZE_CRC32(dwCRC);
|
|
//=========================================================
|
|
// get the size of the buffer to send
|
|
//=========================================================
|
|
DWORD dwCompressedSize;
|
|
BYTE * pTmp = pByte;
|
|
pTmp += sizeof( DWORD ) * 2;
|
|
|
|
memcpy(&dwCompressedSize,pTmp,sizeof(DWORD));
|
|
dwCompressedSize += 16;
|
|
fMofHasChanged = FALSE;
|
|
//===================================================
|
|
// See if we should process this class or not
|
|
//===================================================
|
|
ULONG lLow = dwCRC;
|
|
ULONG lHigh = 0;
|
|
|
|
// DBG_PRINTFA((pBuff,"Event:%S\n",wcsKey));
|
|
|
|
if( NeedToProcessThisMof(wcsKey,lLow,lHigh))
|
|
{
|
|
if( !m_fUpdateNamespace )
|
|
{
|
|
fMofHasChanged = TRUE;
|
|
hr = WBEM_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
hr = SendToMofComp(dwCompressedSize,pByte,wcsKey);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
if( UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh, TRUE))
|
|
{
|
|
CNamespaceManagement Namespace(this);
|
|
Namespace.CreateClassAssociationsToDriver(wcsKey,pByte,lLow,lHigh);
|
|
Namespace.DeleteOldClasses(wcsKey,CVARIANT((long)lLow),CVARIANT((long)lHigh),TRUE);
|
|
}
|
|
else
|
|
{
|
|
UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh,FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh,FALSE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_NO_ERROR;
|
|
}
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::DeleteMofsFromEvent(CVARIANT & vImagePath,CVARIANT & vResourceName, BOOL & fMofHasChanged)
|
|
{
|
|
HRESULT hr = WBEM_E_OUT_OF_MEMORY;
|
|
CAutoWChar wcsTmp(MAX_PATH*2);
|
|
|
|
if( wcsTmp.Valid() )
|
|
{
|
|
hr = WBEM_E_INVALID_OBJECT;
|
|
//=========================================
|
|
// Initialize stuff
|
|
//=========================================
|
|
fMofHasChanged = FALSE;
|
|
|
|
//=================================================================
|
|
// if we have an image path and resource path we are working with
|
|
// file, otherwise it is a binary guidd
|
|
//=================================================================
|
|
if((vResourceName.GetType() != VT_NULL ) && ( vImagePath.GetType() != VT_NULL )){
|
|
|
|
CreateKey( vImagePath.GetStr(), vResourceName.GetStr(),wcsTmp );
|
|
}
|
|
else if( vResourceName.GetType() != VT_NULL ){
|
|
|
|
SetBinaryMofClassName(vResourceName.GetStr(),wcsTmp);
|
|
}
|
|
|
|
if( m_fUpdateNamespace )
|
|
{
|
|
|
|
CNamespaceManagement Namespace(this);
|
|
|
|
Namespace.InitQuery(L"select * from WMIBinaryMofResource where Name = ");
|
|
Namespace.UpdateQuery(L"",wcsTmp);
|
|
|
|
if( Namespace.DeleteOldDrivers(FALSE) )
|
|
{
|
|
hr = WBEM_NO_ERROR;
|
|
fMofHasChanged = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( ThisMofExistsInRegistry(WDM_REG_KEY,wcsTmp, 0, 0, FALSE))
|
|
{
|
|
fMofHasChanged = TRUE;
|
|
}
|
|
hr = WBEM_NO_ERROR;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//**********************************************************************************************************************
|
|
// Functions for the Dredger
|
|
//**********************************************************************************************************************
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// format of string containing mof info is:
|
|
// "WmiBinaryMofResource.HighDateTime=9999,LowDateTime=9999,Name="Whatever"
|
|
//
|
|
// HKLM\Software\Microsoft\WBEM\WDM\WDMBinaryMofResource
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CWMIBinMof::AddThisMofToRegistryIfNeeded(WCHAR * wcsKey, WCHAR * wcsFileName, ULONG & lLowDateTime, ULONG & lHighDateTime, BOOL fSuccess)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
CRegistry RegInfo ;
|
|
|
|
DWORD dwRet = RegInfo.CreateOpen (HKEY_LOCAL_MACHINE, wcsKey) ;
|
|
if ( dwRet == ERROR_SUCCESS )
|
|
{
|
|
CAutoWChar wcsBuf(MAX_PATH);
|
|
if( wcsBuf.Valid() )
|
|
{
|
|
|
|
if( fSuccess )
|
|
{
|
|
swprintf(wcsBuf,L"LowDateTime:%ld,HighDateTime:%ld***Binary mof compiled successfully", lLowDateTime, lHighDateTime);
|
|
}
|
|
else
|
|
{
|
|
swprintf(wcsBuf,L"LowDateTime:%ld,HighDateTime:%ld***Binary mof failed, see WMIPROV.LOG", lLowDateTime, lHighDateTime);
|
|
}
|
|
CHString sTmp = wcsBuf;
|
|
|
|
if ( RegInfo.SetCurrentKeyValue ( wcsFileName,sTmp ) == ERROR_SUCCESS )
|
|
{
|
|
hr = WBEM_S_NO_ERROR ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
RegInfo.Close();
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::ThisMofExistsInRegistry(WCHAR * wcsKey,WCHAR * wcsFileName, ULONG lLowDateTime, ULONG lHighDateTime, BOOL fCompareDates)
|
|
{
|
|
BOOL fExists = FALSE;
|
|
CRegistry RegInfo ;
|
|
|
|
DWORD dwRet = RegInfo.Open (HKEY_LOCAL_MACHINE, wcsKey, KEY_READ) ;
|
|
if ( dwRet == ERROR_SUCCESS )
|
|
{
|
|
CHString chsValue;
|
|
|
|
if ( RegInfo.GetCurrentKeyValue ( wcsFileName,chsValue ) == ERROR_SUCCESS )
|
|
{
|
|
if( fCompareDates )
|
|
{
|
|
CAutoWChar wcsIncomingValue(MAX_PATH);
|
|
CAutoWChar wcsTmp(MAX_PATH);
|
|
|
|
if( wcsIncomingValue.Valid() && wcsTmp.Valid() )
|
|
{
|
|
swprintf(wcsIncomingValue,L"LowDateTime:%ld,HighDateTime:%ld", lLowDateTime, lHighDateTime );
|
|
|
|
WCHAR *wcsToken = NULL;
|
|
|
|
//======================================================
|
|
// Get a ptr to the first *** , if there isn't one, then
|
|
// we have a messed up key
|
|
//======================================================
|
|
wcscpy(wcsTmp,(const WCHAR*)chsValue);
|
|
wcsToken = wcstok(wcsTmp, L"*" );
|
|
if( wcsToken != NULL )
|
|
{
|
|
if( _wcsicmp(wcsToken, wcsIncomingValue) == 0 )
|
|
{
|
|
fExists = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fExists = TRUE;
|
|
}
|
|
}
|
|
}
|
|
RegInfo.Close();
|
|
return fExists;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::DeleteMofFromRegistry(WCHAR * wcsFileName)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
HKEY hKey;
|
|
hr = RegOpenKey(HKEY_LOCAL_MACHINE, WDM_REG_KEY, &hKey);
|
|
if(NO_ERROR == hr)
|
|
{
|
|
hr = RegDeleteValue(hKey,wcsFileName);
|
|
CloseHandle(hKey);
|
|
}
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::DeleteOldDriversInRegistry(KeyList & ArrDriversInRegistry)
|
|
{
|
|
int nSize = ArrDriversInRegistry.GetSize();
|
|
for( int i=0; i < nSize; i++ )
|
|
{
|
|
DeleteMofFromRegistry(ArrDriversInRegistry.GetAt(i));
|
|
}
|
|
return TRUE;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::CopyWDMKeyToDredgeKey()
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
//=======================================================================
|
|
// Open up the WDM Dredge Key and enumerate the keys, copy them into
|
|
// the DredgeReg key
|
|
//=======================================================================
|
|
CRegistry WDMReg;
|
|
CRegistry WDMDregReg;
|
|
|
|
if (ERROR_SUCCESS == WDMReg.Open(HKEY_LOCAL_MACHINE, WDM_REG_KEY, KEY_READ))
|
|
{
|
|
//===============================================================
|
|
// Clean up old stuff
|
|
// Note: You need to open up the parent key, so you can delete
|
|
// the child DREDGE key
|
|
//===============================================================
|
|
if( ERROR_SUCCESS == WDMDregReg.Open(HKEY_LOCAL_MACHINE, WDM_REG_KEY, KEY_READ))
|
|
{
|
|
CHString pchs(DREDGE_KEY);
|
|
WDMDregReg.DeleteKey(&pchs);
|
|
WDMDregReg.Close();
|
|
}
|
|
if( ERROR_SUCCESS == WDMDregReg.CreateOpen(HKEY_LOCAL_MACHINE, WDM_DREDGE_KEY))
|
|
{
|
|
//===============================================================
|
|
// Go through the loop, and copy the keys
|
|
//===============================================================
|
|
BYTE *pValueData = NULL ;
|
|
WCHAR *pValueName = NULL ;
|
|
fSuccess = TRUE;
|
|
|
|
for(DWORD i = 0 ; i < WDMReg.GetValueCount(); i++)
|
|
{
|
|
DWORD dwRc = WDMReg.EnumerateAndGetValues(i, pValueName, pValueData) ;
|
|
if( dwRc == ERROR_SUCCESS )
|
|
{
|
|
CHString chsKey(pValueName);
|
|
CHString chsValue((LPCWSTR)pValueData);
|
|
if ( !WDMDregReg.SetCurrentKeyValue ( chsKey, chsValue ) == ERROR_SUCCESS )
|
|
{
|
|
fSuccess = FALSE;
|
|
}
|
|
delete []pValueData;
|
|
delete []pValueName;
|
|
}
|
|
else
|
|
{
|
|
fSuccess = FALSE;
|
|
}
|
|
if( !fSuccess )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
WDMDregReg.Close();
|
|
}
|
|
WDMReg.Close();
|
|
}
|
|
|
|
return fSuccess;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::GetListOfDriversCurrentlyInRegistry(WCHAR * wcsKey, KeyList & ArrDriversInRegistry)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
CRegistry RegInfo ;
|
|
//==========================================================
|
|
// Open the key for enumeration and go through the sub keys.
|
|
//==========================================================
|
|
HKEY hKey = NULL;
|
|
HRESULT hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, wcsKey, 0, KEY_READ | KEY_QUERY_VALUE,&hKey);
|
|
if( ERROR_SUCCESS == hr )
|
|
{
|
|
WCHAR wcsKeyName[MAX_PATH+2];
|
|
DWORD dwLen = 0;
|
|
int i = 0;
|
|
while( ERROR_SUCCESS == hr )
|
|
{
|
|
dwLen = MAX_PATH+2;
|
|
hr = RegEnumValue(hKey,i,wcsKeyName, &dwLen,0,NULL,NULL,NULL);
|
|
// If we are successful reading the name
|
|
//=======================================
|
|
if(ERROR_SUCCESS == hr )
|
|
{
|
|
ArrDriversInRegistry.Add(wcsKeyName);
|
|
i++;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
{
|
|
fSuccess = FALSE;
|
|
}
|
|
return fSuccess;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIBinMof::ProcessBinaryMofEvent(PWNODE_HEADER WnodeHeader )
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
m_fUpdateNamespace = TRUE;
|
|
if( m_nInit == FULLY_INITIALIZED )
|
|
{
|
|
CWMIStandardShell * pWMI = new CWMIStandardShell;
|
|
|
|
if( pWMI )
|
|
{
|
|
//=======================================================
|
|
// See if a binary mof event is being added or deleted
|
|
//=======================================================
|
|
|
|
if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,WnodeHeader->Guid))
|
|
{
|
|
hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_ADDED,TRUE,m_pWMI->HandleMap(),m_fUpdateNamespace, WMIGUID_QUERY, m_pWMI->Services(),m_pWMI->Handler(), m_pWMI->Context());
|
|
if( S_OK == hr )
|
|
{
|
|
hr = pWMI->ProcessEvent(MOF_ADDED,WnodeHeader);
|
|
}
|
|
}
|
|
else if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,WnodeHeader->Guid))
|
|
{
|
|
hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_DELETED,TRUE,m_pWMI->HandleMap(),m_fUpdateNamespace, WMIGUID_QUERY, m_pWMI->Services(),m_pWMI->Handler(), m_pWMI->Context());
|
|
if( S_OK == hr )
|
|
{
|
|
hr = pWMI->ProcessEvent(MOF_DELETED,WnodeHeader);
|
|
}
|
|
}
|
|
|
|
SAFE_DELETE_PTR(pWMI);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//**********************************************************************************************************************
|
|
// STUFF FOR DREDGE
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//**********************************************************************************************************************
|
|
/////////////////////////////////////////////////////////////////////
|
|
// DREDGE APIS - access ONLY the DREDGE KEY
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::BinaryMofEventChanged(PWNODE_HEADER WnodeHeader )
|
|
{
|
|
BOOL fMofHasChanged = TRUE;
|
|
|
|
if( m_nInit != NOT_INITIALIZED )
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
m_fUpdateNamespace = FALSE;
|
|
CWMIStandardShell * pWMI = new CWMIStandardShell;
|
|
|
|
if( pWMI )
|
|
{
|
|
//=======================================================
|
|
// See if a binary mof event is being added or deleted
|
|
//=======================================================
|
|
|
|
if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,WnodeHeader->Guid))
|
|
{
|
|
hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_ADDED,
|
|
TRUE,
|
|
NULL,
|
|
m_fUpdateNamespace,
|
|
WMIGUID_QUERY,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if( S_OK == hr )
|
|
{
|
|
hr = pWMI->ProcessEvent(MOF_ADDED,WnodeHeader);
|
|
}
|
|
}
|
|
else if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,WnodeHeader->Guid))
|
|
{
|
|
// DO NOTHING
|
|
hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_DELETED,TRUE,
|
|
NULL,
|
|
m_fUpdateNamespace,
|
|
WMIGUID_QUERY,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if( S_OK == hr )
|
|
{
|
|
// hr = pWMI->ProcessEvent(MOF_DELETED,WnodeHeader);
|
|
}
|
|
}
|
|
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
if( pWMI->HasMofChanged() )
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"BinaryMofEventChanged returned TRUE:\n"));
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"BinaryMofEventChanged returned FALSE:\n"));
|
|
}
|
|
fMofHasChanged = pWMI->HasMofChanged();
|
|
SAFE_DELETE_PTR(pWMI);
|
|
}
|
|
|
|
}
|
|
return fMofHasChanged;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
// DREDGE APIS - access ONLY the DREDGE KEY
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIBinMof::BinaryMofsHaveChanged()
|
|
{
|
|
BOOL fBinaryMofHasChanged = FALSE;
|
|
if( m_nInit != NOT_INITIALIZED )
|
|
{
|
|
KeyList ArrDriversInRegistry;
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
m_fUpdateNamespace = FALSE;
|
|
//============================================================
|
|
// Get list of what is currently in the registry
|
|
//============================================================
|
|
BOOL fRc = GetListOfDriversCurrentlyInRegistry(WDM_DREDGE_KEY,ArrDriversInRegistry);
|
|
if( fRc )
|
|
{
|
|
//=====================================================================
|
|
// Get a list of binary mofs from WMI
|
|
// Query WMIBinaryMofResource for list of static mofs
|
|
//=====================================================================
|
|
GetListOfBinaryMofs();
|
|
if( m_uResourceCount > 0 )
|
|
{
|
|
//===============================================================
|
|
// Go through and get all the resources to process one by one
|
|
//===============================================================
|
|
CAutoWChar FileName(MAX_PATH*2);
|
|
CAutoWChar Resource(MAX_PATH*2);
|
|
CAutoWChar TmpKey(MAX_PATH*2);
|
|
|
|
if( FileName.Valid() && Resource.Valid() && TmpKey.Valid() )
|
|
{
|
|
while( GetBinaryMofFileNameAndResourceName(FileName,Resource))
|
|
{
|
|
|
|
//============================================================
|
|
// Process the binary mof, keep going until one needs to
|
|
// be processed
|
|
//============================================================
|
|
ExtractBinaryMofFromFile(FileName,Resource,TmpKey, fBinaryMofHasChanged );
|
|
if( fBinaryMofHasChanged )
|
|
{
|
|
break;
|
|
}
|
|
ArrDriversInRegistry.Remove(TmpKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !fBinaryMofHasChanged )
|
|
{
|
|
//=========================================
|
|
// Query the binary guid
|
|
//=========================================
|
|
CNamespaceManagement * pNamespace = new CNamespaceManagement(this);
|
|
if( pNamespace )
|
|
{
|
|
pNamespace->InitQuery(L"select * from WMIBinaryMofResource where Name != ");
|
|
CWMIStandardShell * pWMI = new CWMIStandardShell;
|
|
|
|
if( pWMI )
|
|
{
|
|
hr = pWMI->Initialize(NULL, FALSE, NULL,m_fUpdateNamespace, WMIGUID_QUERY,NULL,NULL,NULL);
|
|
if( S_OK == hr )
|
|
{
|
|
hr = pWMI->QueryAndProcessAllBinaryGuidInstances(*pNamespace, fBinaryMofHasChanged,&ArrDriversInRegistry);
|
|
}
|
|
SAFE_DELETE_PTR(pWMI);
|
|
}
|
|
SAFE_DELETE_PTR(pNamespace);
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
/* //============================================================
|
|
// If there are any drivers left in the list, then we need
|
|
// to say that the binary mofs have changed
|
|
//============================================================
|
|
if( !fBinaryMofHasChanged )
|
|
{
|
|
if( ArrDriversInRegistry.OldDriversLeftOver() )
|
|
{
|
|
fBinaryMofHasChanged = TRUE;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
else
|
|
{
|
|
//==============================================================================================
|
|
// there is no key, so now we need to return that the registry has changed, so the copy of the
|
|
// keys will be kicked off
|
|
//==============================================================================================
|
|
fBinaryMofHasChanged = TRUE;
|
|
}
|
|
if( m_pMofResourceInfo )
|
|
{
|
|
WmiFreeBuffer( m_pMofResourceInfo );
|
|
}
|
|
|
|
ERRORTRACE((THISPROVIDER,"***************\n"));
|
|
if( fBinaryMofHasChanged )
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"BinaryMofsHaveChanged returned TRUE:\n"));
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"BinaryMofsHaveChanged returned FALSE:\n"));
|
|
}
|
|
}
|
|
return fBinaryMofHasChanged;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//**********************************************************************************************************************
|
|
// Namespace Management Class
|
|
//**********************************************************************************************************************
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CNamespaceManagement::CNamespaceManagement(CWMIBinMof * pOwner)
|
|
{
|
|
m_pObj = pOwner;
|
|
m_nSize = 0;
|
|
m_pwcsQuery = NULL;
|
|
m_fInit = 0;
|
|
m_pwcsSavedQuery = NULL;
|
|
m_fSavedInit = 0;
|
|
m_nSavedSize = 0;
|
|
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
CNamespaceManagement::~CNamespaceManagement()
|
|
{
|
|
SAFE_DELETE_ARRAY( m_pwcsQuery );
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#define SERVICES_PTR m_pObj->WMI()->Services()
|
|
#define CONTEXT_PTR m_pObj->WMI()->Context()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Delete stranded classes in the repository
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CNamespaceManagement::DeleteStrandedClasses(void)
|
|
{
|
|
BOOL fRc = TRUE;
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
IEnumWbemClassObject* pEnum = NULL;
|
|
IEnumWbemClassObject* pEnumofStrandedClasses = NULL;
|
|
// ==================================================================================
|
|
// Get list of drivers
|
|
// ==================================================================================
|
|
InitQuery(L"select * from WMIBinaryMofResource");
|
|
CBSTR strQryLang(L"WQL");
|
|
CBSTR cbstrQry(m_pwcsQuery);
|
|
|
|
hr = SERVICES_PTR->ExecQuery(strQryLang,cbstrQry, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
unsigned long uReturned = 0;
|
|
CVARIANT vDriver, vLow, vHigh;
|
|
IWbemClassObject * pClass = NULL;
|
|
|
|
//================================================================================
|
|
// Initialize query for stranded classes as we go along and clean up the old
|
|
// classes
|
|
//================================================================================
|
|
InitQuery(L"select * from WDMClassesOfDriver where Driver != ");
|
|
while ( TRUE )
|
|
{
|
|
IWbemClassObject * pClass = NULL;
|
|
|
|
if( WBEM_NO_ERROR == (hr = pEnum->Next(2000, 1, &pClass, &uReturned)))
|
|
{
|
|
if( WBEM_NO_ERROR == (hr = pClass->Get(L"Name", 0, &vDriver, 0, 0)))
|
|
{
|
|
//============================================================
|
|
// Correct the query syntax for next query
|
|
//============================================================
|
|
UpdateQuery( L" and Driver != ",vDriver.GetStr());
|
|
}
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pClass );
|
|
if( hr != WBEM_NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
//================================================================
|
|
// Ok, now go after the stranded classes, the ones that don't
|
|
// have any drivers for some reason
|
|
//================================================================
|
|
CBSTR strQryLang(L"WQL");
|
|
CBSTR cbstr(m_pwcsQuery);
|
|
|
|
hr = SERVICES_PTR->ExecQuery(strQryLang,cbstr, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnumofStrandedClasses);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
BOOL bDrivers = FALSE;
|
|
while( TRUE )
|
|
{
|
|
if( WBEM_NO_ERROR == (hr = pEnumofStrandedClasses->Next(2000, 1, &pClass, &uReturned)))
|
|
{
|
|
CVARIANT vPath,vClass;
|
|
pClass->Get(L"ClassName", 0, &vClass, 0, 0);
|
|
if(SUCCEEDED(hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0)))
|
|
{
|
|
hr = DeleteUnusedClassAndDriverInfo( TRUE, vPath.GetStr(),vClass.GetStr() );
|
|
}
|
|
else
|
|
{
|
|
fRc = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR(pClass);
|
|
if( hr != WBEM_NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pEnumofStrandedClasses);
|
|
if(!fRc)
|
|
{
|
|
if( hr != E_OUTOFMEMORY)
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"Stranded instance exist in repository"));
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR(pEnum);
|
|
return fRc;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CNamespaceManagement::DeleteOldDrivers(BOOL fCompareDates)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
IEnumWbemClassObject* pEnum = NULL;
|
|
BOOL fRc = TRUE;
|
|
BSTR strQry = NULL;
|
|
|
|
strQry = SysAllocString(m_pwcsQuery);
|
|
if(strQry != NULL)
|
|
{
|
|
CBSTR strQryLang(L"WQL");
|
|
|
|
hr = SERVICES_PTR->ExecQuery(strQryLang, strQry, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
|
|
SysFreeString(strQry);
|
|
strQry = NULL;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
fRc = FALSE;
|
|
}
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
IWbemClassObject * pClass = NULL;
|
|
unsigned long uReturned = 0;
|
|
CVARIANT vClass;
|
|
hr = WBEM_NO_ERROR;
|
|
|
|
//============================================================================================
|
|
// NOTE: We only deal with drivers extracted from files here, if it is a guid as the result
|
|
// of an event this is handled elsewhere
|
|
//============================================================================================
|
|
while ( hr == WBEM_NO_ERROR )
|
|
{
|
|
IWbemClassObject * pClass = NULL;
|
|
unsigned long uReturned = 0;
|
|
|
|
hr = pEnum->Next(2000, 1, &pClass, &uReturned);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
CVARIANT vLowDate, vHighDate, vName;
|
|
|
|
if( WBEM_NO_ERROR != (hr = pClass->Get(L"Name", 0, &vName, 0, 0)))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( fCompareDates )
|
|
{
|
|
vLowDate.SetLONG(0);
|
|
vHighDate.SetLONG(0);
|
|
|
|
if( WBEM_NO_ERROR != (hr = pClass->Get(L"LowDateTime", 0, &vLowDate, 0, 0)))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( WBEM_NO_ERROR != (hr = pClass->Get(L"HighDateTime", 0, &vHighDate, 0, 0)))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
ERRORTRACE((THISPROVIDER,"Deleting Old Drivers"));
|
|
if( DeleteOldClasses((WCHAR *) vName.GetStr(),vLowDate,vHighDate,fCompareDates ))
|
|
{
|
|
CVARIANT vPath;
|
|
|
|
hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
CBSTR cbstrPath(vPath.GetStr());
|
|
hr = SERVICES_PTR->DeleteInstance(cbstrPath,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
|
|
ERRORTRACE((THISPROVIDER,"We have been requested to delete this mof, it is being removed\n"));
|
|
TranslateAndLog(cbstrPath);
|
|
|
|
}
|
|
if( WBEM_NO_ERROR == hr )
|
|
{
|
|
m_pObj->DeleteMofFromRegistry((WCHAR *) vName.GetStr());
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"Stranded instance: \n"));
|
|
TranslateAndLog(vPath.GetStr());
|
|
|
|
ERRORTRACE((THISPROVIDER,"DeleteInstance return value: %ld\n",hr));
|
|
|
|
ERRORTRACE((THISPROVIDER,"Current query: \n"));
|
|
TranslateAndLog(m_pwcsQuery);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR(pEnum);
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"Cannot delete driver. ExecQuery return value: %ld\n",hr));
|
|
ERRORTRACE((THISPROVIDER,"Current query: \n"));
|
|
TranslateAndLog(m_pwcsQuery);
|
|
}
|
|
|
|
return fRc;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to delete Old classes for a particular driver
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL CNamespaceManagement::DeleteOldClasses(WCHAR * wcsFileName,CVARIANT & vLow, CVARIANT & vHigh, BOOL fCompareDates)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
CAutoWChar wcsTranslatedKey(MAX_PATH*2);
|
|
BOOL fRc = FALSE;
|
|
IEnumWbemClassObject* pEnum = NULL;
|
|
ULONG lHighDateTime = 0L;
|
|
ULONG lLowDateTime = 0L;
|
|
|
|
ERRORTRACE((THISPROVIDER,"Deleting Old Classes for Driver"));
|
|
TranslateAndLog(wcsFileName);
|
|
ERRORTRACE((THISPROVIDER,"*******\n"));
|
|
|
|
if( wcsTranslatedKey.Valid() )
|
|
{
|
|
//================================================================================
|
|
// Initialize everything we need to construct the query
|
|
//================================================================================
|
|
if( fCompareDates )
|
|
{
|
|
lLowDateTime= (ULONG)vLow.GetLONG();
|
|
lHighDateTime= (ULONG)vHigh.GetLONG();
|
|
}
|
|
|
|
ConvertStringToCTypeString( wcsTranslatedKey,wcsFileName );
|
|
//================================================================================
|
|
// Now, pick up all the old classes for this driver
|
|
//================================================================================
|
|
InitQuery(L"select * from WDMClassesOfDriver where Driver = ");
|
|
UpdateQuery(L"",wcsFileName);
|
|
UpdateQuery(L" and (HighDateTime != ",lHighDateTime);
|
|
UpdateQuery(L" or LowDateTime != ", lLowDateTime);
|
|
AddToQuery(L")");
|
|
|
|
BSTR strTmp = NULL;
|
|
strTmp = SysAllocString(m_pwcsQuery);
|
|
if(strTmp != NULL)
|
|
{
|
|
CBSTR strQryLang(L"WQL");
|
|
|
|
hr = SERVICES_PTR->ExecQuery(strQryLang, strTmp, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
|
|
SysFreeString(strTmp);
|
|
strTmp = NULL;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
fRc = FALSE;
|
|
}
|
|
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
IWbemClassObject * pClass = NULL;
|
|
unsigned long uReturned = 0;
|
|
CVARIANT vClass;
|
|
CAutoWChar wcsObjectPath(MAX_PATH*4);
|
|
|
|
if( wcsObjectPath.Valid() )
|
|
{
|
|
while ( TRUE )
|
|
{
|
|
hr = pEnum->Next(2000, 1, &pClass, &uReturned);
|
|
if( hr!= WBEM_NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = pClass->Get(L"ClassName", 0, &vClass, 0, 0);
|
|
if( hr != WBEM_NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
//===========================================================================
|
|
// Now, get this instance of tying the class with this old date
|
|
//===========================================================================
|
|
CVARIANT vPath;
|
|
hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
|
|
if( hr != WBEM_NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
//==========================================================================
|
|
// Now, just because we get a class name here doesn't mean we delete the
|
|
// class, this class could have been updated, in that case we just delete
|
|
// the instance of the WDMClassesOfDriver.
|
|
// Now, we need to check to see if this class really needs to be deleted
|
|
// or not
|
|
//==========================================================================
|
|
IWbemClassObject * pTmp = NULL;
|
|
CBSTR bTmp = vClass.GetStr();
|
|
swprintf(wcsObjectPath,L"WDMClassesOfDriver.ClassName=\"%s\",Driver=\"%s\",HighDateTime=%lu,LowDateTime=%lu",bTmp,wcsTranslatedKey,lHighDateTime,lLowDateTime);
|
|
CBSTR bstrQuery = wcsObjectPath;
|
|
hr = SERVICES_PTR->GetObject(bstrQuery,0,CONTEXT_PTR,&pTmp,NULL);
|
|
//===========================================================================
|
|
// this is simple, if we get an instance of WDMClassesOfDriver
|
|
// with the newer date, then we know it has been updated, so we don't
|
|
// delete the class
|
|
//===========================================================================
|
|
BOOL fDeleteOldClass = TRUE;
|
|
if( hr == WBEM_NO_ERROR )
|
|
{
|
|
fDeleteOldClass = FALSE;
|
|
}
|
|
|
|
hr = DeleteUnusedClassAndDriverInfo( fDeleteOldClass, vPath.GetStr(),vClass.GetStr() );
|
|
//===========================================================================
|
|
// Now, delete the WDM Instance of the Old Driver
|
|
//===========================================================================
|
|
SAFE_RELEASE_PTR( pTmp )
|
|
SAFE_RELEASE_PTR( pClass );
|
|
vClass.Clear();
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pEnum);
|
|
}
|
|
|
|
}
|
|
|
|
if( hr == WBEM_NO_ERROR || hr == WBEM_S_NO_MORE_DATA || hr == WBEM_S_FALSE)
|
|
{
|
|
fRc = TRUE;
|
|
}
|
|
|
|
}
|
|
return fRc;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CNamespaceManagement::CreateInstance ( WCHAR * wcsDriver, WCHAR * wcsClass, ULONG lLowDateTime, ULONG lHighDateTime )
|
|
{
|
|
IWbemClassObject * pInst = NULL, * pClass = NULL;
|
|
|
|
//==================================================
|
|
// Get a pointer to a IWbemClassObject object
|
|
//==================================================
|
|
HRESULT hr;
|
|
CVARIANT cvarName;
|
|
cvarName.SetStr(L"WDMClassesOfDriver");
|
|
|
|
hr = SERVICES_PTR->GetObject(cvarName, 0,CONTEXT_PTR, &pClass, NULL);
|
|
if(FAILED(hr)){
|
|
return FALSE;
|
|
}
|
|
|
|
//=============================================================
|
|
// Spawn a new instance
|
|
//=============================================================
|
|
hr = pClass->SpawnInstance(0, &pInst);
|
|
|
|
SAFE_RELEASE_PTR(pClass);
|
|
if( FAILED(hr) ){
|
|
return hr;
|
|
}
|
|
|
|
//=============================================================
|
|
// Put the data in the instance
|
|
//=============================================================
|
|
CVARIANT vClass, vDriver, vLow, vHigh;
|
|
|
|
vClass.SetStr(wcsClass);
|
|
vDriver.SetStr(wcsDriver);
|
|
vLow.SetLONG(lLowDateTime);
|
|
vHigh.SetLONG(lHighDateTime);
|
|
|
|
hr = pInst->Put(L"Driver", 0, &vDriver, NULL);
|
|
if( hr == WBEM_S_NO_ERROR )
|
|
{
|
|
hr = pInst->Put(L"ClassName", 0, &vClass, NULL);
|
|
|
|
hr = pInst->Put(L"LowDateTime", 0, &vLow, NULL);
|
|
|
|
hr = pInst->Put(L"HighDateTime", 0, &vHigh, NULL);
|
|
if( hr == WBEM_S_NO_ERROR )
|
|
{
|
|
hr = SERVICES_PTR->PutInstance(pInst,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
|
|
}
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pInst);
|
|
if( WBEM_NO_ERROR == hr ){
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CNamespaceManagement::CreateClassAssociationsToDriver(WCHAR * wcsFileName, BYTE* pRes, ULONG lLowDateTime, ULONG lHighDateTime)
|
|
{
|
|
|
|
CBMOFObjList * pol;
|
|
CBMOFObj * po;
|
|
CAnsiUnicode XLate;
|
|
|
|
//===========================================================================
|
|
// Now use the helper functions from David's mofcomp stuff to extract the
|
|
// class names we are going to add the Driver qualifier to.
|
|
// list structure and use it to enumerate the objects.
|
|
//===========================================================================
|
|
BYTE * pByte = m_pObj->DecompressBinaryMof(pRes);
|
|
if( pByte ){
|
|
pol = CreateObjList(pByte);
|
|
if(pol != NULL){
|
|
ResetObjList (pol);
|
|
while(po = NextObj(pol)){
|
|
WCHAR * pName = NULL;
|
|
if(GetName(po, &pName)){
|
|
//===============================================================
|
|
// Now, we have the name of the class in pName, we have the
|
|
// name of the driver, in wcsFileName
|
|
//===============================================================
|
|
CreateInstance(wcsFileName, pName, lLowDateTime, lHighDateTime );
|
|
BMOFFree(pName);
|
|
}
|
|
BMOFFree(po);
|
|
}
|
|
BMOFFree(pol);
|
|
}
|
|
}
|
|
else{
|
|
ERRORTRACE((THISPROVIDER,"Could not tie classes to driver for file:\n"));
|
|
TranslateAndLog(wcsFileName);
|
|
}
|
|
if( pByte ){
|
|
free(pByte);
|
|
}
|
|
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CNamespaceManagement::AllocMemory(WCHAR *& p)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
p = new WCHAR[m_nSize+4];
|
|
if( p )
|
|
{
|
|
memset(p,NULL,m_nSize+4);
|
|
hr = WBEM_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CNamespaceManagement::AddToQuery(WCHAR * p)
|
|
{
|
|
int nNewSize = wcslen(p) * sizeof(WCHAR);
|
|
int nCurrentBuf = 0;
|
|
if( m_pwcsQuery )
|
|
{
|
|
nCurrentBuf = (int)(wcslen(m_pwcsQuery) + 1) * sizeof(WCHAR);
|
|
}
|
|
|
|
if( nNewSize >= (m_nSize - nCurrentBuf))
|
|
{
|
|
int nOldSize = m_nSize;
|
|
WCHAR * pOld = m_pwcsQuery;
|
|
m_nSize += MEMSIZETOALLOCATE;
|
|
|
|
if( SUCCEEDED(AllocMemory(m_pwcsQuery)))
|
|
{
|
|
memcpy(m_pwcsQuery,pOld,nOldSize);
|
|
}
|
|
SAFE_DELETE_ARRAY(pOld);
|
|
}
|
|
if( wcslen(m_pwcsQuery) == 0 )
|
|
{
|
|
wcscpy(m_pwcsQuery,p);
|
|
}
|
|
else
|
|
{
|
|
wcscat(m_pwcsQuery,p);
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CNamespaceManagement::InitQuery(WCHAR * p)
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pwcsQuery);
|
|
m_nSize = MEMSIZETOALLOCATE;
|
|
m_fInit = TRUE;
|
|
if(SUCCEEDED(AllocMemory(m_pwcsQuery)))
|
|
{
|
|
AddToQuery(p);
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CNamespaceManagement::UpdateQuery( WCHAR * pQueryAddOn, WCHAR * wcsParam )
|
|
{
|
|
CAutoWChar wcsTranslatedKey(MAX_PATH*3);
|
|
if( wcsTranslatedKey.Valid() )
|
|
{
|
|
ConvertStringToCTypeString( wcsTranslatedKey,wcsParam );
|
|
|
|
//=============================================
|
|
// The first time only we DON'T add the query
|
|
// add on string, otherwise, we do
|
|
//=============================================
|
|
if( !m_fInit )
|
|
{
|
|
AddToQuery(pQueryAddOn);
|
|
}
|
|
|
|
AddToQuery(L"\"");
|
|
AddToQuery(wcsTranslatedKey);
|
|
AddToQuery(L"\"");
|
|
|
|
m_fInit = FALSE;
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CNamespaceManagement::SaveCurrentQuery()
|
|
{
|
|
m_nSavedSize = m_nSize;
|
|
m_fSavedInit = m_fInit;
|
|
if( SUCCEEDED(AllocMemory(m_pwcsSavedQuery))){
|
|
memcpy(m_pwcsSavedQuery,m_pwcsQuery,m_nSize);
|
|
}
|
|
SAFE_DELETE_ARRAY(m_pwcsQuery);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CNamespaceManagement::RestoreQuery()
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pwcsQuery);
|
|
m_nSize = m_nSavedSize;
|
|
m_fInit = m_fSavedInit;
|
|
|
|
if( SUCCEEDED(AllocMemory(m_pwcsQuery))){
|
|
memcpy(m_pwcsQuery, m_pwcsSavedQuery,m_nSize);
|
|
}
|
|
|
|
m_fSavedInit = 0;
|
|
m_nSavedSize = 0;
|
|
SAFE_DELETE_ARRAY(m_pwcsSavedQuery);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CNamespaceManagement::UpdateQuery( WCHAR * pQueryAddOn, ULONG lLong )
|
|
{
|
|
CAutoWChar wcsBuf(MAX_PATH);
|
|
|
|
if( wcsBuf.Valid() )
|
|
{
|
|
AddToQuery(pQueryAddOn);
|
|
swprintf(wcsBuf,L"%lu",lLong);
|
|
|
|
AddToQuery(wcsBuf);
|
|
m_fInit = FALSE;
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CNamespaceManagement::DeleteUnusedClassAndDriverInfo(BOOL fDeleteOldClass, WCHAR * wcsPath, WCHAR * wcsClass)
|
|
{
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
|
|
if( fDeleteOldClass )
|
|
{
|
|
CBSTR bstr(wcsClass );
|
|
|
|
hr = SERVICES_PTR->DeleteClass(bstr,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
|
|
if( hr != WBEM_NO_ERROR )
|
|
{
|
|
if( WBEM_E_NOT_FOUND != hr )
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"Tried to delete class but couldn't, return code: %ld for class: \n",hr));
|
|
TranslateAndLog(wcsClass);
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_NO_ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if( WBEM_NO_ERROR == hr )
|
|
{
|
|
// Ok, we may or may have not deleted the class, if it was tied to a different driver, we
|
|
// shouldn't have deleted the class, but we want to delete the controlling instance, as
|
|
// that driver is no longer there.
|
|
hr = SERVICES_PTR->DeleteInstance(wcsPath,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
|
|
if( WBEM_NO_ERROR != hr )
|
|
{
|
|
if( hr != WBEM_E_NOT_FOUND )
|
|
{
|
|
ERRORTRACE((THISPROVIDER,"DeleteUnUnsedClasses Stranded instance: \n"));
|
|
TranslateAndLog(wcsPath);
|
|
ERRORTRACE((THISPROVIDER,"DeleteInstance return value: %ld\n",hr));
|
|
}
|
|
|
|
}
|
|
}
|
|
return hr;
|
|
}
|