759 lines
19 KiB
C++
759 lines
19 KiB
C++
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//This file has the implementation for the WMI Provider for WHQL.
|
||
|
//Uses MFC
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
// WhqlObj.cpp : Implementation of CWhqlObj
|
||
|
#include "stdafx.h"
|
||
|
#include "WhqlProv.h"
|
||
|
#include "WhqlObj.h"
|
||
|
#include "setupapi.h"
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CWhqlObj
|
||
|
|
||
|
//Fn which actually checks the signature when passed an Inf File.
|
||
|
extern BOOL IsInfSigned(LPTSTR FullInfPath , IWbemClassObject *pInstance = NULL);
|
||
|
inline VOID AddSlashes(LPTSTR str);
|
||
|
inline SCODE PutPropertyValue( IWbemClassObject* pInstance , LPCTSTR lpszProperty , LPCTSTR lpszValue );
|
||
|
|
||
|
STDMETHODIMP CWhqlObj::Initialize(LPWSTR pszUser, LONG lFlags,
|
||
|
LPWSTR pszNamespace, LPWSTR pszLocale,
|
||
|
IWbemServices *pNamespace,
|
||
|
IWbemContext *pCtx,
|
||
|
IWbemProviderInitSink *pInitSink)
|
||
|
{
|
||
|
if (pNamespace)
|
||
|
pNamespace->AddRef();
|
||
|
|
||
|
//Standard Var Inits.
|
||
|
m_pNamespace = pNamespace;
|
||
|
m_csPathStr.Empty();
|
||
|
m_csAntecedent.Empty();
|
||
|
|
||
|
//Let CIMOM know you are initialized
|
||
|
pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
|
||
|
|
||
|
DEBUGTRACE(L"Provider Initialized\n");
|
||
|
return WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
SCODE CWhqlObj::CreateInstanceEnumAsync(BSTR RefStr, long lFlags, IWbemContext *pCtx,
|
||
|
IWbemObjectSink *pHandler)
|
||
|
{
|
||
|
DEBUGTRACE(L"Provider called for class = %s\n",RefStr);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
IWbemClassObject *pClass = NULL;
|
||
|
IWbemClassObject **ppInstances = NULL;
|
||
|
VOID **ppData = NULL;
|
||
|
LONG cInstances, lIndex;
|
||
|
|
||
|
cInstances = lIndex = 0L;
|
||
|
m_ptrArr.RemoveAll();
|
||
|
m_csPathStr.Empty();
|
||
|
m_csAntecedent.Empty();
|
||
|
|
||
|
|
||
|
// Do a check of arguments and make sure we have pointer to Namespace
|
||
|
if(pHandler == NULL || m_pNamespace == NULL)
|
||
|
return WBEM_E_INVALID_PARAMETER;
|
||
|
|
||
|
// Get a class object from CIMOM
|
||
|
hr = m_pNamespace->GetObject(RefStr, 0, pCtx, &pClass, NULL);
|
||
|
if ( FAILED(hr) )
|
||
|
return WBEM_E_FAILED;
|
||
|
|
||
|
m_pClass = pClass;
|
||
|
|
||
|
VARIANT var;
|
||
|
VariantInit(&var);
|
||
|
Classes_Provided eClasses;
|
||
|
|
||
|
|
||
|
if(lstrcmpi(RefStr , L"Win32_PnPSignedDriver") == 0)
|
||
|
{
|
||
|
eClasses = Class_Win32_PnPSignedDriver;
|
||
|
}
|
||
|
else if(lstrcmpi(RefStr , L"Win32_PnPSignedDriverCIMDataFile") == 0)
|
||
|
{
|
||
|
eClasses = Class_Win32_PnPSignedDriverCIMDataFile;
|
||
|
}
|
||
|
else if(lstrcmpi(RefStr , L"Win32_PnPSignedDriverWin32PnPEntity") == 0)
|
||
|
{
|
||
|
eClasses = Class_Win32_PnPSignedDriverWin32PnPEntity;
|
||
|
}
|
||
|
|
||
|
hr = PutData( pCtx , eClasses);
|
||
|
if ( FAILED(hr) )
|
||
|
return WBEM_E_FAILED;
|
||
|
|
||
|
VariantClear(&var);
|
||
|
hr = pClass->Release();
|
||
|
|
||
|
cInstances = (LONG)m_ptrArr.GetSize();
|
||
|
ppInstances = (IWbemClassObject**)new LPVOID[cInstances];
|
||
|
|
||
|
for(int nIndex = 0 ;nIndex<cInstances ;nIndex++)
|
||
|
ppInstances[nIndex] = (IWbemClassObject*)m_ptrArr[nIndex];
|
||
|
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Send the instances to the caller
|
||
|
hr = pHandler->Indicate(cInstances, ppInstances);
|
||
|
|
||
|
for (lIndex = 0; lIndex < cInstances; lIndex++)
|
||
|
ppInstances[lIndex]->Release();
|
||
|
}
|
||
|
|
||
|
// Cleanup
|
||
|
if (ppInstances)
|
||
|
{
|
||
|
delete []ppInstances;
|
||
|
ppInstances = NULL;
|
||
|
}
|
||
|
m_ptrArr.RemoveAll();
|
||
|
m_csPathStr.Empty();
|
||
|
m_csAntecedent.Empty();
|
||
|
m_csCurPnPID.Empty();
|
||
|
|
||
|
m_pClass = NULL;
|
||
|
// End Cleanup
|
||
|
|
||
|
// Set status
|
||
|
hr = pHandler->SetStatus(0, hr, NULL, NULL);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////
|
||
|
//Obsolete! For testing purposes only
|
||
|
//
|
||
|
int CWhqlObj::GetInfFileCount()
|
||
|
{
|
||
|
TCHAR lpszInfPath[MAX_PATH];
|
||
|
int iInstances = 0;
|
||
|
|
||
|
GetWindowsDirectory(lpszInfPath , sizeof(lpszInfPath));
|
||
|
lstrcat(lpszInfPath , L"\\inf\\*.inf");
|
||
|
|
||
|
WIN32_FIND_DATA findData;
|
||
|
HANDLE hFile = FindFirstFile(lpszInfPath , &findData);
|
||
|
BOOL bRet = TRUE;
|
||
|
|
||
|
while(hFile != INVALID_HANDLE_VALUE && bRet)
|
||
|
{
|
||
|
iInstances++;
|
||
|
bRet = FindNextFile(hFile , &findData);
|
||
|
}
|
||
|
|
||
|
return iInstances;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////
|
||
|
//Fills up pInstance fields passed an Inf file.
|
||
|
//
|
||
|
SCODE CWhqlObj::GetInfData(LPTSTR lpszInfFile , LPTSTR lpszInfSection , LPTSTR szDeviceID , IWbemContext *pCtx ,
|
||
|
IWbemClassObject *pInstance)
|
||
|
{
|
||
|
TCHAR lpReturnedString[2048];
|
||
|
TCHAR lpSectionList[2048];
|
||
|
CStringArray csarrCopyFileSection;
|
||
|
CStringArray csarrCopyFileBinaries;
|
||
|
HRESULT hr = S_FALSE;
|
||
|
HINF InfHandle = SetupOpenInfFile(lpszInfFile, NULL,INF_STYLE_WIN4,NULL);
|
||
|
INFCONTEXT Context;
|
||
|
BOOL bRet ;
|
||
|
|
||
|
if(INVALID_HANDLE_VALUE == InfHandle)
|
||
|
return S_FALSE;
|
||
|
|
||
|
VARIANT v;
|
||
|
VariantInit(&v);
|
||
|
|
||
|
//Find CopyFiles section.
|
||
|
LPTSTR lpSection = NULL;
|
||
|
|
||
|
bRet = SetupFindFirstLine(InfHandle,lpszInfSection,L"CopyFiles",&Context);
|
||
|
if(!bRet)
|
||
|
{
|
||
|
SetupCloseInfFile( InfHandle );
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
bRet = SetupGetLineText(&Context,InfHandle,NULL,NULL,lpReturnedString,
|
||
|
sizeof(lpReturnedString),NULL);
|
||
|
if(!bRet)
|
||
|
{
|
||
|
SetupCloseInfFile( InfHandle );
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
DEBUGTRACE(L"CopyFiles string for file %s is %s\n",lpszInfFile,lpReturnedString);
|
||
|
|
||
|
LPTSTR seps = L",";
|
||
|
LPTSTR token ;
|
||
|
|
||
|
token = wcstok( lpReturnedString, seps );
|
||
|
csarrCopyFileSection.Add(token);//Add token to csarrCopyFileSection
|
||
|
while (token)
|
||
|
{
|
||
|
lpSection = token;
|
||
|
token = wcstok( NULL, seps );
|
||
|
|
||
|
if(token)
|
||
|
csarrCopyFileSection.Add(token);//Add token to csarrCopyFileSection
|
||
|
}
|
||
|
|
||
|
for(int nIndex = 0;nIndex < csarrCopyFileSection.GetSize() ; nIndex++)
|
||
|
{
|
||
|
//Sometimes CopyFile Might have an entry like @mydriver.sys. Take care of that.
|
||
|
if((csarrCopyFileSection[nIndex])[0] == '@')
|
||
|
{
|
||
|
csarrCopyFileBinaries.Add(LPCTSTR(csarrCopyFileSection[nIndex]) + 1);
|
||
|
DEBUGTRACE(L"Adding binary file %s\n" , LPCTSTR(csarrCopyFileSection[nIndex]) + 1);
|
||
|
continue;
|
||
|
}
|
||
|
bRet = SetupFindFirstLine(InfHandle,csarrCopyFileSection[nIndex],NULL,&Context);
|
||
|
|
||
|
//Put all the files mentioned in the CopyFiles section in an array.
|
||
|
LPTSTR token = NULL;
|
||
|
while(bRet)
|
||
|
{
|
||
|
bRet = SetupGetLineText(&Context,InfHandle,NULL,NULL,lpSectionList,
|
||
|
sizeof(lpSectionList),NULL);
|
||
|
|
||
|
token = wcstok(lpSectionList , L",");
|
||
|
if(token != NULL)
|
||
|
lstrcpy(lpSectionList ,token);
|
||
|
|
||
|
DEBUGTRACE(L"Adding binary file %s\n" , lpSectionList);
|
||
|
csarrCopyFileBinaries.Add(lpSectionList);
|
||
|
bRet = SetupFindNextLine(&Context,&Context);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CString csTemp;
|
||
|
|
||
|
TCHAR str[MAX_PATH] ;
|
||
|
for(nIndex = 0 ; nIndex < csarrCopyFileBinaries.GetSize() ; nIndex++)
|
||
|
{
|
||
|
hr = m_pClass->SpawnInstance(0, &pInstance);
|
||
|
m_ptrArr.Add(pInstance);
|
||
|
|
||
|
if(GetSystemDirectory(str , sizeof(str)) == 0)
|
||
|
return S_FALSE;
|
||
|
|
||
|
lstrcat(str , L"\\Drivers\\");
|
||
|
|
||
|
AddSlashes(str);
|
||
|
|
||
|
csarrCopyFileBinaries[nIndex] = str + csarrCopyFileBinaries[nIndex];
|
||
|
|
||
|
csTemp = m_csPathStr ;
|
||
|
csTemp += L":CIM_DataFile.Name=\"";
|
||
|
csTemp += csarrCopyFileBinaries[nIndex] + L"\"";
|
||
|
|
||
|
PutPropertyValue( pInstance , L"Antecedent" , m_csAntecedent );
|
||
|
|
||
|
PutPropertyValue( pInstance , L"Dependent" , csTemp );
|
||
|
|
||
|
//////////////////BugBug !
|
||
|
|
||
|
PutPropertyValue( pInstance , L"PnPID" , m_csCurPnPID );
|
||
|
|
||
|
}
|
||
|
|
||
|
if( InfHandle != INVALID_HANDLE_VALUE )
|
||
|
SetupCloseInfFile( InfHandle );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
//Creates Instances & populates data given the class type asked for
|
||
|
//Classes_Provided eClasses
|
||
|
//
|
||
|
SCODE CWhqlObj::PutData(IWbemContext *pCtx , Classes_Provided eClasses)
|
||
|
{
|
||
|
if(pCtx == NULL)
|
||
|
return S_FALSE;
|
||
|
|
||
|
if( eClasses == Class_Win32_PnPSignedDriverWin32PnPEntity)
|
||
|
{
|
||
|
return CreateAssoc( pCtx );
|
||
|
}
|
||
|
|
||
|
LPCTSTR szRegKey = L"SYSTEM\\CurrentControlSet\\Control\\Class";
|
||
|
HKEY hKey , hSubKey ;
|
||
|
TCHAR szName[MAX_PATH] ;
|
||
|
TCHAR szDeviceID[MAX_PATH] , szClassGuid[MAX_PATH] , szDeviceDesc[MAX_PATH];
|
||
|
LONG nInstanceIndex;
|
||
|
LONG len = sizeof(szName);
|
||
|
HRESULT hr = S_FALSE;
|
||
|
ULONG lRet = 0L;
|
||
|
LONG lIndex = 0L;
|
||
|
|
||
|
IEnumWbemClassObject *pEnum = NULL;
|
||
|
IWbemClassObject *pInstance = NULL;
|
||
|
IWbemClassObject *pObject = NULL;
|
||
|
|
||
|
if(ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE , szRegKey , &hKey))
|
||
|
return S_FALSE;//goto cleanup;
|
||
|
|
||
|
//Get DeviceID , ClassGuid , Description , __NameSpace , __Server from Win32_PnpEntity class
|
||
|
//We need all these fields for further Proc.This call will create an Enum.
|
||
|
|
||
|
BSTR language = SysAllocString(L"WQL");
|
||
|
BSTR query = SysAllocString(L"select DeviceID , ClassGuid , Description , __NameSpace , __Server from Win32_PnpEntity");
|
||
|
|
||
|
hr = m_pNamespace->ExecQuery(language , query ,
|
||
|
WBEM_FLAG_RETURN_IMMEDIATELY|WBEM_FLAG_FORWARD_ONLY, pCtx , &pEnum);
|
||
|
|
||
|
SysFreeString(language);
|
||
|
SysFreeString(query);
|
||
|
|
||
|
if(pEnum == NULL)
|
||
|
return S_FALSE;
|
||
|
|
||
|
VARIANT v;
|
||
|
VariantInit(&v);
|
||
|
m_csAntecedent.Empty();
|
||
|
m_csCurPnPID.Empty();
|
||
|
|
||
|
//Iterate thro' the Enum for each DeviceID.
|
||
|
for(lIndex = 0L ; (WBEM_S_NO_ERROR == pEnum->Next(WBEM_INFINITE , 1 , &pObject , &lRet )) ; )
|
||
|
{
|
||
|
//Fill m_csPathStr.Its value will be used in Antecedent & Dependent in assoc. class.
|
||
|
//At the end of the condition we should have something like
|
||
|
//m_csPathStr = "\\\\A-KJAW-RI1\\root\\CIMV2"
|
||
|
if(m_csPathStr.IsEmpty())
|
||
|
{
|
||
|
hr = pObject->Get(L"__Server", 0, &v, NULL , NULL);
|
||
|
if( SUCCEEDED(hr) )
|
||
|
{
|
||
|
m_csPathStr += L"\\\\";
|
||
|
m_csPathStr += V_BSTR(&v);
|
||
|
hr = pObject->Get(L"__NameSpace", 0, &v, NULL , NULL);
|
||
|
if( SUCCEEDED(hr) )
|
||
|
{
|
||
|
m_csPathStr += L"\\";
|
||
|
m_csPathStr += V_BSTR(&v);
|
||
|
}
|
||
|
DEBUGTRACE(L"Server & Namespace Path = %s\n" , m_csPathStr);
|
||
|
VariantClear(&v);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Get DeviceID from the pObject in the Enum.
|
||
|
hr = pObject->Get(L"DeviceID", 0, &v, NULL , NULL);
|
||
|
if( SUCCEEDED(hr) )
|
||
|
{
|
||
|
if(eClasses == Class_Win32_PnPSignedDriverCIMDataFile)
|
||
|
{
|
||
|
lstrcpy(szDeviceID , V_BSTR(&v));
|
||
|
|
||
|
m_csCurPnPID = szDeviceID;
|
||
|
AddSlashes(szDeviceID);
|
||
|
|
||
|
CString csTemp = m_csPathStr ;
|
||
|
csTemp += L":Win32_PnPSignedDriver.PnPId=\"";
|
||
|
csTemp += szDeviceID;
|
||
|
csTemp += L"\"";
|
||
|
|
||
|
m_csAntecedent = csTemp;//This will be used in assoc. class.
|
||
|
}
|
||
|
|
||
|
lstrcpy(szDeviceID , V_BSTR(&v));
|
||
|
DEBUGTRACE(L"PnPID = %s\n" , szDeviceID);
|
||
|
VariantClear(&v);
|
||
|
}
|
||
|
|
||
|
//Get ClassGuid from the pObject in the Enum.
|
||
|
hr = pObject->Get(L"ClassGuid", 0, &v, NULL , NULL);
|
||
|
if( SUCCEEDED(hr) )
|
||
|
{
|
||
|
lstrcpy(szClassGuid , V_BSTR(&v));
|
||
|
DEBUGTRACE(L"ClassGuid = %s\n" , szClassGuid);
|
||
|
TRACE(V_BSTR(&v));
|
||
|
}
|
||
|
|
||
|
//Get Description from the pObject in the Enum.
|
||
|
hr = pObject->Get(L"Description", 0, &v, NULL , NULL);
|
||
|
if( SUCCEEDED(hr) )
|
||
|
{
|
||
|
lstrcpy(szDeviceDesc , V_BSTR(&v));
|
||
|
DEBUGTRACE(L"DriverDesc = %s\n" , szDeviceDesc);
|
||
|
TRACE(V_BSTR(&v));
|
||
|
}
|
||
|
|
||
|
if(ERROR_SUCCESS == RegOpenKey(hKey, szClassGuid, &hSubKey) )
|
||
|
{
|
||
|
//BugBug:
|
||
|
//Get no. of subKeys for the GUID.
|
||
|
//If there are no subKeys (i presume) this means no Instances of the device
|
||
|
//represented by the GUID are present so we need not Instantiate an Instance Of win32_PnPSignedDriver.
|
||
|
RegQueryInfoKey(hSubKey , NULL , NULL , NULL , &lRet , NULL , NULL , NULL , NULL
|
||
|
, NULL , NULL , NULL);
|
||
|
|
||
|
if(eClasses == Class_Win32_PnPSignedDriver && lRet > 0)
|
||
|
{
|
||
|
hr = m_pClass->SpawnInstance(0, &pInstance);
|
||
|
if(FAILED(hr))
|
||
|
continue;
|
||
|
|
||
|
m_ptrArr.Add(pInstance);
|
||
|
|
||
|
PutPropertyValue( pInstance , L"PnPID" , szDeviceID );
|
||
|
|
||
|
PutPropertyValue( pInstance , L"ClassGuid" , szClassGuid );
|
||
|
|
||
|
//PutPropertyValue( pInstance , L"DriverDesc" , szDeviceDesc );
|
||
|
PutPropertyValue( pInstance , L"Description" , szDeviceDesc );
|
||
|
|
||
|
|
||
|
szName[0] = '\0';
|
||
|
hr = GetService(szDeviceID , szName , (ULONG*)&len);
|
||
|
CStringArray hwidArr;
|
||
|
LPTSTR szHwid = szName;
|
||
|
|
||
|
hwidArr.RemoveAll();
|
||
|
|
||
|
while(len > 0 && *szHwid != '\0')
|
||
|
{
|
||
|
hwidArr.Add(szHwid);
|
||
|
szHwid += lstrlen(szHwid) + 1;
|
||
|
}
|
||
|
|
||
|
if( hwidArr.GetSize() )
|
||
|
{
|
||
|
LPSAFEARRAY psa;
|
||
|
LONG lArrSize = (LONG)hwidArr.GetSize();
|
||
|
SAFEARRAYBOUND rgsabound[] = { lArrSize , 0 };
|
||
|
|
||
|
psa = SafeArrayCreate(VT_BSTR, 1, rgsabound);
|
||
|
if (!psa)
|
||
|
{
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
long dim[1];
|
||
|
BSTR bstr = NULL;
|
||
|
|
||
|
for(int nIdx = 0 ; nIdx < lArrSize ; nIdx++)
|
||
|
{
|
||
|
bstr = hwidArr[nIdx].AllocSysString();
|
||
|
dim[0] = nIdx;
|
||
|
hr = SafeArrayPutElement(psa, dim , bstr);
|
||
|
}
|
||
|
|
||
|
v.vt = VT_ARRAY|VT_BSTR;
|
||
|
v.parray = psa;
|
||
|
hr = pInstance->Put(L"HardwareID", 0, &v, 0 );
|
||
|
VariantClear(&v);
|
||
|
|
||
|
hr = SafeArrayDestroyData(psa);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
nInstanceIndex = 0;
|
||
|
EnumRegKeys(hSubKey , pInstance , szDeviceDesc , szDeviceID , pCtx , eClasses);
|
||
|
RegCloseKey(hSubKey);
|
||
|
|
||
|
if(eClasses == Class_Win32_PnPSignedDriver)
|
||
|
{
|
||
|
PutPropertyValue( pInstance , L"Service" , szName );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
hr = pObject->Release();
|
||
|
}
|
||
|
|
||
|
//cleanup:
|
||
|
RegCloseKey(hKey);
|
||
|
if(pEnum)
|
||
|
pEnum->Release();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////
|
||
|
//Will return the Service the device supports.
|
||
|
//
|
||
|
SCODE CWhqlObj::GetService(IN LPTSTR szDeviceID , OUT LPTSTR szName , IN ULONG* plen )
|
||
|
{
|
||
|
HKEY hSubKey , hInstanceKey;
|
||
|
DWORD dwType = REG_SZ ;
|
||
|
|
||
|
if(ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE , L"SYSTEM\\CurrentControlSet\\Enum", &hSubKey))
|
||
|
return S_FALSE;
|
||
|
|
||
|
if(ERROR_SUCCESS != RegOpenKey(hSubKey , szDeviceID, &hInstanceKey))
|
||
|
{
|
||
|
RegCloseKey(hSubKey);
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
//RegQueryValueEx(hInstanceKey , L"Service", NULL , &dwType
|
||
|
// , (UCHAR*)szName , (ULONG*)&len );
|
||
|
|
||
|
|
||
|
//Return HardwareID from this func. not service.
|
||
|
|
||
|
dwType = REG_MULTI_SZ;
|
||
|
LONG lRet = RegQueryValueEx(hInstanceKey , L"HardwareID", NULL , &dwType
|
||
|
, (UCHAR*)szName , (ULONG*)plen);
|
||
|
|
||
|
RegCloseKey(hSubKey);
|
||
|
RegCloseKey(hInstanceKey);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////
|
||
|
//Enumerates reg key & fills up pInstance fields.
|
||
|
//
|
||
|
SCODE CWhqlObj::EnumRegKeys(HKEY hSubKey , IWbemClassObject* pInstance , LPTSTR szDeviceDesc , LPTSTR szDeviceID ,
|
||
|
IWbemContext *pCtx , Classes_Provided eClasses)
|
||
|
{
|
||
|
LONG nInstanceIndex = 0;
|
||
|
HKEY hInstanceKey;
|
||
|
TCHAR szTempStr[MAX_PATH];
|
||
|
ULONG len = sizeof(szTempStr);
|
||
|
LONG lRet = -1;
|
||
|
DWORD dwType = REG_SZ ;
|
||
|
HRESULT hr = S_FALSE;
|
||
|
BOOL bIsSigned = FALSE;
|
||
|
TCHAR szInfPath[MAX_PATH] , szInfSection[MAX_PATH] , str[MAX_PATH] ;
|
||
|
|
||
|
VARIANT v;
|
||
|
VariantInit(&v);
|
||
|
|
||
|
while(ERROR_SUCCESS == RegEnumKey(hSubKey , nInstanceIndex++, szTempStr , sizeof(szTempStr)) )
|
||
|
{
|
||
|
lRet = RegOpenKey(hSubKey, szTempStr, &hInstanceKey);
|
||
|
if(lRet != ERROR_SUCCESS)
|
||
|
continue;
|
||
|
|
||
|
//Get DriverDesc
|
||
|
len = MAX_PATH;
|
||
|
lRet = RegQueryValueEx(hInstanceKey , L"DriverDesc", NULL , &dwType
|
||
|
, (UCHAR*)szTempStr, &len );
|
||
|
|
||
|
if(lRet != ERROR_SUCCESS)
|
||
|
continue;
|
||
|
|
||
|
if(lstrcmpi(szTempStr , szDeviceDesc) != 0)
|
||
|
{
|
||
|
RegCloseKey(hInstanceKey);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if(eClasses == Class_Win32_PnPSignedDriver)
|
||
|
{
|
||
|
|
||
|
|
||
|
DEBUGTRACE(L"DriverDesc= %s\n" , szTempStr);
|
||
|
|
||
|
//Put DriverDesc
|
||
|
|
||
|
PutPropertyValue( pInstance , L"DriverDesc" , szTempStr );
|
||
|
|
||
|
//Get DriverDate
|
||
|
len = MAX_PATH;
|
||
|
lRet = RegQueryValueEx(hInstanceKey,L"DriverDate", NULL , &dwType , (UCHAR*)szTempStr,(ULONG*)&len );
|
||
|
//if(lRet != ERROR_SUCCESS)
|
||
|
// continue;
|
||
|
DEBUGTRACE(L"DriverDate = %s\n" , szTempStr);
|
||
|
|
||
|
//Put DriverDesc
|
||
|
|
||
|
PutPropertyValue( pInstance , L"DriverDate" , szTempStr );
|
||
|
|
||
|
//Get DriverVersion
|
||
|
len = MAX_PATH;
|
||
|
lRet = RegQueryValueEx(hInstanceKey,L"DriverVersion", NULL , &dwType ,
|
||
|
(UCHAR*)szTempStr,(ULONG*)&len );
|
||
|
//if(lRet != ERROR_SUCCESS)
|
||
|
// continue;
|
||
|
DEBUGTRACE(L"DriverVersion= %s\n" , szTempStr);
|
||
|
|
||
|
//Put DriverVersion
|
||
|
|
||
|
PutPropertyValue( pInstance , L"DriverVersion" , szTempStr );
|
||
|
|
||
|
//Get ProviderName
|
||
|
len = MAX_PATH;
|
||
|
lRet = RegQueryValueEx(hInstanceKey,L"ProviderName", NULL , &dwType ,
|
||
|
(UCHAR*)szTempStr,(ULONG*)&len );
|
||
|
//if(lRet != ERROR_SUCCESS)
|
||
|
// continue;
|
||
|
DEBUGTRACE(L"ProviderName= %s\n" , szTempStr);
|
||
|
|
||
|
//Put ProviderName
|
||
|
|
||
|
PutPropertyValue( pInstance , L"ProviderName" , szTempStr );
|
||
|
}
|
||
|
|
||
|
//Get InfPath
|
||
|
szInfPath[0] = '\0';
|
||
|
len = MAX_PATH;
|
||
|
lRet = RegQueryValueEx(hInstanceKey,L"InfPath", NULL , &dwType , (UCHAR*)szInfPath,(ULONG*)&len );
|
||
|
//if(lRet != ERROR_SUCCESS)
|
||
|
// continue;
|
||
|
DEBUGTRACE(L"InfPath = %s\n" , szInfPath);
|
||
|
|
||
|
//Put InfPath
|
||
|
if(eClasses == Class_Win32_PnPSignedDriver)
|
||
|
{
|
||
|
PutPropertyValue( pInstance , L"InfPath" , szInfPath );
|
||
|
}
|
||
|
|
||
|
//Get Infsection
|
||
|
szInfSection[0] = '\0';
|
||
|
len = MAX_PATH;
|
||
|
lRet = RegQueryValueEx(hInstanceKey,L"InfSection", NULL , &dwType , (UCHAR*)szInfSection,(ULONG*)&len );
|
||
|
//if(lRet != ERROR_SUCCESS)
|
||
|
// continue;
|
||
|
DEBUGTRACE(L"InfSection = %s\n" , szInfSection);
|
||
|
|
||
|
//Get InfsectionExt
|
||
|
szTempStr[0] = '\0';
|
||
|
len = MAX_PATH;
|
||
|
lRet = RegQueryValueEx(hInstanceKey,L"InfSectionExt", NULL , &dwType , (UCHAR*)szTempStr,(ULONG*)&len );
|
||
|
//if(lRet != ERROR_SUCCESS)
|
||
|
// continue;
|
||
|
DEBUGTRACE(L"InfSectionExt = %s\n" , szTempStr);
|
||
|
|
||
|
lstrcat(szInfSection , szTempStr);
|
||
|
|
||
|
//Only if Class_Win32_PnPSignedDriverCIMDataFile call GetInfData to fill up all the
|
||
|
//Win32_PnPSignedDriverCIMDataFile class data.
|
||
|
if(eClasses == Class_Win32_PnPSignedDriverCIMDataFile)
|
||
|
{
|
||
|
GetInfData(szInfPath , szInfSection , szDeviceID , pCtx , pInstance);
|
||
|
}
|
||
|
|
||
|
RegCloseKey(hInstanceKey);
|
||
|
|
||
|
if(eClasses == Class_Win32_PnPSignedDriver)
|
||
|
{
|
||
|
if(GetWindowsDirectory(str , sizeof(str)) == 0)
|
||
|
return S_FALSE;
|
||
|
|
||
|
lstrcat(str , L"\\inf\\" );
|
||
|
lstrcat(str , szInfPath);
|
||
|
IsInfSigned( str , pInstance);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
SCODE CWhqlObj::CreateAssoc( IWbemContext *pCtx )
|
||
|
{
|
||
|
IEnumWbemClassObject *pEnum = NULL;
|
||
|
IWbemClassObject *pInstance = NULL;
|
||
|
IWbemClassObject *pObject = NULL;
|
||
|
|
||
|
CComBSTR language = L"WQL";
|
||
|
CComBSTR query = L"select DeviceID , ClassGuid , __NameSpace , __Server from Win32_PnpEntity";
|
||
|
CComBSTR tmpBstr = NULL;
|
||
|
CComVariant v;
|
||
|
ULONG ulRet = 0;
|
||
|
|
||
|
HRESULT hr = m_pNamespace->ExecQuery(language , query ,
|
||
|
WBEM_FLAG_RETURN_IMMEDIATELY|WBEM_FLAG_FORWARD_ONLY, pCtx , &pEnum);
|
||
|
|
||
|
if(pEnum == NULL)
|
||
|
return hr;
|
||
|
|
||
|
for( ; (WBEM_S_NO_ERROR == pEnum->Next(WBEM_INFINITE , 1 , &pObject , &ulRet )) ; )
|
||
|
{
|
||
|
//Fill m_csPathStr.Its value will be used in Antecedent & Dependent in assoc. class.
|
||
|
//At the end of the condition we should have something like
|
||
|
//m_csPathStr = "\\\\A-KJAW-RI1\\root\\CIMV2"
|
||
|
if(m_csPathStr.IsEmpty())
|
||
|
{
|
||
|
hr = pObject->Get(L"__Server", 0, &v, NULL , NULL);
|
||
|
if( SUCCEEDED(hr) )
|
||
|
{
|
||
|
m_csPathStr += L"\\\\";
|
||
|
m_csPathStr += V_BSTR(&v);
|
||
|
hr = pObject->Get(L"__NameSpace", 0, &v, NULL , NULL);
|
||
|
if( SUCCEEDED(hr) )
|
||
|
{
|
||
|
m_csPathStr += L"\\";
|
||
|
m_csPathStr += V_BSTR(&v);
|
||
|
}
|
||
|
DEBUGTRACE(L"Server & Namespace Path = %s\n" , m_csPathStr);
|
||
|
VariantClear(&v);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hr = m_pClass->SpawnInstance(0, &pInstance);
|
||
|
|
||
|
hr = pObject->Get(L"__PATH", 0, &v, NULL , NULL);
|
||
|
hr = pInstance->Put(L"Dependent", 0, &v, 0 );
|
||
|
|
||
|
v.Clear();
|
||
|
|
||
|
hr = pObject->Get(L"DeviceID", 0, &v, NULL , NULL);
|
||
|
tmpBstr = m_csPathStr + "\\Win32_PnPSignedDriver.PnPID=\"";
|
||
|
tmpBstr += v.bstrVal;
|
||
|
tmpBstr += "\"";
|
||
|
|
||
|
PutPropertyValue( pInstance , L"Antecedent" , tmpBstr );
|
||
|
|
||
|
m_ptrArr.Add(pInstance);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
VOID AddSlashes(LPTSTR str)
|
||
|
{
|
||
|
LONG len = lstrlen(str);
|
||
|
TCHAR szTmp[MAX_PATH];
|
||
|
int nIndex1,nIndex2;
|
||
|
for(nIndex1 = nIndex2= 0 ; nIndex1 < len ; nIndex1++ , nIndex2++)
|
||
|
{
|
||
|
if(str[nIndex1] == '\\')
|
||
|
szTmp[nIndex2++] = '\\';
|
||
|
szTmp[nIndex2] = str[nIndex1];
|
||
|
}
|
||
|
szTmp[nIndex2] = '\0';
|
||
|
lstrcpy(str , szTmp);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID DEBUGTRACE(LPTSTR pszText , ... )
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
TCHAR szDebugStr[256];
|
||
|
|
||
|
va_list argList;
|
||
|
va_start(argList, pszText);
|
||
|
vswprintf(szDebugStr , pszText, argList);
|
||
|
va_end(argList);
|
||
|
|
||
|
OutputDebugString(szDebugStr);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
SCODE PutPropertyValue( IWbemClassObject* pInstance , LPCTSTR lpszProperty , LPCTSTR lpszValue )
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
if(pInstance == NULL)
|
||
|
return hr;
|
||
|
|
||
|
CComVariant var;
|
||
|
var = lpszValue;
|
||
|
|
||
|
hr = pInstance->Put(lpszProperty , 0, &var, 0 );
|
||
|
return hr;
|
||
|
}
|