3898 lines
80 KiB
C++
3898 lines
80 KiB
C++
|
//***************************************************************************
|
||
|
//
|
||
|
// TestInfo.CPP
|
||
|
//
|
||
|
// Module: CDM Provider
|
||
|
//
|
||
|
// Purpose: Defines the CClassPro class. An object of this class is
|
||
|
// created by the class factory for each connection.
|
||
|
//
|
||
|
// Copyright (c) 2000 Microsoft Corporation
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
// @@BEGIN_DDKSPLIT
|
||
|
//
|
||
|
// What is left to do:
|
||
|
//
|
||
|
// Finish reboot diagnostics - This involves persisting the pending
|
||
|
// result in the schema and then trying to query for the actual
|
||
|
// results later
|
||
|
//
|
||
|
// Keep more than 1 historical result instance. This involves
|
||
|
// persisting the historical results in the schema and picking them
|
||
|
// up from there
|
||
|
// @@END_DDKSPLIT
|
||
|
|
||
|
|
||
|
#include <objbase.h>
|
||
|
|
||
|
#ifndef _MT
|
||
|
#define _MT
|
||
|
#endif
|
||
|
|
||
|
#include <wbemidl.h>
|
||
|
|
||
|
#include "debug.h"
|
||
|
#include "testinfo.h"
|
||
|
#include "wbemmisc.h"
|
||
|
#include "cimmap.h"
|
||
|
#include "reload.h"
|
||
|
|
||
|
IWbemServices *pCimServices;
|
||
|
IWbemServices *pWdmServices;
|
||
|
|
||
|
HRESULT TestInfoInitialize(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will establishes a connection to the root\wmi and
|
||
|
root\cimv2 namespaces in global memory
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
WmipAssert(pCimServices == NULL);
|
||
|
WmipAssert(pWdmServices == NULL);
|
||
|
|
||
|
hr = WmiConnectToWbem(L"root\\cimv2",
|
||
|
&pCimServices);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = WmiConnectToWbem(L"root\\wmi",
|
||
|
&pWdmServices);
|
||
|
|
||
|
if (hr != WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
pCimServices->Release();
|
||
|
pCimServices = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
void TestInfoDeinitialize(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will disestablish a connection to the root\wmi and
|
||
|
root\cimv2 namespaces in global memory
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(pCimServices != NULL);
|
||
|
WmipAssert(pWdmServices != NULL);
|
||
|
|
||
|
pCimServices->Release();
|
||
|
pCimServices = NULL;
|
||
|
|
||
|
pWdmServices->Release();
|
||
|
pWdmServices = NULL;
|
||
|
}
|
||
|
|
||
|
CTestServices::CTestServices()
|
||
|
/*+++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Constructor for CTestServices class
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WdmTestClassName = NULL;
|
||
|
WdmSettingClassName = NULL;
|
||
|
WdmSettingListClassName = NULL;
|
||
|
WdmResultClassName = NULL;
|
||
|
WdmOfflineResultClassName = NULL;
|
||
|
CdmTestClassName = NULL;
|
||
|
CdmTestRelPath = NULL;
|
||
|
CdmResultClassName = NULL;
|
||
|
CdmSettingClassName = NULL;
|
||
|
CdmTestForMSEClassName = NULL;
|
||
|
CdmTestForMSERelPath = NULL;
|
||
|
CdmSettingForTestClassName = NULL;
|
||
|
CdmSettingForTestRelPath = NULL;
|
||
|
CdmResultForMSEClassName = NULL;
|
||
|
CdmResultForTestClassName = NULL;
|
||
|
CdmTestForSoftwareClassName = NULL;
|
||
|
CdmTestForSoftwareRelPath = NULL;
|
||
|
CdmTestInPackageClassName = NULL;
|
||
|
CdmTestInPackageRelPath = NULL;
|
||
|
CdmResultInPackageClassName = NULL;
|
||
|
CdmResultInPackageRelPath = NULL;
|
||
|
CimClassMappingClassName = NULL;
|
||
|
CimRelPaths = NULL;
|
||
|
WdmRelPaths = NULL;
|
||
|
PnPDeviceIdsX = NULL;
|
||
|
WdmInstanceNames = NULL;
|
||
|
CdmSettingsList = NULL;
|
||
|
CdmResultsList = NULL;
|
||
|
Next = NULL;
|
||
|
Prev = NULL;
|
||
|
}
|
||
|
|
||
|
CTestServices::~CTestServices()
|
||
|
/*+++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Destructor for CTestServices class
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if (WdmTestClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(WdmTestClassName);
|
||
|
}
|
||
|
|
||
|
if (WdmSettingClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(WdmSettingClassName);
|
||
|
}
|
||
|
|
||
|
if (WdmResultClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(WdmResultClassName);
|
||
|
}
|
||
|
|
||
|
if (WdmOfflineResultClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(WdmOfflineResultClassName);
|
||
|
}
|
||
|
|
||
|
if (WdmSettingListClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(WdmSettingListClassName);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CdmTestClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestClassName);
|
||
|
}
|
||
|
|
||
|
if (CdmTestRelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestRelPath);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CdmResultClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmResultClassName);
|
||
|
}
|
||
|
|
||
|
if (CdmSettingClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmSettingClassName);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CdmTestForMSEClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestForMSEClassName);
|
||
|
}
|
||
|
|
||
|
FreeTheBSTRArray(CdmTestForMSERelPath, RelPathCount);
|
||
|
|
||
|
if (CdmSettingForTestClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmSettingForTestClassName);
|
||
|
}
|
||
|
|
||
|
if (CdmSettingForTestRelPath != NULL)
|
||
|
{
|
||
|
for (i = 0; i < RelPathCount; i++)
|
||
|
{
|
||
|
delete CdmSettingForTestRelPath[i];
|
||
|
}
|
||
|
WmipFree(CdmSettingForTestRelPath);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CdmResultForMSEClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmResultForMSEClassName);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CdmResultForTestClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmResultForTestClassName);
|
||
|
}
|
||
|
|
||
|
if (CdmTestForSoftwareClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestForSoftwareClassName);
|
||
|
}
|
||
|
|
||
|
if (CdmTestForSoftwareRelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestForSoftwareRelPath);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CdmTestInPackageClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestInPackageClassName);
|
||
|
}
|
||
|
|
||
|
if (CdmTestInPackageRelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestInPackageRelPath);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CdmResultInPackageClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmResultInPackageClassName);
|
||
|
}
|
||
|
|
||
|
if (CdmResultInPackageRelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(CdmResultInPackageRelPath);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (CimClassMappingClassName != NULL)
|
||
|
{
|
||
|
SysFreeString(CimClassMappingClassName);
|
||
|
}
|
||
|
|
||
|
FreeTheBSTRArray(CimRelPaths, RelPathCount);
|
||
|
FreeTheBSTRArray(WdmRelPaths, RelPathCount);
|
||
|
FreeTheBSTRArray(WdmInstanceNames, RelPathCount);
|
||
|
FreeTheBSTRArray(PnPDeviceIdsX, RelPathCount);
|
||
|
|
||
|
if (CdmSettingsList != NULL)
|
||
|
{
|
||
|
for (i = 0; i < RelPathCount; i++)
|
||
|
{
|
||
|
delete CdmSettingsList[i];
|
||
|
}
|
||
|
WmipFree(CdmSettingsList);
|
||
|
}
|
||
|
|
||
|
if (CdmResultsList != NULL)
|
||
|
{
|
||
|
for (i = 0; i < RelPathCount; i++)
|
||
|
{
|
||
|
delete &CdmResultsList[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOLEAN ClassIsCdmBaseClass(
|
||
|
BSTR ClassName,
|
||
|
BOOLEAN *IsTestClass
|
||
|
)
|
||
|
/*+++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine determines if the class name is a CDM base class name
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ClassName is the name of the class
|
||
|
|
||
|
*IsTestClass returns TRUE if the class name is CIM_DiagnosticTest
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if class is a CDM base class else FALSE
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(ClassName != NULL);
|
||
|
WmipAssert(IsTestClass != NULL);
|
||
|
|
||
|
if (_wcsicmp(ClassName, L"CIM_DiagnosticTest") == 0)
|
||
|
{
|
||
|
*IsTestClass = TRUE;
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if ((_wcsicmp(ClassName, L"CIM_DiagnosticResult") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticSetting") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticResultForMSE") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticResultForTest") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticTestForMSE") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticTestSoftware") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticTestInPackage") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticResultInPackage") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticResultForMSE") == 0) ||
|
||
|
(_wcsicmp(ClassName, L"CIM_DiagnosticSettingForTest") == 0))
|
||
|
{
|
||
|
*IsTestClass = FALSE;
|
||
|
return(TRUE);
|
||
|
}
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetCdmClassNamesFromOne(
|
||
|
PWCHAR CdmClass
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine obtains the names of all of the CDM classes from the
|
||
|
name of a single CDM class
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
CdmClass is the name of the CDM class
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
IWbemServices * pCdmServices = GetCdmServices();
|
||
|
VARIANT v, vClass, vSuper;
|
||
|
HRESULT hr, hrDontCare;
|
||
|
BOOLEAN IsTestClass;
|
||
|
BSTR SuperClass;
|
||
|
BSTR CdmTestClass;
|
||
|
|
||
|
//
|
||
|
// First thing is that we need to do is figure out what kind of
|
||
|
// class we have been handed. If it is a CIM_DiagnosticTest derived
|
||
|
// class then we can proceed to obtain all of the other class names
|
||
|
// via qualifiers. If not then we have to link back from the class
|
||
|
// we have to the CIM_DiagnosticTest derived class via the
|
||
|
// CdmDiagTest qualifier.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Get a class object for Cdm class passed and then check the
|
||
|
// __SUPERCLASS property to see which CDM class it is derived from.
|
||
|
//
|
||
|
SuperClass = SysAllocString(CdmClass);
|
||
|
|
||
|
if (SuperClass == NULL)
|
||
|
{
|
||
|
return(WBEM_E_OUT_OF_MEMORY);
|
||
|
}
|
||
|
|
||
|
v.vt = VT_BSTR;
|
||
|
v.bstrVal = SuperClass;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
hr = WmiGetPropertyByName(pCdmServices,
|
||
|
v.bstrVal,
|
||
|
L"__SuperClass",
|
||
|
CIM_STRING,
|
||
|
&vSuper);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
#ifdef VERBOSE_DEBUG
|
||
|
WmipDebugPrint(("CDMPROV: Class %ws has superclass of %ws\n",
|
||
|
SuperClass, vSuper.bstrVal));
|
||
|
#endif
|
||
|
|
||
|
if (_wcsicmp(v.bstrVal, vSuper.bstrVal) == 0)
|
||
|
{
|
||
|
//
|
||
|
// When the superclass is the same as the base
|
||
|
// class then we are at the top of the class tree
|
||
|
// and so this class must not be in the CDM
|
||
|
// heirarchy. In this case the cdm provider cannot
|
||
|
// support it.
|
||
|
//
|
||
|
hr = WBEM_E_NOT_FOUND;
|
||
|
VariantClear(&vSuper);
|
||
|
} else if (ClassIsCdmBaseClass(vSuper.bstrVal, &IsTestClass)) {
|
||
|
//
|
||
|
// We have found a CDM base class
|
||
|
//
|
||
|
if (! IsTestClass)
|
||
|
{
|
||
|
//
|
||
|
// The CDM base class was not the test class so
|
||
|
// lookup the CdmDiagTest qualifier to find it
|
||
|
//
|
||
|
PWCHAR Name = L"CdmDiagTest";
|
||
|
VARTYPE VarType = VT_BSTR;
|
||
|
|
||
|
hr = WmiGetQualifierListByName(pCdmServices,
|
||
|
CdmClass,
|
||
|
NULL,
|
||
|
1,
|
||
|
&Name,
|
||
|
&VarType,
|
||
|
&vClass);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
CdmTestClass = vClass.bstrVal;
|
||
|
#ifdef VERBOSE_DEBUG
|
||
|
WmipDebugPrint(("CDMPROV: Class %ws has a CdmDiagTestClass %ws\n",
|
||
|
CdmClass, CdmTestClass));
|
||
|
#endif
|
||
|
}
|
||
|
} else {
|
||
|
CdmTestClass = SysAllocString(CdmClass);
|
||
|
if (CdmTestClass == NULL)
|
||
|
{
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
#ifdef VERBOSE_DEBUG
|
||
|
WmipDebugPrint(("CDMPROV: Class %ws is already CdmDiagTestClass\n",
|
||
|
CdmClass));
|
||
|
#endif
|
||
|
}
|
||
|
VariantClear(&vSuper);
|
||
|
} else {
|
||
|
//
|
||
|
// This is a more basic class, but is not the CDM base
|
||
|
// class, so we need to continue up the derivation
|
||
|
// chain
|
||
|
//
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VariantClear(&v);
|
||
|
v = vSuper;
|
||
|
|
||
|
} while ((CdmTestClass == NULL) && (hr == WBEM_S_NO_ERROR));
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
PWCHAR Names[11];
|
||
|
VARTYPE VarType[11];
|
||
|
VARIANT Values[11];
|
||
|
|
||
|
//
|
||
|
// Now that we know the CDM Diagnostic test class name we can
|
||
|
// go and discover the rest of the CDM class names via
|
||
|
// the appropriate qualifiers on the Cdm Test class.
|
||
|
//
|
||
|
Names[0] = L"CimClassMapping";
|
||
|
VarType[0] = VT_BSTR;
|
||
|
VariantInit(&Values[0]);
|
||
|
|
||
|
Names[1] = L"CdmDiagResult";
|
||
|
VarType[1] = VT_BSTR;
|
||
|
VariantInit(&Values[1]);
|
||
|
|
||
|
Names[2] = L"CdmDiagSetting";
|
||
|
VarType[2] = VT_BSTR;
|
||
|
VariantInit(&Values[2]);
|
||
|
|
||
|
Names[3] = L"CdmDiagTestForMSE";
|
||
|
VarType[3] = VT_BSTR;
|
||
|
VariantInit(&Values[3]);
|
||
|
|
||
|
Names[4] = L"CdmDiagResultForMSE";
|
||
|
VarType[4] = VT_BSTR;
|
||
|
VariantInit(&Values[4]);
|
||
|
|
||
|
Names[5] = L"CdmDiagResultForTest";
|
||
|
VarType[5] = VT_BSTR;
|
||
|
VariantInit(&Values[5]);
|
||
|
|
||
|
Names[6] = L"CdmDiagTestSoftware";
|
||
|
VarType[6] = VT_BSTR;
|
||
|
VariantInit(&Values[6]);
|
||
|
|
||
|
Names[7] = L"CdmDiagTestInPackage";
|
||
|
VarType[7] = VT_BSTR;
|
||
|
VariantInit(&Values[7]);
|
||
|
|
||
|
Names[8] = L"CdmDiagResultInPackage";
|
||
|
VarType[8] = VT_BSTR;
|
||
|
VariantInit(&Values[8]);
|
||
|
|
||
|
Names[9] = L"CdmDiagSettingForTest";
|
||
|
VarType[9] = VT_BSTR;
|
||
|
VariantInit(&Values[9]);
|
||
|
|
||
|
Names[10] = L"WdmDiagTest";
|
||
|
VarType[10] = VT_BSTR;
|
||
|
VariantInit(&Values[10]);
|
||
|
|
||
|
hr = WmiGetQualifierListByName(pCdmServices,
|
||
|
CdmTestClass,
|
||
|
NULL,
|
||
|
11,
|
||
|
Names,
|
||
|
VarType,
|
||
|
Values);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Remember the class names
|
||
|
//
|
||
|
CimClassMappingClassName = Values[0].bstrVal;
|
||
|
|
||
|
CdmResultClassName = Values[1].bstrVal;
|
||
|
CdmSettingClassName = Values[2].bstrVal;
|
||
|
CdmTestForMSEClassName = Values[3].bstrVal;
|
||
|
CdmResultForMSEClassName = Values[4].bstrVal;
|
||
|
CdmResultForTestClassName = Values[5].bstrVal;
|
||
|
CdmTestForSoftwareClassName = Values[6].bstrVal;
|
||
|
CdmTestInPackageClassName = Values[7].bstrVal;
|
||
|
CdmResultInPackageClassName = Values[8].bstrVal;
|
||
|
CdmSettingForTestClassName = Values[9].bstrVal;
|
||
|
|
||
|
WdmTestClassName = Values[10].bstrVal;
|
||
|
|
||
|
//
|
||
|
// Now that we have got all of the Cdm class names we need
|
||
|
// to get the WdmDiagResult, WdmDiagSetting and
|
||
|
// WdmDiagSettingList classes
|
||
|
//
|
||
|
Names[0] = L"WdmDiagResult";
|
||
|
VariantInit(&Values[0]);
|
||
|
hr = WmiGetQualifierListByName(pCdmServices,
|
||
|
CdmResultClassName,
|
||
|
NULL,
|
||
|
1,
|
||
|
Names,
|
||
|
VarType,
|
||
|
Values);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
WdmResultClassName = Values[0].bstrVal;
|
||
|
|
||
|
|
||
|
//
|
||
|
// See if this is an offline diagnostic class
|
||
|
//
|
||
|
Names[0] = L"WdmDiagOfflineResult";
|
||
|
VariantInit(&Values[0]);
|
||
|
hrDontCare = WmiGetQualifierListByName(pCdmServices,
|
||
|
CdmResultClassName,
|
||
|
NULL,
|
||
|
1,
|
||
|
Names,
|
||
|
VarType,
|
||
|
Values);
|
||
|
if (hrDontCare == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
WdmOfflineResultClassName = Values[0].bstrVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
Names[0] = L"WdmDiagSetting";
|
||
|
VariantInit(&Values[0]);
|
||
|
hr = WmiGetQualifierListByName(pCdmServices,
|
||
|
CdmSettingClassName,
|
||
|
NULL,
|
||
|
1,
|
||
|
Names,
|
||
|
VarType,
|
||
|
Values);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
WdmSettingClassName = Values[0].bstrVal;
|
||
|
|
||
|
Names[0] = L"WdmDiagSettingList";
|
||
|
VariantInit(&Values[0]);
|
||
|
hr = WmiGetQualifierListByName(pCdmServices,
|
||
|
CdmSettingClassName,
|
||
|
NULL,
|
||
|
1,
|
||
|
Names,
|
||
|
VarType,
|
||
|
Values);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Whew, we got all of our class names
|
||
|
// successfully. Setup the CdmTestClassName which
|
||
|
// denotes that we are all setup properly
|
||
|
//
|
||
|
WdmSettingListClassName = Values[0].bstrVal;
|
||
|
|
||
|
CdmTestClassName = CdmTestClass;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::BuildResultRelPaths(
|
||
|
IN int RelPathIndex,
|
||
|
IN BSTR ExecutionId,
|
||
|
OUT BSTR *ResultRelPath,
|
||
|
OUT BSTR *ResultForMSERelPath,
|
||
|
OUT BSTR *ResultForTestRelPath
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will create the string names for the CDM Result
|
||
|
relative paths for a specific index. These are for the classes
|
||
|
|
||
|
CIM_DiagnosticResult
|
||
|
CIM_DiagnosticResultForMSE
|
||
|
CIM_DiagnosticResultForTest
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex is the index into the list of result objects
|
||
|
|
||
|
ExecutionId is the unique id used for the execution
|
||
|
|
||
|
ResultRelPath returns with the result relpath
|
||
|
|
||
|
ResultForMSERelPath returns with the ResultForMSE association
|
||
|
relpath
|
||
|
|
||
|
ResultForTestRelPath returns with the ResultForTest association
|
||
|
relpath
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
PWCHAR RelPath;
|
||
|
HRESULT hr;
|
||
|
ULONG AllocSize;
|
||
|
WCHAR s1[2*MAX_PATH];
|
||
|
WCHAR s2[2*MAX_PATH];
|
||
|
|
||
|
RelPath = (PWCHAR)WmipAlloc(4096);
|
||
|
if (RelPath != NULL)
|
||
|
{
|
||
|
//
|
||
|
// Create the relpaths for the result classes and associations
|
||
|
//
|
||
|
wsprintfW(RelPath, L"%ws.DiagnosticCreationClassName=\"%ws\",DiagnosticName=\"%ws\",ExecutionID=\"%ws\"",
|
||
|
CdmResultClassName,
|
||
|
AddSlashesToStringExW(s1, WdmRelPaths[RelPathIndex]),
|
||
|
CdmTestClassName,
|
||
|
ExecutionId);
|
||
|
|
||
|
*ResultRelPath = SysAllocString(RelPath);
|
||
|
|
||
|
if (*ResultRelPath != NULL)
|
||
|
{
|
||
|
wsprintfW(RelPath, L"%ws.Result=\"%ws\",SystemElement=\"%ws\"",
|
||
|
CdmResultForMSEClassName,
|
||
|
AddSlashesToStringExW(s1, *ResultRelPath),
|
||
|
AddSlashesToStringExW(s2, CimRelPaths[RelPathIndex]));
|
||
|
*ResultForMSERelPath = SysAllocString(RelPath);
|
||
|
|
||
|
wsprintfW(RelPath, L"%ws.DiagnosticResult=\"%ws\",DiagnosticTest=\"%ws\"",
|
||
|
CdmResultForTestClassName,
|
||
|
AddSlashesToStringExW(s1, *ResultRelPath),
|
||
|
AddSlashesToStringExW(s2, CdmTestRelPath));
|
||
|
*ResultForTestRelPath = SysAllocString(RelPath);
|
||
|
|
||
|
|
||
|
if ((*ResultForMSERelPath == NULL) ||
|
||
|
(*ResultForTestRelPath == NULL))
|
||
|
{
|
||
|
SysFreeString(*ResultRelPath);
|
||
|
|
||
|
if (*ResultForMSERelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(*ResultForMSERelPath);
|
||
|
}
|
||
|
|
||
|
if (*ResultForTestRelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(*ResultForTestRelPath);
|
||
|
}
|
||
|
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
} else {
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
WmipFree(RelPath);
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CTestServices::BuildTestRelPaths(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will create the string names for the CDM Test
|
||
|
relative paths for all index
|
||
|
|
||
|
These are for the following classes:
|
||
|
|
||
|
CIM_DiagnosticTest,
|
||
|
CIM_DiagnosticTestForMSE
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
PWCHAR RelPath;
|
||
|
int i;
|
||
|
HRESULT hr;
|
||
|
WCHAR s1[MAX_PATH];
|
||
|
WCHAR s2[MAX_PATH];
|
||
|
ULONG AllocSize;
|
||
|
|
||
|
RelPath = (PWCHAR)WmipAlloc(4096);
|
||
|
|
||
|
if (RelPath != NULL)
|
||
|
{
|
||
|
wsprintfW(RelPath, L"%ws.Name=\"%ws\"",
|
||
|
CdmTestClassName, CdmTestClassName);
|
||
|
CdmTestRelPath = SysAllocString(RelPath);
|
||
|
if (CdmTestRelPath != NULL)
|
||
|
{
|
||
|
AllocSize = RelPathCount * sizeof(BSTR);
|
||
|
CdmTestForMSERelPath = (PWCHAR *)WmipAlloc(AllocSize);
|
||
|
if (CdmTestForMSERelPath != NULL)
|
||
|
{
|
||
|
memset(CdmTestForMSERelPath, 0, AllocSize);
|
||
|
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
for (i = 0; (i < RelPathCount) && (hr == WBEM_S_NO_ERROR); i++)
|
||
|
{
|
||
|
wsprintfW(RelPath, L"%ws.Antecedent=\"%ws\",Dependent=\"%ws\"",
|
||
|
CdmTestForMSEClassName,
|
||
|
AddSlashesToStringExW(s1, CimRelPaths[i]),
|
||
|
AddSlashesToStringExW(s2, CdmTestRelPath));
|
||
|
CdmTestForMSERelPath[i] = SysAllocString(RelPath);
|
||
|
if (CdmTestForMSERelPath[i] == NULL)
|
||
|
{
|
||
|
SysFreeString(CdmTestRelPath);
|
||
|
CdmTestRelPath = NULL;
|
||
|
|
||
|
FreeTheBSTRArray(CdmTestForMSERelPath, RelPathCount);
|
||
|
CdmTestForMSERelPath = NULL;
|
||
|
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
SysFreeString(CdmTestRelPath);
|
||
|
CdmTestRelPath = NULL;
|
||
|
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
WmipFree(RelPath);
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::BuildSettingForTestRelPath(
|
||
|
OUT BSTR *RelPath,
|
||
|
IN IWbemClassObject *pCdmSettingInstance
|
||
|
)
|
||
|
{
|
||
|
WCHAR *Buffer;
|
||
|
VARIANT v;
|
||
|
WCHAR s[MAX_PATH];
|
||
|
HRESULT hr;
|
||
|
|
||
|
WmipAssert(RelPath != NULL);
|
||
|
WmipAssert(pCdmSettingInstance != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
Buffer = (WCHAR *)WmipAlloc(4096);
|
||
|
if (Buffer != NULL)
|
||
|
{
|
||
|
hr = WmiGetProperty(pCdmSettingInstance,
|
||
|
L"__RELPATH",
|
||
|
CIM_REFERENCE,
|
||
|
&v);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
wsprintfW(Buffer, L"%ws.Element=\"%ws.Name=\\\"%ws\\\"\",Setting=\"%ws\"",
|
||
|
CdmSettingForTestClassName,
|
||
|
CdmTestClassName,
|
||
|
CdmTestClassName,
|
||
|
AddSlashesToStringExW(s, v.bstrVal));
|
||
|
VariantClear(&v);
|
||
|
|
||
|
*RelPath = SysAllocString(Buffer);
|
||
|
if (*RelPath != NULL)
|
||
|
{
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WmipFree(Buffer);
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT CTestServices::ParseSettingList(
|
||
|
VARIANT *SettingList,
|
||
|
CWbemObjectList *CdmSettings,
|
||
|
CBstrArray *CdmSettingForTestRelPath,
|
||
|
int RelPathIndex
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will obtain all of the settings for a particular test
|
||
|
and store them into a settings list object
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SettingList points at a variant continaing an array of embedded
|
||
|
WDM setting objects
|
||
|
|
||
|
CdmSettings points at a WbemObjectList class
|
||
|
|
||
|
CdmSettingForTestRelPath has the relpaths for the cdm settings for
|
||
|
test classes
|
||
|
|
||
|
RelPathIndex is the relpath index associated with the settings
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IWbemClassObject *pWdmSettingInstance;
|
||
|
IWbemClassObject *pCdmSettingInstance;
|
||
|
LONG Index, UBound, LBound, NumberElements;
|
||
|
LONG i;
|
||
|
IUnknown *punk;
|
||
|
BSTR s;
|
||
|
WCHAR SettingId[MAX_PATH];
|
||
|
VARIANT v;
|
||
|
|
||
|
WmipAssert(SettingList != NULL);
|
||
|
WmipAssert(CdmSettingForTestRelPath != NULL);
|
||
|
WmipAssert(SettingList->vt == (CIM_OBJECT | CIM_FLAG_ARRAY));
|
||
|
WmipAssert(CdmSettings != NULL);
|
||
|
|
||
|
hr = WmiGetArraySize(SettingList->parray,
|
||
|
&LBound,
|
||
|
&UBound,
|
||
|
&NumberElements);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CdmSettingForTestRelPath->Initialize(NumberElements);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CdmSettings->Initialize(NumberElements);
|
||
|
|
||
|
for (i = 0, Index = LBound;
|
||
|
(i < NumberElements) && (hr == WBEM_S_NO_ERROR);
|
||
|
i++, Index++)
|
||
|
{
|
||
|
hr = SafeArrayGetElement(SettingList->parray,
|
||
|
&Index,
|
||
|
&punk);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = punk->QueryInterface(IID_IWbemClassObject,
|
||
|
(PVOID *)&pWdmSettingInstance);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CreateInst(GetCdmServices(),
|
||
|
&pCdmSettingInstance,
|
||
|
CdmSettingClassName,
|
||
|
NULL);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CopyBetweenCdmAndWdmClasses(pCdmSettingInstance,
|
||
|
pWdmSettingInstance,
|
||
|
TRUE);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Set CdmSetting.SettingId to a unique
|
||
|
// setting id
|
||
|
//
|
||
|
wsprintfW(SettingId, L"%ws_%d_%d",
|
||
|
CdmTestClassName,
|
||
|
RelPathIndex,
|
||
|
i);
|
||
|
s = SysAllocString(SettingId);
|
||
|
if (s != NULL)
|
||
|
{
|
||
|
VariantInit(&v);
|
||
|
v.vt = VT_BSTR;
|
||
|
v.bstrVal = s;
|
||
|
hr = WmiSetProperty(pCdmSettingInstance,
|
||
|
L"SettingId",
|
||
|
&v);
|
||
|
VariantClear(&v);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = BuildSettingForTestRelPath(&s,
|
||
|
pCdmSettingInstance);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
CdmSettingForTestRelPath->Set(i,
|
||
|
s);
|
||
|
|
||
|
CdmSettings->Set(i,
|
||
|
pCdmSettingInstance,
|
||
|
TRUE);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (hr != WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
pCdmSettingInstance->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pWdmSettingInstance->Release();
|
||
|
}
|
||
|
punk->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetCdmTestSettings(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will obtain all of the CDM settings available for all
|
||
|
instnaces of the test
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WCHAR Query[MAX_PATH * 2];
|
||
|
WCHAR s[MAX_PATH];
|
||
|
ULONG AllocSize;
|
||
|
BSTR sWQL, sQuery;
|
||
|
IEnumWbemClassObject *pWdmEnumInstances;
|
||
|
IWbemClassObject *pWdmInstance;
|
||
|
int i;
|
||
|
ULONG Count;
|
||
|
HRESULT hr;
|
||
|
VARIANT SettingList;
|
||
|
|
||
|
//
|
||
|
// We need to get all of the settings exposed by the WDM class and
|
||
|
// then convert them to Cdm classes.
|
||
|
//
|
||
|
|
||
|
sWQL = SysAllocString(L"WQL");
|
||
|
|
||
|
if (sWQL != NULL)
|
||
|
{
|
||
|
AllocSize = RelPathCount * sizeof(CWbemObjectList *);
|
||
|
|
||
|
CdmSettingsList = (CWbemObjectList **)WmipAlloc(AllocSize);
|
||
|
if (CdmSettingsList != NULL)
|
||
|
{
|
||
|
memset(CdmSettingsList, 0, AllocSize);
|
||
|
|
||
|
AllocSize = RelPathCount * sizeof(CBstrArray *);
|
||
|
CdmSettingForTestRelPath = (CBstrArray **)WmipAlloc(AllocSize);
|
||
|
if (CdmSettingForTestRelPath != NULL)
|
||
|
{
|
||
|
memset(CdmSettingForTestRelPath, 0, AllocSize);
|
||
|
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
for (i = 0; (i < RelPathCount) && (hr == WBEM_S_NO_ERROR); i++)
|
||
|
{
|
||
|
CdmSettingsList[i] = new CWbemObjectList();
|
||
|
CdmSettingForTestRelPath[i] = new CBstrArray;
|
||
|
|
||
|
wsprintfW(Query, L"select * from %ws where InstanceName = \"%ws\"",
|
||
|
WdmSettingListClassName,
|
||
|
AddSlashesToStringW(s, WdmInstanceNames[i]));
|
||
|
sQuery = SysAllocString(Query);
|
||
|
if (sQuery != NULL)
|
||
|
{
|
||
|
hr = pWdmServices->ExecQuery(sWQL,
|
||
|
sQuery,
|
||
|
WBEM_FLAG_FORWARD_ONLY |
|
||
|
WBEM_FLAG_ENSURE_LOCATABLE,
|
||
|
NULL,
|
||
|
&pWdmEnumInstances);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = pWdmEnumInstances->Next(WBEM_INFINITE,
|
||
|
1,
|
||
|
&pWdmInstance,
|
||
|
&Count);
|
||
|
if ((hr == WBEM_S_NO_ERROR) &&
|
||
|
(Count == 1))
|
||
|
{
|
||
|
hr = WmiGetProperty(pWdmInstance,
|
||
|
L"SettingList",
|
||
|
CIM_FLAG_ARRAY | CIM_OBJECT,
|
||
|
&SettingList);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
if (SettingList.vt & VT_ARRAY)
|
||
|
{
|
||
|
hr = ParseSettingList(&SettingList,
|
||
|
CdmSettingsList[i],
|
||
|
CdmSettingForTestRelPath[i],
|
||
|
i);
|
||
|
} else {
|
||
|
hr = WBEM_E_FAILED;
|
||
|
}
|
||
|
VariantClear(&SettingList);
|
||
|
}
|
||
|
pWdmInstance->Release();
|
||
|
}
|
||
|
|
||
|
pWdmEnumInstances->Release();
|
||
|
} else {
|
||
|
//
|
||
|
// There must not be any predefined settings
|
||
|
//
|
||
|
hr = CdmSettingsList[i]->Initialize(0);
|
||
|
}
|
||
|
|
||
|
SysFreeString(sQuery);
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
SysFreeString(sWQL);
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::InitializeCdmClasses(
|
||
|
PWCHAR CdmClass
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will setup this class and initialize everything so
|
||
|
that the provider can interact with the CDM and WDM classes
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
CdmClass is the name of the CDM class
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr, hrDontCare;
|
||
|
ULONG AllocSize;
|
||
|
int i;
|
||
|
|
||
|
WmipAssert(CdmClass != NULL);
|
||
|
|
||
|
WmipAssert(! IsThisInitialized());
|
||
|
|
||
|
//
|
||
|
// We assume that this method will always be the first one called
|
||
|
// by the class provider
|
||
|
//
|
||
|
if ((pCimServices == NULL) &&
|
||
|
(pWdmServices == NULL))
|
||
|
{
|
||
|
hr = TestInfoInitialize();
|
||
|
if (hr != WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
return(hr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// We are given a random CDM class name - it could be a test,
|
||
|
// setting, association, etc so we need to go from that class name
|
||
|
// and obtain all of the class names related to this diagnostic
|
||
|
//
|
||
|
hr = GetCdmClassNamesFromOne(CdmClass);
|
||
|
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Use worker function to determine which
|
||
|
// Wdm relpaths map to which Cdm relpaths
|
||
|
//
|
||
|
hr = MapWdmClassToCimClass(pWdmServices,
|
||
|
pCimServices,
|
||
|
WdmTestClassName,
|
||
|
CimClassMappingClassName,
|
||
|
&PnPDeviceIdsX,
|
||
|
&WdmInstanceNames,
|
||
|
&WdmRelPaths,
|
||
|
&CimRelPaths,
|
||
|
&RelPathCount);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Obtain all of the possible settings for this test
|
||
|
//
|
||
|
hr = GetCdmTestSettings();
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Initialize the results object lists
|
||
|
//
|
||
|
CdmResultsList = new CResultList[RelPathCount];
|
||
|
|
||
|
//
|
||
|
// Build the test class instance relpaths
|
||
|
//
|
||
|
hr = BuildTestRelPaths();
|
||
|
|
||
|
// @@BEGIN_DDKSPLIT
|
||
|
#ifdef REBOOT_DIAGNOSTICS
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hrDontCare = GatherRebootResults();
|
||
|
}
|
||
|
#else
|
||
|
//
|
||
|
// Reboot diagnostics are not yet supported
|
||
|
//
|
||
|
#endif
|
||
|
// @@END_DDKSPLIT
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
IWbemServices *CTestServices::GetWdmServices(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
Accessor for the WDM namespace IWbemServices
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
IWbemServices
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(pWdmServices != NULL);
|
||
|
return(pWdmServices);
|
||
|
}
|
||
|
|
||
|
IWbemServices *CTestServices::GetCdmServices(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
Accessor for the CIM namespace IWbemServices
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
IWbemServices
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(pCimServices != NULL);
|
||
|
|
||
|
return(pCimServices);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::WdmPropertyToCdmProperty(
|
||
|
IN IWbemClassObject *pCdmClassInstance,
|
||
|
IN IWbemClassObject *pWdmClassInstance,
|
||
|
IN BSTR PropertyName,
|
||
|
IN OUT VARIANT *PropertyValue,
|
||
|
IN CIMTYPE CdmCimType,
|
||
|
IN CIMTYPE WdmCimType
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will convert a property in a Wdm class into the form
|
||
|
required for the property in the Cdm class.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pCdmClassInstance is the instnace of the Cdm class that will get
|
||
|
the property value
|
||
|
|
||
|
pWdmClassInstance is the instance of the Wdm class that has the
|
||
|
property value
|
||
|
|
||
|
PropertyName is the name of the property in the Wdm and Cdm classes
|
||
|
|
||
|
PropertyValue on entry has the value of the property in the Wdm
|
||
|
instance and on return has the value to set in the Cdm instance
|
||
|
|
||
|
CdmCimType is the property type for the property in the Cdm
|
||
|
instance
|
||
|
|
||
|
WdmCimType is the property type for the property in the Wdm
|
||
|
instance
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
BSTR Mapped;
|
||
|
VARIANT vClassName;
|
||
|
CIMTYPE BaseWdmCimType, BaseCdmCimType;
|
||
|
CIMTYPE WdmCimArray, CdmCimArray;
|
||
|
LONG i;
|
||
|
|
||
|
WmipAssert(pCdmClassInstance != NULL);
|
||
|
WmipAssert(pWdmClassInstance != NULL);
|
||
|
WmipAssert(PropertyName != NULL);
|
||
|
WmipAssert(PropertyValue != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
//
|
||
|
// Rules for converting Wdm Classes into Cdm Classes
|
||
|
// Wdm Class Type Cdm Class Type Conversion Done
|
||
|
// enumeration string Build string from enum
|
||
|
//
|
||
|
BaseWdmCimType = WdmCimType & ~CIM_FLAG_ARRAY;
|
||
|
BaseCdmCimType = CdmCimType & ~CIM_FLAG_ARRAY;
|
||
|
WdmCimArray = WdmCimType & CIM_FLAG_ARRAY;
|
||
|
CdmCimArray = CdmCimType & CIM_FLAG_ARRAY;
|
||
|
|
||
|
if (((BaseWdmCimType == CIM_UINT32) ||
|
||
|
(BaseWdmCimType == CIM_UINT16) ||
|
||
|
(BaseWdmCimType == CIM_UINT8)) &&
|
||
|
(BaseCdmCimType == CIM_STRING) &&
|
||
|
(WdmCimArray == CdmCimArray) &&
|
||
|
(PropertyValue->vt != VT_NULL))
|
||
|
{
|
||
|
hr = WmiGetProperty(pWdmClassInstance,
|
||
|
L"__Class",
|
||
|
CIM_STRING,
|
||
|
&vClassName);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
if (WdmCimArray)
|
||
|
{
|
||
|
SAFEARRAYBOUND Bounds;
|
||
|
SAFEARRAY *Array;
|
||
|
ULONG Value;
|
||
|
LONG UBound, LBound, Elements, Index;
|
||
|
|
||
|
//
|
||
|
// We have an array of enumeration types to convert into an
|
||
|
// array of corresponding strings
|
||
|
//
|
||
|
hr = WmiGetArraySize(PropertyValue->parray,
|
||
|
&LBound,
|
||
|
&UBound,
|
||
|
&Elements);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
Bounds.lLbound = LBound;
|
||
|
Bounds.cElements = Elements;
|
||
|
Array = SafeArrayCreate(VT_BSTR,
|
||
|
1,
|
||
|
&Bounds);
|
||
|
if (Array != NULL)
|
||
|
{
|
||
|
for (i = 0;
|
||
|
(i < Elements) && (hr == WBEM_S_NO_ERROR);
|
||
|
i++)
|
||
|
{
|
||
|
|
||
|
Index = i + LBound;
|
||
|
hr = SafeArrayGetElement(PropertyValue->parray,
|
||
|
&Index,
|
||
|
&Value);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = LookupValueMap(GetWdmServices(),
|
||
|
vClassName.bstrVal,
|
||
|
PropertyName,
|
||
|
Value,
|
||
|
&Mapped);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = SafeArrayPutElement(Array,
|
||
|
&Index,
|
||
|
Mapped);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
VariantClear(PropertyValue);
|
||
|
PropertyValue->vt = VT_BSTR | VT_ARRAY;
|
||
|
PropertyValue->parray = Array;
|
||
|
} else {
|
||
|
SafeArrayDestroy(Array);
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// We need to convert a scalar enumeration type into the
|
||
|
// corresponding string. First we need to get the Wdm class
|
||
|
// object and from that get the Values and ValueMap qualifiers
|
||
|
// to determine the string we need to place into the cim class
|
||
|
//
|
||
|
hr = LookupValueMap(GetWdmServices(),
|
||
|
vClassName.bstrVal,
|
||
|
PropertyName,
|
||
|
PropertyValue->uiVal,
|
||
|
&Mapped);
|
||
|
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
VariantClear(PropertyValue);
|
||
|
PropertyValue->vt = VT_BSTR;
|
||
|
PropertyValue->bstrVal = Mapped;
|
||
|
}
|
||
|
}
|
||
|
VariantClear(&vClassName);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
//
|
||
|
// No conversion needs to occur
|
||
|
//
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::CdmPropertyToWdmProperty(
|
||
|
IN IWbemClassObject *pWdmClassInstance,
|
||
|
IN IWbemClassObject *pCdmClassInstance,
|
||
|
IN BSTR PropertyName,
|
||
|
IN OUT VARIANT *PropertyValue,
|
||
|
IN CIMTYPE WdmCimType,
|
||
|
IN CIMTYPE CdmCimType
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will convert a property in a Cdm class into the form
|
||
|
required for the property in the Wdm class.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pWdmClassInstance is the instance of the Wdm class that has the
|
||
|
property value
|
||
|
|
||
|
pCdmClassInstance is the instnace of the Cdm class that will get
|
||
|
the property value
|
||
|
|
||
|
PropertyName is the name of the property in the Wdm and Cdm classes
|
||
|
|
||
|
PropertyValue on entry has the value of the property in the Wdm
|
||
|
instance and on return has the value to set in the Cdm instance
|
||
|
|
||
|
WdmCimType is the property type for the property in the Wdm
|
||
|
instance
|
||
|
|
||
|
CdmCimType is the property type for the property in the Cdm
|
||
|
instance
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
|
||
|
WmipAssert(pCdmClassInstance != NULL);
|
||
|
WmipAssert(pWdmClassInstance != NULL);
|
||
|
WmipAssert(PropertyName != NULL);
|
||
|
WmipAssert(PropertyValue != NULL);
|
||
|
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
//
|
||
|
// Rules for converting Wdm Classes into Cdm Classes
|
||
|
// Wdm Class Type Cdm Class Type Conversion Done
|
||
|
//
|
||
|
|
||
|
|
||
|
//
|
||
|
// There are no conversion requirements when converting from Cdm to
|
||
|
// Wdm instances
|
||
|
//
|
||
|
return(WBEM_S_NO_ERROR);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::CopyBetweenCdmAndWdmClasses(
|
||
|
IN IWbemClassObject *pDestinationInstance,
|
||
|
IN IWbemClassObject *pSourceInstance,
|
||
|
IN BOOLEAN WdmToCdm
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will do the work to copy and convert all properties in
|
||
|
an instance of a Wdm or Cdm class to an instance of a Cdm or Wdm
|
||
|
class.
|
||
|
|
||
|
Note that properties from one instance are only copied to
|
||
|
properties of another instance when the property names are
|
||
|
identical. No assumption is ever made on the name of the
|
||
|
properties. The only info used to determine how to convert a
|
||
|
property is based upon the source and destination cim type.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pDestinationInstance is the class instance that the properties will
|
||
|
be copied into
|
||
|
|
||
|
pSourceInstance is the class instance that the properties will be
|
||
|
copied from
|
||
|
|
||
|
WdmToCdm is TRUE if copying from Wdm to Cdm, else FALSE
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
VARIANT PropertyValue;
|
||
|
BSTR PropertyName;
|
||
|
CIMTYPE SourceCimType, DestCimType;
|
||
|
HRESULT hrDontCare;
|
||
|
|
||
|
WmipAssert(pDestinationInstance != NULL);
|
||
|
WmipAssert(pSourceInstance != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
//
|
||
|
// Now we need to move over all of the properties from the source
|
||
|
// class into the destination class. Note that some properties need
|
||
|
// some special effort such as OtherCharacteristics which needs
|
||
|
// to be converted from an enumeration value (in wdm) to a
|
||
|
// string (in CDM).
|
||
|
//
|
||
|
// Our strategy is to enumerate all of the proeprties in the
|
||
|
// source class and then look for a property with the same name
|
||
|
// and type in the destination class. If so we just copy over the
|
||
|
// value. If the data type is different we need to do some
|
||
|
// conversion.
|
||
|
//
|
||
|
|
||
|
|
||
|
|
||
|
hr = pSourceInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
//
|
||
|
// Get a property from the source class
|
||
|
//
|
||
|
hr = pSourceInstance->Next(0,
|
||
|
&PropertyName,
|
||
|
&PropertyValue,
|
||
|
&SourceCimType,
|
||
|
NULL);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Try to get a property with the same name from the
|
||
|
// dest class. If the identically named property does
|
||
|
// not exist in the destination class then it is ignored
|
||
|
//
|
||
|
hrDontCare = pDestinationInstance->Get(PropertyName,
|
||
|
0,
|
||
|
NULL,
|
||
|
&DestCimType,
|
||
|
NULL);
|
||
|
|
||
|
if (hrDontCare == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
|
||
|
if (WdmToCdm)
|
||
|
{
|
||
|
hr = WdmPropertyToCdmProperty(pDestinationInstance,
|
||
|
pSourceInstance,
|
||
|
PropertyName,
|
||
|
&PropertyValue,
|
||
|
DestCimType,
|
||
|
SourceCimType);
|
||
|
} else {
|
||
|
hr = CdmPropertyToWdmProperty(pDestinationInstance,
|
||
|
pSourceInstance,
|
||
|
PropertyName,
|
||
|
&PropertyValue,
|
||
|
DestCimType,
|
||
|
SourceCimType);
|
||
|
}
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// Try to place the transformed property into the
|
||
|
// destination class.
|
||
|
//
|
||
|
hr = pDestinationInstance->Put(PropertyName,
|
||
|
0,
|
||
|
&PropertyValue,
|
||
|
0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SysFreeString(PropertyName);
|
||
|
VariantClear(&PropertyValue);
|
||
|
|
||
|
} else if (hr == WBEM_S_NO_MORE_DATA) {
|
||
|
//
|
||
|
// This signifies the end of the enumerations
|
||
|
//
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
break;
|
||
|
}
|
||
|
} while (hr == WBEM_S_NO_ERROR);
|
||
|
|
||
|
pSourceInstance->EndEnumeration();
|
||
|
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::QueryWdmTest(
|
||
|
OUT IWbemClassObject *pCdmTest,
|
||
|
IN int RelPathIndex
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will query the Wdm test class instance and copy the results
|
||
|
into the Cdm Test class instance
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pCdmTest points at the Cdm Test class instance
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
IWbemClassObject *pWdmTest;
|
||
|
HRESULT hr;
|
||
|
|
||
|
WmipAssert(pCdmTest != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
hr = ConnectToWdmClass(RelPathIndex,
|
||
|
&pWdmTest);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CopyBetweenCdmAndWdmClasses(pCdmTest,
|
||
|
pWdmTest,
|
||
|
TRUE);
|
||
|
pWdmTest->Release();
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
#define OBJECTCOLONSIZE (((sizeof(L"object:")/sizeof(WCHAR)))-1)
|
||
|
|
||
|
HRESULT CTestServices::FillTestInParams(
|
||
|
OUT IWbemClassObject *pInParamInstance,
|
||
|
IN IWbemClassObject *pCdmSettings,
|
||
|
IN BSTR ExecutionID
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IWbemServices *pWdmServices;
|
||
|
VARIANT v;
|
||
|
VARIANT PropertyValues[2];
|
||
|
PWCHAR PropertyNames[2];
|
||
|
PWCHAR ClassName;
|
||
|
IWbemClassObject *pRunTestIn;
|
||
|
IWbemClassObject *pWdmSettingsInstance;
|
||
|
IWbemQualifierSet *pQualSet;
|
||
|
|
||
|
WmipAssert(pInParamInstance != NULL);
|
||
|
|
||
|
pWdmServices = GetWdmServices();
|
||
|
|
||
|
pRunTestIn = NULL;
|
||
|
|
||
|
//
|
||
|
// Get the name of the embedded class for the RunTestIn input
|
||
|
// parameter. This should be an embedded class that contains all of
|
||
|
// the input parameters. We get this from the __CIMTYPE qualifier
|
||
|
// on the RunTestIn property.
|
||
|
//
|
||
|
// We need to do this since the wmiprov can't
|
||
|
// handle anything with an embedded object as an input parameter to
|
||
|
// a method
|
||
|
//
|
||
|
hr = pInParamInstance->GetPropertyQualifierSet(L"RunTestIn",
|
||
|
&pQualSet);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = WmiGetQualifier(pQualSet,
|
||
|
L"CIMTYPE",
|
||
|
VT_BSTR,
|
||
|
&v);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
if (_wcsnicmp(v.bstrVal, L"object:", OBJECTCOLONSIZE) == 0)
|
||
|
{
|
||
|
ClassName = v.bstrVal + OBJECTCOLONSIZE;
|
||
|
hr = CreateInst(pWdmServices,
|
||
|
&pRunTestIn,
|
||
|
ClassName,
|
||
|
NULL);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CreateInst(pWdmServices,
|
||
|
&pWdmSettingsInstance,
|
||
|
WdmSettingClassName,
|
||
|
NULL);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
if (pCdmSettings != NULL)
|
||
|
{
|
||
|
hr = CopyBetweenCdmAndWdmClasses(pWdmSettingsInstance,
|
||
|
pCdmSettings,
|
||
|
FALSE);
|
||
|
}
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
PWCHAR PropertyNames[2];
|
||
|
VARIANT PropertyValues[2];
|
||
|
|
||
|
PropertyNames[0] = L"DiagSettings";
|
||
|
PropertyValues[0].vt = VT_UNKNOWN;
|
||
|
PropertyValues[0].punkVal = pWdmSettingsInstance;
|
||
|
PropertyNames[1] = L"ExecutionID";
|
||
|
PropertyValues[1].vt = VT_BSTR;
|
||
|
PropertyValues[1].bstrVal = ExecutionID;
|
||
|
|
||
|
hr = WmiSetPropertyList(pRunTestIn,
|
||
|
2,
|
||
|
PropertyNames,
|
||
|
PropertyValues);
|
||
|
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
PropertyValues[0].vt = VT_UNKNOWN;
|
||
|
PropertyValues[0].punkVal = pRunTestIn;
|
||
|
hr = WmiSetProperty(pInParamInstance,
|
||
|
L"RunTestIn",
|
||
|
&PropertyValues[0]);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// We can release here since we know that wbem
|
||
|
// took a ref count when we set the property
|
||
|
//
|
||
|
pWdmSettingsInstance->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
VariantClear(&v);
|
||
|
}
|
||
|
pQualSet->Release();
|
||
|
}
|
||
|
|
||
|
if ((hr != WBEM_S_NO_ERROR) && (pRunTestIn != NULL))
|
||
|
{
|
||
|
pRunTestIn->Release();
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetTestOutParams(
|
||
|
IN IWbemClassObject *OutParams,
|
||
|
OUT IWbemClassObject *pCdmResult,
|
||
|
OUT ULONG *Result
|
||
|
)
|
||
|
{
|
||
|
|
||
|
HRESULT hr;
|
||
|
VARIANT v;
|
||
|
IWbemClassObject *pRunTestOut;
|
||
|
IWbemClassObject *pWdmResult;
|
||
|
|
||
|
WmipAssert(OutParams != NULL);
|
||
|
WmipAssert(pCdmResult != NULL);
|
||
|
WmipAssert(Result != NULL);
|
||
|
|
||
|
hr = WmiGetProperty(OutParams,
|
||
|
L"RunTestOut",
|
||
|
CIM_OBJECT,
|
||
|
&v);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = v.punkVal->QueryInterface(IID_IWbemClassObject,
|
||
|
(PVOID *)&pRunTestOut);
|
||
|
VariantClear(&v);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = WmiGetProperty(pRunTestOut,
|
||
|
L"Result",
|
||
|
CIM_UINT32,
|
||
|
&v);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
*Result = v.ulVal;
|
||
|
VariantClear(&v);
|
||
|
|
||
|
hr = WmiGetProperty(pRunTestOut,
|
||
|
L"DiagResult",
|
||
|
CIM_OBJECT,
|
||
|
&v);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
if (v.vt != VT_NULL)
|
||
|
{
|
||
|
hr = v.punkVal->QueryInterface(IID_IWbemClassObject,
|
||
|
(PVOID *)&pWdmResult);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CopyBetweenCdmAndWdmClasses(pCdmResult,
|
||
|
pWdmResult,
|
||
|
TRUE);
|
||
|
pWdmResult->Release();
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_FAILED;
|
||
|
}
|
||
|
VariantClear(&v);
|
||
|
}
|
||
|
}
|
||
|
pRunTestOut->Release();
|
||
|
}
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
LONG GlobalExecutionID;
|
||
|
|
||
|
BSTR CTestServices::GetExecutionID(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
BSTR s;
|
||
|
WCHAR x[MAX_PATH];
|
||
|
|
||
|
//
|
||
|
// We make up a unique execution ID for this test by using the
|
||
|
// current date and time plus a unique counter. The execution id
|
||
|
// must be unique.
|
||
|
//
|
||
|
s = GetCurrentDateTime();
|
||
|
if (s != NULL)
|
||
|
{
|
||
|
wsprintfW(x, L"%ws*%08x", s, InterlockedIncrement(&GlobalExecutionID));
|
||
|
SysFreeString(s);
|
||
|
s = SysAllocString(x);
|
||
|
}
|
||
|
return(s);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CTestServices::ExecuteWdmTest(
|
||
|
IN IWbemClassObject *pCdmSettings,
|
||
|
OUT IWbemClassObject *pCdmResult,
|
||
|
IN int RelPathIndex,
|
||
|
OUT ULONG *Result,
|
||
|
OUT BSTR *ExecutionID
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will execute a test on the Wdm class instance and copy
|
||
|
the results back to the Cdm results instance, along with creating
|
||
|
all result instance relpaths
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pCdmSettings is a CDM settings instance that is used to create the
|
||
|
wdm settings instance that is used to run the test. This may be
|
||
|
NULL if default test settings are assumed
|
||
|
|
||
|
pCdmResult is a CDM result instance that returns with the results
|
||
|
form the test
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
*Result returns with the return value result from the test
|
||
|
|
||
|
*ExecutionId returns with the unique execution id for the test
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IWbemClassObject *pOutParams;
|
||
|
IWbemClassObject *pInParamInstance;
|
||
|
BSTR s;
|
||
|
|
||
|
WmipAssert(pCdmResult != NULL);
|
||
|
WmipAssert(Result != NULL);
|
||
|
WmipAssert(ExecutionID != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
//
|
||
|
// Run in the caller's context so that if he is not able to access
|
||
|
// the WDM classes, he can't
|
||
|
//
|
||
|
hr = CoImpersonateClient();
|
||
|
if (hr != WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
*ExecutionID = GetExecutionID();
|
||
|
|
||
|
if (*ExecutionID != NULL)
|
||
|
{
|
||
|
s = SysAllocString(L"RunTest");
|
||
|
if (s != NULL)
|
||
|
{
|
||
|
hr = GetMethodInParamInstance(GetWdmServices(),
|
||
|
WdmTestClassName,
|
||
|
s,
|
||
|
&pInParamInstance);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = FillTestInParams(pInParamInstance,
|
||
|
pCdmSettings,
|
||
|
*ExecutionID);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = pWdmServices->ExecMethod(WdmRelPaths[RelPathIndex],
|
||
|
s,
|
||
|
0,
|
||
|
NULL,
|
||
|
pInParamInstance,
|
||
|
&pOutParams,
|
||
|
NULL);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
|
||
|
hr = GetTestOutParams(pOutParams,
|
||
|
pCdmResult,
|
||
|
Result);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
//
|
||
|
// if the test requires the device being
|
||
|
// taken offline then do that now
|
||
|
//
|
||
|
hr = OfflineDeviceForTest(pCdmResult,
|
||
|
*ExecutionID,
|
||
|
RelPathIndex);
|
||
|
|
||
|
}
|
||
|
pOutParams->Release();
|
||
|
}
|
||
|
}
|
||
|
pInParamInstance->Release();
|
||
|
}
|
||
|
SysFreeString(s);
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
CoRevertToSelf();
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::StopWdmTest(
|
||
|
IN int RelPathIndex,
|
||
|
OUT ULONG *Result,
|
||
|
OUT BOOLEAN *TestingStopped
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will attempt to stop an executing WDM test
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
*Result returns with the result value
|
||
|
|
||
|
*TestingStopped returns TRUE if testing was stopped successfully
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IWbemClassObject *OutParams;
|
||
|
BSTR s;
|
||
|
IWbemServices *pWdmServices;
|
||
|
VARIANT Value;
|
||
|
|
||
|
WmipAssert(Result != NULL);
|
||
|
WmipAssert(TestingStopped != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
|
||
|
//
|
||
|
// Run in the caller's context so that if he is not able to access
|
||
|
// the WDM classes, he can't
|
||
|
//
|
||
|
hr = CoImpersonateClient();
|
||
|
if (hr != WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
pWdmServices = GetWdmServices();
|
||
|
|
||
|
s = SysAllocString(L"DiscontinueTest");
|
||
|
if (s != NULL)
|
||
|
{
|
||
|
hr = pWdmServices->ExecMethod(WdmRelPaths[RelPathIndex],
|
||
|
s,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&OutParams,
|
||
|
NULL);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = WmiGetProperty(OutParams,
|
||
|
L"Result",
|
||
|
CIM_UINT32,
|
||
|
&Value);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
*Result = Value.ulVal;
|
||
|
VariantClear(&Value);
|
||
|
|
||
|
hr = WmiGetProperty(OutParams,
|
||
|
L"TestingStopped",
|
||
|
CIM_BOOLEAN,
|
||
|
&Value);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
*TestingStopped = (Value.boolVal != 0) ? TRUE : FALSE;
|
||
|
VariantClear(&Value);
|
||
|
}
|
||
|
}
|
||
|
OutParams->Release();
|
||
|
}
|
||
|
SysFreeString(s);
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
CoRevertToSelf();
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetRelPathIndex(
|
||
|
BSTR CimRelPath,
|
||
|
int *RelPathIndex
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the RelPathIndex for a specific Cim
|
||
|
Relpath
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
CimRelPath is the Cim relpath
|
||
|
|
||
|
*RelPathIndex returns with the relpath index
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
WmipAssert(CimRelPath != NULL);
|
||
|
|
||
|
WmipAssert(CimRelPaths != NULL);
|
||
|
WmipAssert(WdmRelPaths != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
for (i = 0; i < RelPathCount; i++)
|
||
|
{
|
||
|
if (_wcsicmp(CimRelPath, CimRelPaths[i]) == 0)
|
||
|
{
|
||
|
*RelPathIndex = i;
|
||
|
return(WBEM_S_NO_ERROR);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(WBEM_E_NOT_FOUND);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::ConnectToWdmClass(
|
||
|
IN int RelPathIndex,
|
||
|
OUT IWbemClassObject **ppWdmClassObject
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return a IWbemClassObject pointer associated
|
||
|
with the RelPath index
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
*ppWdmClassObject returns with an instance for the relpaht
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
WmipAssert(ppWdmClassObject != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
//
|
||
|
// Run in the caller's context so that if he is not able to access
|
||
|
// the WDM classes, he can't
|
||
|
//
|
||
|
hr = CoImpersonateClient();
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
*ppWdmClassObject = NULL;
|
||
|
hr = GetWdmServices()->GetObject(WdmRelPaths[RelPathIndex],
|
||
|
WBEM_FLAG_USE_AMENDED_QUALIFIERS,
|
||
|
NULL,
|
||
|
ppWdmClassObject,
|
||
|
NULL);
|
||
|
CoRevertToSelf();
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CTestServices::FillInCdmResult(
|
||
|
OUT IWbemClassObject *pCdmResult,
|
||
|
IN IWbemClassObject *pCdmSettings,
|
||
|
IN int RelPathIndex,
|
||
|
IN BSTR ExecutionID
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will fill in the various properties needed in a CDM
|
||
|
result instance
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pCdmResult has its properties set
|
||
|
|
||
|
pCdmSettings has the settings used to execute the test. This can be
|
||
|
NULL
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
ExecutionID has a unique id used to execute the test
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr, hrDontCare;
|
||
|
WCHAR s[MAX_PATH];
|
||
|
PWCHAR PropertyNames[12];
|
||
|
VARIANT PropertyValues[12];
|
||
|
ULONG PropertyCount;
|
||
|
BSTR ss;
|
||
|
|
||
|
WmipAssert(pCdmResult != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
PropertyNames[0] = L"DiagnosticCreationClassName";
|
||
|
PropertyValues[0].vt = VT_BSTR;
|
||
|
PropertyValues[0].bstrVal = WdmRelPaths[RelPathIndex];
|
||
|
|
||
|
PropertyNames[1] = L"DiagnosticName";
|
||
|
PropertyValues[1].vt = VT_BSTR;
|
||
|
PropertyValues[1].bstrVal = CdmTestClassName;
|
||
|
|
||
|
PropertyNames[2] = L"ExecutionID";
|
||
|
PropertyValues[2].vt = VT_BSTR;
|
||
|
PropertyValues[2].bstrVal = ExecutionID;
|
||
|
|
||
|
PropertyNames[3] = L"TimeStamp";
|
||
|
PropertyValues[3].vt = VT_BSTR;
|
||
|
PropertyValues[3].bstrVal = GetCurrentDateTime();
|
||
|
|
||
|
PropertyNames[4] = L"TestCompletionTime";
|
||
|
PropertyValues[4].vt = VT_BSTR;
|
||
|
PropertyValues[4].bstrVal = GetCurrentDateTime();
|
||
|
|
||
|
PropertyNames[5] = L"IsPackage";
|
||
|
PropertyValues[5].vt = VT_BOOL;
|
||
|
PropertyValues[5].boolVal = VARIANT_FALSE;
|
||
|
|
||
|
//
|
||
|
// These properties are copied from pCdmSettings
|
||
|
//
|
||
|
if (pCdmSettings != NULL)
|
||
|
{
|
||
|
PropertyNames[6] = L"TestWarningLevel";
|
||
|
hrDontCare = WmiGetProperty(pCdmSettings,
|
||
|
L"TestWarningLevel",
|
||
|
CIM_UINT16,
|
||
|
&PropertyValues[6]);
|
||
|
|
||
|
PropertyNames[7] = L"ReportSoftErrors";
|
||
|
hrDontCare = WmiGetProperty(pCdmSettings,
|
||
|
L"ReportSoftErrors",
|
||
|
CIM_BOOLEAN,
|
||
|
&PropertyValues[7]);
|
||
|
|
||
|
PropertyNames[8] = L"ReportStatusMessages";
|
||
|
hrDontCare = WmiGetProperty(pCdmSettings,
|
||
|
L"ReportStatusMessages",
|
||
|
CIM_BOOLEAN,
|
||
|
&PropertyValues[8]);
|
||
|
|
||
|
PropertyNames[9] = L"HaltOnError";
|
||
|
hrDontCare = WmiGetProperty(pCdmSettings,
|
||
|
L"HaltOnError",
|
||
|
CIM_BOOLEAN,
|
||
|
&PropertyValues[9]);
|
||
|
|
||
|
PropertyNames[10] = L"QuickMode";
|
||
|
hrDontCare = WmiGetProperty(pCdmSettings,
|
||
|
L"QuickMode",
|
||
|
CIM_BOOLEAN,
|
||
|
&PropertyValues[10]);
|
||
|
|
||
|
PropertyNames[11] = L"PercentOfTestCoverage";
|
||
|
hrDontCare = WmiGetProperty(pCdmSettings,
|
||
|
L"PercentOfTestCoverage",
|
||
|
CIM_UINT8,
|
||
|
&PropertyValues[11]);
|
||
|
|
||
|
PropertyCount = 12;
|
||
|
} else {
|
||
|
PropertyCount = 6;
|
||
|
}
|
||
|
|
||
|
hr = WmiSetPropertyList(pCdmResult,
|
||
|
PropertyCount,
|
||
|
PropertyNames,
|
||
|
PropertyValues);
|
||
|
|
||
|
VariantClear(&PropertyValues[3]);
|
||
|
VariantClear(&PropertyValues[4]);
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::QueryOfflineResult(
|
||
|
OUT IWbemClassObject *pCdmResult,
|
||
|
IN BSTR ExecutionID,
|
||
|
IN int RelPathIndex
|
||
|
)
|
||
|
{
|
||
|
WCHAR Query[MAX_PATH * 2];
|
||
|
WCHAR s[MAX_PATH];
|
||
|
BSTR sWQL, sQuery;
|
||
|
IEnumWbemClassObject *pWdmEnumInstances;
|
||
|
IWbemClassObject *pWdmResult, *pWdmInstance;
|
||
|
ULONG Count;
|
||
|
HRESULT hr;
|
||
|
VARIANT vResult;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
WmipAssert(WdmOfflineResultClassName != NULL);
|
||
|
|
||
|
//
|
||
|
// Run in the caller's context so that if he is not able to access
|
||
|
// the WDM classes, he can't
|
||
|
//
|
||
|
hr = CoImpersonateClient();
|
||
|
if (hr != WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
sWQL = SysAllocString(L"WQL");
|
||
|
|
||
|
if (sWQL != NULL)
|
||
|
{
|
||
|
wsprintfW(Query, L"select * from %ws where InstanceName = \"%ws\"",
|
||
|
WdmOfflineResultClassName,
|
||
|
AddSlashesToStringW(s, WdmInstanceNames[RelPathIndex]));
|
||
|
sQuery = SysAllocString(Query);
|
||
|
if (sQuery != NULL)
|
||
|
{
|
||
|
hr = GetWdmServices()->ExecQuery(sWQL,
|
||
|
sQuery,
|
||
|
WBEM_FLAG_FORWARD_ONLY |
|
||
|
WBEM_FLAG_ENSURE_LOCATABLE,
|
||
|
NULL,
|
||
|
&pWdmEnumInstances);
|
||
|
SysFreeString(sQuery);
|
||
|
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = pWdmEnumInstances->Next(WBEM_INFINITE,
|
||
|
1,
|
||
|
&pWdmInstance,
|
||
|
&Count);
|
||
|
if ((hr == WBEM_S_NO_ERROR) &&
|
||
|
(Count == 1))
|
||
|
{
|
||
|
//
|
||
|
// Check that the result has the correct execution
|
||
|
// ID
|
||
|
//
|
||
|
hr = WmiGetProperty(pWdmInstance,
|
||
|
L"ExecutionID",
|
||
|
CIM_STRING,
|
||
|
&vResult);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
if (_wcsicmp(ExecutionID, vResult.bstrVal) != 0)
|
||
|
{
|
||
|
hr = WBEM_E_FAILED;
|
||
|
WmipDebugPrint(("CdmProv: Expected execution ID %ws, but got %ws\n",
|
||
|
ExecutionID, vResult.bstrVal));
|
||
|
}
|
||
|
VariantClear(&vResult);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
|
||
|
hr = WmiGetProperty(pWdmInstance,
|
||
|
L"TestResult",
|
||
|
CIM_OBJECT,
|
||
|
&vResult);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = (vResult.punkVal)->QueryInterface(IID_IWbemClassObject,
|
||
|
(PVOID *)&pWdmResult);
|
||
|
VariantClear(&vResult);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CopyBetweenCdmAndWdmClasses(pCdmResult,
|
||
|
pWdmResult,
|
||
|
TRUE);
|
||
|
pWdmResult->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
pWdmInstance->Release();
|
||
|
}
|
||
|
pWdmEnumInstances->Release();
|
||
|
}
|
||
|
}
|
||
|
SysFreeString(sWQL);
|
||
|
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
CoRevertToSelf();
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
//@@BEGIN_DDKSPLIT
|
||
|
HRESULT CTestServices::GatherRebootResults(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will check the schema to see if there were any tests
|
||
|
that were pending reboot for this DiagnosticTest and if so gather
|
||
|
the results of them.
|
||
|
|
||
|
When a test is pending reboot, it gets stored as an instance of the
|
||
|
static class CDMPROV_Result. The instance contains the Test class
|
||
|
name, the result class name, the PnPId of the device stack and the
|
||
|
result object. What we do is get all of the saved results for this
|
||
|
DiagTest and then see if they apply to any of the PnP Device Ids
|
||
|
for the WdmTest. If so then we call the device to retrieve the
|
||
|
results and build the result objects.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
|
||
|
#ifdef REBOOT_DIAGNOSTICS
|
||
|
HRESULT hr, hrDontCare;
|
||
|
WCHAR Query[2*MAX_PATH];
|
||
|
BSTR sQuery, sWQL;
|
||
|
IEnumWbemClassObject *pEnumInstances;
|
||
|
IWbemClassObject *pInstance;
|
||
|
IWbemClassObject *pCdmResult;
|
||
|
int i;
|
||
|
ULONG Count;
|
||
|
VARIANT vResult, vPnPId, vExecutionID;
|
||
|
BSTR ExecutionId;
|
||
|
|
||
|
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
|
||
|
sWQL = SysAllocString(L"WQL");
|
||
|
|
||
|
if (sWQL != NULL)
|
||
|
{
|
||
|
wsprintfW(Query, L"select * from CdmProv_Result where CdmTestClass = \"%ws\"\n",
|
||
|
CdmTestClassName);
|
||
|
sQuery = SysAllocString(Query);
|
||
|
if (sQuery != NULL)
|
||
|
{
|
||
|
hrDontCare = GetCdmServices()->ExecQuery(sWQL,
|
||
|
sQuery,
|
||
|
WBEM_FLAG_FORWARD_ONLY |
|
||
|
WBEM_FLAG_ENSURE_LOCATABLE,
|
||
|
NULL,
|
||
|
&pEnumInstances);
|
||
|
SysFreeString(sQuery);
|
||
|
|
||
|
|
||
|
if (hrDontCare == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = pEnumInstances->Next(WBEM_INFINITE,
|
||
|
1,
|
||
|
&pInstance,
|
||
|
&Count);
|
||
|
if ((hr == WBEM_S_NO_ERROR) &&
|
||
|
(Count == 1))
|
||
|
{
|
||
|
hr = WmiGetProperty(pInstance,
|
||
|
L"PnPId",
|
||
|
CIM_STRING,
|
||
|
&vPnPId);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
for (i = 0; i < RelPathCount; i++)
|
||
|
{
|
||
|
if (_wcsicmp(vPnPId.bstrVal, PnPDeviceIdsX[i]) == 0)
|
||
|
{
|
||
|
//
|
||
|
// We found an instance for this class
|
||
|
// and PnPId. get out the stored
|
||
|
// result, assign it a new execution
|
||
|
// id, and then retrieve the active
|
||
|
// result from the driver
|
||
|
//
|
||
|
PWCHAR PropertyNames[2];
|
||
|
VARIANT Values[2];
|
||
|
CIMTYPE CimTypes[2];
|
||
|
|
||
|
PropertyNames[0] = L"CdmResult";
|
||
|
CimTypes[0] = CIM_OBJECT;
|
||
|
PropertyNames[1] = L"ResultTag";
|
||
|
CimTypes[1] = CIM_STRING;
|
||
|
|
||
|
hr = WmiGetPropertyList(pInstance,
|
||
|
PropertyNames,
|
||
|
CimTypes,
|
||
|
Values);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = (Values[0].punkVal)->QueryInterface(IID_IWbemClassObject,
|
||
|
(PVOID *)&pCdmResult);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = WmiGetProperty(pCdmResult,
|
||
|
L"ExecutionID",
|
||
|
CIM_STRING,
|
||
|
&vExecutionId);
|
||
|
WmipAssert(vExecutionId.vt != VT_NULL);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = QueryOfflineResult(pCdmResult,
|
||
|
Values[1].bstrVal,
|
||
|
i);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = SetResultObject(pCdmResult,
|
||
|
i,
|
||
|
vExecutionId.bstrVal);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = FillInCdmResult(pCdmResult,
|
||
|
NULL,
|
||
|
i,
|
||
|
ExecutionId);
|
||
|
if (hr != WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hrDontCare = SetResultObject(NULL,
|
||
|
i,
|
||
|
0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
VariantClear(&Values[0]);
|
||
|
VariantClear(&Values[1]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
VariantClear(&vPnPId);
|
||
|
}
|
||
|
}
|
||
|
pEnumInstances->Release();
|
||
|
}
|
||
|
}
|
||
|
SysFreeString(sWQL);
|
||
|
}
|
||
|
return(hr);
|
||
|
#else
|
||
|
return(WBEM_S_NO_ERROR);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CTestServices::PersistResultInSchema(
|
||
|
IN IWbemClassObject *pCdmResult,
|
||
|
IN BSTR ExecutionID,
|
||
|
IN int RelPathIndex
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will persist a diagnostic result into the schema
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IWbemClassObject *pPendingTest;
|
||
|
IUnknown *punk;
|
||
|
WCHAR *PropertyNames[5];
|
||
|
VARIANT PropertyValues[5];
|
||
|
|
||
|
WmipAssert(pCdmResult != NULL);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
hr = CreateInst(GetCdmServices(),
|
||
|
&pPendingTest,
|
||
|
L"CDMProv_Result",
|
||
|
NULL);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = pCdmResult->QueryInterface(IID_IUnknown,
|
||
|
(PVOID *)&punk);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
PropertyNames[0] = L"PnPId";
|
||
|
PropertyValues[0].vt = VT_BSTR;
|
||
|
PropertyValues[0].bstrVal = PnPDeviceIdsX[RelPathIndex];
|
||
|
|
||
|
PropertyNames[1] = L"CdmTestClass";
|
||
|
PropertyValues[1].vt = VT_BSTR;
|
||
|
PropertyValues[1].bstrVal = CdmTestClassName;
|
||
|
|
||
|
PropertyNames[2] = L"CdmResultClass";
|
||
|
PropertyValues[2].vt = VT_BSTR;
|
||
|
PropertyValues[2].bstrVal = CdmResultClassName;
|
||
|
|
||
|
PropertyNames[3] = L"CdmResult";
|
||
|
PropertyValues[3].vt = VT_UNKNOWN;
|
||
|
PropertyValues[3].punkVal = punk;
|
||
|
|
||
|
PropertyNames[4] = L"ExecutionID";
|
||
|
PropertyValues[4].vt = VT_BSTR;
|
||
|
PropertyValues[4].bstrVal = ExecutionID;
|
||
|
|
||
|
hr = WmiSetPropertyList(pPendingTest,
|
||
|
5,
|
||
|
PropertyNames,
|
||
|
PropertyValues);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = GetCdmServices()->PutInstance(pPendingTest,
|
||
|
WBEM_FLAG_CREATE_OR_UPDATE,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
}
|
||
|
punk->Release();
|
||
|
}
|
||
|
pPendingTest->Release();
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
//@@END_DDKSPLIT
|
||
|
|
||
|
HRESULT CTestServices::OfflineDeviceForTest(
|
||
|
IWbemClassObject *pCdmResult,
|
||
|
BSTR ExecutionID,
|
||
|
int RelPathIndex
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = WBEM_S_NO_ERROR;
|
||
|
ULONG Status;
|
||
|
VARIANT v;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
|
||
|
//
|
||
|
// First determine if the test is one where it expects to be taken
|
||
|
// offline and that the result from the RunTest method indicates
|
||
|
// that an offline execution is pending
|
||
|
//
|
||
|
if (WdmOfflineResultClassName != NULL)
|
||
|
{
|
||
|
//
|
||
|
// The device expects to be taken offline since it had a
|
||
|
// WdmOfflineResultClass qualifier on the CIM_DiagnosticResult
|
||
|
// class. Now see if the OtherStateDescription property in the
|
||
|
// CIM_DiagnosticResult is set to "Offline Pending Execution"
|
||
|
//
|
||
|
hr = WmiGetProperty(pCdmResult,
|
||
|
L"OtherStateDescription",
|
||
|
CIM_STRING,
|
||
|
&v);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
if (_wcsicmp(v.bstrVal, L"Offline Pending Execution") == 0)
|
||
|
{
|
||
|
//
|
||
|
// Ok, the test is waiting for the device to be taken
|
||
|
// offline. Lets do this now and then when the device
|
||
|
// comes back, pickup the results from the
|
||
|
// OfflineResultClass
|
||
|
//
|
||
|
|
||
|
// @@BEGIN_DDKSPLIT
|
||
|
//#define FORCE_REBOOT_REQUIRED
|
||
|
#ifdef FORCE_REBOOT_REQUIRED
|
||
|
Status = ERROR_INVALID_PARAMETER;
|
||
|
#else
|
||
|
// @@END_DDKSPLIT
|
||
|
|
||
|
//
|
||
|
// Make sure to use the clients security context to try
|
||
|
// to bring the device offline.
|
||
|
//
|
||
|
hr = CoImpersonateClient();
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
Status = RestartDevice(PnPDeviceIdsX[RelPathIndex]);
|
||
|
CoRevertToSelf();
|
||
|
}
|
||
|
|
||
|
// @@BEGIN_DDKSPLIT
|
||
|
#endif
|
||
|
// @@END_DDKSPLIT
|
||
|
|
||
|
if (Status == ERROR_SUCCESS)
|
||
|
{
|
||
|
hr = QueryOfflineResult(pCdmResult,
|
||
|
ExecutionID,
|
||
|
RelPathIndex);
|
||
|
} else {
|
||
|
//
|
||
|
// For some reason we were not able to bring the
|
||
|
// device offline. Most likely this is because the
|
||
|
// device is critical to the system and cannot be
|
||
|
// taken offline right now - for example a disk
|
||
|
// that is in the paging path.
|
||
|
//
|
||
|
|
||
|
// @@BEGIN_DDKSPLIT
|
||
|
#if REBOOT_DIAGNOSTICS
|
||
|
// What we'll need to do is to remember that
|
||
|
// this test is pending and so the next time the
|
||
|
// system is rebooted we can check for the results
|
||
|
// of this test and report them.
|
||
|
//
|
||
|
hr = PersistResultInSchema(pCdmResult,
|
||
|
RelPathIndex);
|
||
|
#else
|
||
|
//
|
||
|
// Reboot diagnostics are not currently supported.
|
||
|
//
|
||
|
|
||
|
// @@END_DDKSPLIT
|
||
|
|
||
|
hr = WBEM_E_FAILED;
|
||
|
|
||
|
// @@BEGIN_DDKSPLIT
|
||
|
#endif
|
||
|
// @@END_DDKSPLIT
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
VariantClear(&v);
|
||
|
} else {
|
||
|
//
|
||
|
// Since the OtherStateDescription was not set then we
|
||
|
// assume that the tests isn't setup to go offline and has
|
||
|
// already been completed
|
||
|
//
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOLEAN CTestServices::IsThisInitialized(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine determines if this class has been initialized to
|
||
|
access CDM and WDM classes
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if initialiezed else FALSE
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
return( (CdmTestClassName != NULL) );
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::AddResultToList(
|
||
|
IN IWbemClassObject *ResultInstance,
|
||
|
IN BSTR ExecutionID,
|
||
|
IN int RelPathIndex
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will add a result object and the related association
|
||
|
relpaths to the list of result objects for the test
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ResultInstance is an instance of CIM_DiagnosticResults
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
ExecutionID
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Never fails
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
BSTR ResultRelPath;
|
||
|
BSTR ResultForMSERelPath;
|
||
|
BSTR ResultForTestRelPath;
|
||
|
|
||
|
WmipAssert(ResultInstance != NULL);
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
//
|
||
|
// If there is a new result object then establish the various
|
||
|
// result relpaths for it
|
||
|
//
|
||
|
hr = BuildResultRelPaths(RelPathIndex,
|
||
|
ExecutionID,
|
||
|
&ResultRelPath,
|
||
|
&ResultForMSERelPath,
|
||
|
&ResultForTestRelPath);
|
||
|
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
hr = CdmResultsList[RelPathIndex].Add(ResultInstance,
|
||
|
ResultRelPath,
|
||
|
ResultForMSERelPath,
|
||
|
ResultForTestRelPath);
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetResultsList(
|
||
|
IN int RelPathIndex,
|
||
|
OUT ULONG *ResultsCount,
|
||
|
OUT IWbemClassObject ***Results
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
return(CdmResultsList[RelPathIndex].GetResultsList(ResultsCount,
|
||
|
Results));
|
||
|
}
|
||
|
|
||
|
void CTestServices::ClearResultsList(
|
||
|
int RelPathIndex
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
CdmResultsList[RelPathIndex].Clear();
|
||
|
}
|
||
|
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCimRelPath(
|
||
|
int RelPathIndex
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cim relpath for a RelPathIndex
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cim RelPath. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(CimRelPaths != NULL);
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
return(CimRelPaths[RelPathIndex]);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmTestRelPath(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm Test class relpath
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Test Class RelPath. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
return(CdmTestRelPath);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmTestClassName(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm Test class name
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Test Class Name. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmTestClassName);
|
||
|
}
|
||
|
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmResultClassName(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm Result class name
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Result Class Name. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmResultClassName);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetCdmResultByResultRelPath(
|
||
|
IN int RelPathIndex,
|
||
|
IN PWCHAR ObjectPath,
|
||
|
OUT IWbemClassObject **ppCdmResult
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm Result object for a specific RelPath
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Result RelPath or NULL of there is no ressult object for the
|
||
|
relpath. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
hr = CdmResultsList[RelPathIndex].GetResultByResultRelPath(ObjectPath,
|
||
|
ppCdmResult);
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetCdmResultByResultForMSERelPath(
|
||
|
IN int RelPathIndex,
|
||
|
IN PWCHAR ObjectPath,
|
||
|
OUT IWbemClassObject **ppCdmResult
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm Result object for a specific RelPath
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Result RelPath or NULL of there is no ressult object for the
|
||
|
relpath. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
hr = CdmResultsList[RelPathIndex].GetResultByResultForMSERelPath(ObjectPath,
|
||
|
ppCdmResult);
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CTestServices::GetCdmResultByResultForTestRelPath(
|
||
|
IN int RelPathIndex,
|
||
|
IN PWCHAR ObjectPath,
|
||
|
OUT IWbemClassObject **ppCdmResult
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm Result object for a specific RelPath
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Result RelPath or NULL of there is no ressult object for the
|
||
|
relpath. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
hr = CdmResultsList[RelPathIndex].GetResultByResultForTestRelPath(ObjectPath,
|
||
|
ppCdmResult);
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmSettingClassName(
|
||
|
void
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm settings class name
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Settings class name. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmSettingClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmSettingRelPath(
|
||
|
int RelPathIndex,
|
||
|
ULONG SettingIndex
|
||
|
)
|
||
|
/*+++
|
||
|
Routine Description:
|
||
|
|
||
|
This routine will return the Cdm settings relpath by relpath index
|
||
|
and index with the settings for that relpath.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RelPathIndex
|
||
|
|
||
|
SettingIndex
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Cdm Settings relpath. This should not be freed
|
||
|
|
||
|
---*/
|
||
|
{
|
||
|
CWbemObjectList *CdmSettings;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
WmipAssert(CdmSettingsList != NULL);
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
CdmSettings = CdmSettingsList[RelPathIndex];
|
||
|
|
||
|
return(CdmSettings->GetRelPath(SettingIndex));
|
||
|
}
|
||
|
|
||
|
IWbemClassObject *CTestServices::GetCdmSettingObject(
|
||
|
int RelPathIndex,
|
||
|
ULONG SettingIndex
|
||
|
)
|
||
|
{
|
||
|
CWbemObjectList *CdmSettings;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
WmipAssert(CdmSettingsList != NULL);
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
CdmSettings = CdmSettingsList[RelPathIndex];
|
||
|
|
||
|
return(CdmSettings->Get(SettingIndex));
|
||
|
}
|
||
|
|
||
|
ULONG CTestServices::GetCdmSettingCount(
|
||
|
int RelPathIndex
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
WmipAssert(CdmSettingsList != NULL);
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
return(CdmSettingsList[RelPathIndex]->GetListSize());
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmTestForMSEClassName(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmTestForMSEClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmTestForMSERelPath(
|
||
|
int RelPathIndex
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmTestForMSERelPath[RelPathIndex]);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmSettingForTestClassName(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmSettingForTestClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmSettingForTestRelPath(
|
||
|
int RelPathIndex,
|
||
|
ULONG SettingIndex
|
||
|
)
|
||
|
{
|
||
|
CBstrArray *BstrArray;
|
||
|
BSTR s;
|
||
|
|
||
|
WmipAssert(RelPathIndex < RelPathCount);
|
||
|
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
|
||
|
if (CdmSettingForTestRelPath != NULL)
|
||
|
{
|
||
|
BstrArray = CdmSettingForTestRelPath[RelPathIndex];
|
||
|
s = BstrArray->Get(SettingIndex);
|
||
|
} else {
|
||
|
s = NULL;
|
||
|
}
|
||
|
|
||
|
return(s);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmResultForMSEClassName(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmResultForMSEClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmResultForTestClassName(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmResultForTestClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmTestForSoftwareClassName(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmTestForSoftwareClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmTestForSoftwareRelPath(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmTestForSoftwareRelPath);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmTestInPackageClassName(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmTestInPackageClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */CTestServices::GetCdmTestInPackageRelPath(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmTestInPackageRelPath);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmResultInPackageClassName(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmResultInPackageClassName);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CTestServices::GetCdmResultInPackageRelPath(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsThisInitialized());
|
||
|
return(CdmResultInPackageRelPath);
|
||
|
}
|
||
|
|
||
|
|
||
|
CWbemObjectList::CWbemObjectList()
|
||
|
{
|
||
|
//
|
||
|
// Constructor, init internal values
|
||
|
//
|
||
|
List = NULL;
|
||
|
RelPaths = NULL;
|
||
|
ListSize = 0xffffffff;
|
||
|
}
|
||
|
|
||
|
CWbemObjectList::~CWbemObjectList()
|
||
|
{
|
||
|
//
|
||
|
// Destructor, free memory held by this class
|
||
|
//
|
||
|
if (List != NULL)
|
||
|
{
|
||
|
WmipFree(List);
|
||
|
}
|
||
|
List = NULL;
|
||
|
|
||
|
if (RelPaths != NULL)
|
||
|
{
|
||
|
FreeTheBSTRArray(RelPaths, ListSize);
|
||
|
RelPaths = NULL;
|
||
|
}
|
||
|
|
||
|
ListSize = 0xffffffff;
|
||
|
}
|
||
|
|
||
|
HRESULT CWbemObjectList::Initialize(
|
||
|
ULONG NumberPointers
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
ULONG AllocSize;
|
||
|
|
||
|
//
|
||
|
// Initialize class by allocating internal list array
|
||
|
//
|
||
|
|
||
|
WmipAssert(List == NULL);
|
||
|
|
||
|
if (NumberPointers != 0)
|
||
|
{
|
||
|
AllocSize = NumberPointers * sizeof(IWbemClassObject *);
|
||
|
List = (IWbemClassObject **)WmipAlloc(AllocSize);
|
||
|
if (List != NULL)
|
||
|
{
|
||
|
memset(List, 0, AllocSize);
|
||
|
AllocSize = NumberPointers * sizeof(BSTR);
|
||
|
|
||
|
RelPaths = (BSTR *)WmipAlloc(AllocSize);
|
||
|
if (RelPaths != NULL)
|
||
|
{
|
||
|
memset(RelPaths, 0, AllocSize);
|
||
|
ListSize = NumberPointers;
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
} else {
|
||
|
WmipDebugPrint(("CDMProv: Could not alloc memory for CWbemObjectList RelPaths\n"));
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
} else {
|
||
|
WmipDebugPrint(("CDMProv: Could not alloc memory for CWbemObjectList\n"));
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
} else {
|
||
|
ListSize = NumberPointers;
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
ULONG CWbemObjectList::GetListSize(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// Accessor for list size
|
||
|
//
|
||
|
|
||
|
WmipAssert(IsInitialized());
|
||
|
|
||
|
return(ListSize);
|
||
|
}
|
||
|
|
||
|
IWbemClassObject *CWbemObjectList::Get(
|
||
|
ULONG Index
|
||
|
)
|
||
|
{ IWbemClassObject *Pointer;
|
||
|
|
||
|
WmipAssert(Index < ListSize);
|
||
|
WmipAssert(IsInitialized());
|
||
|
|
||
|
Pointer = List[Index];
|
||
|
|
||
|
return(Pointer);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CWbemObjectList::Set(
|
||
|
IN ULONG Index,
|
||
|
IN IWbemClassObject *Pointer,
|
||
|
IN BOOLEAN KeepRelPath
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
VARIANT v;
|
||
|
|
||
|
WmipAssert(Index < ListSize);
|
||
|
WmipAssert(IsInitialized());
|
||
|
|
||
|
if (Pointer != NULL)
|
||
|
{
|
||
|
hr = WmiGetProperty(Pointer,
|
||
|
L"__RelPath",
|
||
|
CIM_REFERENCE,
|
||
|
&v);
|
||
|
if (hr == WBEM_S_NO_ERROR)
|
||
|
{
|
||
|
RelPaths[Index] = v.bstrVal;
|
||
|
List[Index] = Pointer;
|
||
|
} else {
|
||
|
if (! KeepRelPath)
|
||
|
{
|
||
|
RelPaths[Index] = NULL;
|
||
|
List[Index] = Pointer;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if (RelPaths[Index] != NULL)
|
||
|
{
|
||
|
SysFreeString(RelPaths[Index]);
|
||
|
RelPaths[Index] = NULL;
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
List[Index] = NULL;
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
BSTR /* NOFREE */ CWbemObjectList::GetRelPath(
|
||
|
IN ULONG Index
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(Index < ListSize);
|
||
|
WmipAssert(IsInitialized());
|
||
|
|
||
|
return(RelPaths[Index]);
|
||
|
}
|
||
|
|
||
|
BOOLEAN CWbemObjectList::IsInitialized(
|
||
|
)
|
||
|
{
|
||
|
return((ListSize == 0) ||
|
||
|
((List != NULL) && (RelPaths != NULL)));
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Linked list management routines
|
||
|
//
|
||
|
CTestServices *CTestServices::GetNext(
|
||
|
)
|
||
|
{
|
||
|
return(Next);
|
||
|
}
|
||
|
|
||
|
CTestServices *CTestServices::GetPrev(
|
||
|
)
|
||
|
{
|
||
|
return(Prev);
|
||
|
}
|
||
|
|
||
|
|
||
|
void CTestServices::InsertSelf(
|
||
|
CTestServices **Head
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(Next == NULL);
|
||
|
WmipAssert(Prev == NULL);
|
||
|
|
||
|
if (*Head != NULL)
|
||
|
{
|
||
|
Next = (*Head);
|
||
|
(*Head)->Prev = this;
|
||
|
}
|
||
|
*Head = this;
|
||
|
}
|
||
|
|
||
|
BOOLEAN CTestServices::ClaimCdmClassName(
|
||
|
PWCHAR CdmClassName
|
||
|
)
|
||
|
{
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmTestClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmResultClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmSettingClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmTestForMSEClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmSettingForTestClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmResultForMSEClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmResultForTestClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmTestForSoftwareClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmTestInPackageClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (_wcsicmp(CdmClassName, CdmResultInPackageClassName) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
CBstrArray::CBstrArray()
|
||
|
{
|
||
|
Array = NULL;
|
||
|
ListSize = 0xffffffff;
|
||
|
}
|
||
|
|
||
|
CBstrArray::~CBstrArray()
|
||
|
{
|
||
|
ULONG i;
|
||
|
|
||
|
if (Array != NULL)
|
||
|
{
|
||
|
for (i = 0; i < ListSize; i++)
|
||
|
{
|
||
|
if (Array[i] != NULL)
|
||
|
{
|
||
|
SysFreeString(Array[i]);
|
||
|
}
|
||
|
}
|
||
|
WmipFree(Array);
|
||
|
}
|
||
|
|
||
|
ListSize = 0xffffffff;
|
||
|
}
|
||
|
|
||
|
HRESULT CBstrArray::Initialize(
|
||
|
ULONG ListCount
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = WBEM_S_NO_ERROR;
|
||
|
ULONG AllocSize;
|
||
|
|
||
|
if (ListCount != 0)
|
||
|
{
|
||
|
AllocSize = ListCount * sizeof(BSTR *);
|
||
|
Array = (BSTR *)WmipAlloc(AllocSize);
|
||
|
if (Array != NULL)
|
||
|
{
|
||
|
memset(Array, 0, AllocSize);
|
||
|
ListSize = ListCount;
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
} else {
|
||
|
ListSize = ListCount;
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
BOOLEAN CBstrArray::IsInitialized(
|
||
|
)
|
||
|
{
|
||
|
return( (Array != NULL) || (ListSize == 0) );
|
||
|
}
|
||
|
|
||
|
BSTR CBstrArray::Get(
|
||
|
ULONG Index
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(Index < ListSize);
|
||
|
|
||
|
WmipAssert(IsInitialized());
|
||
|
|
||
|
return(Array[Index]);
|
||
|
}
|
||
|
|
||
|
void CBstrArray::Set(
|
||
|
ULONG Index,
|
||
|
BSTR s
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(Index < ListSize);
|
||
|
|
||
|
WmipAssert(IsInitialized());
|
||
|
|
||
|
Array[Index] = s;
|
||
|
}
|
||
|
|
||
|
ULONG CBstrArray::GetListSize(
|
||
|
)
|
||
|
{
|
||
|
WmipAssert(IsInitialized());
|
||
|
|
||
|
return(ListSize);
|
||
|
}
|
||
|
|
||
|
CResultList::CResultList()
|
||
|
{
|
||
|
ListSize = 0;
|
||
|
ListEntries = 0;
|
||
|
List = NULL;
|
||
|
}
|
||
|
|
||
|
CResultList::~CResultList()
|
||
|
{
|
||
|
ULONG i;
|
||
|
|
||
|
Clear();
|
||
|
if (List != NULL)
|
||
|
{
|
||
|
WmipFree(List);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CResultList::Clear(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
ULONG i;
|
||
|
PRESULTENTRY Entry;
|
||
|
|
||
|
if (List != NULL)
|
||
|
{
|
||
|
for (i = 0; i < ListEntries; i++)
|
||
|
{
|
||
|
Entry = &List[i];
|
||
|
if (Entry->ResultInstance != NULL)
|
||
|
{
|
||
|
Entry->ResultInstance->Release();
|
||
|
Entry->ResultInstance = NULL;
|
||
|
}
|
||
|
|
||
|
if (Entry->ResultRelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(Entry->ResultRelPath);
|
||
|
Entry->ResultRelPath = NULL;
|
||
|
}
|
||
|
|
||
|
if (Entry->ResultForMSERelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(Entry->ResultForMSERelPath);
|
||
|
Entry->ResultForMSERelPath = NULL;
|
||
|
}
|
||
|
|
||
|
if (Entry->ResultForTestRelPath != NULL)
|
||
|
{
|
||
|
SysFreeString(Entry->ResultForTestRelPath);
|
||
|
Entry->ResultForTestRelPath = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ListEntries = 0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The result list will grow itself this many entries at a time
|
||
|
//
|
||
|
#define RESULTLISTGROWSIZE 4
|
||
|
|
||
|
HRESULT CResultList::Add(
|
||
|
IWbemClassObject *CdmResultInstance,
|
||
|
BSTR CdmResultRelPath,
|
||
|
BSTR CdmResultForMSERelPath,
|
||
|
BSTR CdmResultForTestRelPath
|
||
|
)
|
||
|
{
|
||
|
ULONG AllocSize;
|
||
|
PRESULTENTRY NewList, Entry;
|
||
|
ULONG CurrentSize;
|
||
|
|
||
|
EnterCdmCritSection();
|
||
|
|
||
|
if (List == NULL)
|
||
|
{
|
||
|
//
|
||
|
// We are starting with an empty list
|
||
|
//
|
||
|
AllocSize = RESULTLISTGROWSIZE * sizeof(RESULTENTRY);
|
||
|
List = (PRESULTENTRY)WmipAlloc(AllocSize);
|
||
|
if (List == NULL)
|
||
|
{
|
||
|
LeaveCdmCritSection();
|
||
|
return(WBEM_E_OUT_OF_MEMORY);
|
||
|
}
|
||
|
memset(List, 0, AllocSize);
|
||
|
ListSize = RESULTLISTGROWSIZE;
|
||
|
ListEntries = 0;
|
||
|
} else if (ListEntries == ListSize) {
|
||
|
//
|
||
|
// The list needs to grow, so we allocate more memory and copy
|
||
|
// over the current list
|
||
|
//
|
||
|
CurrentSize = ListSize * sizeof(RESULTENTRY);
|
||
|
AllocSize = CurrentSize + (RESULTLISTGROWSIZE * sizeof(RESULTENTRY));
|
||
|
NewList = (PRESULTENTRY)WmipAlloc(AllocSize);
|
||
|
if (NewList == NULL)
|
||
|
{
|
||
|
LeaveCdmCritSection();
|
||
|
return(WBEM_E_OUT_OF_MEMORY);
|
||
|
}
|
||
|
|
||
|
memset(NewList, 0, AllocSize);
|
||
|
memcpy(NewList, List, CurrentSize);
|
||
|
WmipFree(List);
|
||
|
List = NewList;
|
||
|
ListSize += RESULTLISTGROWSIZE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// We have room to add a new entry to the list
|
||
|
//
|
||
|
Entry = &List[ListEntries++];
|
||
|
Entry->ResultInstance = CdmResultInstance;
|
||
|
Entry->ResultInstance->AddRef();
|
||
|
Entry->ResultRelPath = CdmResultRelPath;
|
||
|
Entry->ResultForMSERelPath = CdmResultForMSERelPath;
|
||
|
Entry->ResultForTestRelPath = CdmResultForTestRelPath;
|
||
|
|
||
|
LeaveCdmCritSection();
|
||
|
return(WBEM_S_NO_ERROR);
|
||
|
}
|
||
|
|
||
|
HRESULT CResultList::GetResultsList(
|
||
|
OUT ULONG *Count,
|
||
|
OUT IWbemClassObject ***Objects
|
||
|
)
|
||
|
{
|
||
|
IWbemClassObject **Things;
|
||
|
HRESULT hr;
|
||
|
ULONG i;
|
||
|
|
||
|
EnterCdmCritSection();
|
||
|
|
||
|
*Count = ListEntries;
|
||
|
if (ListEntries != 0)
|
||
|
{
|
||
|
Things = (IWbemClassObject **)WmipAlloc( ListEntries *
|
||
|
sizeof(IWbemClassObject *));
|
||
|
if (Things != NULL)
|
||
|
{
|
||
|
*Objects = Things;
|
||
|
|
||
|
for (i = 0; i < ListEntries; i++)
|
||
|
{
|
||
|
Things[i] = List[i].ResultInstance;
|
||
|
Things[i]->AddRef();
|
||
|
}
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
} else {
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
} else {
|
||
|
*Objects = NULL;
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
LeaveCdmCritSection();
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CResultList::GetResultByResultRelPath(
|
||
|
PWCHAR ObjectPath,
|
||
|
IWbemClassObject **ppResult
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
ULONG i;
|
||
|
|
||
|
hr = WBEM_E_NOT_FOUND;
|
||
|
|
||
|
EnterCdmCritSection();
|
||
|
|
||
|
for (i = 0; i < ListEntries; i++)
|
||
|
{
|
||
|
if (_wcsicmp(ObjectPath, List[i].ResultRelPath) == 0)
|
||
|
{
|
||
|
*ppResult = List[i].ResultInstance;
|
||
|
(*ppResult)->AddRef();
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LeaveCdmCritSection();
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CResultList::GetResultByResultForMSERelPath(
|
||
|
PWCHAR ObjectPath,
|
||
|
IWbemClassObject **ppResult
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
ULONG i;
|
||
|
|
||
|
hr = WBEM_E_NOT_FOUND;
|
||
|
|
||
|
EnterCdmCritSection();
|
||
|
|
||
|
for (i = 0; i < ListEntries; i++)
|
||
|
{
|
||
|
if (_wcsicmp(ObjectPath, List[i].ResultForMSERelPath) == 0)
|
||
|
{
|
||
|
*ppResult = List[i].ResultInstance;
|
||
|
(*ppResult)->AddRef();
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LeaveCdmCritSection();
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT CResultList::GetResultByResultForTestRelPath(
|
||
|
PWCHAR ObjectPath,
|
||
|
IWbemClassObject **ppResult
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
ULONG i;
|
||
|
|
||
|
hr = WBEM_E_NOT_FOUND;
|
||
|
|
||
|
EnterCdmCritSection();
|
||
|
|
||
|
for (i = 0; i < ListEntries; i++)
|
||
|
{
|
||
|
if (_wcsicmp(ObjectPath, List[i].ResultForTestRelPath) == 0)
|
||
|
{
|
||
|
*ppResult = List[i].ResultInstance;
|
||
|
(*ppResult)->AddRef();
|
||
|
hr = WBEM_S_NO_ERROR;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LeaveCdmCritSection();
|
||
|
return(hr);
|
||
|
}
|