/*++ Copyright (C) 1999-2001 Microsoft Corporation Module Name: Abstract: History: --*/ // ***************************************************** // // Testmods.cpp // // ***************************************************** #include "precomp.h" #include #include #include #include #include #include #include #include #include #include #define TESTMOD_NOTIF L"TESTMOD_NOTIF" int TestSuiteStressTest::iRunning = 0; int __cdecl IsNT(void) { OSVERSIONINFO os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if(!GetVersionEx(&os)) return FALSE; // should never happen return os.dwPlatformId == VER_PLATFORM_WIN32_NT; } int __cdecl IsWinMgmt(void) { return FALSE; } int GetDiff(SYSTEMTIME tEnd, SYSTEMTIME tStart) { int iRet = 0; __int64 iTemp = (tEnd.wDay * 1000000000) + (tEnd.wHour * 10000000) + (tEnd.wMinute * 100000) + (tEnd.wSecond * 1000) + tEnd.wMilliseconds; iTemp -= ((tStart.wDay * 1000000000) + (tStart.wHour * 10000000) + (tStart.wMinute * 100000) + (tStart.wSecond * 1000) + tStart.wMilliseconds); iRet = (int) iTemp; return iRet; } // ***************************************************** HRESULT SetBoolQfr(IWbemClassObject *pObj, LPWSTR lpPropName, LPWSTR lpQfrName) { HRESULT hr; VARIANT vTemp; VariantInit(&vTemp); IWbemQualifierSet *pQS = NULL; hr = pObj->GetPropertyQualifierSet(lpPropName, &pQS); if (SUCCEEDED(hr)) { vTemp.boolVal = true; vTemp.vt = VT_BOOL; hr = pQS->Put(lpQfrName, &vTemp, 3); VariantClear(&vTemp); pQS->Release(); } return hr; } // ***************************************************** HRESULT SetAsKey(IWbemClassObject *pObj, LPWSTR lpPropName) { HRESULT hr; hr = SetBoolQfr(pObj, lpPropName, L"key"); return hr; } // ***************************************************** HRESULT SetStringProp(IWbemClassObject *pObj, LPWSTR lpPropName, LPWSTR lpValue, BOOL bKey, CIMTYPE ct ) { HRESULT hr = WBEM_S_NO_ERROR; VARIANT vTemp; VariantInit(&vTemp); vTemp.bstrVal = SysAllocString(lpValue); vTemp.vt = VT_BSTR; hr = pObj->Put(lpPropName, 0, &vTemp, ct); VariantClear(&vTemp); if (SUCCEEDED(hr) && bKey) hr = SetAsKey(pObj, lpPropName); return hr; } // ***************************************************** HRESULT SetIntProp(IWbemClassObject *pObj, LPWSTR lpPropName, DWORD dwValue, BOOL bKey, CIMTYPE ct) { HRESULT hr = WBEM_S_NO_ERROR; VARIANT vTemp; VariantInit(&vTemp); switch(ct) { case CIM_BOOLEAN: V_BOOL(&vTemp) = (BOOL)dwValue; vTemp.vt = VT_BOOL; break; case CIM_SINT8: case CIM_UINT8: case CIM_CHAR16: V_UI1(&vTemp) = (unsigned char)dwValue; vTemp.vt = VT_UI1; break; case CIM_SINT16: V_I2(&vTemp) = (short)dwValue; vTemp.vt = VT_I2; break; case CIM_UINT16: case CIM_SINT32: case CIM_UINT32: V_I4(&vTemp) = dwValue; vTemp.vt = VT_I4; break; default: vTemp.vt = VT_NULL; break; } hr = pObj->Put(lpPropName, 0, &vTemp, ct); VariantClear(&vTemp); if (SUCCEEDED(hr) && bKey) hr = SetAsKey(pObj, lpPropName); return hr; } // ***************************************************** DWORD GetNumericValue (IWbemClassObject *pObj, LPWSTR lpPropName) { DWORD dwRet = 0; VARIANT vTemp; VariantInit(&vTemp); HRESULT hr = pObj->Get(lpPropName, 0, &vTemp, NULL, NULL); if (SUCCEEDED(hr)) dwRet = vTemp.lVal; VariantClear(&vTemp); return dwRet; } // ***************************************************** _bstr_t GetStringValue (IWbemClassObject *pObj, LPWSTR lpPropName) { _bstr_t sRet; VARIANT vTemp; VariantInit(&vTemp); HRESULT hr = pObj->Get(lpPropName, 0, &vTemp, NULL, NULL); if (SUCCEEDED(hr) && vTemp.vt == VT_BSTR) sRet = vTemp.bstrVal; else sRet = L""; VariantClear(&vTemp); return sRet; } // ***************************************************** HRESULT ValidateProperty(IWbemClassObject *pObj, LPWSTR lpPropName, CIMTYPE cimtype, VARIANT *vDefault) { HRESULT hr = WBEM_S_NO_ERROR; VARIANT vTemp; CIMTYPE ct; VariantInit(&vTemp); hr = pObj->Get(lpPropName, 0, &vTemp, &ct, NULL); if (SUCCEEDED(hr)) { if (vDefault == NULL) { if (vTemp.vt != VT_NULL) hr = WBEM_E_FAILED; } else if (cimtype != ct) hr = WBEM_E_TYPE_MISMATCH; else { // FIXME: Deal with arrays!!! if (vDefault->vt == VT_I4) { switch(vTemp.vt) { case VT_I4: if (V_I4(&vTemp) != V_I4(vDefault)) hr = WBEM_E_FAILED; break; case VT_I2: if (V_I2(&vTemp) != V_I4(vDefault)) hr = WBEM_E_FAILED; break; case VT_UI1: if (V_UI1(&vTemp) != V_I4(vDefault)) hr = WBEM_E_FAILED; break; case VT_BOOL: if ((!V_BOOL(&vTemp)) != (!V_I4(vDefault))) hr = WBEM_E_FAILED; break; case VT_R4: if (V_R4(&vTemp) != V_I4(vDefault)) hr = WBEM_E_FAILED; break; case VT_R8: if (V_R8(&vTemp) != V_I4(vDefault)) hr = WBEM_E_FAILED; break; default: hr = WBEM_E_FAILED; break; } } else if (vDefault->vt == VT_BSTR) { if (_wcsicmp(vDefault->bstrVal,vTemp.bstrVal)) hr = WBEM_E_FAILED; } } } VariantClear(&vTemp); return hr; } // ***************************************************** HRESULT ValidateProperty(IWbemClassObject *pObj, LPWSTR lpPropName, CIMTYPE cimtype, DWORD dwVal) { HRESULT hr = WBEM_S_NO_ERROR; VARIANT vTemp; VariantInit(&vTemp); V_I4(&vTemp) = dwVal; vTemp.vt = VT_I4; hr = ValidateProperty(pObj, lpPropName, cimtype, &vTemp); VariantClear(&vTemp); return hr; } // ***************************************************** HRESULT ValidateProperty(IWbemClassObject *pObj, LPWSTR lpPropName, CIMTYPE cimtype, LPWSTR lpVal) { HRESULT hr = WBEM_S_NO_ERROR; VARIANT vTemp; VariantInit(&vTemp); V_BSTR(&vTemp) = SysAllocString(lpVal); vTemp.vt = VT_BSTR; hr = ValidateProperty(pObj, lpPropName, cimtype, &vTemp); VariantClear(&vTemp); return hr; } // ***************************************************** // // SuiteManager // // ***************************************************** HRESULT SuiteManager::RunSuite(int iSuiteNum, IWmiDbSession *pSession, IWmiDbController *pController, IWmiDbHandle *pScope) { HRESULT hr = WBEM_S_NO_ERROR; int i =0; switch(iSuiteNum) { case SUITE_FUNC: dwTotalSuites++; hr = ppSuites[0]->RunSuite(pSession, pController, pScope); dwNumSuccess = ppSuites[0]->GetNumSuccess(); dwNumFailed = ppSuites[0]->GetNumFailed(); dwNumRun = ppSuites[0]->GetNumRun(); break; case SUITE_ERR: dwTotalSuites++; hr = ppSuites[2]->RunSuite(pSession, pController, pScope); dwNumSuccess = ppSuites[1]->GetNumSuccess(); dwNumFailed = ppSuites[1]->GetNumFailed(); dwNumRun = ppSuites[1]->GetNumRun(); break; case SUITE_STRESS: dwTotalSuites++; hr = ppSuites[1]->RunSuite(pSession, pController, pScope); dwNumSuccess = ppSuites[2]->GetNumSuccess(); dwNumFailed = ppSuites[2]->GetNumFailed(); dwNumRun = ppSuites[2]->GetNumRun(); break; case SUITE_CUST: dwTotalSuites++; hr = ppSuites[3]->RunSuite(pSession, pController, pScope); dwNumSuccess = ppSuites[2]->GetNumSuccess(); dwNumFailed = ppSuites[2]->GetNumFailed(); dwNumRun = ppSuites[2]->GetNumRun(); break; case SUITE_ALL: for (i = 0; i < NUM_INITIAL_SUITES; i++) { pController->FlushCache(0); dwTotalSuites++; hr = ppSuites[i]->RunSuite(pSession, pController, pScope); dwNumSuccess += ppSuites[i]->GetNumSuccess(); dwNumFailed += ppSuites[i]->GetNumFailed(); dwNumRun += ppSuites[i]->GetNumRun(); if (FAILED(hr)) { if (ppSuites[i]->StopOnFailure()) break; } } break; default: hr = WBEM_E_INVALID_PARAMETER; break; } return hr; } // ***************************************************** void SuiteManager::DumpResults(BOOL bDetail) { dwNumRun = 0; dwNumSuccess = 0; dwNumFailed = 0; printf("*********************************\n"); printf("* R E S U L T S *\n"); printf("*********************************\n"); for (int i = 0; i < NUM_INITIAL_SUITES; i++) { dwNumRun += ppSuites[i]->GetNumRun(); dwNumSuccess += ppSuites[i]->GetNumSuccess(); dwNumFailed += ppSuites[i]->GetNumFailed(); } printf("*********************************\n\n"); printf("* Suites Run %ld \n", dwTotalSuites); printf("* Scenarios Run %ld \n", dwNumRun); printf("* Succeeded %ld \n", dwNumSuccess); printf("* Failed %ld \n", dwNumFailed); if (dwNumRun) printf("* Pass Rate %lG \n", ((float)dwNumSuccess/(float)dwNumRun)*100); printf("*********************************\n\n"); } SuiteManager::SuiteManager(const wchar_t *pszFileName, const wchar_t *pszLogon, int nMaxThreads, int nMaxDepth, int nMaxNumObjs) { iMaxThreads = nMaxThreads; iMaxDepth = nMaxDepth; iMaxNumObjs = nMaxNumObjs; dwTotalSuites = 0; dwNumRun = 0; dwNumSuccess = 0; dwNumFailed = 0; tStartTime = 0; tEndTime = 0; ppSuites = (TestSuite **) new TestSuite *[NUM_INITIAL_SUITES]; ppSuites[0] = new TestSuiteFunctionality(pszFileName, pszLogon); ppSuites[1] = new TestSuiteStressTest(pszFileName, nMaxDepth, nMaxNumObjs, nMaxThreads); ppSuites[2] = new TestSuiteErrorTest(pszFileName, nMaxThreads); ppSuites[3] = new TestSuiteCustRepDrvr(pszFileName); } SuiteManager::~SuiteManager() { //for (int i = 0; i < NUM_INITIAL_SUITES; i++) //delete ppSuites[i]; delete ppSuites; } // ***************************************************** // // StatData // // ***************************************************** StatData::StatData() { pNext = NULL; hrErrorCode = 0; } StatData::~StatData() { } // ***************************************************** void StatData::PrintData() { wprintf(L"* %d:%d:%d.%d - %s\n", EndTime.wHour, EndTime.wMinute, EndTime.wSecond, EndTime.wMilliseconds, (const wchar_t *)szDescription); wprintf(L" %s with error code %X [Duration = %ld ms]\n", (SUCCEEDED(hrErrorCode) ? L"succeeded" : L"FAILED"), hrErrorCode, dwDuration); if (pNext) pNext->PrintData(); } // ***************************************************** // // TestSuite // // ***************************************************** void TestSuite::DumpResults() { printf("*********************************\n"); if (pStats) pStats->PrintData(); } // ***************************************************** TestSuite::TestSuite(const wchar_t *pszFileName) { hMajorResult = WBEM_S_NO_ERROR; sResult = L""; pStats = NULL; pEndStat = NULL; dwNumSuccess = 0; dwNumFailed = 0; dwNumRun = 0; sprintf(szFileName, "%S", pszFileName); } // ***************************************************** TestSuite::~TestSuite() { delete pStats; } // ***************************************************** BOOL TestSuite::RecordResult(HRESULT hrInput, const wchar_t *pszDetails, long lMilliseconds, ...) { BOOL bRet = TRUE; wchar_t wMsg[1024]; va_list argptr; va_start(argptr, lMilliseconds); vswprintf(wMsg, pszDetails, argptr); va_end(argptr); if (FAILED(hrInput)) { wprintf(L"ERROR: * %s FAILED (%X)\n", wMsg, hrInput); } if (strlen(szFileName)) { FILE *fp = fopen(szFileName, "ab"); if (fp) { SYSTEMTIME EndTime; GetLocalTime(&EndTime); fprintf(fp, "* %d:%d:%d.%d - %S\r\n", EndTime.wHour, EndTime.wMinute, EndTime.wSecond, EndTime.wMilliseconds, (const wchar_t *)wMsg); fprintf(fp, " %s with error code %X [Duration = %ld ms]\r\n", (SUCCEEDED(hrInput) ? "succeeded" : "FAILED"), hrInput, lMilliseconds); fclose(fp); } } if (SUCCEEDED(hrInput)) dwNumSuccess++; else dwNumFailed++; dwNumRun++; return bRet; } // ***************************************************** HRESULT TestSuite::GetObject(IWmiDbHandle *pScope, LPWSTR lpObjName, DWORD dwHandleType, DWORD dwNumObjects, IWmiDbHandle **pHandle, IWbemClassObject **pObj, LPWSTR lpParent) { HRESULT hr = WBEM_S_NO_ERROR; IWbemPath *pPath = NULL; *pObj =NULL; *pHandle = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); if (SUCCEEDED(hr)) { hr = pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, lpObjName); hr = pSession->GetObject(pScope, pPath, 0, dwHandleType, pHandle); if (SUCCEEDED(hr)) { IWmiDbHandle *pTemp = *pHandle; hr = pTemp->QueryInterface(IID_IWbemClassObject, (void **)pObj); if (SUCCEEDED(hr)) { // Verify the object. Make sure it contains the // properties that were created - no more, no less. if (dwNumObjects != (DWORD)-1) { DWORD dwRet = GetNumericValue(*pObj, L"__Property_Count"); if (dwRet != dwNumObjects) hr = WBEM_E_INVALID_OBJECT; } _bstr_t sRet = GetStringValue(*pObj, L"__Namespace"); if (!sRet.length()) hr = WBEM_E_INVALID_NAMESPACE; if (lpParent != NULL) { sRet = GetStringValue(*pObj, L"__SuperClass"); if (_wcsicmp(lpParent, sRet)) hr = WBEM_E_INVALID_SUPERCLASS; } } } pPath->Release(); } else wprintf(L"WARNING: call failed to CoCreateInstance (IID_IWbemPath).\n"); if (FAILED(hr)) { if (*pHandle) (*pHandle)->Release(); if (*pObj) (*pObj)->Release(); } return hr; } // ***************************************************** // // TestSuiteFunctionality // // ***************************************************** BOOL TestSuiteFunctionality::StopOnFailure() { return TRUE; } // ***************************************************** HRESULT TestSuiteFunctionality::RunSuite(IWmiDbSession *_pSession, IWmiDbController *_pController, IWmiDbHandle *_pScope) { wprintf(L" *** Functionality Suite running... *** \n"); RecordResult(0, L" *** Functionality Suite running... *** \n", 0); HRESULT hr = 0; pSession = _pSession; pController = _pController; pScope = _pScope; try { ValidateAPIs(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while validating APIs", 0); } try { hr = CreateObjects(); // If we can't create objects, fail. } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while creating objects.", 0); goto Exit; } if (SUCCEEDED(hr)) { try { hr = GetObjects(); // If we can't retrieve objects, fail. } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while retrieving objects.", 0); hr = WBEM_E_FAILED; goto Exit; } if (SUCCEEDED(hr)) { try { HandleTypes(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing handle types.", 0); hr = WBEM_E_FAILED; goto Exit; } try { VerifyCIMClasses(); } catch (...){ RecordResult(WBEM_E_FAILED, L"Caught an exception while testing CIM class types.", 0); hr = WBEM_E_FAILED; goto Exit; } try { VerifyCIMTypes(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing CIM property types.", 0); hr = WBEM_E_FAILED; goto Exit; } try { VerifyMethods(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while verifying methods.", 0); hr = WBEM_E_FAILED; goto Exit; } try { UpdateObjects(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while updating objects.", 0); hr = WBEM_E_FAILED; goto Exit; } try { ChangeHierarchy(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing hierarchy changes.", 0); hr = WBEM_E_FAILED; goto Exit; } try { VerifyContainers(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing containers.", 0); hr = WBEM_E_FAILED; goto Exit; } try { Security(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing security.", 0); hr = WBEM_E_FAILED; goto Exit; } try { VerifyTransactions(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing transactions.", 0); hr = WBEM_E_FAILED; goto Exit; } if (Interfaces[IWmiDbBatchSession_pos]) { try { Batch(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing batch operations.", 0); hr = WBEM_E_FAILED; goto Exit; } } try { DeleteObjects(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing deletes.", 0); hr = WBEM_E_FAILED; goto Exit; } if (Interfaces[IWbemQuery_pos]) { try { Query(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception while testing queries.", 0); hr = WBEM_E_FAILED; goto Exit; } } } } Exit: return hr; } // ***************************************************** TestSuiteFunctionality::TestSuiteFunctionality(const wchar_t *pszFile, const wchar_t *pszLogon) : TestSuite(pszFile) { sLogon = pszLogon; } // ***************************************************** TestSuiteFunctionality::~TestSuiteFunctionality() { } // ***************************************************** HRESULT TestSuiteFunctionality::ValidateAPIs() { HRESULT hr; SYSTEMTIME tStartTime, tEndTime; DWORD dwResult = 0; // Make sure all the required interfaces are supported. // These are: IWmiDbController, IWmiDbSession, IWmiDbHandle, IWmiBinaryObjectPath, // IWmiDbBatchSession, IWmiDbIterator // Since the first four have already been proven if we have gotten to this point, // so just try the others. IWmiDbBatchSession *pBatch= NULL; hr = pSession->QueryInterface(IID_IWmiDbBatchSession, (void **)&pBatch); RecordResult(hr, L"Supports IWmiDbBatchSession", 0); if (SUCCEEDED(hr)) { Interfaces[IWmiDbBatchSession_pos] = TRUE; pBatch->Release(); } else Interfaces[IWmiDbBatchSession_pos] = FALSE; IWbemQuery *pQuery = NULL; hr = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery); RecordResult(hr, L"Supports IWbemQuery", 0); if (SUCCEEDED(hr)) { Interfaces[IWbemQuery_pos] = TRUE; IWmiDbIterator *pIterator = NULL; wchar_t szTmp[100]; wcscpy(szTmp, L"select * from __Namespace"); // This has got to be supported... pQuery->Parse(L"SQL", szTmp, 0); GetLocalTime(&tStartTime); hr = pSession->ExecQuery(pScope, pQuery, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pIterator); GetLocalTime(&tEndTime); if (SUCCEEDED(hr)) { if (pIterator != NULL) { RecordResult(WBEM_S_NO_ERROR, L"Supports IWmiDbIterator", 0); Interfaces[IWmiDbIterator_pos] = TRUE; pIterator->Release(); } else { Interfaces[IWmiDbIterator_pos] = FALSE; RecordResult(WBEM_E_NOT_FOUND, L"Supports IWmiDbIterator", 0); } } pQuery->Release(); RecordResult(hr, L"Execute query: 'select * from __Namespace'", GetDiff(tEndTime,tStartTime)); } else { Interfaces[IWbemQuery_pos] = FALSE; Interfaces[IWmiDbIterator_pos] = FALSE; } // Check the optional APIs RecordResult(pController->SetCallTimeout(30000), L"IWmiDbController::SetCallTimeout 30 secs. ", 0); RecordResult(pController->GetStatistics(WMIDB_FLAG_TOTAL_HANDLES, &dwResult), L"IWmiDbController::GetStatistics (Total Handles)", 0); RecordResult(pController->GetStatistics(WMIDB_FLAG_CACHE_SATURATION, &dwResult), L"IWmiDbController::GetStatistics (Cache Saturation)", 0); RecordResult(pController->GetStatistics(WMIDB_FLAG_CACHE_HIT_RATE, &dwResult), L"IWmiDbController::GetStatistics (Cache Hit Rate)", 0); // Set decoration. RecordResult(pSession->SetDecoration(L"MACHINE1", L"root\\default"), L"IWmiDbSession::SetDecoration (Machine1, root\\default)", 0); return WBEM_S_NO_ERROR; // We are only testing non-essential interfaces here. } // ***************************************************** HRESULT TestSuiteFunctionality::CreateObjects() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; VARIANT vClass; VariantInit(&vClass); // Everything needs to be scoped to pScope! // We should only fail this call if a *major* piece of functionality does not work. // If the flag doesn't work, oh well. IWbemClassObject *pParentClass = NULL; IWmiDbHandle *pParentHandle = NULL; hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pParentClass); if (SUCCEEDED(hr)) { // class Parent1 { [key] uint32 Key1; }; pParentClass->Put(L"Key1", 0, NULL, CIM_UINT32); SetAsKey(pParentClass, L"Key1"); SetStringProp(pParentClass, L"__Class", L"Parent1"); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pParentClass, WBEM_FLAG_CREATE_OR_UPDATE, WMIDB_HANDLE_TYPE_COOKIE, &pParentHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject (Parent1, Key1=uint32, cookie)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { if (!pParentHandle) RecordResult(WBEM_E_UNEXPECTED, L"IWmiDbSession::PutObject populating handle", 0); else { pParentClass->Release(); GetLocalTime(&tStartTime); hr = pParentHandle->QueryInterface(IID_IWbemClassObject, (void **)&pParentClass); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbHandle::QueryInterface (IWbemClassObject)", GetDiff(tEndTime,tStartTime)); // class Child1:Parent1 { [key] uint32 Key1; string Prop1;}; if (SUCCEEDED(hr)) { IWbemClassObject *pChildClass = NULL; IWmiDbHandle *pChildHandle = NULL; hr = pParentClass->SpawnDerivedClass(0, &pChildClass); if (FAILED(hr)) { RecordResult(hr, L"IWbemClassObject::SpawnDerivedClass", 0); return hr; } SetStringProp(pChildClass, L"__Class", L"Child1"); pChildClass->Put(L"Prop1", 0, NULL, CIM_STRING); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pChildClass, WBEM_FLAG_CREATE_OR_UPDATE, WMIDB_HANDLE_TYPE_COOKIE, &pChildHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject (Child1:Parent1, Prop1=string, cookie)", GetDiff(tEndTime,tStartTime)); // instance of Child1 { Key1 = 1; Prop1 = "ABCDEF";}; if (SUCCEEDED(hr)) { IWbemClassObject *pChildInstance = NULL; IWmiDbHandle *pInst = NULL; pChildClass->Release(); GetLocalTime(&tStartTime); hr = pChildHandle->QueryInterface(IID_IWbemClassObject, (void **)&pChildClass); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbHandle::QueryInterface (IWbemClassObject)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { pChildClass->SpawnInstance(0, &pChildInstance); SetStringProp(pChildInstance, L"Prop1", L"ABCDEF"); vClass.lVal = 1; vClass.vt = VT_I4; hr = pChildInstance->Put(L"Key1", 0, &vClass, CIM_UINT32); VariantClear(&vClass); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pChildInstance, WBEM_FLAG_CREATE_ONLY, WMIDB_HANDLE_TYPE_COOKIE, &pInst); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - create_only (Child1.Key1=1)", GetDiff(tEndTime,tStartTime)); if (pInst) pInst->Release(); else if (SUCCEEDED(hr)) RecordResult(WBEM_E_UNEXPECTED, L"IWmiDbSession::PutObject populating handle", 0); pChildInstance->Release(); } } // instance of Parent1 {Key1 =2;}; IWbemClassObject *pParentInst = NULL; IWmiDbHandle *pInst = NULL; pParentClass->SpawnInstance(0, &pParentInst); vClass.lVal = 2; vClass.vt = VT_I4; hr = pParentInst->Put(L"Key1", 0, &vClass, CIM_UINT32); VariantClear(&vClass); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pParentInst, WBEM_FLAG_CREATE_OR_UPDATE, WMIDB_HANDLE_TYPE_COOKIE, &pInst); RecordResult(hr, L"IWmiDbSession::PutObject (Parent1.Key1=2)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr) && pInst) { // This seems pointless, but this makes sure we can scope // to objects that are not of class __Namespace: // Create a class "SubScope1", scoped to the Parent1=2 Sleep(1000); IWbemClassObject *pScopeObj = NULL; IWmiDbHandle *pScopeHandle = NULL; // #pragma namespace // class SubScope1 { [key] uint32 Key1;}; hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pScopeObj); if (SUCCEEDED(hr)) { pScopeObj->Put(L"Key1", 0, NULL, CIM_UINT32); SetStringProp(pScopeObj, L"__Class", L"SubScope1"); SetAsKey(pScopeObj, L"Key1"); GetLocalTime(&tStartTime); hr = pSession->PutObject(pInst, IID_IWbemClassObject, pScopeObj, WBEM_FLAG_CREATE_OR_UPDATE, WMIDB_HANDLE_TYPE_COOKIE, &pScopeHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject (Parent1=2:SubScope1, Key1=uint32, cookie)", GetDiff(tEndTime,tStartTime)); // instance of SubScope1 {Key1 = 1;}; if (pScopeHandle) { pScopeObj->Release(); pScopeHandle->QueryInterface(IID_IWbemClassObject, (void **)&pScopeObj); if (pScopeObj) { IWbemClassObject *pScopeInst = NULL; IWmiDbHandle *pScopeInstHandle = NULL; pScopeObj->SpawnInstance(0, &pScopeInst); if (pScopeInst) { vClass.lVal = 1; vClass.vt = VT_I4; pScopeInst->Put(L"Key1", 0, &vClass, CIM_UINT32); VariantClear(&vClass); GetLocalTime(&tStartTime); hr = pSession->PutObject(pInst, IID_IWbemClassObject, pScopeInst, WBEM_FLAG_CREATE_OR_UPDATE, WMIDB_HANDLE_TYPE_COOKIE, &pScopeInstHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject (Parent1=2:SubScope1.Key1=1)", GetDiff(tEndTime,tStartTime)); if (pScopeInstHandle) pScopeInstHandle->Release(); pScopeInst->Release(); } // class SubScope2: SubScope1 {[key] uint32 Key1; string Prop1;}; IWbemClassObject *pScopeObj2 = NULL; IWmiDbHandle *pScope2Handle = NULL; pScopeObj->SpawnDerivedClass(0, &pScopeObj2); if (pScopeObj2) { pScopeObj2->Put(L"Prop1", 0, NULL, CIM_STRING); SetStringProp(pScopeObj2, L"__Class", L"SubScope2"); GetLocalTime(&tStartTime); hr = pSession->PutObject(pInst, IID_IWbemClassObject, pScopeObj2, WBEM_FLAG_CREATE_OR_UPDATE, WMIDB_HANDLE_TYPE_COOKIE, &pScope2Handle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject (SubScope2:SubScope1)", GetDiff(tEndTime,tStartTime)); if (pScope2Handle) pScope2Handle->Release(); pScopeObj2->Release(); } } pScopeHandle->Release(); } pScopeObj->Release(); } pInst->Release(); } } pParentInst->Release(); if (pChildClass) pChildClass->Release(); if (pChildHandle) pChildHandle->Release(); } } hr = WBEM_S_NO_ERROR; // nothing else is fatal } pParentClass->Release(); if(pParentHandle) pParentHandle->Release(); } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::GetObjects() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; BOOL bFatal = FALSE; // Retrieve and verify the objects we already created. // Failing Parent1, Child1 or the instances is fatal. // class Parent1 { [key] uint32 Key1; }; IWbemClassObject *pObj = NULL; IWmiDbHandle *pHandle = NULL; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (Parent1) - cookie", GetDiff(tEndTime,tStartTime)); if (pObj) RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, (VARIANT *)NULL), L"Validating Parent1.Key1", 0); else bFatal = TRUE; // Make sure they have the same IUnknown pointers // We perform this test only once. //if (pHandle != NULL && pObj != NULL) // RecordResult(((IUnknown *)pObj == (IUnknown *)pHandle)?0:WBEM_E_TYPE_MISMATCH, L"IWbemClassObject and IWmiDbHandle have same IUnknown pointers", 0); if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); // class Child1:Parent1 { [key] uint32 Key1; string Prop1;}; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Child1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pHandle, &pObj, L"Parent1"); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (Child1) - cookie", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, (VARIANT *)NULL), L"Validating Child1.Key1", 0); RecordResult(ValidateProperty(pObj, L"Prop1", CIM_STRING, (VARIANT *)NULL), L"Validating Child.Prop1", 0); if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); } else bFatal = TRUE; // instance of Parent1 {Key1 =2;}; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Parent1=2", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (Parent1=2) - cookie", GetDiff(tEndTime,tStartTime)); IWmiDbHandle *pInstHandle = NULL; if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, 2), L"Validating Parent1=2.Key1", 0); if (pObj) pObj->Release(); pInstHandle = pHandle;// save it, this is our scope! } else bFatal = TRUE; // instance of Child1 { Key1 = 1; Prop1 = "ABCDEF";}; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Child1=1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pHandle, &pObj, L"Parent1"); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (Child1=1) - cookie", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, 1), L"Validating Child1.Key1=1", 0); RecordResult(ValidateProperty(pObj, L"Prop1", CIM_STRING, L"ABCDEF"), L"Validating Child1=1.Prop1", 0); if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); } // instance of Child1 { Key1 = 1}; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Parent1=1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pHandle, &pObj, L"Parent1"); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (Parent1=1) - specifying parent class", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, 1), L"Validating Child1.Key1=1", 0); RecordResult(ValidateProperty(pObj, L"Prop1", CIM_STRING, L"ABCDEF"), L"Validating Child1=1.Prop1", 0); if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); } // Full path (including all scopes) GetLocalTime(&tStartTime); hr = GetObject(pScope, L"\\\\.\\root\\default\\test:Parent1=2:SubScope1=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (test:Parent1=2:SubScope1=1) - cookie", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { if (pHandle) pHandle->Release(); if (pObj) pObj->Release(); } // Full path (including all scopes) GetLocalTime(&tStartTime); hr = GetObject(pScope, L"\\\\.\\root\\default\\test", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (\\\\.\\root\\default\\test) - cookie", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { if (pHandle) pHandle->Release(); if (pObj) pObj->Release(); } if (pInstHandle) { // class SubScope1 { [key] uint32 Key1;}; GetLocalTime(&tStartTime); hr = GetObject(pInstHandle, L"SubScope1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (SubScope1) - cookie", GetDiff(tEndTime,tStartTime)); if (pObj) RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, (VARIANT *)NULL), L"Validating SubScope1.Key1", 0); if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); // class SubScope2: SubScope1 {[key] uint32 Key1; string Prop1;}; GetLocalTime(&tStartTime); hr = GetObject(pInstHandle, L"SubScope2", WMIDB_HANDLE_TYPE_COOKIE, 2, &pHandle, &pObj, L"SubScope1"); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (SubScope2) - cookie", GetDiff(tEndTime,tStartTime)); if (pObj) { RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, (VARIANT *)NULL), L"Validating SubScope2.Key1", 0); RecordResult(ValidateProperty(pObj, L"Prop1", CIM_STRING, (VARIANT *)NULL), L"Validating SubScope2.Prop1", 0); } if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); // instance of SubScope1 {Key1 = 1;}; GetLocalTime(&tStartTime); hr = GetObject(pInstHandle, L"SubScope1=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (SubScope1=1) - cookie", GetDiff(tEndTime,tStartTime)); if (pObj) RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, 1), L"Validating SubScope1.Key1=1", 0); if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); GetLocalTime(&tStartTime); hr = GetObject(pInstHandle, L"..", WMIDB_HANDLE_TYPE_COOKIE, -1, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"GetObject (..) - cookie", GetDiff(tEndTime, tStartTime)); if (pObj) pObj->Release(); if (pHandle) pHandle->Release(); pInstHandle->Release(); } // Changing the decoration from \\MACHINE1\root\default to \\MACHINE2\root\test should cause no error... RecordResult(pSession->SetDecoration(L"MACHINE2", L"root\\test"), L"IWmiDbSession::SetDecoration (Machine2, root\\test)", 0); hr = pScope->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { _IWmiObject *pInt = NULL; hr = pObj->QueryInterface(IID__IWmiObject, (void **)&pInt); pObj->Release(); if (SUCCEEDED(hr)) { hr = pInt->SetDecoration(L"MACHINE2", L"root\\test"); RecordResult(hr, L"_IWmiObject::SetDecoration (root object)", 0); pInt->Release(); RecordResult(GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj), L"IWmiDbSession::GetObject (changed decoration)", 0); } } if (pHandle) pHandle->Release(); if (pObj) { // Ensure that the decoration is what we asked for. RecordResult(!_wcsicmp(GetStringValue(pObj, L"__Namespace"), L"root\\test\\test")?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::SetDecoration properly decorates namespace.", 0); RecordResult(!_wcsicmp(GetStringValue(pObj, L"__Server"), L"MACHINE2")?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::SetDecoration properly decorates server name.", 0); pObj->Release(); } if (bFatal) hr = WBEM_E_FAILED; else hr = WBEM_S_NO_ERROR; return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::HandleTypes() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; // Try all the different handle types. // Cookie, versioned, exclusive, protected.| subscoped // no_caching, strong caching, weak caching // Caching we can't verify, but at least we can find out // if we get an error when we try to use it... IWmiDbHandle *pHandle = NULL; IWbemClassObject *pObj = NULL; IWbemPath *pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); if (SUCCEEDED(hr)) { pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1=2"); GetLocalTime(&tStartTime); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE|WMIDB_HANDLE_TYPE_NO_CACHE, &pHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) no cache", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) pHandle->Release(); GetLocalTime(&tStartTime); hr = pSession->GetObjectDirect(pScope, pPath, 0, IID_IWbemClassObject, (void **)&pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObjectDirect (Parent1=2) ", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) pObj->Release(); GetLocalTime(&tStartTime); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE|WMIDB_HANDLE_TYPE_STRONG_CACHE, &pHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) strong cache", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) pHandle->Release(); GetLocalTime(&tStartTime); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE|WMIDB_HANDLE_TYPE_WEAK_CACHE, &pHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) weak cache", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) pHandle->Release(); // Try out the handle types: // COOKIE blocks nothing and is never validated. // VERSIONED blocks nothing, but is rendered obsolete on Put // PROTECTED handles are blocked by exclusive handles // EXCLUSIVE handles are blocked if there are protected handles, // they block other exclusive handles, and they block the // rendering of a cookie or versioned handle into an object. // SUBSCOPES apply to all dependent objects. // Now, we take out 4 handles: one of each type, IWmiDbHandle *pVersioned = NULL, *pCookie = NULL, *pProtected = NULL, *pExclusive = NULL; hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pCookie); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) cookie", 0); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_VERSIONED, &pVersioned); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) versioned", 0); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_PROTECTED, &pProtected); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) protected", 0); DWORD dwHandleType = 0; if (pCookie) { pCookie->GetHandleType(&dwHandleType); if (dwHandleType == WMIDB_HANDLE_TYPE_INVALID) RecordResult(WBEM_E_INVALID_OBJECT, L"Cookie handle unaffected by protected lock", 0); } if (pVersioned) { pVersioned->GetHandleType(&dwHandleType); if (dwHandleType == WMIDB_HANDLE_TYPE_INVALID) RecordResult(WBEM_E_INVALID_OBJECT, L"Versioned handle unaffected by protected lock", 0); } // The exclusive lock should fail... if (pProtected) { hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pExclusive); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0), L"IWmiDbSession::GetObject (Parent1=2) exclusive (protected outstanding)", 0); if (SUCCEEDED(hr)) pExclusive->Release(); // We should *not* fail to get a cookie or a versioned handle. hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pHandle); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) cookie (protected outstanding)", 0); if (SUCCEEDED(hr)) pHandle->Release(); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_VERSIONED, &pHandle); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) versioned (protected outstanding)", 0); if (SUCCEEDED(hr)) pHandle->Release(); // A second protected should be OK. hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_PROTECTED, &pHandle); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) protected (protected outstanding)", 0); if (SUCCEEDED(hr)) pHandle->Release(); pProtected->GetHandleType(&dwHandleType); RecordResult(dwHandleType == WMIDB_HANDLE_TYPE_PROTECTED?0:WBEM_E_FAILED,L"First protected handle remains after second released", 0); pProtected->Release(); } // With no protected lock, exclusive should succeed. hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pExclusive); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) exclusive", 0); // Now we should fail to get a protected handle... if (pExclusive) { hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_PROTECTED, &pProtected); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0), L"IWmiDbSession::GetObject (Parent1=2) protected (exclusive outstanding)", 0); if (SUCCEEDED(hr)) pProtected->Release(); // We should *not* fail to get a cookie or a versioned handle. hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pHandle); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) cookie (exclusive outstanding)", 0); if (SUCCEEDED(hr)) pHandle->Release(); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_VERSIONED, &pHandle); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2) versioned (exclusive outstanding)", 0); if (SUCCEEDED(hr)) pHandle->Release(); // It should fail to get another exclusive handle. hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pHandle); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0), L"IWmiDbSession::GetObject (Parent1=2) exclusive (exclusive outstanding)", 0); if (SUCCEEDED(hr)) pHandle->Release(); // We should fail to render a cookie as an object. IWbemClassObject *pObj =NULL; hr = pCookie->QueryInterface(IID_IWbemClassObject, (void **)&pObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0), L"IWmiDbHandle::QueryInterface (cookie - exclusive outstanding)", 0); if (SUCCEEDED(hr)) pObj->Release(); // An exclusive lock on Parent should work, if its not subscoped... pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1"); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pHandle); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1 - exclusive)", 0); if (SUCCEEDED(hr)) pHandle->Release(); // We should be able to view the exclusive object. hr = pExclusive->QueryInterface(IID_IWbemClassObject, (void **)&pObj); RecordResult(hr, L"IWmiDbHandle::QueryInterface (exclusive)", 0); if (pObj) { // We should be able to update it. hr = pSession->PutObject(pScope, IID_IWbemClassObject, pExclusive, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pHandle); RecordResult(hr, L"IWmiDbSession::PutObject (Parent1=2 - exclusive)", 0); pObj->Release(); if (SUCCEEDED(hr)) { // Now our versioned handle should be out-of-date... pExclusive->Release(); pHandle->Release(); hr = pVersioned->QueryInterface(IID_IWbemClassObject, (void **)&pObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0),L"IWmiDbHandle::QueryInterface (versioned - out-of-date)", 0); if (SUCCEEDED(hr)) pObj->Release(); } } } if (pCookie) pCookie->Release(); if (pVersioned) pVersioned->Release(); pCookie = NULL, pVersioned = NULL, pProtected = NULL, pExclusive = NULL; // Now, verify if all this worked for subscopes. // An exclusive handle on Parent1=2 should block subscoped protected handles on Parent1 // An exclusive handle on Child1 should block subscoped protected handles on Parent1 // A subscoped protected handle on Parent1 should block an exclusive lock on Parent1=2 // A subscoped protected handle on Parent1 should block an exclusive lock on Child1 pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1=2"); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pHandle); if (SUCCEEDED(hr)) { pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1"); hr = pSession->GetObject(pScope, pPath,0, WMIDB_HANDLE_TYPE_SUBSCOPED|WMIDB_HANDLE_TYPE_EXCLUSIVE, &pExclusive); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0),L"IWmiDbSession::GetObject (subscoped exclusive class, exclusive instance outstanding)", 0); if (SUCCEEDED(hr)) pExclusive->Release(); pHandle->Release(); } pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Child1"); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pHandle); if (SUCCEEDED(hr)) { pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1"); hr = pSession->GetObject(pScope, pPath,0, WMIDB_HANDLE_TYPE_SUBSCOPED|WMIDB_HANDLE_TYPE_EXCLUSIVE, &pExclusive); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0),L"IWmiDbSession::GetObject (subscoped exclusive class, exclusive child outstanding)", 0); if (SUCCEEDED(hr)) pExclusive->Release(); pHandle->Release(); } pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1"); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_EXCLUSIVE|WMIDB_HANDLE_TYPE_SUBSCOPED, &pHandle); if (SUCCEEDED(hr)) { pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1=2"); hr = pSession->GetObject(pScope, pPath,0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pExclusive); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0),L"IWmiDbSession::GetObject (exclusive instance, exclusive subscoped parent lock outstanding)", 0); if (SUCCEEDED(hr)) pExclusive->Release(); pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Child1"); hr = pSession->GetObject(pScope, pPath,0, WMIDB_HANDLE_TYPE_EXCLUSIVE, &pExclusive); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:0),L"IWmiDbSession::GetObject (exclusive class, exclusive subscoped parent lock outstanding)", 0); if (SUCCEEDED(hr)) pExclusive->Release(); pHandle->Release(); } pPath->Release(); } return hr; } // ***************************************************** HRESULT SetBoolQualifier(IWbemClassObject *pObj, LPWSTR lpQfrName, LPWSTR lpPropName = NULL) { HRESULT hr; IWbemQualifierSet *pQS = NULL; if (lpPropName == NULL) pObj->GetQualifierSet(&pQS); else pObj->GetPropertyQualifierSet(lpPropName, &pQS); if (pQS) { VARIANT vTemp; VariantInit(&vTemp); vTemp.boolVal = true; vTemp.vt = VT_BOOL; hr = pQS->Put(lpQfrName, &vTemp, 3); VariantClear(&vTemp); pQS->Release(); } return hr; } // ***************************************************** HRESULT CreateClass (IWmiDbHandle **ppRet, IWmiDbSession *pSession, IWmiDbHandle *pScope, LPWSTR lpClassName, LPWSTR lpQfrName, CIMTYPE ctKey1, LPWSTR lpParent = NULL, LPWSTR lpPropQfr = NULL, CIMTYPE ctKey2=0, DWORD dwOptionalHandle = 0) { HRESULT hr = WBEM_S_NO_ERROR; IWbemClassObject *pObj = NULL; if (lpParent) { IWbemPath *pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); if (SUCCEEDED(hr)) { IWmiDbHandle *pParent = NULL; pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, lpParent); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pParent); if (SUCCEEDED(hr)) { IWbemClassObject *pParentObj = NULL; hr = pParent->QueryInterface(IID_IWbemClassObject, (void **)&pParentObj); if (SUCCEEDED(hr)) { hr = pParentObj->SpawnDerivedClass(0, &pObj); pParentObj->Release(); } pParent->Release(); } pPath->Release(); } } else { hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pObj); } if (SUCCEEDED(hr)) { SetStringProp(pObj, L"__Class", lpClassName); if (ctKey1) { pObj->Put(L"Key1", 0, NULL, ctKey1); SetAsKey(pObj, L"Key1"); if (ctKey1 == CIM_REFERENCE && !_wcsicmp(lpClassName, L"Association1")) { IWbemQualifierSet *pQS = NULL; pObj->GetPropertyQualifierSet(L"Key1", &pQS); VARIANT vTemp; VariantInit(&vTemp); vTemp.bstrVal = SysAllocString(L"ref:Parent1"); vTemp.vt = VT_BSTR; pQS->Put(L"CIMTYPE", &vTemp, 3); pQS->Release(); VariantClear(&vTemp); } } if (ctKey2) { pObj->Put(L"Key2", 0, NULL, ctKey2); SetAsKey(pObj, L"Key2"); if (ctKey2 == CIM_REFERENCE && !_wcsicmp(lpClassName, L"Association1")) { IWbemQualifierSet *pQS = NULL; pObj->GetPropertyQualifierSet(L"Key2", &pQS); VARIANT vTemp; VariantInit(&vTemp); vTemp.bstrVal = SysAllocString(L"ref:Child1"); vTemp.vt = VT_BSTR; pQS->Put(L"CIMTYPE", &vTemp, 3); pQS->Release(); VariantClear(&vTemp); } } if (lpQfrName) SetBoolQualifier(pObj, lpQfrName); if (lpPropQfr) SetBoolQualifier(pObj, lpPropQfr, L"Key1"); // Put the object in the database. hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, WMIDB_HANDLE_TYPE_COOKIE|dwOptionalHandle, ppRet); pObj->Release(); } return hr; } // ***************************************************** HRESULT CreateInstance(IWmiDbHandle **ppRet, IWmiDbSession *pSession, IWmiDbHandle *pScope, LPWSTR lpClassName, LPWSTR lpKeyValue, CIMTYPE ctKey1, LPWSTR lpKey2 = NULL, CIMTYPE ctKey2=0, DWORD dwOptionalHandle = 0, DWORD dwFlags = 0) { HRESULT hr = WBEM_S_NO_ERROR; IWbemPath*pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); if (SUCCEEDED(hr)) { IWmiDbHandle *pParent = NULL; pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, lpClassName); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pParent); if (SUCCEEDED(hr)) { IWbemClassObject *pParentObj = NULL; hr = pParent->QueryInterface(IID_IWbemClassObject, (void **)&pParentObj); if (SUCCEEDED(hr)) { IWbemClassObject *pObj = NULL; pParentObj->SpawnInstance(0, &pObj); if (pObj) { if (ctKey1 == CIM_STRING || ctKey1 == CIM_REFERENCE || ctKey1 == CIM_DATETIME) SetStringProp(pObj, L"Key1", lpKeyValue, FALSE, ctKey1); else if (ctKey1 != 0) SetIntProp(pObj, L"Key1", _wtoi(lpKeyValue), FALSE, ctKey1); if (ctKey2 == CIM_STRING || ctKey2 == CIM_REFERENCE || ctKey2 == CIM_DATETIME) SetStringProp(pObj, L"Key2", lpKey2, FALSE, ctKey1); else if (ctKey2 != 0) SetIntProp(pObj, L"Key2", _wtoi(lpKey2), FALSE, ctKey1); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, dwFlags, WMIDB_HANDLE_TYPE_COOKIE|dwOptionalHandle, ppRet); pObj->Release(); } pParentObj->Release(); } pParent->Release(); } pPath->Release(); } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::VerifyCIMClasses() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; IWmiDbHandle *pRet = NULL; // Verifies most of the standard practices of CIM. // All we want to do here is confirm that the documented concepts // are stored correctly. We don't want to check anything that WMI // should handle internally, since that may change. GetLocalTime(&tStartTime); hr = CreateClass(&pRet, pSession, pScope, L"Abstract1", L"abstract", CIM_UINT32); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating abstract class (Abstract1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { pRet->Release(); hr = CreateInstance(&pRet, pSession, pScope, L"Abstract1", L"1", CIM_UINT32); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:0, L"Failing to create instance of abstract class (Abstract1=1)", 0); if (SUCCEEDED(hr)) pRet->Release(); } // Singleton class. This can have only one instance, total, including // parent or derived classes. GetLocalTime(&tStartTime); hr = CreateClass(NULL, pSession, pScope, L"Singleton1", L"singleton", 0); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating singleton class (Singleton1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = CreateClass(NULL, pSession, pScope, L"Singleton2", L"singleton", 0, L"Singleton1"); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating derived singleton class (Singleton2:Singleton1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { bool bSuccess = false; GetLocalTime(&tStartTime); hr = CreateInstance(NULL, pSession, pScope, L"Singleton2", NULL, 0); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating derived singleton instance (Singleton2=@)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = CreateInstance(NULL, pSession, pScope, L"Singleton1", NULL, 0); GetLocalTime(&tEndTime); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:0, L"Failing to create second singleton instance (Singleton1=@)", GetDiff(tEndTime,tStartTime)); } } } // Associations - classes and instances GetLocalTime(&tStartTime); hr = CreateClass(NULL, pSession, pScope, L"Association1", L"association", CIM_REFERENCE, NULL, NULL, CIM_REFERENCE); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating association class (Association1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = CreateInstance(&pRet, pSession, pScope, L"Association1", L"test:Parent1=2", CIM_REFERENCE, L"test:Child1=1", CIM_REFERENCE); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating association instance (Association1.Key1=\"Parent1=2\",Key2=\"Child1=1\")", GetDiff(tEndTime,tStartTime)); // When we retrieve this object, the two end-points should be translatable into two valid objects. if (SUCCEEDED(hr)) { IWbemClassObject *pObj = NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { VARIANT vTemp; VariantInit(&vTemp); hr = pObj->Get(L"Key1", 0, &vTemp, NULL, NULL); if (SUCCEEDED(hr) && vTemp.vt == VT_BSTR) { IWbemPath*pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, vTemp.bstrVal); IWmiDbHandle *pTemp = NULL; hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pTemp); RecordResult(hr, L"Verifying reference value (Association1.Key1 = Parent1=2)", 0); if (SUCCEEDED(hr)) pTemp->Release(); pPath->Release(); } VariantClear(&vTemp); pObj->Release(); } pRet->Release(); } } // Unkeyed class. This class has no defined key. The object path is dynamically generated. // Instances can only be retrieved by query, not by GetObject. GetLocalTime(&tStartTime); hr = CreateClass(NULL, pSession, pScope, L"Unkeyed1", L"unkeyed", 0); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating unkeyed class (Unkeyed1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = CreateInstance(&pRet, pSession, pScope, L"Unkeyed1", NULL, 0); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating unkeyed instance (Unkeyed1=?)", GetDiff(tEndTime,tStartTime)); if (pRet) { IWbemClassObject *pObj = NULL; GetLocalTime(&tStartTime); hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbHandle::QueryInterface (Unkeyed1)", GetDiff(tEndTime,tStartTime)); pRet->Release(); if (SUCCEEDED(hr)) pObj->Release(); } } // Keyholes. A keyhole property should be populated if left blank. Verify on string and int. hr = CreateClass(NULL, pSession, pScope, L"Keyhole1", NULL, CIM_UINT32, NULL, L"keyhole"); RecordResult(hr, L"Creating class Keyhole1", 0); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = CreateInstance(&pRet, pSession, pScope, L"Keyhole1", NULL, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating keyhole instance (Keyhole1=?)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { IWbemClassObject *pObj =NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { VARIANT vTemp; VariantInit(&vTemp); long lTemp = 0; hr = pObj->Get(L"Key1", 0, &vTemp, NULL, NULL); RecordResult(SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal > 0 ? WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Verifying populated keyhole value (Keyhole1=?).", 0); lTemp = vTemp.lVal; VariantClear(&vTemp); // Now updating this object should leave the value alone... IWmiDbHandle *pTemp = NULL; GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, WMIDB_HANDLE_TYPE_COOKIE, &pTemp); GetLocalTime(&tEndTime); RecordResult(hr, L"Updating existing keyhole (Keyhole1=1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { IWbemClassObject *pTempObj = NULL; hr = pTemp->QueryInterface(IID_IWbemClassObject, (void **)&pTempObj); if (SUCCEEDED(hr)) { hr = pTempObj->Get(L"Key1", 0, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal == lTemp)?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Verifying update of keyhole instance (Keyhole1=1)", 0); VariantClear(&vTemp); pTempObj->Release(); } pTemp->Release(); } pObj->Release(); } pRet->Release(); } } // Compound keys. Create an instance in one order, should be able to retrieve it in the other. hr = CreateClass(NULL, pSession, pScope, L"CompoundKeys1", NULL, CIM_UINT32, NULL, NULL, CIM_UINT32); RecordResult(hr, L"Creating class CompoundKeys1", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"CompoundKeys1", L"1", CIM_UINT32, L"2", CIM_UINT32); RecordResult(hr, L"Creating instance CompoundKeys1=1,2", 0); if (SUCCEEDED(hr)) { pRet = NULL; IWbemClassObject *pObj =NULL; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"CompoundKeys1.Key2=2,Key1=1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pRet, &pObj, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (CompoundKeys1.Key2=2,Key1=1)", GetDiff(tEndTime,tStartTime)); if (pObj) pObj->Release(); if (pRet) pRet->Release(); } hr = CreateInstance(NULL, pSession, pScope, L"CompoundKeys1", L"1", CIM_UINT32, L"1", CIM_UINT32, 0, WBEM_FLAG_CREATE_ONLY); RecordResult(hr, L"Creating instance CompoundKeys1=1,1", 0); if (SUCCEEDED(hr)) { pRet = NULL; IWbemClassObject *pObj =NULL; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"CompoundKeys1.Key2=1,Key1=1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pRet, &pObj, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (CompoundKeys1.Key2=1,Key1=1)", GetDiff(tEndTime,tStartTime)); if (pObj) pObj->Release(); if (pRet) pRet->Release(); } } // Make sure it supports string keyholes. hr = CreateClass(NULL, pSession, pScope, L"Keyhole2", NULL, CIM_STRING, NULL, L"keyhole"); RecordResult(hr, L"Creating class Keyhole2", 0); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = CreateInstance(&pRet, pSession, pScope, L"Keyhole2", NULL, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating keyhole instance (Keyhole2=?)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { IWbemClassObject *pObj =NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { VARIANT vTemp; VariantInit(&vTemp); hr = pObj->Get(L"Key1", 0, &vTemp, NULL, NULL); RecordResult(SUCCEEDED(hr) && vTemp.vt == VT_BSTR && wcslen(vTemp.bstrVal) ? WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Verifying populated keyhole value (Keyhole2).", 0); VariantClear(&vTemp); pObj->Release(); } pRet->Release(); } } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::VerifyMethods() { HRESULT hr; IWmiDbHandle *pRet = NULL; SYSTEMTIME tStartTime, tEndTime; // Methods. This should support methods and method parameters for storage and retrieval. hr = CreateClass(&pRet, pSession, pScope, L"Method1", NULL, CIM_STRING, NULL, NULL, NULL, WMIDB_HANDLE_TYPE_NO_CACHE); RecordResult(hr, L"Creating class Method1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pClass = NULL; if (SUCCEEDED(hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass))) { IWbemQualifierSet *pQS = NULL; VARIANT vTemp; VariantInit(&vTemp); // One method with no parameters. pClass->PutMethod(L"Method1", 0, NULL, NULL); pClass->GetMethodQualifierSet(L"Method1", &pQS); vTemp.vt = VT_BSTR; vTemp.bstrVal = SysAllocString(L"This method has no parameters."); pQS->Put(L"Description", &vTemp, 0); pQS->Release(); VariantClear(&vTemp); // One method with in and out parameters IWbemClassObject *pIn = NULL; IWbemClassObject *pOut = NULL; hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pIn); SetStringProp(pIn, L"__Class", L"__Parameters"); hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pOut); SetStringProp(pOut, L"__Class", L"__Parameters"); // Each parameter needs to have zero-based "id" fields. SetStringProp(pIn, L"InParam1", L"in"); SetIntProp(pIn, L"InParam2", 1); SetStringProp(pOut, L"OutParam1", L"out"); hr = pIn->GetPropertyQualifierSet(L"InParam1", &pQS); if (SUCCEEDED(hr)) { vTemp.vt = VT_I4; vTemp.lVal = 0; hr = pQS->Put(L"id", &vTemp, 0); VariantClear(&vTemp); pQS->Release(); } hr = pIn->GetPropertyQualifierSet(L"InParam2", &pQS); if (SUCCEEDED(hr)) { vTemp.vt = VT_I4; vTemp.lVal = 1; hr = pQS->Put(L"id", &vTemp, 0); pQS->Release(); VariantClear(&vTemp); } hr = pOut->GetPropertyQualifierSet(L"OutParam1", &pQS); if (SUCCEEDED(hr)) { vTemp.vt = VT_I4; vTemp.lVal = 2; hr = pQS->Put(L"id", &vTemp, 0); vTemp.vt = VT_BSTR; vTemp.bstrVal = SysAllocString(L"This is an out parameter."); pQS->Put(L"Description", &vTemp, 0); pQS->Release(); VariantClear(&vTemp); } hr = pClass->PutMethod(L"Method2", 0, pIn, pOut); pIn->Release(); pOut->Release(); hr = pClass->GetMethodQualifierSet(L"Method2", &pQS); if (SUCCEEDED(hr)) { vTemp.vt = VT_BSTR; vTemp.bstrVal = SysAllocString(L"This method has in and out parameters."); pQS->Put(L"Description", &vTemp, 0); pQS->Release(); VariantClear(&vTemp); } GetLocalTime(&tStartTime); IWmiDbHandle *pNew = NULL; hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, WMIDB_HANDLE_TYPE_COOKIE|WMIDB_HANDLE_TYPE_NO_CACHE, &pNew); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating a class with methods (Method1)", GetDiff(tEndTime,tStartTime)); // Retrieve it and make sure it contains all the components we just created. if (SUCCEEDED(hr)) { IWbemClassObject *pNewObj =NULL; hr = pNew->QueryInterface(IID_IWbemClassObject, (void **)&pNewObj); if (SUCCEEDED(hr)) { RecordResult(pNewObj->GetMethod(L"Method1", 0, &pIn, &pOut), L"Verifying existence of Method1.Method1", 0); if (pIn) pIn->Release(); if (pOut) pOut->Release(); RecordResult(pNewObj->GetMethod(L"Method2", 0, &pIn, &pOut), L"Verifying existence of Method1.Method2", 0); RecordResult((pIn == NULL)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Verifying existence of in parameters on Method1.Method2", 0); RecordResult((pOut == NULL)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Verifying existence of out parameters on Method1.Method2", 0); if (pIn) { hr = ValidateProperty(pIn, L"InParam1", CIM_STRING, L"in"); RecordResult(hr, L"Verifying Method1.Method2.InParam1", 0); hr = ValidateProperty(pIn, L"InParam2", CIM_UINT32, 1); RecordResult(hr,L"Verifying Method1.Method2.InParam2", 0); pIn->Release(); } if (pOut) { hr = pOut->Get(L"OutParam1", 0, &vTemp, NULL, NULL); RecordResult(SUCCEEDED(hr) && vTemp.vt == VT_BSTR && !_wcsicmp(vTemp.bstrVal, L"out")?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Verifying Method1.Method2.OutParam1", 0); VariantClear(&vTemp); hr = pOut->GetPropertyQualifierSet(L"OutParam1", &pQS); if (SUCCEEDED(hr)) { hr = pQS->Get(L"Description", NULL, &vTemp, NULL); RecordResult(SUCCEEDED(hr) && vTemp.vt == VT_BSTR && !_wcsicmp(vTemp.bstrVal, L"This is an out parameter.") ?WBEM_S_NO_ERROR:WBEM_E_FAILED,L"Verifying qualifier Method1.Method2.OutParam1.Description", 0); VariantClear(&vTemp); hr = pQS->Get(L"id", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal == 2) ? WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Driver preserves method parameter ID.", 0); VariantClear(&vTemp); pQS->Release(); } pOut->Release(); } pNewObj->GetMethodQualifierSet(L"Method2", &pQS); if (pQS) { hr = pQS->Get(L"Description", NULL, &vTemp, NULL); RecordResult(SUCCEEDED(hr) && vTemp.vt == VT_BSTR && !_wcsicmp(vTemp.bstrVal, L"This method has in and out parameters.") ?WBEM_S_NO_ERROR:WBEM_E_FAILED,L"Verifying qualifier Method1.Method2.Description", 0); pQS->Release(); VariantClear(&vTemp); } pNewObj->Release(); } pNew->Release(); } pClass->Release(); } pRet->Release(); } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::VerifyCIMTypes() { HRESULT hr; SYSTEMTIME tStartTime, tEndTime; IWmiDbHandle *pRet = NULL; IWbemClassObject *pTemp = NULL; // Case-insensitive searches should always work!!! GetLocalTime(&tStartTime); hr = GetObject(pScope, L"parent1.key1=2", WMIDB_HANDLE_TYPE_COOKIE, 1, &pRet, &pTemp); GetLocalTime(&tEndTime); RecordResult(hr, L"Case-insensitive retrieval (parent1.key1=2)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { pRet->Release(); pTemp->Release(); } GetLocalTime(&tStartTime); hr = GetObject(pScope, L"child1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pRet, &pTemp); GetLocalTime(&tEndTime); RecordResult(hr, L"Case-insensitive retrieval (child1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { pRet->Release(); pTemp->Release(); } // Null. If a property is saved as null, it should be returned as null (and not blank). hr = CreateClass(&pRet, pSession, pScope, L"Nulls1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Nulls1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pClass = NULL; if (SUCCEEDED(hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass))) { pRet->Release(); hr = pClass->Put(L"Prop1", 0, NULL, CIM_STRING); hr = pClass->Put(L"Prop2", 0, NULL, CIM_UINT32); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, WMIDB_HANDLE_TYPE_COOKIE, &pRet); if (SUCCEEDED(hr)) { pClass->Release(); pRet->Release(); hr = CreateInstance(&pRet, pSession, pScope, L"Nulls1", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance Nulls1=1", 0); if (SUCCEEDED(hr)) { hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass); if (SUCCEEDED(hr)) { hr = ValidateProperty(pClass, L"Prop1", CIM_STRING, (VARIANT *)NULL); RecordResult(hr, L"Persisting null string data (Nulls1=1.Prop1)", 0); hr = ValidateProperty(pClass, L"Prop2", CIM_UINT32, (VARIANT *)NULL); RecordResult(hr, L"Persisting null uint32 data (Nulls1=1.Prop2)", 0); pClass->Release(); } pRet->Release(); } } } } // Not_Null. Should disallow null on instances. Should disallow null keys hr = CreateClass(&pRet, pSession, pScope, L"Not_Null1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Not_Null1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pClass = NULL; if (SUCCEEDED(hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass))) { pClass->Put(L"Prop1", 0, NULL, CIM_STRING); SetBoolQualifier(pClass, L"not_null", L"Prop1"); pRet->Release(); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, WMIDB_HANDLE_TYPE_COOKIE, &pRet); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"Not_Null1", L"1", CIM_UINT32); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:0, L"Disallowing nulls in a not_null property (Not_Null1.Prop1)", 0); if (pRet) pRet->Release(); } pClass->Release(); } else pRet->Release(); } // Qualifiers + flavors on instances+classes+properties // Storage and retrieval (no cache!) ToInstance and ToSubclass flavors should be preserved. IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pRet, &pObj); RecordResult(hr, L"Retrieving Parent1", 0); if (SUCCEEDED(hr)) { pRet->Release(); IWbemQualifierSet *pQS = NULL; VARIANT vTemp; VariantInit(&vTemp); pObj->GetQualifierSet(&pQS); if (pQS) { vTemp.lVal = 1; vTemp.vt = VT_I4; pQS->Put(L"Number", &vTemp, WBEM_FLAVOR_NOT_OVERRIDABLE|WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS); SetBoolQualifier(pObj, L"Boolean"); pQS->Release(); VariantClear(&vTemp); } pObj->GetPropertyQualifierSet(L"Key1", &pQS); if (pQS) { vTemp.bstrVal = SysAllocString(L"Test"); vTemp.vt = VT_BSTR; pQS->Put(L"Text", &vTemp, WBEM_FLAVOR_NOT_OVERRIDABLE|WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE); pQS->Release(); VariantClear(&vTemp); } hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, WMIDB_HANDLE_TYPE_COOKIE, &pRet); RecordResult(SUCCEEDED(hr) ? WBEM_E_FAILED : WBEM_S_NO_ERROR, L"Storing propagated qualifier on class with instances", 0); /*** NOVA COMPATIBILITY: We can't add a propagated qualifier to a class with instances. if (SUCCEEDED(hr)) { pObj->Release(); hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { pObj->GetQualifierSet(&pQS); if (pQS) { hr = pQS->Get(L"Number", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal == 1)?0:WBEM_E_FAILED, L"Storing and retrieving class int32 (Parent1.Number) qualifiers", 0); VariantClear(&vTemp); hr = pQS->Get(L"Boolean", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BOOL && vTemp.boolVal == -1)?0:WBEM_E_FAILED, L"Storing and retrieving class boolean (Parent1.Boolean) qualifiers", 0); VariantClear(&vTemp); pQS->Release(); } pObj->GetPropertyQualifierSet(L"Key1", &pQS); if (pQS) { hr = pQS->Get(L"Text", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BSTR && !_wcsicmp(L"Test", vTemp.bstrVal))?0:WBEM_E_FAILED, L"Storing and retrieving class text (Parent1.Key1.Text) qualifiers", 0); VariantClear(&vTemp); pQS->Release(); } pObj->Release(); } pRet->Release(); } else pObj->Release(); // If that worked, we should be able to retrieve the // subclass and instance and see the same qualifiers on them. hr = GetObject(pScope, L"Parent1=2", WMIDB_HANDLE_TYPE_COOKIE, 1, &pRet, &pObj); RecordResult(hr, L"Retrieving Parent1=2", 0); if (SUCCEEDED(hr)) { pRet->Release(); pObj->GetQualifierSet(&pQS); if (pQS) { hr = pQS->Get(L"Number", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal == 1)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Verifying new propogated qualifier on class in existing instance (Parent1=2.Number)", 0); VariantClear(&vTemp); vTemp.lVal = 10; vTemp.vt = VT_I4; pQS->Put(L"InstanceNumber", &vTemp, 0); VariantClear(&vTemp); pQS->Release(); } pObj->GetPropertyQualifierSet(L"Key1", &pQS); if (pQS) { hr = pQS->Get(L"Text", NULL, &vTemp, 0); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BSTR )?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Verifying new propogated qualifier on property in existing instance (Parent1=2.Text)", 0); VariantClear(&vTemp); vTemp.lVal = 20; vTemp.vt = VT_I4; pQS->Put(L"InstanceNumber", &vTemp, 0); VariantClear(&vTemp); pQS->Release(); } hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, WMIDB_HANDLE_TYPE_COOKIE, &pRet); if (SUCCEEDED(hr)) { pObj->Release(); hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { // We should have two instance qualifiers pObj->GetQualifierSet(&pQS); if (pQS) { hr = pQS->Get(L"Number", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal == 1)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Verifying propogated qualifier on instance (Parent1=2.Number)", 0); VariantClear(&vTemp); hr = pQS->Get(L"InstanceNumber", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal == 10)?0:WBEM_E_FAILED, L"Storing and retrieving instance int32 (Parent1=2.InstanceNumber) qualifiers", 0); VariantClear(&vTemp); pQS->Release(); } pObj->GetPropertyQualifierSet(L"Key1", &pQS); if (pQS) { hr = pQS->Get(L"InstanceNumber", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_I4 && vTemp.lVal == 20)?0:WBEM_E_FAILED, L"Storing and retrieving instance int32 (Parent1=2.Key1.InstanceNumber) qualifiers", 0); VariantClear(&vTemp); pQS->Release(); } pObj->Release(); } pRet->Release(); } else pObj->Release(); } */ } // Indexed property. The repository should create an index for it. We have no way of verifying that it did, though. hr = CreateClass(&pRet, pSession, pScope, L"Index1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Index1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pClass = NULL; if (SUCCEEDED(hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass))) { pClass->Put(L"IndexProp1", 0, NULL, CIM_UINT32); SetBoolQualifier(pClass, L"indexed", L"IndexProp1"); pClass->Put(L"Prop2", 0, NULL, CIM_STRING); pRet->Release(); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, WMIDB_HANDLE_TYPE_COOKIE, &pRet); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating class with indexes (Index1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { // Create an instance IWbemClassObject *pIndex = NULL; IWmiDbHandle *pInst = NULL; pClass->SpawnInstance(0, &pIndex); SetIntProp(pIndex, L"Key1", 1); SetIntProp(pIndex, L"IndexProp1", 100); SetStringProp(pIndex, L"Prop2", L"Some value."); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pIndex, 0, WMIDB_HANDLE_TYPE_COOKIE, &pInst); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating instance with indexed data (Index1=1)", GetDiff(tEndTime,tStartTime)); if (pInst) pInst->Release(); pIndex->Release(); // Now index Prop2. /* NOVA COMPATIBLITY: Not supported (yet) SetBoolQualifier(pClass, L"indexed", L"Prop2"); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Adding index to a property with existing data (Index1.Prop2)", GetDiff(tEndTime,tStartTime)); */ pRet->Release(); } pClass->Release(); } else pRet->Release(); } // Defaults. All default data should propogate between classes and new instances. New defaults // must be copied if class modified. hr = CreateClass(&pRet, pSession, pScope, L"Default1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Default1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pClass = NULL; if (SUCCEEDED(hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass))) { SetStringProp(pClass, L"StringDefault", L"This is the string default"); SetIntProp(pClass, L"IntDefault", 0); pClass->Put(L"IntNoDefault", 0, NULL, CIM_UINT32); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating class with default data (Default1)", GetDiff(tEndTime,tStartTime)); IWbemClassObject *pInst = NULL; pClass->SpawnInstance(0, &pInst); SetIntProp(pInst, L"Key1", 1); SetIntProp(pInst, L"IntDefault", NULL, FALSE, NULL); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pInst, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating instance using default data (Default1=1)", GetDiff(tEndTime,tStartTime)); pInst->Release(); /* NOVA COMPATIBLITY: Not supported (yet) // Add a new default, and change a different default in the class. pClass->Put(L"IntDefault", 0, NULL, CIM_UINT32); // Make sure a non-null default is overridable. SetIntProp(pClass, L"IntNoDefault", 99); SetStringProp(pClass, L"StringDefault2", L"This is a new string default."); SetStringProp(pClass, L"RefDefault", L"Testing", FALSE, CIM_REFERENCE); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Updating class with new default data and existing instances (Default1)", GetDiff(tEndTime,tStartTime)); */ pClass->Release(); /* IWmiDbHandle *pHand = NULL; hr = GetObject(pScope, L"Default1=1", WMIDB_HANDLE_TYPE_COOKIE, 6, &pHand, &pClass); RecordResult(hr, L"Retrieving Default1=1", 0); if (SUCCEEDED(hr)) { RecordResult( ValidateProperty(pClass, L"StringDefault", CIM_STRING, L"This is the string default"), L"Validating propogated default Default1=1.StringDefault", 0); RecordResult( ValidateProperty(pClass, L"IntDefault", CIM_UINT32, (VARIANT *)NULL), L"Validating overriding null Default1=1.IntDefault", 0); pClass->Release(); pHand->Release(); } */ } pRet->Release(); } // Supported property datatypes and boundaries. // * uint8 * uint16 * [uint32] * uint64 // * sint8 * sint16 * sint32 * sint64 // * real32 * real64 * char16 * datetime // * [reference] * object * boolean * [string] // Skip references since they only apply to associations, tested elsewhere. hr = CreateClass(&pRet, pSession, pScope, L"AllDatatypes1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class AllDatatypes1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pClass = NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass); if (SUCCEEDED(hr)) { pClass->Put(L"string", NULL, NULL, CIM_STRING); pClass->Put(L"dt", NULL, NULL, CIM_DATETIME); pClass->Put(L"boolean", NULL, NULL, CIM_BOOLEAN); pClass->Put(L"sint8", NULL, NULL, CIM_SINT8); pClass->Put(L"sint16", NULL, NULL, CIM_SINT16); pClass->Put(L"sint32", NULL, NULL, CIM_SINT32); pClass->Put(L"sint64", NULL, NULL, CIM_SINT64); pClass->Put(L"uint8", NULL, NULL, CIM_UINT8); pClass->Put(L"uint16", NULL, NULL, CIM_UINT16); pClass->Put(L"uint32", NULL, NULL, CIM_UINT32); pClass->Put(L"uint64", NULL, NULL, CIM_UINT64); pClass->Put(L"real32", NULL, NULL, CIM_REAL32); pClass->Put(L"real64", NULL, NULL, CIM_REAL64); pClass->Put(L"char16", NULL, NULL, CIM_CHAR16); pClass->Put(L"object", NULL, NULL, CIM_OBJECT); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject (AllDatatypes1)", GetDiff(tEndTime,tStartTime)); // Now create several instances: // One with upper bounds exercised: IWbemClassObject *pInst1 = NULL; pClass->SpawnInstance(0, &pInst1); if (pInst1) { SetIntProp(pInst1, L"Key1", 1); SetIntProp(pInst1, L"boolean", true, FALSE, CIM_BOOLEAN); SetIntProp(pInst1, L"sint8", 127, FALSE, CIM_SINT8); SetIntProp(pInst1, L"sint16", 32767, FALSE, CIM_SINT16); SetIntProp(pInst1, L"sint32", 2147483647, FALSE, CIM_SINT32); SetIntProp(pInst1, L"uint8", 255, FALSE, CIM_UINT8); SetIntProp(pInst1, L"uint16", 65533, FALSE, CIM_UINT16); SetIntProp(pInst1, L"uint32", 4294967294, FALSE, CIM_UINT32); SetStringProp(pInst1, L"string", L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÂÁÃÄÆÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôøùúûüýþÿ"); SetStringProp(pInst1, L"dt", L"29991231235959.999999+000", 0, CIM_DATETIME); SetIntProp(pInst1, L"char16", 0xFF, FALSE, CIM_CHAR16); VARIANT vTemp; VariantInit(&vTemp); V_R4(&vTemp) = (float)3.402823E38; vTemp.vt = VT_R4; pInst1->Put(L"real32", NULL, &vTemp, CIM_REAL32); VariantClear(&vTemp); V_R8(&vTemp) = (double)1.7969313486231E308; vTemp.vt = VT_R8; pInst1->Put(L"real64", NULL, &vTemp, CIM_REAL64); VariantClear(&vTemp); V_BSTR(&vTemp) = SysAllocString(L"922337203685477580"); vTemp.vt = VT_BSTR; pInst1->Put(L"uint64", NULL, &vTemp, CIM_UINT64); VariantClear(&vTemp); V_BSTR(&vTemp) = SysAllocString(L"922337203685477580"); vTemp.vt = VT_BSTR; pInst1->Put(L"sint64", NULL, &vTemp, CIM_SINT64); VariantClear(&vTemp); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pInst1, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - upper bounds, all datatypes (AllDatatypes1=1)", GetDiff(tEndTime,tStartTime)); pInst1->Release(); IWmiDbHandle *pTempHandle = NULL; IWbemClassObject *pTempObj = NULL; hr = GetObject(pScope, L"AllDatatypes1=1", WMIDB_HANDLE_TYPE_COOKIE, 16, &pTempHandle, &pTempObj); RecordResult(hr, L"Retrieving AllDatatypes1=1", 0); if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pTempObj, L"boolean", CIM_BOOLEAN, true), L"Validating AllDatatypes1=1.boolean", 0); RecordResult(ValidateProperty(pTempObj, L"sint8", CIM_SINT8, 127), L"Validating AllDatatypes1=1.sint8", 0); RecordResult(ValidateProperty(pTempObj, L"sint16", CIM_SINT16, 32767), L"Validating AllDatatypes1=1.sint16", 0); RecordResult(ValidateProperty(pTempObj, L"sint32", CIM_SINT32, 2147483647), L"Validating AllDatatypes1=1.sint32", 0); RecordResult(ValidateProperty(pTempObj, L"uint8", CIM_UINT8, 255), L"Validating AllDatatypes1=1.uint8", 0); RecordResult(ValidateProperty(pTempObj, L"uint16", CIM_UINT16, 65533), L"Validating AllDatatypes1=1.uint16", 0); RecordResult(ValidateProperty(pTempObj, L"uint32", CIM_UINT32, 4294967294), L"Validating AllDatatypes1=1.uint32", 0); RecordResult(ValidateProperty(pTempObj, L"string", CIM_STRING, L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÂÁÃÄÆÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôøùúûüýþÿ"), L"Validating AllDatatypes1=1.string", 0); RecordResult(ValidateProperty(pTempObj, L"dt", CIM_DATETIME, L"29991231235959.999999+000"), L"Validating AllDatatypes1=1.datetime", 0); RecordResult(ValidateProperty(pTempObj, L"char16", CIM_CHAR16, 0xFF), L"Validating AllDatatypes1=1.char16", 0); hr = pTempObj->Get(L"real32", 0, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_R4)?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=1.real32", 0); VariantClear(&vTemp); hr = pTempObj->Get(L"real64", 0, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_R8)?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=1.real64", 0); VariantClear(&vTemp); hr = pTempObj->Get(L"uint64", NULL, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BSTR)?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=1.uint64", 0); VariantClear(&vTemp); hr = pTempObj->Get(L"sint64", NULL, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BSTR)?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=1.sint64", 0); VariantClear(&vTemp); pTempObj->Release(); pTempHandle->Release(); } } // Test the lower non-null bounds. hr = pClass->SpawnInstance(0, &pInst1); if (SUCCEEDED(hr)) { SetIntProp(pInst1, L"Key1", 2); SetIntProp(pInst1, L"boolean", 0, FALSE, CIM_BOOLEAN); SetIntProp(pInst1, L"sint8", 127, FALSE, CIM_SINT8); SetIntProp(pInst1, L"sint16", 32767, FALSE, CIM_SINT16); SetIntProp(pInst1, L"sint32", 2147483647, FALSE, CIM_SINT32); SetIntProp(pInst1, L"uint8", 0, FALSE, CIM_UINT8); SetIntProp(pInst1, L"uint16", 0, FALSE, CIM_UINT16); SetIntProp(pInst1, L"uint32", 0, FALSE, CIM_UINT32); SetStringProp(pInst1, L"string", L"."); SetStringProp(pInst1, L"dt", L"00000000000001.000000+000", 0, CIM_DATETIME); SetIntProp(pInst1, L"char16", 1, FALSE, CIM_CHAR16); VARIANT vTemp; VariantInit(&vTemp); V_R4(&vTemp) = (float)-3.402823E38; vTemp.vt = VT_R4; pInst1->Put(L"real32", NULL, &vTemp, CIM_REAL32); VariantClear(&vTemp); V_R8(&vTemp) = (double)-1.79769313486231E308 ; vTemp.vt = VT_R8; pInst1->Put(L"real64", NULL, &vTemp, CIM_REAL64); VariantClear(&vTemp); V_BSTR(&vTemp) = SysAllocString(L"0"); vTemp.vt = VT_BSTR; pInst1->Put(L"uint64", NULL, &vTemp, CIM_UINT64); VariantClear(&vTemp); V_BSTR(&vTemp) = SysAllocString(L"-922337203685477580"); vTemp.vt = VT_BSTR; pInst1->Put(L"sint64", NULL, &vTemp, CIM_SINT64); VariantClear(&vTemp); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pInst1, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - lower bounds, all datatypes (AllDatatypes1=1)", GetDiff(tEndTime,tStartTime)); pInst1->Release(); IWmiDbHandle *pTempHandle = NULL; IWbemClassObject *pTempObj = NULL; hr = GetObject(pScope, L"AllDatatypes1=2", WMIDB_HANDLE_TYPE_COOKIE, 16, &pTempHandle, &pTempObj); RecordResult(hr, L"Retrieving AllDatatypes1=2", 0); if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pTempObj, L"boolean", CIM_BOOLEAN, (DWORD)0), L"Validating AllDatatypes1=2.boolean", 0); RecordResult(ValidateProperty(pTempObj, L"sint8", CIM_SINT8, 127), L"Validating AllDatatypes1=2.sint8", 0); RecordResult(ValidateProperty(pTempObj, L"sint16", CIM_SINT16, 32767), L"Validating AllDatatypes1=2.sint16", 0); RecordResult(ValidateProperty(pTempObj, L"sint32", CIM_SINT32, 2147483647), L"Validating AllDatatypes1=2.sint32", 0); RecordResult(ValidateProperty(pTempObj, L"uint8", CIM_UINT8, (DWORD)0), L"Validating AllDatatypes1=2.uint8", 0); RecordResult(ValidateProperty(pTempObj, L"uint16", CIM_UINT16, (DWORD)0), L"Validating AllDatatypes1=2.uint16", 0); RecordResult(ValidateProperty(pTempObj, L"uint32", CIM_UINT32, (DWORD)0), L"Validating AllDatatypes1=2.uint32", 0); RecordResult(ValidateProperty(pTempObj, L"string",CIM_STRING, L"."), L"Validating AllDatatypes1=2.string", 0); RecordResult(ValidateProperty(pTempObj, L"dt", CIM_DATETIME, L"00000000000001.000000+000"), L"Validating AllDatatypes1=2.datetime", 0); RecordResult(ValidateProperty(pTempObj, L"char16", CIM_CHAR16, 1), L"Validating AllDatatypes1=1.char16", 0); hr = pTempObj->Get(L"real32", NULL, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_R4 )?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=2.real32", 0); VariantClear(&vTemp); hr = pTempObj->Get(L"real64", NULL, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_R8 )?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=2.real64", 0); VariantClear(&vTemp); hr = pTempObj->Get(L"uint64", NULL, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BSTR )?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=2.uint64", 0); VariantClear(&vTemp); hr = pTempObj->Get(L"sint64", NULL, &vTemp, NULL, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BSTR )?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Validating AllDatatypes1=2.sint64", 0); VariantClear(&vTemp); pTempObj->Release(); pTempHandle->Release(); } } // Finally, an instance with only the embedded object populated. hr = pClass->SpawnInstance(0, &pInst1); if (SUCCEEDED(hr)) { IWmiDbHandle *pParent = NULL; IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pParent, &pObj); RecordResult(hr, L"Retrieving Parent1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pNewEmbed = NULL; VARIANT vTemp; VariantInit(&vTemp); pObj->SpawnInstance(0, &pNewEmbed); SetIntProp(pNewEmbed, L"Key1", 1); // This overlap should succeed since its an embedded object! vTemp.vt = VT_UNKNOWN; V_UNKNOWN(&vTemp) = (IUnknown *)pNewEmbed; SetIntProp(pInst1, L"Key1", 3); hr = pInst1->Put(L"object", NULL, &vTemp, CIM_OBJECT); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pInst1, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - embedded object (AllDatatypes1=3.object)", GetDiff(tEndTime,tStartTime)); pParent->Release(); pObj->Release(); VariantClear(&vTemp); hr = GetObject(pScope, L"AllDatatypes1=3", WMIDB_HANDLE_TYPE_COOKIE, 16, &pParent, &pObj); RecordResult(hr, L"Retrieving AllDatatypes1=3", 0); if (SUCCEEDED(hr)) { hr = pObj->Get(L"object", NULL, &vTemp, NULL, NULL); if (SUCCEEDED(hr)) { IWbemClassObject *pTemp = NULL; if (vTemp.vt == VT_UNKNOWN) { pTemp = (IWbemClassObject *)V_UNKNOWN(&vTemp); RecordResult(ValidateProperty(pTemp, L"Key1", CIM_UINT32, 1), L"Validating property AllDatatypes1=3.object.Key1", 0); RecordResult(ValidateProperty(pTemp, L"__Class", CIM_STRING, L"Parent1"), L"Validating property AllDatatypes1=3.object.__Class", 0); VariantClear(&vTemp); } else RecordResult(WBEM_E_FAILED, L"Embedded object property is IUnknown * (AllDatatypes1=3.object)", 0); } else RecordResult(hr, L"IWbemClassObject::Get (AllDatatypes1=3.object)", 0); pParent->Release(); pObj->Release(); } } pInst1->Release(); } // Also, an instance with an embedded object of an unknown class hr = pClass->SpawnInstance(0, &pInst1); if (SUCCEEDED(hr)) { IWmiDbHandle *pParent = NULL; IWbemClassObject *pObj = NULL; hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { SetStringProp(pObj, L"Key1", NULL, TRUE); SetStringProp(pObj, L"__Class", L"BrandNew"); IWbemClassObject *pNewEmbed = NULL; VARIANT vTemp; VariantInit(&vTemp); pObj->SpawnInstance(0, &pNewEmbed); SetStringProp(pNewEmbed, L"Key1", L"XXX"); // This overlap should succeed since its an embedded object! vTemp.vt = VT_UNKNOWN; V_UNKNOWN(&vTemp) = (IUnknown *)pNewEmbed; SetIntProp(pInst1, L"Key1", 4); hr = pInst1->Put(L"object", NULL, &vTemp, CIM_OBJECT); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pInst1, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - embedded object of undefined class (AllDatatypes1=4) ", GetDiff(tEndTime,tStartTime)); pObj->Release(); VariantClear(&vTemp); hr = GetObject(pScope, L"AllDatatypes1=4", WMIDB_HANDLE_TYPE_COOKIE, 16, &pParent, &pObj); RecordResult(hr, L"Retrieving AllDatatypes1=4", 0); if (SUCCEEDED(hr)) { hr = pObj->Get(L"object", NULL, &vTemp, NULL, NULL); if (SUCCEEDED(hr)) { IWbemClassObject *pTemp = NULL; if (vTemp.vt == VT_UNKNOWN) { pTemp = (IWbemClassObject *)V_UNKNOWN(&vTemp); RecordResult(ValidateProperty(pTemp, L"Key1", CIM_STRING, L"XXX"), L"Validating property AllDatatypes1=4.object.Key1", 0); RecordResult(ValidateProperty(pTemp, L"__Class", CIM_STRING, L"BrandNew"), L"Validating property AllDatatypes1=3.object.__Class", 0); VariantClear(&vTemp); } else RecordResult(WBEM_E_FAILED, L"Embedded object property is IUnknown * (AllDatatypes1=4.object)", 0); } else RecordResult(hr, L"IWbemClassObject::Get (AllDatatypes1=4.object)", 0); pParent->Release(); pObj->Release(); } } pInst1->Release(); } pClass->Release(); } pRet->Release(); } // Class with arrays and blobs. Test updates and default data. hr = CreateClass(&pRet, pSession, pScope, L"Arrays1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Arrays1", 0); if (SUCCEEDED(hr)) { BSTR sTemp; IWbemClassObject *pClass = NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass); if (SUCCEEDED(hr)) { // A blob with no default value. pClass->Put(L"Blob1", NULL, NULL, CIM_UINT8|CIM_FLAG_ARRAY); VARIANT vValue; VariantInit(&vValue); // A 32-bit int array with default 101,2,5000 long why[1]; DWORD t; SAFEARRAYBOUND aBounds[1]; aBounds[0].cElements = 3; // 3 elements to start. aBounds[0].lLbound = 0; SAFEARRAY* pArray = SafeArrayCreate(VT_I4, 1, aBounds); why[0] = 0; t = 101; SafeArrayPutElement(pArray, why, &t); why[0] = 1; t = 2; SafeArrayPutElement(pArray, why, &t); why[0] = 2; t = 5000; SafeArrayPutElement(pArray, why, &t); vValue.vt = VT_ARRAY|VT_I4; V_ARRAY(&vValue) = pArray; pClass->Put(L"Uint32Array1", NULL, &vValue, CIM_UINT32|CIM_FLAG_ARRAY); VariantClear(&vValue); // A string array with default A,B,C pArray = SafeArrayCreate(VT_BSTR, 1, aBounds); why[0] = 0; sTemp = SysAllocString(L"A"); hr = SafeArrayPutElement(pArray, why, sTemp); why[0] = 1; sTemp = SysAllocString(L"B"); SafeArrayPutElement(pArray, why, sTemp); why[0] = 2; sTemp = SysAllocString(L"C"); SafeArrayPutElement(pArray, why, sTemp); vValue.vt = VT_ARRAY|VT_BSTR; V_ARRAY(&vValue) = pArray; hr = pClass->Put(L"StringArray1", NULL, &vValue, CIM_STRING|CIM_FLAG_ARRAY); VariantClear(&vValue); // An object array with no default. pClass->Put(L"ObjectArray1", NULL, NULL, CIM_OBJECT | CIM_FLAG_ARRAY); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - uint8, uint32, string arrays (Arrays1)", GetDiff(tEndTime,tStartTime)); VariantClear(&vValue); // Create an instance that populates the blob data. Verify that the defaults are OK. IWbemClassObject *pInst = NULL; pClass->SpawnInstance(0, &pInst); if (pInst) { SetIntProp(pInst, L"Key1", 1); // Create some blob data (100,200,0) unsigned char t1; pArray = SafeArrayCreate(VT_UI1, 1, aBounds); why[0] = 0; t1 = 100; SafeArrayPutElement(pArray, why, &t1); why[0] = 1; t1 = 200; SafeArrayPutElement(pArray, why, &t1); why[0] = 2; t1 = 0; SafeArrayPutElement(pArray, why, &t1); V_ARRAY(&vValue) = pArray; vValue.vt = VT_ARRAY|VT_UI1; hr = pInst->Put(L"Blob1", NULL, &vValue, CIM_FLAG_ARRAY|CIM_UINT8); VariantClear(&vValue); // Create an embedded object aBounds[0].cElements = 1; pArray = SafeArrayCreate(VT_UNKNOWN, 1, aBounds); why[0] = 0; IWmiDbHandle *pParent = NULL; IWbemClassObject *pObj1 = NULL; hr = GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pParent, &pObj1); RecordResult(hr, L"Retrieving Parent1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pNewEmbed = NULL; VARIANT vTemp; VariantInit(&vTemp); pObj1->SpawnInstance(0, &pNewEmbed); SetIntProp(pNewEmbed, L"Key1", 1); // This overlap should succeed since its an embedded object! SafeArrayPutElement(pArray, why, pNewEmbed); V_ARRAY(&vValue) = pArray; vValue.vt = VT_ARRAY|VT_UNKNOWN; hr = pInst->Put(L"ObjectArray1", NULL, &vValue, CIM_FLAG_ARRAY|CIM_OBJECT); VariantClear(&vValue); pParent->Release(); pObj1->Release(); } // Override the default on the string array (C,B) aBounds[0].cElements = 2; // Removing one... pArray = SafeArrayCreate(VT_BSTR, 1, aBounds); why[0] = 0; sTemp = SysAllocString(L"C"); SafeArrayPutElement(pArray, why, sTemp); why[0] = 1; sTemp = SysAllocString(L"B"); SafeArrayPutElement(pArray, why, sTemp); vValue.vt = VT_ARRAY|VT_BSTR; V_ARRAY(&vValue) = pArray; hr = pInst->Put(L"StringArray1", NULL, &vValue, CIM_STRING|CIM_FLAG_ARRAY); VariantClear(&vValue); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pInst, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - blob data (Arrays1=1)", GetDiff(tEndTime,tStartTime)); VariantClear(&vValue); pInst->Release(); if (SUCCEEDED(hr)) { // Now verify all the individual elements: IWbemClassObject *pObj = NULL; IWmiDbHandle *pHandle = NULL; GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Arrays1=1", WMIDB_HANDLE_TYPE_COOKIE, 5, &pHandle, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject - array instance (Arrays1=1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { // Blob1 should be 100,200,0 - in that order. hr = pObj->Get(L"Blob1", NULL, &vValue, NULL, NULL); if (SUCCEEDED(hr) && (vValue.vt == (VT_ARRAY|VT_UI1))) { BYTE temp1=0, temp2=0, temp3=0; pArray = V_ARRAY(&vValue); if (pArray) { long lTemp=0; SafeArrayGetElement(pArray, &lTemp, &temp1); lTemp = 1; SafeArrayGetElement(pArray, &lTemp, &temp2); lTemp = 2; SafeArrayGetElement(pArray, &lTemp, &temp3); } RecordResult((temp1==100 && temp2==200 && temp3==0)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Validating Arrays1=1.object value (100,200,0)", 0); } else RecordResult(WBEM_E_FAILED, L"IWbemClassObject::Get (Arrays1=1.blob1)", 0); VariantClear(&vValue); // Uint32Array1 should be 101,2,5000 hr = pObj->Get(L"Uint32Array1", NULL, &vValue, NULL, NULL); if (SUCCEEDED(hr) && vValue.vt == (VT_ARRAY|VT_I4)) { DWORD temp1=0, temp2=0, temp3=0; pArray = V_ARRAY(&vValue); if (pArray) { long lUBound = 0; SafeArrayGetUBound(pArray, 1, &lUBound); if (lUBound != 2) RecordResult(WBEM_E_FAILED, L"Validating correct number of array elements (Arrays1=1.Uint32Array1)",0); else { long lTemp=0; SafeArrayGetElement(pArray, &lTemp, &temp1); lTemp = 1; SafeArrayGetElement(pArray, &lTemp, &temp2); lTemp = 2; SafeArrayGetElement(pArray, &lTemp, &temp3); } } RecordResult((temp1==101 && temp2==2 && temp3==5000)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Validating Arrays1=1.Uint32Array1 default value (101,2,5000)", 0); } else RecordResult(WBEM_E_FAILED, L"IWbemClassObject::Get (Arrays1=1.Uint32Array1)", 0); VariantClear(&vValue); // Object Array 1 should contain Parent1=1 hr = pObj->Get(L"ObjectArray1", NULL, &vValue, NULL, NULL); if (SUCCEEDED(hr) && vValue.vt == (VT_ARRAY|VT_UNKNOWN)) { pArray = V_ARRAY(&vValue); if (pArray) { long lTemp = 0; long lUBound = 0; IUnknown *pUnk = NULL; SafeArrayGetUBound(pArray, 1, &lUBound); if (lUBound != 0) RecordResult(WBEM_E_FAILED, L"Validating correct number of array elements (Arrays1=1.ObjectArray1)", 0); SafeArrayGetElement(pArray, &lTemp, &pUnk); if (pUnk) { IWbemClassObject *pObj = NULL; pUnk->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (pObj) { RecordResult(ValidateProperty(pObj, L"__Class", CIM_STRING, L"Parent1"), L"Validating Arrays1=1.ObjectArray1.__Class", 0); RecordResult(ValidateProperty(pObj, L"Key1", CIM_UINT32, 1), L"Validating Arrays1=1.ObjectArray1.__Class", 0); pObj->Release(); } } else RecordResult(WBEM_E_FAILED, L"Validating object array element (Arrays1=1.ObjectArray1)", 0); } VariantClear(&vValue); } else RecordResult(WBEM_E_FAILED, L"IWbemClassObject::Get (Arrays1=1.ObjectArray1)", 0); // The string array should be C,B hr = pObj->Get(L"StringArray1", NULL, &vValue, NULL, NULL); if (SUCCEEDED(hr) && vValue.vt == (VT_ARRAY|VT_BSTR)) { BSTR sTemp1 = NULL, sTemp2 = NULL; pArray = V_ARRAY(&vValue); if (pArray) { long lTemp = 0; long lUBound = 0; SafeArrayGetUBound(pArray, 1, &lUBound); if (lUBound != 1) RecordResult(WBEM_E_FAILED, L"Validating size of overridden instance array Arrays1=1.StringArray1 ", 0); SafeArrayGetElement(pArray, &lTemp, &sTemp1); lTemp = 1; SafeArrayGetElement(pArray, &lTemp, &sTemp2); } if (sTemp1 && sTemp2) { RecordResult((!_wcsicmp(L"C",sTemp1) && !_wcsicmp(L"B",sTemp2))?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Validating Arrays1=1.StringArray1 value ('C','B')",0); } if (sTemp1) SysFreeString(sTemp1); if (sTemp2) SysFreeString(sTemp2); } else RecordResult(WBEM_E_FAILED, L"IWbemClassObject::Get (Arrays1=1.StringArray1", 0); VariantClear(&vValue); pObj->Release(); pHandle->Release(); } } } } pRet->Release(); } // Supported qualifier properties: // * [sint32] * real64 * [boolean] * [string] hr = CreateClass(&pRet, pSession, pScope, L"Qualifiers1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Qualifiers1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pClass = NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pClass); if (SUCCEEDED(hr)) { IWbemQualifierSet *pQfr = NULL; pClass->GetQualifierSet(&pQfr); if (pQfr) { VARIANT vTemp; VariantInit(&vTemp); vTemp.vt = VT_R8; V_R8(&vTemp) = 123456.789; hr = pQfr->Put(L"RealQfr", &vTemp, 3); VariantClear(&vTemp); if (SUCCEEDED(hr)) { hr = pSession->PutObject(pScope, IID_IWbemClassObject, pClass, 0, 0, NULL); RecordResult(hr, L"IWmiDbSession::PutObject - class with real64 qualifier (Qualifiers1)", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pNewHand = NULL; IWbemClassObject *pNewObj = NULL; hr = GetObject(pScope, L"Qualifiers1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pNewHand, &pNewObj); RecordResult(hr, L"Retrieving Qualifiers1", 0); if (SUCCEEDED(hr)) { pNewObj->GetQualifierSet(&pQfr); if (pQfr) { hr = pQfr->Get(L"RealQfr", NULL, &vTemp, NULL); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_R8 && vTemp.dblVal != 0)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Validating Real64 qualifier (Qualifiers1.RealQfr)", 0); VariantClear(&vTemp); } pNewHand->Release(); pNewObj->Release(); } else RecordResult(WBEM_E_FAILED, L"Retrieving class Qualifiers1", 0); } } VariantClear(&vTemp); pQfr->Release(); } pClass->Release(); } pRet->Release(); } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::UpdateObjects() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; IWmiDbHandle *pRet = NULL; IWbemClassObject *pObj = NULL; // Verify that the update only flag works. hr = GetObject(pScope, L"Child1=1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pRet, &pObj); RecordResult(hr, L"Retrieving Child1=1", 0); if (SUCCEEDED(hr)) { SetStringProp(pObj, L"Prop1", L"ZXYWVU"); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, WBEM_FLAG_UPDATE_ONLY, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - update only (Child1=1)", GetDiff(tEndTime,tStartTime)); // Updating keys should create another instance. Both should be retrievable. SetIntProp(pObj, L"Key1", 3); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - changing keys (Child1=3)", GetDiff(tEndTime,tStartTime)); pRet->Release(); pObj->Release(); GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Child1=1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pRet, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (Child1=1)", GetDiff(tEndTime,tStartTime)); GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Child1=3", WMIDB_HANDLE_TYPE_COOKIE, 2, &pRet, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (Child1=3)", GetDiff(tEndTime,tStartTime)); } // Updating a class should work if we didn't change anything. hr = GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pRet, &pObj); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, WBEM_FLAG_UPDATE_ONLY, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - update populated class with no changes, retrieved (Parent1)", GetDiff(tEndTime,tStartTime)); pRet->Release(); pObj->Release(); } hr = CreateClass(NULL, pSession,pScope, L"Parent1", NULL, CIM_UINT32); RecordResult(hr, L"IWmiDbSession::PutObject - update populated class with no changes, cocreated (Parent1)", GetDiff(tEndTime,tStartTime)); GetLocalTime(&tStartTime); hr = GetObject(pScope, L"Child1=1", WMIDB_HANDLE_TYPE_COOKIE, 2, &pRet, &pObj); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (Child1=1) following parent update.", GetDiff(tEndTime,tStartTime)); // Create a new class with instances and default data, and try the acceptable conversions (numeric, no loss of precision) hr = CreateClass(&pRet, pSession, pScope, L"Convert1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Convert1", 0); if (SUCCEEDED(hr)) { hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { SetIntProp(pObj, L"Uint8ToSint8", 10, FALSE, CIM_UINT8); SetIntProp(pObj, L"Sint8ToSint16", 20, FALSE, CIM_SINT8); SetIntProp(pObj, L"Sint16ToUint32", 30, FALSE, CIM_SINT16); SetIntProp(pObj, L"Uint32ToReal32", 40, FALSE, CIM_UINT32); VARIANT vTemp; VariantInit(&vTemp); V_R4(&vTemp) = (float)1.2; vTemp.vt = VT_R4; pObj->Put(L"Real32ToReal64", NULL, &vTemp, NULL); VariantClear(&vTemp); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL); if (SUCCEEDED(hr)) { SetIntProp(pObj, L"Uint8ToSint8", 11, FALSE, CIM_SINT8); SetIntProp(pObj, L"Sint8ToSint16", 21, FALSE, CIM_SINT16); SetIntProp(pObj, L"Sint16ToUint32", 31, FALSE, CIM_UINT32); hr = pObj->Delete(L"Uint32ToReal32"); V_R4(&vTemp) = 41; vTemp.vt = VT_R4; pObj->Put(L"Uint32ToReal32", NULL, &vTemp, CIM_REAL32); VariantClear(&vTemp); V_R8(&vTemp) = 11.2; vTemp.vt = VT_R8; pObj->Put(L"Real32ToReal64", NULL, &vTemp, CIM_REAL64); VariantClear(&vTemp); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - converting numeric types (Convert1=1)", GetDiff(tEndTime,tStartTime)); // Create an instance with only default data. hr = CreateInstance(NULL, pSession, pScope, L"Convert1", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance Convert1=1", 0); if (SUCCEEDED(hr)) { // Verify that the conversion worked... IWmiDbHandle *pTemp = NULL; IWbemClassObject *pTempObj = NULL; hr = GetObject(pScope, L"Convert1=1", WMIDB_HANDLE_TYPE_COOKIE, 6, &pTemp, &pTempObj); RecordResult(hr, L"Retrieving Convert1=1", 0); if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pTempObj, L"Uint8ToSint8", CIM_SINT8, 11), L"Validating Convert1.Uint8ToSint8", 0); RecordResult(ValidateProperty(pTempObj, L"Sint8ToSint16", CIM_SINT16, 21), L"Validating Convert1.Sint8ToSint16", 0); RecordResult(ValidateProperty(pTempObj, L"Sint16ToUint32", CIM_UINT32, 31), L"Validating Convert1.Sint16ToUint32", 0); RecordResult(ValidateProperty(pTempObj, L"Uint32ToReal32", CIM_REAL32, 41), L"Validating Convert1.Uint32ToReal32", 0); pTempObj->Get(L"Real32ToReal64", 0, &vTemp, NULL, NULL); RecordResult((vTemp.vt == VT_R8 && vTemp.dblVal == 11.2), L"Validating Convert1=1.Real32ToReal64", 0); pTemp->Release(); pTempObj->Release(); VariantClear(&vTemp); } } } pObj->Release(); } pRet->Release(); } // Now retrieve a child object from the cache, and make sure // that an update to the parent object wipes out the cached child object. hr = CreateClass(&pRet, pSession, pScope, L"NestedCache", NULL, CIM_UINT32); RecordResult(hr, L"Creating class NestedCache", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pChildClass = NULL, *pChildInst = NULL; hr = CreateClass(&pChildClass, pSession, pScope, L"NestedCacheChild", NULL, CIM_UINT32, L"NestedCache", NULL, NULL, WMIDB_HANDLE_TYPE_STRONG_CACHE); RecordResult(hr, L"Creating class NestedCacheChild", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(&pChildInst, pSession, pScope, L"NestedCacheChild", L"1", CIM_UINT32, NULL, NULL, WMIDB_HANDLE_TYPE_STRONG_CACHE); RecordResult(hr, L"Creating instance NestedCacheChild1=1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pChildClassObj = NULL, *pChildInstObj = NULL, *pParentObj = NULL; // Instantiate both the instance and the child class, and release. hr = pChildClass->QueryInterface(IID_IWbemClassObject, (void **)&pChildClassObj); hr = pChildInst->QueryInterface(IID_IWbemClassObject, (void **)&pChildInstObj); if (pChildClassObj) pChildClassObj->Release(); if (pChildInstObj) pChildInstObj->Release(); // If we add a property to the parent class, it should // show up in both the child and instance, if we instantiate them. hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pParentObj); if (SUCCEEDED(hr)) { SetIntProp(pParentObj, L"ParentProperty", 1); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pParentObj, 0, 0, NULL); if (SUCCEEDED(hr)) { hr = pChildClass->QueryInterface(IID_IWbemClassObject, (void **)&pChildClassObj); if (SUCCEEDED(hr)) { RecordResult(pChildClassObj->Get(L"ParentProperty", 0, NULL, NULL, NULL), L"Updating parent object refreshes/updates cached child class", 0); pChildClassObj->Release(); } hr = pChildInst->QueryInterface(IID_IWbemClassObject, (void **)&pChildInstObj); if (SUCCEEDED(hr)) { RecordResult(pChildInstObj->Get(L"ParentProperty", 0, NULL, NULL, NULL), L"Updating parent object refreshes/updates cached child class instance", 0); pChildInstObj->Release(); } } pParentObj->Release(); } pChildInst->Release(); } pChildClass->Release(); } pRet->Release(); } // Verify Rename functions. hr = CreateClass(NULL, pSession, pScope, L"Rename1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Rename1", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"Rename1", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance Rename1=1", 0); if (SUCCEEDED(hr)) { IWbemPath*pPath1, *pPath2; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath1); hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath2); // Rename key values. pPath1->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"test:Rename1=1"); pPath2->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"test:Rename1=2"); hr = pSession->RenameObject(pPath1, pPath2, 0, 0, NULL); RecordResult(hr, L"RenameObject (test:Rename1=1 -> Rename1=2)", 0); if (SUCCEEDED(hr)) { // Rename scope. pPath1->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"test:Rename1=2"); pPath2->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"test:Child1=1:Rename1=2"); hr = pSession->RenameObject(pPath1, pPath2, 0, 0, NULL); RecordResult(hr, L"RenameObject (test:Rename1=2 -> test:Child1=1:Rename1=2)", 0, 0, NULL); } pPath1->Release(); pPath2->Release(); } } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::ChangeHierarchy() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; // Adding an existing class to a parent should work, as long // as it doesn't change the key. hr = CreateClass(NULL, pSession, pScope, L"Child2", NULL, CIM_UINT32); RecordResult(hr, L"Creating class Child2", 0); if (SUCCEEDED(hr)) { bool bSuccess = false; GetLocalTime(&tStartTime); hr = CreateClass(NULL, pSession, pScope, L"Child2", NULL, CIM_UINT32, L"Parent1"); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - add new parent (Child2:Parent1)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) bSuccess = true; // Changing the parent of a class should work if the key is the same. GetLocalTime(&tStartTime); hr = CreateClass(NULL, pSession, pScope, L"Child2", NULL, CIM_UINT32, L"Child1"); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - change parent (Child2:Child1)", GetDiff(tEndTime,tStartTime)); // Removing the parent of a class should work if the key is the same. if (bSuccess) { GetLocalTime(&tStartTime); hr = CreateClass(NULL, pSession, pScope, L"Child2", NULL, CIM_UINT32); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - remove parent (Child2)", GetDiff(tEndTime,tStartTime)); } } GetLocalTime(&tEndTime); return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::VerifyContainers() { HRESULT hr = 0; wchar_t wTmp[128]; SYSTEMTIME tStartTime, tEndTime; for (int i = 101; i <= 200; i++) { swprintf(wTmp, L"%ld", i); hr = CreateInstance(NULL, pSession, pScope, L"Parent1", wTmp, CIM_UINT32); } IWbemPath*pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); hr = CreateClass(NULL, pSession, pScope, L"Container1", NULL, CIM_STRING); RecordResult(hr, L"Creating class Container1", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pContainer = NULL; hr = CreateInstance (&pContainer, pSession, pScope, L"Container1", L"Stuff", CIM_STRING, NULL, NULL, WMIDB_HANDLE_TYPE_CONTAINER); RecordResult(hr, L"Creating instance Container1='Stuff'", 0); if (SUCCEEDED(hr)) { for (i = 101; i <= 200; i++) { swprintf(wTmp, L"test:Parent1=%ld", i); pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, wTmp); hr = pSession->AddObject(pContainer, pPath, 0, 0, NULL); RecordResult(hr, L"Adding %s to Container1='Stuff'", 0, wTmp); if (FAILED(hr)) break; } for (i = 180; i <= 200; i++) { swprintf(wTmp, L"test:Parent1=%ld", i); pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, wTmp); hr = pSession->RemoveObject(pContainer, pPath, 0); RecordResult(hr, L"Removing %s from Container1='Stuff'", 0, wTmp); if (FAILED(hr)) break; } IWmiDbIterator *pIt = NULL; hr = pSession->Enumerate(pContainer, 0, WMIDB_HANDLE_TYPE_COOKIE, &pIt); RecordResult(hr, L"Enumerating Container1='Stuff'", 0); if (SUCCEEDED(hr)) { // Iterator int iNum = 100; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; GetLocalTime(&tStartTime); hr = pIt->NextBatch(iNum, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwNumRet, (void **)ppHandle); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbIterator::NextBatch (%ld results) ", GetDiff(tEndTime,tStartTime), dwNumRet); for (int j = 0; j < (int)dwNumRet; j++) ppHandle[j]->Release(); delete ppHandle; if (pIt) pIt->Release(); } IWbemQuery *pQuery = NULL; hr = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery); if (SUCCEEDED(hr)) { pQuery->Parse(L"SQL", L"select * from Parent1 where Key1 < 100", 0); hr = pSession->ExecQuery(pContainer, pQuery, WMIDB_FLAG_QUERY_SHALLOW, WMIDB_HANDLE_TYPE_VERSIONED, NULL, &pIt); RecordResult(hr, L"Executing SHALLOW query select * from Parent1 where Key1 < 100 scoped to Container1='Stuff'", 0); if (SUCCEEDED(hr)) { // Iterator int iNum = 10; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; GetLocalTime(&tStartTime); hr = pIt->NextBatch(iNum, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwNumRet, (void **)ppHandle); GetLocalTime(&tEndTime); if (dwNumRet != 0) RecordResult(WBEM_E_FAILED, L"Shallow query scoped to Container1='Stuff' returns results.", 0); for (int j = 0; j < (int)dwNumRet; j++) ppHandle[j]->Release(); delete ppHandle; if (pIt) pIt->Release(); } pQuery->Parse(L"SQL", L"select * from Parent1 where Key1 <= 200", 0); hr = pSession->ExecQuery(pContainer, pQuery, WMIDB_FLAG_QUERY_DEEP, WMIDB_HANDLE_TYPE_VERSIONED, NULL, &pIt); RecordResult(hr, L"Executing DEEP query select * from Parent1 where Key1 <= 200 scoped to Container1='Stuff'", 0); if (SUCCEEDED(hr)) { // Iterator int iNum = 10; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; GetLocalTime(&tStartTime); hr = pIt->NextBatch(iNum, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwNumRet, (void **)ppHandle); GetLocalTime(&tEndTime); if (dwNumRet == 0) RecordResult(WBEM_E_FAILED, L"Deep query scoped to Container1='Stuff' returns no results.", 0); for (int j = 0; j < (int)dwNumRet; j++) ppHandle[j]->Release(); delete ppHandle; if (pIt) pIt->Release(); } pQuery->Parse(L"SQL", L"references of {test:Parent1=101}", 0); hr = pSession->ExecQuery(pScope, pQuery, 0, WMIDB_HANDLE_TYPE_VERSIONED, NULL, &pIt); RecordResult(hr, L"Executing query references of {Parent1=101} ", 0); if (SUCCEEDED(hr)) { // Iterator int iNum = 10; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; GetLocalTime(&tStartTime); hr = pIt->NextBatch(iNum, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwNumRet, (void **)ppHandle); GetLocalTime(&tEndTime); if (dwNumRet == 0) RecordResult(WBEM_E_FAILED, L"References of query scoped to container returns no results.", 0); for (int j = 0; j < (int)dwNumRet; j++) ppHandle[j]->Release(); delete ppHandle; if (pIt) pIt->Release(); } } else RecordResult(WBEM_E_FAILED, L"CoCreateInstance (IWbemQuery) failed. Tests skipped", 0); pContainer->Release(); } // Special case; The __Instances container IWmiDbHandle *pRet = NULL; IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"__Instances=\"Parent1\"", WMIDB_HANDLE_TYPE_COOKIE|WMIDB_HANDLE_TYPE_CONTAINER, -1, &pRet, &pObj); RecordResult(hr, L"Retrieving __Instances of Parent1", 0); if (SUCCEEDED(hr)) { // Add and remove should fail regardless. // Enumeration should retrieve all instances of this class pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1=101"); hr = pSession->AddObject(pRet, pPath, 0, 0, NULL); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Verifying AddObject fails for __Instances container", 0); hr = pSession->RemoveObject(pRet, pPath, 0); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Verifying RemoveObject fails for __Instances container", 0); IWmiDbIterator *pIt; hr = pSession->Enumerate(pRet, 0, WMIDB_HANDLE_TYPE_COOKIE, &pIt); if (SUCCEEDED(hr)) { // Iterator int iNum = 100; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; GetLocalTime(&tStartTime); hr = pIt->NextBatch(iNum, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwNumRet, (void **)ppHandle); GetLocalTime(&tEndTime); if (!dwNumRet) RecordResult(WBEM_E_FAILED, L"IWmiDbIterator::NextBatch (%ld results) ", GetDiff(tEndTime,tStartTime), dwNumRet); else RecordResult(hr, L"IWmiDbIterator::NextBatch (%ld results) ", GetDiff(tEndTime,tStartTime), dwNumRet); for (int j = 0; j < (int)dwNumRet; j++) ppHandle[j]->Release(); delete ppHandle; if (pIt) pIt->Release(); } pRet->Release(); pObj->Release(); } pPath->Release(); } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::VerifyTransactions() { HRESULT hr = WBEM_S_NO_ERROR; wchar_t wTmp[128]; SYSTEMTIME tStartTime, tEndTime; IWmiDbHandle *pHandle = NULL; IWbemClassObject *pObj = NULL; GUID transguid; // Transaction 1: Begin, Insert, Insert, Commit => 2 objects IWbemTransaction *pTrans = NULL; hr = pSession->QueryInterface(IID_IWbemTransaction, (void **)&pTrans); if (FAILED(hr)) { RecordResult(hr, L"Repository supports IWbemTransaction", 0); return hr; } // Precreate the __Transaction and __UncommittedEvent classes. hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { SetStringProp(pObj, L"__Class", L"__Transaction"); SetStringProp(pObj, L"GUID", L"", TRUE); SetStringProp(pObj, L"ClientComment", L""); SetStringProp(pObj, L"ClientID", L""); SetIntProp(pObj, L"State", 0, FALSE, CIM_UINT32); SetStringProp(pObj, L"Start", L"", FALSE, CIM_DATETIME); SetStringProp(pObj, L"LastUpdate", L"", FALSE, CIM_DATETIME); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating __Transaction class", GetDiff(tEndTime, tStartTime)); pObj->Release(); } hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { IWbemQualifierSet *pQS = NULL; SetStringProp(pObj, L"__Class", L"__UncommittedEvent"); SetIntProp(pObj, L"EventID", 0, CIM_UINT32, TRUE); SetBoolQfr(pObj, L"EventID", L"keyhole"); SetStringProp(pObj, L"TransactionGUID", L""); SetBoolQfr(pObj, L"TransactionGUID", L"indexed"); SetStringProp(pObj, L"NamespaceName", L""); SetStringProp(pObj, L"ClassName", L""); hr = pObj->Put(L"OldObject", 0, NULL, CIM_OBJECT); hr = pObj->Put(L"NewObject", 0, NULL, CIM_OBJECT); SetIntProp(pObj, L"Transacted", 1, FALSE, CIM_BOOLEAN); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"Creating __UncommittedEvent class", GetDiff(tEndTime, tStartTime)); pObj->Release(); } hr = CoCreateGuid(&transguid); hr = pTrans->Begin(0, 0, &transguid); RecordResult(hr, L"IWmiDbSession::Begin", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"Trans1", NULL, CIM_UINT32); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"Trans1", L"1", CIM_UINT32); if (SUCCEEDED(hr)) { ULONG uState = 0; hr = pTrans->QueryState(0, &uState); RecordResult(uState == WBEM_TRANSACTION_STATE_PENDING? WBEM_S_NO_ERROR:WBEM_E_FAILED, L"QueryState returns PENDING", 0); hr = pTrans->Commit(0); RecordResult(hr, L"IWmiDbSession::Commit", 0); // Make sure both objects are still in the db. hr = GetObject(pScope, L"Trans1=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); RecordResult(hr, L"Verifying Commit worked (creating Trans1)", 0); if (pHandle) pHandle->Release(); if (pObj) pObj->Release(); } else pTrans->Rollback(0); } else pTrans->Rollback(0); } pHandle = NULL; pObj = NULL; // Transaction 2: Begin, Insert, Delete, Commit => No object hr = CoCreateGuid(&transguid); hr = pTrans->Begin(0, 0, &transguid); RecordResult(hr, L"IWmiDbSession::Begin", 0); if (SUCCEEDED(hr)) { hr = CreateClass(&pHandle, pSession, pScope, L"Trans1", NULL, CIM_UINT32); if (SUCCEEDED(hr)) { hr = pSession->DeleteObject(pScope, 0, IID_IWmiDbHandle, pHandle); if (SUCCEEDED(hr)) { hr = pTrans->Commit(0); RecordResult(hr, L"IWmiDbSession::Commit", 0); // Make sure both objects are still in the db. hr = GetObject(pScope, L"Trans1=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); RecordResult(FAILED(hr)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Verifying Commit worked (deleting Trans1)", 0); if (pHandle) pHandle->Release(); } else pTrans->Rollback(0); } else pTrans->Rollback(0); } pHandle = NULL; /* // Transaction 3: Begin, Insert, Rollback => No object hr = CoCreateGuid(&transguid); hr = pTrans->Begin(0, 0, &transguid); RecordResult(hr, L"IWmiDbSession::Begin", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"Trans2", NULL, CIM_UINT32); if (SUCCEEDED(hr)) { hr = pTrans->Rollback(0); RecordResult(hr, L"IWmiDbSession::Rollback", 0); // Make sure both objects are still in the db. hr = GetObject(pScope, L"Trans2", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHandle, &pObj); RecordResult(FAILED(hr)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Verifying Rollback worked (rollback Trans2)", 0); if (pHandle) pHandle->Release(); } else pTrans->Rollback(0); } pTrans->Release(); */ return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::Query() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; DWORD dwCompLevel = 0; DWORD dwNumElements = 0; struct TestQueries { wchar_t *pszQuery; DWORD dwCompLevel; BOOL bStopOnFail; BOOL bResults; }; // Just a few general tests... // 0 = select + where clause TestQueries tests[] = {L"select * from Parent1", 0, TRUE, TRUE, L"select Key1, Prop1 from Child1", 0, FALSE, TRUE, L"select * from Parent1 where Key1 = 1", 0,FALSE, TRUE, L"select * from Parent1 where Key1 != 1", 0,FALSE, TRUE, L"select * from Parent1 where Key1 <> 1", 0,FALSE, TRUE, L"select * from Parent1 where Key1 > 0", 0,FALSE, TRUE, L"select * from Parent1 where Key1 < 0", 0,FALSE, FALSE, L"select * from Parent1 where Key1 >= 0", 0,FALSE, TRUE, L"select * from Parent1 where Key1 <= 0", 0,FALSE, FALSE, L"select * from Parent1 where Key1 is null", 0,FALSE, FALSE, L"select * from Parent1 where Key1 is not null", 0,FALSE, TRUE, L"select * from Parent1 where Key1 = 0 or Key1 = 1", 0,FALSE, TRUE, L"select * from Parent1 where Key1 = 1 and Key1 <> 0", 0,FALSE, TRUE, L"select * from Parent1 where ((Key1 = 1 or Key1 = 2) and Key1 <> 0)", 0,FALSE, TRUE, L"select * from Parent1 where Key1 in (1,2,3)", 0,FALSE, TRUE, L"select * from Parent1 where Key1 not in (0,1,2)", 0,FALSE, TRUE, L"select * from Child1 where Prop1 = \"ZZZ\"", 0, FALSE, FALSE, L"select * from Child1 where NOT Prop1 = \"ZZZ\"", 0, FALSE, TRUE, L"select * from Child1 where Prop1 <> \"ZZZ\"", 0, FALSE, TRUE, L"select * from Child1 where Prop1 not like \"ZZZ%\"", 0, FALSE, TRUE, L"select * from Child1 where upper(Prop1) <> \"ZZZ\"", 0, FALSE, TRUE, L"select * from AllDatatypes1 where datepart(mm, dt) = 12", 0, FALSE, TRUE, L"select * from AllDatatypes1 where datepart(yy, dt) = 2999", 0, FALSE, TRUE, // Property to property comparison L"select * from CompoundKeys1 where Key1 = Key2 ", 0, FALSE, TRUE, L"select * from CompoundKeys1 where Key2 > Key1 ", 0, FALSE, TRUE, L"select * from CompoundKeys1 where Key1 <> Key2", 0, FALSE, TRUE, L"select * from CompoundKeys1 where Key2 < Key1 ", 0, FALSE, FALSE, // Schema queries L"select * from __Instances", 0, FALSE, TRUE, L"select * from Parent1 where __Class = 'Child1'", 0, FALSE, TRUE, L"select * from Parent1 where __Genus = 2", 0, FALSE, TRUE, L"select * from Parent1 where __Dynasty = 'Parent1'", 0, FALSE, FALSE, //L"select * from Parent1 where __Derivation[0] = 'Parent1'", 0, FALSE, TRUE, L"select * from meta_class", 0, FALSE, TRUE, L"select * from meta_class where __this isa 'Parent1'", 0, FALSE, TRUE, L"select * from meta_class where __SuperClass = 'Parent1'", 0, FALSE, TRUE, // 1 = TempQL L"references of {Parent1=2}", 1, TRUE, TRUE, L"references of {Parent1}", 1, FALSE, TRUE, L"references of {Parent1=2} where ResultClass=Association1", 1, FALSE, TRUE, L"references of {Parent1=2} where RequiredQualifier=Association", 1, FALSE, TRUE, L"references of {Parent1=2} where Role=Key1", 1, FALSE, TRUE, L"references of {Parent1=2} where ClassDefsOnly", 1, FALSE, TRUE, L"references of {Parent1=2} where Role=Key1 RequiredQualifier=Association", 1, FALSE, TRUE, L"associators of {Parent1=2}", 1, TRUE, TRUE, L"associators of {Parent1}", 1, FALSE, TRUE, L"associators of {Parent1=2} where ResultClass=Child1", 1, FALSE, TRUE, L"associators of {Parent1=2} where AssocClass=Association1", 1, FALSE, TRUE, L"associators of {Parent1=2} where Role=Key1", 1, FALSE, TRUE, L"associators of {Parent1=2} where RequiredQualifier=Description", 1, FALSE, FALSE, L"associators of {Parent1=2} where RequiredAssocQualifier=Association", 1, FALSE, TRUE, L"associators of {Parent1=2} where ClassDefsOnly", 1, FALSE, TRUE, L"associators of {Parent1=2} where ResultClass=Child1 AssocClass=Association1 Role=Key1", 1, FALSE, TRUE, // 2 = simple joins, order by, insert/update/delete L"select * from Parent1 order by Key1", 2, FALSE, TRUE, //L"update Child1 set Prop1 = \"ABC\" where Key1= 1", 2, FALSE, FALSE, //L"insert into Child1 (Key1, Prop1) values (99, L\"Test\")", 2, FALSE,FALSE, L"delete from Child1 where Key1 = 1", 2, FALSE, FALSE, //L"select * from Parent1, Child1 where Parent1.Key1= Child1.Key1", 2, TRUE, TRUE, // 3 = SQL-92, subselects, transactions, union //L"select * from Parent1 as p inner join Child1 as c on p.Key1=c.Key1", 3, TRUE, TRUE, //L"select * from Parent1 where Key1 between 1 and 10", 3, FALSE, TRUE, //L"select Key1 from Child1 where Prop1 like \"A%\"", 3,FALSE, TRUE, //L"select Key1 from Child1 where Prop1 not like \"A%\"", 3,FALSE,TRUE, //L"select * from Parent1 where Key1 in (select Key1 from Child1)", 3,FALSE, TRUE, //L"select * from Parent1 where Key1 not in (select Key1 from Child1)", 3,FALSE, TRUE, //L"select Key1 from Parent1 UNION select Key1 from Child1", 3, FALSE, TRUE, //L"begin transaction", 3, FALSE,FALSE, //L"rollback transaction", 3, FALSE, FALSE }; dwNumElements = sizeof(tests) / sizeof(TestQueries); IWmiDbIterator *pIterator = NULL; IWbemQuery *pQuery = NULL; hr = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery); if (SUCCEEDED(hr)) { for (int i = 0; i < (int)dwNumElements; i++) { hr = pQuery->Parse(L"SQL", tests[i].pszQuery, 0); if (FAILED(hr)) { RecordResult(hr, L"IWbemQuery parsing %s", 0, tests[i].pszQuery); continue; } DWORD dwResults = 0; GetLocalTime(&tStartTime); hr = pSession->ExecQuery(pScope, pQuery, 0, WMIDB_HANDLE_TYPE_COOKIE, &dwResults, &pIterator); GetLocalTime(&tEndTime); RecordResult(hr, tests[i].pszQuery, GetDiff(tEndTime,tStartTime)); if (dwResults == WBEM_REQUIREMENTS_START_POSTFILTER) RecordResult(hr, L"WARNING: Query must be post-filtered with this driver.", 0); if (FAILED(hr) && tests[i].bStopOnFail) { dwCompLevel = (tests[i].dwCompLevel)-1; break; } else if (SUCCEEDED(hr)) { if (tests[i].bResults) { // Iterator int iNum = 5; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; GetLocalTime(&tStartTime); hr = pIterator->NextBatch(iNum, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwNumRet, (void **)ppHandle); GetLocalTime(&tEndTime); if (FAILED(hr)) RecordResult(hr, L"IWmiDbIterator::NextBatch ", GetDiff(tEndTime,tStartTime)); else { if (dwNumRet == 0) { wprintf(L" [QUERY: %s]\n", tests[i].pszQuery); RecordResult(WBEM_E_FAILED, L"IWmiDbIterator::NextBatch - results expected", GetDiff(tEndTime,tStartTime)); } } for (int j = 0; j < (int)dwNumRet; j++) ppHandle[j]->Release(); delete ppHandle; } if (pIterator) pIterator->Release(); } } } wchar_t wTemp[100]; swprintf(wTemp, L"QUERY COMPLIANCE LEVEL = %ld", dwCompLevel); RecordResult(0, wTemp, 0); return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::Batch() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; // WMIDB_FLAG_ATOMIC or WMIDB_FLAG_BEST_EFFORT // Put objects: IWmiDbHandle *pRet = NULL; IWbemClassObject *pClass = NULL; hr = GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pRet, &pClass); RecordResult(hr, L"Retrieving Parent1", 0); if (SUCCEEDED(hr)) { IWmiDbBatchSession *pBatch = NULL; hr = pSession->QueryInterface(IID_IWmiDbBatchSession, (void **)&pBatch); if (SUCCEEDED(hr)) { IWbemClassObject *pObj = NULL; WMIOBJECT_BATCH batch; batch.dwArraySize = 3; batch.pElements = new WMI_BATCH_OBJECT_ACCESS[3]; for (int i = 0; i < 3; i++) { IWbemClassObject *Obj = NULL; batch.pElements[i].pPath = NULL; pClass->SpawnInstance(0, &pObj); SetIntProp(pObj, L"Key1", i+4); batch.pElements[i].pHandle = pObj; batch.pElements[i].dwFlags = 0; } GetLocalTime(&tStartTime); hr = pBatch->PutObjects(pScope, WMIDB_FLAG_ATOMIC, WMIDB_HANDLE_TYPE_COOKIE, &batch); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbBatchSession::PutObjects - atomic (Parent1=4,Parent1=5,Parent1=6)", GetDiff(tEndTime,tStartTime)); pObj = (IWbemClassObject *)batch.pElements[0].pHandle; pObj->Put(L"Key1", NULL, NULL, CIM_UINT32); // nullifying a key should cause a failure, but "best effort" should succeed overall. pObj = (IWbemClassObject *)batch.pElements[1].pHandle; SetIntProp(pObj, L"Key1", 5); pObj = (IWbemClassObject *)batch.pElements[2].pHandle; SetIntProp(pObj, L"Key1", 6); GetLocalTime(&tStartTime); hr = pBatch->PutObjects(pScope, WMIDB_FLAG_BEST_EFFORT, WMIDB_HANDLE_TYPE_COOKIE, &batch); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbBatchSession::PutObjects - best effort (Parent1=null key, Parent1=5,Parent1=6)", GetDiff(tEndTime,tStartTime)); RecordResult(FAILED(batch.pElements[0].hRes) ? WBEM_S_NO_ERROR: WBEM_E_FAILED, L"IWmiDbBatchSession::PutObjects - recorded failure " L" on null key (Parent1)", 0); if (SUCCEEDED(hr)) { for (i = 0; i < 3; i++) { if (SUCCEEDED(batch.pElements[i].hRes) && batch.pElements[i].pReturnHandle) batch.pElements[i].pReturnHandle->Release(); batch.pElements[i].pHandle->Release(); batch.pElements[i].pReturnHandle = NULL; } } pBatch->Release(); delete batch.pElements; } pRet->Release(); pClass->Release(); } // Get IWmiDbBatchSession *pBatch = NULL; hr = pSession->QueryInterface(IID_IWmiDbBatchSession, (void **)&pBatch); if (SUCCEEDED(hr)) { IWbemPath*pPath = NULL; WMIOBJECT_BATCH batch; batch.dwArraySize = 3; batch.pElements = new WMI_BATCH_OBJECT_ACCESS[3]; for (int i = 0; i < 3; i++) { batch.pElements[i].pReturnHandle = NULL; batch.pElements[i].dwFlags = 0; batch.pElements[i].pHandle = NULL; batch.pElements[i].hRes = 0; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); batch.pElements[i].pPath = pPath; } batch.pElements[0].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1"); batch.pElements[1].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1=2"); batch.pElements[2].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Child1=1"); GetLocalTime(&tStartTime); hr = pBatch->GetObjects(pScope, WMIDB_FLAG_ATOMIC, WMIDB_HANDLE_TYPE_COOKIE, &batch); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbBatchSession::GetObjects - atomic: (Parent1,Parent1=2,Child1=1)", GetDiff(tEndTime,tStartTime)); for (i = 0; i < 3; i++) { if (SUCCEEDED(batch.pElements[i].hRes) && batch.pElements[i].pReturnHandle) batch.pElements[i].pReturnHandle->Release(); batch.pElements[i].pReturnHandle = NULL; } batch.pElements[0].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1=0"); GetLocalTime(&tStartTime); hr = pBatch->GetObjects(pScope, WMIDB_FLAG_BEST_EFFORT, WMIDB_HANDLE_TYPE_COOKIE, &batch); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbBatchSession::GetObjects - best effort: (Parent1=0 (invalid),Parent1=2,Child1=1)", GetDiff(tEndTime,tStartTime)); for (i = 0; i < 3; i++) { if (SUCCEEDED(batch.pElements[i].hRes) && batch.pElements[i].pReturnHandle) batch.pElements[i].pReturnHandle->Release(); } // Delete. batch.pElements[0].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"BogusClass"); batch.pElements[1].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"AnotherBogusClass"); batch.pElements[2].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Child1=4"); GetLocalTime(&tStartTime); hr = pBatch->DeleteObjects(pScope, WMIDB_FLAG_BEST_EFFORT, &batch); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbBatchSession::DeleteObjects - best effort: (BogusClass, AnotherBogusClass, Child1=4)", GetDiff(tEndTime,tStartTime)); for (i = 0; i < 3; i++) { if (i < 2) RecordResult(FAILED(batch.pElements[i].hRes)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::DeleteObjects - expected failure code.", 0); batch.pElements[i].pPath->Release(); } } GetLocalTime(&tEndTime); return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::Security() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; PNTSECURITY_DESCRIPTOR pDescr = NULL; HANDLE hToken; HANDLE hThread = GetCurrentThread(); { TOKEN_PRIVILEGES tp; LUID luid; HANDLE hProcHandle; BOOL bRet = false; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hProcHandle )) { if(!LookupPrivilegeValue(NULL, SE_TCB_NAME , &luid)) { wprintf(L"Unable to lookup privilege (%ld)", GetLastError() ); CloseHandle(hProcHandle); } else { tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bRet = AdjustTokenPrivileges(hProcHandle, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL ); if (!bRet) { wprintf(L"Unable to adjust token privileges (%ld)\n", GetLastError()); CloseHandle(hProcHandle); } else { wchar_t temp[400]; wcscpy(temp, (const wchar_t *)sLogon); wchar_t *pDomain = NULL; wchar_t *pUser = wcschr(temp, L'\\'); if (!pUser) { pUser = temp; pDomain = 0; } else { pUser++; pDomain = temp; } temp[pUser-pDomain-1] = '\0'; if (LogonUser(pUser,pDomain, L"", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken)) { BOOL bRet = SetThreadToken(&hThread, hToken); bRet = ImpersonateLoggedOnUser(hToken); bRet = true; } else { wprintf(L"Unable to logon user %s (%ld)\n", (const wchar_t *)sLogon, GetLastError()); CloseHandle(hProcHandle); bRet = FALSE; } } } } if (bRet) { IWmiDbHandle *pParentClass = NULL; IWbemClassObject *pTemp = NULL; hr = GetObject(pScope, L"Parent1=2", WMIDB_HANDLE_TYPE_VERSIONED|WMIDB_HANDLE_TYPE_SUBSCOPED, 1, &pParentClass, &pTemp); RecordResult(hr, L"Retrieving Parent1=2", 0); if (SUCCEEDED(hr)) { pParentClass->Release(); CNtAcl *pAcl = NULL; CNtSid *sid = new CNtSid(sLogon); pDescr = (PNTSECURITY_DESCRIPTOR)new BYTE[4096]; InitializeSecurityDescriptor(pDescr, SECURITY_DESCRIPTOR_REVISION); if (SetSecurityDescriptorOwner(pDescr, sid->GetPtr(), false)) { BOOL bRet = SetSecurityDescriptorGroup(pDescr, sid->GetPtr(), false); CNtAce *ace = new CNtAce(WBEM_FULL_WRITE_REP|DELETE, ACCESS_DENIED_ACE_TYPE, CONTAINER_INHERIT_ACE, sLogon); pAcl = new CNtAcl; pAcl->AddAce(ace); CNtAce *ace2 = new CNtAce(WBEM_ENABLE, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, sLogon); pAcl->AddAce(ace2); if (SetSecurityDescriptorDacl(pDescr, true, pAcl->GetPtr(), false)) { SECURITY_DESCRIPTOR_CONTROL ctrl; DWORD dwRev = 0; BOOL bRes = GetSecurityDescriptorControl(pDescr, &ctrl,&dwRev); if (bRes) { if (!(ctrl & SE_SELF_RELATIVE)) // Source is not absolute!! { PNTSECURITY_DESCRIPTOR pNew = NULL; DWORD dwSize = 0; dwSize = GetSecurityDescriptorLength(pDescr); pNew = (PNTSECURITY_DESCRIPTOR)CWin32DefaultArena::WbemMemAlloc(dwSize); ZeroMemory(pNew, dwSize); hr = MakeSelfRelativeSD(pDescr, pNew, &dwSize); delete pDescr; pDescr = pNew; if (!IsValidSecurityDescriptor(pDescr)) hr = WBEM_E_FAILED; } } // First, revoke write and delete from the object itself. DWORD dwLen = GetSecurityDescriptorLength(pDescr); GetLocalTime(&tStartTime); hr = ((_IWmiObject *)pTemp)->WriteProp(L"__SECURITY_DESCRIPTOR", 0, dwLen, dwLen, CIM_UINT8|CIM_FLAG_ARRAY, pDescr); if (SUCCEEDED(hr)) hr = pSession->PutObject(pScope, IID_IWbemClassObject, pTemp, WBEM_FLAG_USE_SECURITY_DESCRIPTOR, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - revoke write & delete from Parent1=2 ", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { hr = pSession->PutObject(pScope, IID_IWbemClassObject, pTemp, 0, 0, NULL); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Verifying Parent1=2 permissions", 0); IWmiDbHandle *pParentClass = NULL; IWbemClassObject *pTemp3 = NULL; GetLocalTime(&tStartTime); IWbemPath *pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); if (SUCCEEDED(hr)) { hr = pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"Parent1=2"); hr = pSession->GetObject(pScope, pPath, WBEM_FLAG_USE_SECURITY_DESCRIPTOR, WMIDB_HANDLE_TYPE_VERSIONED, &pParentClass); if (SUCCEEDED(hr)) { hr = pParentClass->QueryInterface(IID_IWbemClassObject, (void **)&pTemp3); } } //hr = GetObject(pScope, L"Parent1=2", WMIDB_HANDLE_TYPE_VERSIONED, // 1, &pParentClass, &pTemp3); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (Parent1=2)", GetDiff(tEndTime,tStartTime)); if (pTemp3) { VARIANT vTemp; VariantInit(&vTemp); hr = pTemp3->Get(L"__SECURITY_DESCRIPTOR", 0, &vTemp, NULL, NULL); RecordResult(vTemp.vt == CIM_UINT8+CIM_FLAG_ARRAY?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::GetObject - security descriptor populated", 0); VariantClear(&vTemp); if (pTemp3) pTemp3->Release(); if (pParentClass) pParentClass->Release(); // We should be able to delete this permission. GetLocalTime(&tStartTime); hr = pTemp->Put(L"__SECURITY_DESCRIPTOR", 0, NULL, CIM_UINT8|CIM_FLAG_ARRAY); if (SUCCEEDED(hr)) hr = pSession->PutObject(pScope, IID_IWbemClassObject, pTemp, WBEM_FLAG_USE_SECURITY_DESCRIPTOR | WBEM_FLAG_REMOVE_CHILD_SECURITY, 0, NULL); RecordResult(hr, L"Removing security (Parent1=2)", 0); GetLocalTime(&tEndTime); // Make sure it's gone!! hr = pSession->GetObject(pScope, pPath, WBEM_FLAG_USE_SECURITY_DESCRIPTOR, WMIDB_HANDLE_TYPE_VERSIONED, &pParentClass); if (SUCCEEDED(hr)) { hr = pParentClass->QueryInterface(IID_IWbemClassObject, (void **)&pTemp3); if (SUCCEEDED(hr)) { hr = pTemp3->Get(L"__SECURITY_DESCRIPTOR", 0, &vTemp, NULL, NULL); RecordResult(vTemp.vt == VT_NULL?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::GetObject - security descriptor deleted", 0); VariantClear(&vTemp); } } pPath->Release(); } } pTemp->Release(); } } } CloseHandle (hToken); } CloseHandle (hThread); } return hr; } // ***************************************************** HRESULT TestSuiteFunctionality::DeleteObjects() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; IWmiDbHandle *pRet = NULL; // Delete the objects we created. // They should be gone if we try to access them again. // Auto-delete handle. On releasing the handle, the object should be automatically deleted. GetLocalTime(&tStartTime); hr = CreateClass(&pRet, pSession, pScope, L"DeleteMeWhenDone", NULL, CIM_UINT32, NULL, NULL, NULL, WMIDB_HANDLE_TYPE_AUTODELETE); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - autodelete handle (DeleteMeWhenDone)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { IWmiDbHandle *pInst = NULL; // Creating a nested object with an auto-delete handle should fail. hr = CreateInstance(&pInst, pSession, pScope, L"DeleteMeWhenDone", L"1", CIM_UINT32, NULL, NULL, WMIDB_HANDLE_TYPE_AUTODELETE); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"IWmiDbSession::PutObject - nested autodelete handle (DeleteMeWhenDone=1)", 0); if (pInst) pInst->Release(); hr = CreateInstance(&pInst, pSession, pScope, L"DeleteMeWhenDone", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance DeleteMeWhenDone=1", 0); if (SUCCEEDED(hr)) { pRet->Release(); DWORD dwType = 0; pInst->GetHandleType(&dwType); RecordResult((dwType == WMIDB_HANDLE_TYPE_INVALID)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"IWmiDbHandle::Release of autodeleted handle does not invalidate dependent object handles (DeleteMeWhenDone=1)", 0); pInst->Release(); IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"DeleteMeWhenDone=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pRet, &pObj); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR,L"Autodeleted dependent object deleted on release (DeleteMeWhenDone=1)",0); if (SUCCEEDED(hr)) { pRet->Release(); pObj->Release(); } hr = GetObject(pScope, L"DeleteMeWhenDone", WMIDB_HANDLE_TYPE_COOKIE, 1, &pRet, &pObj); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR,L"Autodeleted object deleted on release (DeleteMeWhenDone)",0); if (SUCCEEDED(hr)) { pRet->Release(); pObj->Release(); } } } // Create and Delete a class hr = CreateClass(&pRet, pSession, pScope, L"DeleteMe", NULL, CIM_UINT32); RecordResult(hr, L"Creating class DeleteMe", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"DeleteMe", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance DeleteMe=1", 0); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = pSession->DeleteObject(pScope, 0, IID_IWmiDbHandle, pRet); // Give it the class handle. GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::DeleteObject (DeleteMe)", GetDiff(tEndTime,tStartTime)); // The instance should be gone also. if (SUCCEEDED(hr)) { IWmiDbHandle *pHand = NULL; IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"DeleteMe=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHand, &pObj); RecordResult(FAILED(hr)?WBEM_S_NO_ERROR:WBEM_E_FAILED,L"Verifying that instance was removed when class deleted (DeleteMe=1)", 0); if (SUCCEEDED(hr)) { pHand->Release(); pObj->Release(); } } } pRet->Release(); } // Create an association. // Deleting the end-points should leave a valid association. hr = CreateClass(NULL, pSession, pScope, L"DeleteAssociation", L"Association", CIM_REFERENCE, NULL, NULL, CIM_REFERENCE); RecordResult(hr, L"Creating class DeleteAssociation", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"Deleter", NULL, CIM_STRING); RecordResult(hr, L"IWmiDbSession::PutObject - Deleter", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pLeft = NULL, *pRight = NULL, *pAssoc = NULL; hr = CreateInstance(&pLeft, pSession, pScope, L"Deleter", L"Left side", CIM_STRING); RecordResult(hr, L"IWmiDbSession::PutObject - Deleter=\"Left side\"", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(&pRight, pSession, pScope, L"Deleter", L"Right side", CIM_STRING); RecordResult(hr, L"IWmiDbSession::PutObject - Deleter=\"Right side\"", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(&pAssoc, pSession, pScope, L"DeleteAssociation", L"test:Deleter=\"Left side\"", CIM_REFERENCE, L"test:Deleter=\"Right side\"", CIM_REFERENCE); RecordResult(hr, L"IWmiDbSession::PutObject - DeleteAssociation='Left side', 'Right side'", 0); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = pSession->DeleteObject(pScope, 0, IID_IWmiDbHandle, pLeft); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::DeleteObject (Deleter='Left side')", GetDiff(tEndTime, tStartTime)); if (SUCCEEDED(hr)) { IWmiDbHandle *pHand = NULL; IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"DeleteAssociation.Key1=\"test:Deleter=\\\"Left side\\\"\",Key2=\"test:Deleter=\\\"Right side\\\"\"", WMIDB_HANDLE_TYPE_COOKIE, 2, &pHand, &pObj); RecordResult(hr, L"IWmiDbSession::GetObject - association with deleted left end-point " L"(DeleteAssociation.Key1=\"test:Deleter=\\\"Left side\\\"\",Key2=\"test:Deleter=\\\"Right side\\\"\")",0); if (SUCCEEDED(hr)) { RecordResult(ValidateProperty(pObj, L"Key1", CIM_REFERENCE, L"test:Deleter=\"Left side\""), L"Validating deleted reference property", 0); pHand->Release(); pObj->Release(); } } // Deleting the association should leave alone the good end-point. GetLocalTime(&tStartTime); hr = pSession->DeleteObject(pScope, 0, IID_IWmiDbHandle, pAssoc); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::DeleteObject (DeleteAssociation)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { IWmiDbHandle *pHand = NULL; IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"Deleter=\"Right side\"", WMIDB_HANDLE_TYPE_COOKIE, 1, &pHand, &pObj); RecordResult(hr, L"IWmiDbSession::GetObject - endpoint of deleted association (Deleter=\"Right side\")", 0); if (SUCCEEDED(hr)) { pHand->Release(); pObj->Release(); } } pAssoc->Release(); } pRight->Release(); } pLeft->Release(); } } } // Create and Delete class - should erase derived classes hr = CreateClass(&pRet, pSession, pScope, L"DeleteParent", NULL, CIM_UINT32); RecordResult(hr, L"Creating class DeleteParent", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pChildClass = NULL; hr = CreateClass(&pChildClass, pSession, pScope, L"DeleteChild", NULL, CIM_UINT32, L"DeleteParent"); RecordResult(hr, L"Creating class DeleteChild", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pGrandChild = NULL; hr = CreateClass(&pGrandChild, pSession, pScope, L"DeleteGrandChild", NULL, CIM_UINT32, L"DeleteChild"); RecordResult(hr, L"Creating class DeleteGrandChild", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pChildInstance = NULL, *pParentInstance = NULL; hr = CreateInstance(&pChildInstance, pSession, pScope, L"DeleteGrandChild", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance DeleteGrandChild=1", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(&pParentInstance, pSession, pScope, L"DeleteParent", L"2", CIM_UINT32); RecordResult(hr, L"Creating instance DeleteParent=1", 0); if (SUCCEEDED(hr)) { IWbemPath*pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); if (SUCCEEDED(hr)) { IWmiDbHandle *pTest = NULL; IWbemClassObject *pTestObj = NULL; hr = GetObject(pScope, L"DeleteGrandChild=1", WMIDB_HANDLE_TYPE_VERSIONED, -1, &pTest, &pTestObj); RecordResult(hr, L"Retrieving DeleteGrandChild=1", 0); if (SUCCEEDED(hr)) { pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"DeleteParent"); GetLocalTime(&tStartTime); hr = pSession->DeleteObject(pScope, 0, IID_IWbemPath, pPath); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::DeleteObject - class with subclasses (DeleteParent)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { DWORD dwType; pRet->GetHandleType(&dwType); RecordResult((dwType==WMIDB_HANDLE_TYPE_INVALID)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Verifying outstanding cookie object handle not invalidated on delete object (DeleteParent)", 0); pTest->GetHandleType(&dwType); RecordResult((dwType==WMIDB_HANDLE_TYPE_INVALID)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Verifying outstanding dependent versioned handle invalidated on delete object (DeleteGrandChild=1)", 0); IWmiDbHandle *pTemp = NULL; IWbemClassObject *pTempObj = NULL; hr = GetObject(pScope, L"DeleteGrandChild=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pTemp, &pTempObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR), L"Verifying subclass instance (DeleteGrandChild=1) was deleted", 0); if (SUCCEEDED(hr)) { pTemp->Release(); pTempObj->Release(); } hr = GetObject(pScope, L"DeleteGrandChild", WMIDB_HANDLE_TYPE_COOKIE, 1, &pTemp, &pTempObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR), L"Verifying subclass (DeleteGrandChild) was deleted", 0); if (SUCCEEDED(hr)) { pTemp->Release(); pTempObj->Release(); } hr = GetObject(pScope, L"DeleteChild", WMIDB_HANDLE_TYPE_COOKIE, 1, &pTemp, &pTempObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR), L"Verifying subclass (DeleteChild) was deleted", 0); if (SUCCEEDED(hr)) { pTemp->Release(); pTempObj->Release(); } } pTest->Release(); pTestObj->Release(); } pPath->Release(); } pParentInstance->Release(); } pChildInstance->Release(); } pGrandChild->Release(); } pChildClass->Release(); } pRet->Release(); } // Create & Delete scope - should erase classes hr = CreateClass(&pRet, pSession, pScope, L"DeleteScope", NULL, CIM_UINT32); RecordResult(hr, L"Creating class DeleteScope", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pSubClass = NULL, *pSubInst = NULL; hr = CreateClass(&pSubClass, pSession, pRet, L"DeleteSubClass", NULL, CIM_UINT32); RecordResult(hr, L"Creating class DeleteSubClass", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(&pSubInst, pSession, pRet, L"DeleteSubClass", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance DeleteSubClass=1", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pRet, L"DeleteSubClass2", NULL, CIM_STRING); RecordResult(hr, L"Creating class DeleteSubClass2", 0); if (SUCCEEDED(hr)) { GetLocalTime(&tStartTime); hr = pSession->DeleteObject(pScope, 0, IID_IWmiDbHandle, pRet); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::DeleteObject - scoping object (DeleteScope)", GetDiff(tEndTime,tStartTime)); if (SUCCEEDED(hr)) { IWmiDbHandle *pTemp = NULL; IWbemClassObject *pTempObj = NULL; hr = GetObject(pScope, L"DeleteSubClass=1", WMIDB_HANDLE_TYPE_COOKIE, 1, &pTemp, &pTempObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR), L"Verifying subclass instance (DeleteSubClass=1) was deleted", 0); if (SUCCEEDED(hr)) { pTemp->Release(); pTempObj->Release(); } hr = GetObject(pScope, L"DeleteSubClass2", WMIDB_HANDLE_TYPE_COOKIE, 1, &pTemp, &pTempObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR), L"Verifying subclass (DeleteSubClass2) was deleted", 0); if (SUCCEEDED(hr)) { pTemp->Release(); pTempObj->Release(); } hr = GetObject(pScope, L"DeleteSubClass", WMIDB_HANDLE_TYPE_COOKIE, 1, &pTemp, &pTempObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR), L"Verifying subclass (DeleteSubClass) was deleted", 0); if (SUCCEEDED(hr)) { pTemp->Release(); pTempObj->Release(); } hr = GetObject(pScope, L"DeleteScope", WMIDB_HANDLE_TYPE_COOKIE, 1, &pTemp, &pTempObj); RecordResult((SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR), L"Verifying scope object (DeleteScope) was deleted", 0); if (SUCCEEDED(hr)) { pTemp->Release(); pTempObj->Release(); } } } pSubInst->Release(); } pSubClass->Release(); } pRet->Release(); } hr = CreateInstance(&pRet, pSession, pScope, L"Parent1", L"1001", CIM_UINT32); if (SUCCEEDED(hr)) { IWbemClassObject *pObj = NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { hr = pSession->DeleteObject(pScope, 0, IID_IWbemClassObject, pObj); RecordResult(hr, L"DeleteObject by IWbemClassObject *", 0); } } GetLocalTime(&tEndTime); return hr; } // ***************************************************** // // TestSuiteErrorTest // // ***************************************************** BOOL TestSuiteErrorTest::StopOnFailure() { return FALSE; } HRESULT TestSuiteErrorTest::RunSuite(IWmiDbSession *_pSession, IWmiDbController *_pController, IWmiDbHandle *_pScope) { RecordResult (0, L" *** Error Verification Suite running... *** \n", 0); wprintf(L" *** Error Verification Suite running... *** \n"); HRESULT hr = WBEM_S_NO_ERROR; pSession = _pSession; pController = _pController; pScope = _pScope; try { TryInvalidHierarchy(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception of an unknown type during hierarchy testing.\n", 0); hr = WBEM_E_FAILED; } try { TryChangeDataType(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception of an unknown type during data type change testing.\n", 0); hr = WBEM_E_FAILED; } try { TryInvalidQuery(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception of an unknown type during invalid query testing.\n", 0); hr = WBEM_E_FAILED; } try { TryLongStrings(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception of an unknown type during long string testing.\n", 0); hr = WBEM_E_FAILED; } try // Most likely to GPF last. { TryInvalidParams(); } catch (...) { RecordResult(WBEM_E_FAILED, L"Caught an exception of an unknown type testing invalid parameters.\n", 0); hr = WBEM_E_FAILED; } return hr; } // ***************************************************** TestSuiteErrorTest::TestSuiteErrorTest(const wchar_t *pszFile, int iNumThreads) : TestSuite(pszFile) { iThreads = iNumThreads; if(iThreads <= 0) iThreads = 1; } // ***************************************************** TestSuiteErrorTest::~TestSuiteErrorTest() { } // ***************************************************** HRESULT TestSuiteErrorTest::TryInvalidParams() { HRESULT hr = WBEM_S_NO_ERROR; DWORD dwWaste = 0; IWmiDbHandle *pWaste1 = NULL; IWmiDbSession *pWaste2 = NULL; IWbemPath*pPath = NULL; IWbemClassObject *pObj = NULL; // Ensure that we get the appropriate error message back, // and that no crash occurs... // HRESULT IWmiDbController::Logon([in] WMIDB_LOGON_TEMPLATE *pLogonParms,[in] DWORD dwFlags, // [in] DWORD dwRequestedHandleType, [out] IWmiDbSession **ppSession, [out] IWmiDbHandle **ppRootNamespace ); hr = pController->Logon(NULL, 0, WMIDB_HANDLE_TYPE_COOKIE, &pWaste2, &pWaste1); RecordResult((hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED), L"IWmiDbController::Logon - null logon template failed to return INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) { if (pWaste1) pWaste1->Release(); if (pWaste2) pWaste2->Release(); } // HRESULT IWmiDbController::GetLogonTemplate([in] LCID lLocale,[in] DWORD dwFlags,[out] WMIDB_LOGON_TEMPLATE **ppLogonTemplate); // HRESULT IWmiDbController::FreeLogonTemplate([in, out] WMIDB_LOGON_TEMPLATE **ppTemplate); WMIDB_LOGON_TEMPLATE *pTemplate = NULL; hr = pController->GetLogonTemplate(0, 0, &pTemplate); RecordResult(hr, L"IWmiDbController::GetLogonTemplate = zero Locale", 0); if (FAILED(hr)) { hr = pController->GetLogonTemplate(0x409, 0, &pTemplate); RecordResult(hr, L"IWmiDbController::GetLogonTemplate - locale 0x409", 0); } if (pTemplate) { hr = pController->Logon(pTemplate, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbController::Logon - null session pointer returns INVALID_PARAMETER", 0); hr = pController->FreeLogonTemplate(NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbController::FreeLogonTemplate - null parameter returns INVALID_PARAMETER", 0); hr = pController->FreeLogonTemplate(&pTemplate); RecordResult(hr, L"IWmiDbController::FreeLogonTemplate", 0); pTemplate = NULL; hr = pController->FreeLogonTemplate(&pTemplate); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR: WBEM_E_FAILED, L"IWmiDbController::FreeLogonTemplate - " L"pointer to null parameter returns INVALID_PARAMETER", 0); } // HRESULT IWmiDbController::SetCallTimeout([in] DWORD dwMaxTimeout); hr = pController->SetCallTimeout(0); RecordResult(hr == WBEM_E_INVALID_PARAMETER || hr == E_NOTIMPL ?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbController::SetCallTimeout 0 ms returns INVALID_PARAMETER", 0); // HRESULT IWmiDbController::SetCacheValue([in] DWORD dwMaxBytes); // This is valid anywhere from 0 to 4g, if we have the memory. // HRESULT IWmiDbController::FlushCache([in] DWORD dwFlags); // No invalid parameters here. We also don't want to do this now. // HRESULT IWmiDbController::GetStatistics([in] DWORD dwParameter,[out] DWORD *pdwValue); hr = pController->GetStatistics(WMIDB_FLAG_TOTAL_HANDLES, 0); RecordResult(hr == WBEM_E_INVALID_PARAMETER || hr == E_NOTIMPL?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbController::GetStatistics - null parameter returns INVALID_PARAMETER",0); hr = pController->GetStatistics(0, &dwWaste); RecordResult(SUCCEEDED(hr) ? WBEM_E_FAILED: WBEM_S_NO_ERROR, L"IWmiDbController::GetStatistics - null parameter fails", 0); // HRESULT IWmiDbSession::SetDecoration([in] LPWSTR lpMachineName,[in] LPWSTR lpNamespacePath); hr = pSession->SetDecoration(NULL, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::SetDecoration - null parameters", 0); hr = pSession->SetDecoration(L"MACHINE1", NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::SetDecoration - null namespace parameter", 0); hr = pSession->SetDecoration(NULL, L"root\\test"); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::SetDecoration - null machine name parameter", 0); // HRESULT IWmiDbSession::GetObject([in] IWmiDbHandle *pScope,[in] IWbemPath*pPath,[in] DWORD dwFlags, // [in] DWORD dwRequestedHandleType,[out] IWmiDbHandle **ppResult ); hr = pSession->GetObject(pScope, NULL, 0, WMIDB_HANDLE_TYPE_COOKIE, &pWaste1); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::GetObject - null binary object path", 0); if (SUCCEEDED(hr)) pWaste1->Release(); hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); if (SUCCEEDED(hr)) { pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L""); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pWaste1); RecordResult(FAILED(hr)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::GetObject - blank object path", 0); if (SUCCEEDED(hr)) pWaste1->Release(); pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"__Namespace"); // this should be valid. hr = pSession->GetObject(NULL, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, &pWaste1); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::GetObject - null scope returns INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) pWaste1->Release(); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_INVALID, &pWaste1); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::GetObject - invalid handle type returns INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) pWaste1->Release(); hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::GetObject - null return pointer returns INVALID_PARAMETER", 0); pPath->Release(); } else wprintf(L"WARNING: call failed to CoCreateInstance (IID_IWbemPath). Tests skipped.\n"); // HRESULT IWmiDbSession::PutObject([in] IWmiDbHandle *pScope,[in] IUnknown *pObjToPut, // [in] DWORD dwFlags, [in] DWORD dwRequestedHandleType, [out] IWmiDbHandle **ppResult); hr = pSession->PutObject(pScope, IID_IWbemClassObject, NULL, 0, WMIDB_HANDLE_TYPE_COOKIE, &pWaste1); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::PutObject - null object returns INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) pWaste1->Release(); hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { SetStringProp(pObj, L"__Class", L"ErrorTest1"); SetIntProp(pObj, L"Key1", 0, true); hr = pSession->PutObject(NULL, IID_IUnknown, pObj, 0, WMIDB_HANDLE_TYPE_COOKIE, &pWaste1); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::PutObject - null scope returns INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) pWaste1->Release(); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, WMIDB_HANDLE_TYPE_INVALID, &pWaste1); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::PutObject - invalid handle type returns INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) pWaste1->Release(); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, NULL, NULL); RecordResult(hr, L"IWmiDbSession::PutObject - null return pointer", 0); pObj->Release(); } else wprintf(L"WARNING: call failed to CoCreateInstance (IID_IWbemClassObject). Tests skipped.\n"); // HRESULT IWmiDbSession::DeleteObject([in] IWmiDbHandle *pScope,[in] IUnknown *pObjId,[in] DWORD dwFlags); hr = pSession->DeleteObject(NULL, NULL, IID_IWmiDbHandle, 0); RecordResult( hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::PutObject - null parameters", 0); hr = pSession->DeleteObject(pScope, NULL, IID_IUnknown, 0); RecordResult( hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::PutObject - null IUnknown *", 0); { IWbemQuery *pQuery = NULL; IWmiDbIterator *pResult = NULL; hr = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery); if (SUCCEEDED(hr)) { // HRESULT IWmiDbSession::ExecQuery([in] IWmiDbHandle *pScope,[in] IWbemQuery *pQuery, // [in] DWORD dwFlags,[in] DWORD dwRequestedHandleType,[out] DWORD *pFlags, [out] IWmiDbIterator **ppQueryResult); hr = pSession->ExecQuery(pScope, NULL, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pResult); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::ExecQuery - null query returns INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) pResult->Release(); pQuery->Parse(L"SQL", L"select * from ErrorTest1", 0); hr = pSession->ExecQuery(NULL, pQuery, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pResult); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::ExecQuery - null scope returns INVALID_PARAMETER", 0); if (SUCCEEDED(hr)) pResult->Release(); hr = pSession->ExecQuery(pScope, pQuery, 0, WMIDB_HANDLE_TYPE_INVALID, NULL, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbSession::ExecQuery - null iterator parameter returns INVALID_PARAMETER", 0); RecordResult(hr = pSession->ExecQuery(pScope, pQuery, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pResult), L"IWmiDbSession::ExecQuery - select * from ErrorTest1", 0); if (SUCCEEDED(hr)) { IUnknown * objs[5]; hr = pResult->NextBatch(1, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwWaste, (void **)&objs); RecordResult(hr == WBEM_S_NO_MORE_DATA?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbIterator::NextBatch - end of rowset returns S_NO_MORE_DATA", 0); pResult->Release(); } CreateInstance(NULL, pSession, pScope, L"ErrorTest1", L"1", CIM_UINT32); CreateInstance(NULL, pSession, pScope, L"ErrorTest1", L"2", CIM_UINT32); CreateInstance(NULL, pSession, pScope, L"ErrorTest1", L"3", CIM_UINT32); CreateInstance(NULL, pSession, pScope, L"ErrorTest1", L"4", CIM_UINT32); CreateInstance(NULL, pSession, pScope, L"ErrorTest1", L"5", CIM_UINT32); RecordResult(hr = pSession->ExecQuery(pScope, pQuery, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pResult), L"IWmiDbSession::ExecQuery - select * from ErrorTest1", 0); if (SUCCEEDED(hr)) { IUnknown * objs[5]; // HRESULT IWmiDbIterator::NextBatch([in] DWORD dwNumRequested,[in] DWORD dwTimeOutSeconds,[in] DWORD dwFlags, // [in] DWORD dwRequestedHandleType,[in] const IID *pIIDRequestedInterface,[out] DWORD *pdwNumReturned, // [out, size_is(dwNumRequested), length_is(*pdwNumReturned)]IUnknown **ppObjects ); hr = pResult->NextBatch(0, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwWaste, (void **)&objs); RecordResult(hr == WBEM_E_INVALID_PARAMETER ? WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbIterator::NextBatch - dwNumRequested is zero returns INVALID_PARAMETER", 0); hr = pResult->NextBatch(1, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, &dwWaste, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER ? WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbIterator::NextBatch - NULL IUnknown ** returns INVALID_PARAMETER", 0); hr = pResult->NextBatch(1, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbHandle, NULL, (void **)&objs); RecordResult(hr, L"IWmiDbIterator::NextBatch - null num returned parameter", 0); hr = pResult->NextBatch(1, 0, 0, WMIDB_HANDLE_TYPE_COOKIE, IID_IWmiDbBatchSession, &dwWaste, (void **)&objs); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"IWmiDbIterator::NextBatch - invalid IID", 0); hr = pResult->NextBatch(1, 0, 0, WMIDB_HANDLE_TYPE_INVALID, IID_IWmiDbBatchSession, &dwWaste, (void **)&objs); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"IWmiDbIterator::NextBatch - invalid handle type", 0); // HRESULT IWmiDbIterator::Cancel ( [in] DWORD dwFlags); hr = pResult->Cancel(0); RecordResult(hr, L"IWmiDbIterator::Cancel (0)", 0); } pQuery->Release(); } else wprintf(L"WARNING: call failed to CoCreateInstance (IID_IWbemQuery). Tests skipped.\n"); } { IWmiDbBatchSession *pBatch = NULL; hr = pSession->QueryInterface(IID_IWmiDbBatchSession, (void **)&pBatch); if (SUCCEEDED(hr)) { WMIOBJECT_BATCH batch; batch.dwArraySize = 3; batch.pElements = new WMI_BATCH_OBJECT_ACCESS[3]; for (int i = 0; i < 3; i++) { batch.pElements[i].pReturnHandle = NULL; batch.pElements[i].dwFlags = 0; batch.pElements[i].pHandle = NULL; batch.pElements[i].hRes = 0; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); batch.pElements[i].pPath = pPath; } batch.pElements[0].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"ErrorTest1=5"); batch.pElements[1].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"ErrorTest1=4"); batch.pElements[2].pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, L"ErrorTest1=3"); // HRESULT IWmiDbBatchSession::GetObjects([in] IWmiDbHandle *pScope,[in] DWORD dwFlags, // [in] DWORD dwRequestedHandleType,[in, out] WMIOBJECT_BATCH *pBatch); hr = pBatch->GetObjects(pScope, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::GetObjects - null batch", 0); hr = pBatch->GetObjects(NULL, 0, WMIDB_HANDLE_TYPE_COOKIE, &batch); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::GetObjects - null scope", 0); hr = pBatch->GetObjects(pScope, 0, WMIDB_HANDLE_TYPE_INVALID, &batch); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::GetObjects - invalid handle type", 0); // HRESULT IWmiDbBatchSession::DeleteObjects([in] IWmiDbHandle *pScope,[in] DWORD dwFlags,[in] WMIOBJECT_BATCH *pBatch); hr = pBatch->DeleteObjects(pScope, 0, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::DeleteObjects - null batch", 0); hr = pBatch->DeleteObjects(NULL, 0, &batch); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::DeleteObjects - null scope", 0); for (i = 0; i < 3; i++) { batch.pElements[i].pPath->Release(); batch.pElements[i].pPath = NULL; } // HRESULT IWmiDbBatchSession::PutObjects([in] IWmiDbHandle *pScope,[in] DWORD dwFlags, // [in] DWORD dwRequestedHandleType,[in, out] WMIOBJECT_BATCH *pBatch); hr = pBatch->PutObjects(pScope, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::PutObjects - null batch", 0); hr = pBatch->PutObjects(NULL, 0, WMIDB_HANDLE_TYPE_COOKIE, &batch); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::PutObjects - null scope", 0); hr = pBatch->PutObjects(pScope, 0, WMIDB_HANDLE_TYPE_INVALID, &batch); RecordResult(hr == WBEM_E_INVALID_PARAMETER?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbBatchSession::PutObjects - invalid handle type", 0); pBatch->Release(); } else wprintf(L"WARNING: call failed to IWmiDbSession::QueryInterface (IWmiDbBatchSession). Tests skipped\n"); } return hr; } // ***************************************************** HRESULT TestSuiteErrorTest::TryInvalidHierarchy() { HRESULT hr = WBEM_S_NO_ERROR; // key migration: An instance exists in one class, then // is persisted under a derived or superclass. This // should fail at the driver level. hr = CreateClass(NULL, pSession, pScope, L"ErrorParent1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorParent1", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorChild1", NULL, CIM_UINT32, L"ErrorParent1"); RecordResult(hr, L"Creating class ErrorChild1", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorChild1", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance ErrorChild1=1", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorParent1", L"1", CIM_UINT32); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver prevents key migration (ErrorChild1=1)", 0); if (FAILED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorParent1", L"2", CIM_UINT32); RecordResult(hr, L"Creating instance ErrorParent1=2", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorChild1", L"2", CIM_UINT32); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver prevents key migration (ErrorParent1=2)", 0); } else wprintf(L"WARNING: Failed to create instance ErrorParent1=2. Tests skipped.\n"); } } else wprintf(L"WARNING: Failed to create instance ErrorChild1=1. Tests skipped.\n"); } else wprintf(L"WARNING: Failed to create class ErrorChild1. Tests skipped.\n"); } else wprintf(L"WARNING: Failed to create class ErrorParent1. Tests skipped.\n"); // parent report to self. ClassB reports to ClassA. // Driver should disallow updating ClassA to report to ClassB. hr = CreateClass(NULL, pSession, pScope, L"ErrorParent2", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorParent2", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorChild2", NULL, CIM_UINT32, L"ErrorParent2"); RecordResult(hr, L"Creating class ErrorChild2", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorParent2", NULL, CIM_UINT32, L"ErrorChild2"); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver prevents circular parent-child relationship. (ErrorParent2:ErrorChild2)", 0); if (FAILED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorGrandChild2", NULL, CIM_UINT32, L"ErrorChild2"); RecordResult(hr, L"Creating class ErrorGrandChild2", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorParent2", NULL, CIM_UINT32, L"ErrorGrandChild2"); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver prevents circular parent-child relationship. (ErrorParent2:ErrorGrandChild2)", 0); } else wprintf(L"WARNING: Failed to create class ErrorGrandChild2. Tests skipped\n"); } } else wprintf(L"WARNING: Failed to create class ErrorChild2. Tests skipped\n"); } else wprintf(L"WARNING: Failed to create class ErrorParent2. Tests skipped.\n"); // Move child with instances. ClassB reports to ClassA. // Driver should disallow changing ClassB's parent if // there are instances. // CORRECTION: This is OK if the classes have the same keys. /* hr = CreateClass(NULL, pSession, pScope, L"ErrorParent3", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorParent3", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorParent3_1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorParent3_1", 0); } if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorChild3", NULL, CIM_UINT32, L"ErrorParent3"); RecordResult(hr, L"Creating class ErrorChild3", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorChild3", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance ErrorChild3=1", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorChild3", NULL, CIM_UINT32, L"ErrorParent3_1"); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver prevents changing parent class when there are instances.", 0); if (FAILED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorParent3", NULL, CIM_UINT32, L"ErrorParent3_1"); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver prevents changing parent class when derived class has instances.", 0); } } else wprintf(L"WARNING: Failed to create instance ErrorChild3=1. Tests skipped\n"); } else wprintf(L"WARNING: Failed to create class ErrorChild3. Tests skipped\n"); } else wprintf(L"WARNING: Failed to create class ErrorParent3. Tests skipped\n"); */ // Change key with subclasses or instances. If a class // has instances, driver should disallow // adding or dropping key properties. hr = CreateClass(NULL, pSession, pScope, L"ErrorParent4", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorParent4", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorChild4", NULL, CIM_UINT32, L"ErrorParent4"); RecordResult(hr, L"Creating class ErrorChild4", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorParent4", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance ErrorParent4=1", 0); if (SUCCEEDED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorParent4", NULL, CIM_UINT32, NULL, NULL, CIM_UINT32); RecordResult(FAILED(hr)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver prevents adding key property when instances exist (ErrorParent4).", 0); if (FAILED(hr)) { hr = CreateClass(NULL, pSession, pScope, L"ErrorChild4", NULL, CIM_UINT32, L"ErrorParent4", NULL, CIM_UINT32); RecordResult(hr, L"Driver prevents changing key when there are instances (ErrorChild4)", 0); } } } else wprintf(L"WARNING: Failed to create class ErrorChild4. Test skipped.\n"); } else wprintf(L"WARNING: Failed to create class ErrorParent4. Test skipped.\n"); // Add property that exists in child. Driver should // disallow adding a property to a parent class that // already exists in one of its derived classes. hr = CreateClass(NULL, pSession, pScope, L"ErrorParent5", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorParent5", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pHandle = NULL; IWbemClassObject *pObj = NULL; hr = CreateClass(&pHandle, pSession, pScope, L"ErrorChild5", NULL, CIM_UINT32, L"ErrorParent5"); RecordResult(hr, L"Creating class ErrorChild5", 0); if (SUCCEEDED(hr)) { hr = pHandle->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { SetStringProp(pObj, L"Prop1", L""); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, NULL, NULL); if (SUCCEEDED(hr)) { IWmiDbHandle *pTemp1 = NULL; IWbemClassObject *pTemp2 = NULL; hr = GetObject(pScope, L"ErrorParent5", WMIDB_HANDLE_TYPE_COOKIE, -1, &pTemp1, &pTemp2); RecordResult(hr, L"Retrieving ErrorParent5", 0); if (SUCCEEDED(hr)) { SetIntProp(pTemp2, L"Prop1", 0); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pTemp2, 0, NULL, NULL); RecordResult(FAILED(hr)?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver denies parent property that overrides one in derived class.", 0); pTemp1->Release(); pTemp2->Release(); } else wprintf(L"WARNING: Failed to retrieve class ErrorParent5. Tests skipped\n"); } else wprintf(L"WARNING: Failed to persist ErrorChild5. Tests skipped\n"); pObj->Release(); } pHandle->Release(); } else wprintf(L"WARNING: Failed to create class ErrorChild5. Test skipped.\n"); } else wprintf(L"WARNING: Failed to create class ErrorParent5. Test skipped.\n"); return hr; } // ***************************************************** HRESULT TestSuiteErrorTest::TryLongStrings() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; wchar_t * wLongText = new wchar_t [4096]; wchar_t * wLongName = new wchar_t [512]; for (int i = 0; i < 4090; i++) wLongText[i] = L'x'; wLongText[4090] = L'\0'; for (i = 0; i < 511; i++) wLongName[i] = L'z'; wLongName[511] = L'\0'; // Long class names, key names and values IWmiDbHandle *pRet = NULL; hr = CreateClass(NULL, pSession, pScope, wLongName, NULL, CIM_UINT32); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver denies class name greater than 255 characters.", 0); hr = CreateClass(&pRet, pSession, pScope, L"LongStrings1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class LongStrings1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pObj = NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { IWmiDbHandle *pHand=NULL; SetStringProp(pObj, wLongName, L""); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL); RecordResult(SUCCEEDED(hr)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver denies property name greater than 255 characters.", 0); hr = pObj->Delete(wLongName); hr = SetIntProp(pObj, L"Key1", 0, TRUE); hr = SetStringProp(pObj, L"Prop1", L""); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, WMIDB_HANDLE_TYPE_COOKIE, &pHand); if (SUCCEEDED(hr)) { long lOrigLen = 0; IWbemClassObject *pObj2 = NULL; hr = pHand->QueryInterface(IID_IWbemClassObject, (void **)&pObj2); if (SUCCEEDED(hr)) { IWbemClassObject *pObj3 = NULL; pObj2->SpawnInstance(0, &pObj3); SetIntProp(pObj3, L"Key1", 1); SetStringProp(pObj3, L"Prop1", wLongText); lOrigLen = GetStringValue(pObj3, L"Prop1").length(); IWbemQualifierSet *pQS = NULL; pObj3->GetQualifierSet(&pQS); if (pQS) { VARIANT vTemp; VariantInit(&vTemp); vTemp.vt = VT_BSTR; vTemp.bstrVal = SysAllocString(wLongText); pQS->Put(L"Description", &vTemp, 0); pQS->Release(); VariantClear(&vTemp); } GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj3, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject - long string data (LongStrings1.Prop1)", GetDiff(tEndTime,tStartTime)); pObj3->Release(); pObj2->Release(); } pHand->Release(); GetLocalTime(&tStartTime); hr = GetObject(pScope, L"LongStrings1=1", WMIDB_HANDLE_TYPE_COOKIE, -1, &pHand, &pObj2); RecordResult(hr, L"Retrieving LongStrings1=1", 0); if (SUCCEEDED(hr)) { GetLocalTime(&tEndTime); long lLen = GetStringValue(pObj2, L"Prop1").length(); RecordResult((lLen < lOrigLen)?WBEM_E_FAILED:WBEM_S_NO_ERROR, L"Driver retrieves long strings", GetDiff(tEndTime,tStartTime)); IWbemQualifierSet *pQS = NULL; pObj2->GetQualifierSet(&pQS); if (pQS) { VARIANT vTemp; VariantInit(&vTemp); hr = pQS->Get(L"Description", NULL, &vTemp, NULL); lLen = wcslen(vTemp.bstrVal); RecordResult((SUCCEEDED(hr) && vTemp.vt == VT_BSTR && (int)lLen >= (int)lOrigLen) ? WBEM_S_NO_ERROR: WBEM_E_FAILED, L"Driver retrieves long qualifiers", GetDiff(tEndTime, tStartTime)); VariantClear(&vTemp); pQS->Release(); } pObj2->Release(); } } else wprintf(L"WARNING: Failed to create instance LongStrings1=1. Tests skipped.\n"); pObj->Release(); } pRet->Release(); } else wprintf(L"WARNING: Failed to create class LongStrings1. Tests skipped.\n"); delete wLongText; delete wLongName; return hr; } // ***************************************************** HRESULT TestSuiteErrorTest::TryChangeDataType() { HRESULT hr = WBEM_S_NO_ERROR; // We have already verified that we can make the // valid conversions. Now try the invalid ones: IWmiDbHandle *pRet = NULL; hr = CreateClass(&pRet, pSession, pScope, L"ErrorTestDataType1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorTestDataType1", 0); if (SUCCEEDED(hr)) { IWbemClassObject *pObj = NULL; hr = pRet->QueryInterface(IID_IWbemClassObject, (void **)&pObj); if (SUCCEEDED(hr)) { pObj->Put(L"string", NULL, NULL, CIM_STRING); pObj->Put(L"datetime", NULL, NULL, CIM_DATETIME); pObj->Put(L"real64", NULL, NULL, CIM_REAL64); pObj->Put(L"uint64", NULL, NULL, CIM_UINT64); pObj->Put(L"object", NULL, NULL, CIM_OBJECT); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorTestDataType1", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance ErrorTestDataType1=1", 0); //pObj->Delete(L"string"); //pObj->Put(L"string", NULL, NULL, CIM_DATETIME); //RecordResult(FAILED(pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL))?WBEM_S_NO_ERROR:WBEM_E_FAILED, // L"Driver denies conversion from string to datetime", 0); pObj->Delete(L"string"); pObj->Put(L"string", NULL, NULL, CIM_UINT32); RecordResult(FAILED(pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL))?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver denies conversion from string to uint32", 0); /* *** Sanj's ReconcileWith function doesn't catch these for some reason pObj->Delete(L"string"); pObj->Put(L"string", NULL, NULL, CIM_REFERENCE); RecordResult(FAILED(pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL))?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver denies conversion from string to reference", 0); pObj->Delete(L"string"); pObj->Delete(L"uint64"); pObj->Put(L"uint64", NULL, NULL, CIM_UINT32); RecordResult(FAILED(pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL))?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver denies conversion from int64 to int32", 0); pObj->Delete(L"real64"); pObj->Put(L"real64", NULL, NULL, CIM_UINT64); RecordResult(FAILED(pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL))?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver denies conversion from int64 to real64", 0); pObj->Delete(L"real64"); pObj->Delete(L"datetime"); pObj->Put(L"datetime", NULL, NULL, CIM_STRING); RecordResult(FAILED(pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL))?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver denies conversion from datetime to string", 0); pObj->Delete(L"datetime"); pObj->Delete(L"object"); pObj->Put(L"object", NULL, NULL, CIM_REFERENCE); RecordResult(FAILED(pSession->PutObject(pScope, IID_IWbemClassObject, pObj, 0, 0, NULL))?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"Driver denies conversion from object to reference", 0); */ } else wprintf(L"WARNING: Failed to persist class ErrorTestDataType1. Tests skipped\n"); } pRet->Release(); } else wprintf(L"WARNING: Failed to create class ErrorTestDataType1. Tests skipped\n"); return hr; } // ***************************************************** HRESULT TestSuiteErrorTest::TryInvalidQuery() { HRESULT hr = WBEM_S_NO_ERROR; // If we perform a query on a partially secured, // or partially locked result set. // This should succeed but return WBEM_S_PARTIAL_RESULTS // If the class itself is locked, we should get a denial. // If a child class is locked, we should get partial results. hr = CreateClass(NULL, pSession, pScope, L"ErrorTestQuery1", NULL, CIM_UINT32); RecordResult(hr, L"Creating class ErrorTestQuery1", 0); if (SUCCEEDED(hr)) { hr = CreateInstance(NULL, pSession, pScope, L"ErrorTestQuery1", L"1", CIM_UINT32); RecordResult(hr, L"Creating instance ErrorTestQuery=1", 0); hr = CreateInstance(NULL, pSession, pScope, L"ErrorTestQuery1", L"2", CIM_UINT32); RecordResult(hr, L"Creating instance ErrorTestQuery=2", 0); if (SUCCEEDED(hr)) { IWmiDbHandle *pRet = NULL; IWbemClassObject *pObj = NULL; hr = GetObject(pScope, L"ErrorTestQuery1=1", WMIDB_HANDLE_TYPE_EXCLUSIVE, -1, &pRet, &pObj); RecordResult(hr, L"Retrieving ErrorTestQuery1=1", 0); if (SUCCEEDED(hr)) { IWbemQuery *pQuery = NULL; hr = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery); if (SUCCEEDED(hr)) { IWmiDbIterator *pIt = NULL; pQuery->Parse(L"SQL", L"select * from ErrorTestQuery1", 0); hr = pSession->ExecQuery(pScope, pQuery, 0,WMIDB_HANDLE_TYPE_COOKIE, NULL, &pIt); if (SUCCEEDED(hr)) { DWORD dwNumRet = 0; IUnknown * blah[2]; hr = pIt->NextBatch(2, 0, 0, WMIDB_HANDLE_TYPE_PROTECTED, IID_IWmiDbHandle, &dwNumRet, (void **)&blah); RecordResult(hr == WBEM_S_PARTIAL_RESULTS || hr == WBEM_S_NO_MORE_DATA?WBEM_S_NO_ERROR:WBEM_E_FAILED, L"IWmiDbIterator::NextBatch returns PARTIAL_RESULTS when some results locked.", 0); pIt->Release(); } pQuery->Release(); } pRet->Release(); pObj->Release(); } } } return hr; } // ***************************************************** // // TestSuiteStressTest // // ***************************************************** BOOL TestSuiteStressTest::StopOnFailure() { return FALSE; } // ***************************************************** HRESULT TestSuiteStressTest::RunSuite(IWmiDbSession *_pSession, IWmiDbController *_pController, IWmiDbHandle *_pScope) { RecordResult(0, L" *** Stress Suite running... *** \n", 0); wprintf(L" *** Stress Suite running... *** \n"); HRESULT hr = WBEM_S_NO_ERROR; pSession = _pSession; pController = _pController; pScope = _pScope; HANDLE hThread = 0; DWORD dwThreadID = 0; HANDLE hThreadEvent = CreateEvent(NULL, FALSE, FALSE, TESTMOD_NOTIF); for (int i = 0; i < iThreads; i++) { hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)THREAD_RunTest, this, 0, &dwThreadID); if (hThread) { CloseHandle(hThread); printf("Created thread #%ld\n", i+1); } else printf("Failed to create thread #%ld\n", i+1); } if (WaitForSingleObject(hThreadEvent, 30*60*1000) != WAIT_OBJECT_0) hr = WBEM_S_TIMEDOUT; return hr; } // ***************************************************** TestSuiteStressTest::TestSuiteStressTest(const wchar_t *pszFile, int nDepth, int nMaxObjs, int nMaxThreads) : TestSuite(pszFile) { iDepth = nDepth; iObjs = nMaxObjs; iThreads = nMaxThreads; if (iThreads < 1) iThreads = 1; } // ***************************************************** TestSuiteStressTest::~TestSuiteStressTest() { } // ***************************************************** HRESULT WINAPI TestSuiteStressTest::THREAD_RunTest(TestSuiteStressTest *pTest) { HRESULT hr = WBEM_S_NO_ERROR; hr = CoInitialize(NULL); CRITICAL_SECTION crit; InitializeCriticalSection(&crit); EnterCriticalSection(&crit); iRunning++; LeaveCriticalSection(&crit); try { hr = CreateClass (NULL, pTest->pSession, pTest->pScope, L"IntKey1", NULL, CIM_UINT32); pTest->RecordResult(hr, L"Created stress class IntKey1", 0); if (SUCCEEDED(hr)) hr = pTest->RunVanillaTest(L"IntKey1"); hr = CreateClass (NULL, pTest->pSession, pTest->pScope, L"StringKey1", NULL, CIM_STRING); pTest->RecordResult(hr, L"Created stress class StringKey1", 0); if (SUCCEEDED(hr)) hr = pTest->RunVanillaTest(L"StringKey1"); hr = CreateClass (NULL, pTest->pSession, pTest->pScope, L"ReferenceKey1", L"Association", CIM_REFERENCE, NULL, NULL, CIM_REFERENCE); pTest->RecordResult(hr, L"Created stress class ReferenceKey1", 0); if (SUCCEEDED(hr)) hr = pTest->RunVanillaTest(L"ReferenceKey1"); } catch (...) { pTest->RecordResult(WBEM_E_FAILED, L"Stress testing caught an exception of an unknown type on thread %ld\n", 0, GetCurrentThreadId()); } // Sort out the order and the failure allowances try { hr = pTest->CreateNamespaces(); } catch (...) { pTest->RecordResult(WBEM_E_FAILED, L"Stress testing caught an exception of an unknown type on thread %ld\n", 0, GetCurrentThreadId()); } EnterCriticalSection(&crit); iRunning--; if (!iRunning) { HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, TESTMOD_NOTIF); if (hEvent) { SetEvent(hEvent); CloseHandle(hEvent); } } LeaveCriticalSection(&crit); DeleteCriticalSection(&crit); return hr; } // ***************************************************** int GetNumNamespaces(int iTotal) { int iRet = 1; int iTemp = iTotal/200; if (iTemp > iRet) iRet = iTemp; return iRet; } // ***************************************************** int GetNumClasses(int iTotal) { int iRet = 1; int iTemp = iTotal/20; if (iTemp > iRet) iRet = iTemp; return iRet; } // ***************************************************** int GetNumInstances(int iTotal) { int iRet = 1; int iTemp = iTotal; iTemp -= (GetNumClasses(iTotal)*GetNumNamespaces(iTotal)); iTemp = iTemp/GetNumClasses(iTotal); if (iTemp > iRet) iRet = iTemp; return iRet; } // ***************************************************** HRESULT TestSuiteStressTest::RunVanillaTest (LPWSTR lpClassName) { DWORD arrTypes[50]; CWStringArray arrKeys, arrPaths; _bstr_t sClassName; wchar_t wTemp[512]; IWmiDbHandle *pHandle = NULL; IWbemClassObject *pClass = NULL; VARIANT vTemp; VariantInit(&vTemp); int iNum = 0; time_t tBegin, tEnd; int iActual = 0; wchar_t szTmp[100]; HRESULT hr = GetObject(pScope, lpClassName, WMIDB_HANDLE_TYPE_COOKIE, -1, &pHandle, &pClass); RecordResult(hr, L"Retrieving %s", 0, lpClassName); if (SUCCEEDED(hr)) { pClass->Get(L"__Genus", 0, &vTemp, NULL, NULL); if (vTemp.lVal == 1) { CIMTYPE cimtype; BSTR strName; VariantClear(&vTemp); // Get the keys. pClass->BeginEnumeration(0); while (pClass->Next(0, &strName, NULL, &cimtype, NULL) == S_OK) { IWbemQualifierSet *pQS = NULL; pClass->GetPropertyQualifierSet(strName, &pQS); if (pQS) { if (pQS->Get(L"key", NULL, NULL, NULL) == S_OK) { arrKeys.Add((const wchar_t *)strName); arrTypes[arrKeys.Size()-1] = cimtype; } pQS->Release(); } SysFreeString(strName); } pClass->EndEnumeration(); if (arrKeys.Size() > 0) { // Use keys to generate n objects. hr = pClass->Get(L"__Class", 0, &vTemp, NULL, NULL); sClassName = vTemp.bstrVal; VariantClear(&vTemp); iNum = iObjs; int iStart = 1; iActual = 0; __int64 dwTime = 0; WMIOBJECT_BATCH batch; batch.dwArraySize = 250; batch.pElements = new WMI_BATCH_OBJECT_ACCESS[250]; IWmiDbBatchSession *pBatch = NULL; hr = pSession->QueryInterface(IID_IWmiDbBatchSession, (void **)&pBatch); tBegin = time(0); int iCounter = 0; for (int i = iStart; i < iNum+iStart; i++) { IWbemClassObject *pInst = NULL; hr = pClass->SpawnInstance(0, &pInst); if (SUCCEEDED(hr)) { for (int j = 0; j < arrKeys.Size(); j++) { CIMTYPE ct = arrTypes[j]; switch(ct) { case CIM_STRING: vTemp.vt = VT_BSTR; swprintf(szTmp, L"%X=%ld", rand(), i); V_BSTR(&vTemp) = SysAllocString(szTmp); break; case CIM_REFERENCE: vTemp.vt = VT_BSTR; swprintf(szTmp, L"root:XXX%X=%ld", rand(), i); V_BSTR(&vTemp) = SysAllocString(szTmp); break; case CIM_UINT64: vTemp.vt = VT_R8; vTemp.dblVal = (double)i; break; default: vTemp.vt = VT_I4; V_I4(&vTemp) = i; break; } hr = pInst->Put((const wchar_t *)arrKeys.GetAt(j), 0, &vTemp, ct); VariantClear(&vTemp); } pInst->Get(L"__RelPath", 0, &vTemp, NULL, NULL); arrPaths.Add(vTemp.bstrVal); VariantClear(&vTemp); batch.pElements[iCounter].pHandle = pInst; iCounter++; } if (iCounter == 250 || i == (iNum+iStart-1)) { for (int j = iCounter; j < 250; j++) batch.pElements[j].pHandle = NULL; batch.dwArraySize = iCounter; iCounter = 0; hr = pBatch->PutObjects(pScope, 0, WMIDB_HANDLE_TYPE_COOKIE|WMIDB_HANDLE_TYPE_NO_CACHE, &batch); for (j = 0; j < 250; j++) { if (batch.pElements[j].pHandle) { batch.pElements[j].pHandle->Release(); batch.pElements[j].pHandle = NULL; if (batch.pElements[j].hRes == 0) { batch.pElements[j].pReturnHandle->Release(); iActual++; } } } } } tEnd = time(0); dwTime = (tEnd-tBegin); if (dwTime && iActual) { swprintf(wTemp, L"Average time to put = %ld", ((dwTime)*1000)/iActual); printf("Average PutObjects time (%S): %ld ms\n", lpClassName, ((dwTime)*1000)/iActual); RecordResult(0, wTemp, 0); } else printf("Average PutObjects time (%S): 0 ms\n", lpClassName); pBatch->Release(); delete batch.pElements; /* HANDLE hThisProcess = GetCurrentProcess(); PROCESS_MEMORY_COUNTERS counters; if (GetProcessMemoryInfo(hThisProcess, &counters, sizeof(PROCESS_MEMORY_COUNTERS))) { printf("=== CURRENT MEMORY USAGE === \n"); printf("PageFaultCount %ld\n", counters.PageFaultCount); printf("WorkingSetSize %ld\n", counters.WorkingSetSize); printf("PeakWorkingSetSize %ld\n", counters.PeakWorkingSetSize); printf("QuotaPeakPagedPoolUsage %ld\n", counters.QuotaPeakPagedPoolUsage); printf("QuotaPagedPoolUsage %ld\n", counters.QuotaPagedPoolUsage); printf("QuotaPeakNonPagedPoolUsage %ld\n", counters.QuotaPeakNonPagedPoolUsage); printf("QuotaNonPagedPoolUsage %ld\n", counters.QuotaNonPagedPoolUsage); printf("PagefileUsage %ld\n", counters.PagefileUsage); printf("PeakPagefileUsage %ld\n\n", counters.PeakPagefileUsage); } */ // Query the entire class and time results. IWbemQuery *pQuery = NULL; DWORD dwFlags = 0; DWORD dwType = WMIDB_HANDLE_TYPE_COOKIE|WMIDB_HANDLE_TYPE_NO_CACHE; IWmiDbIterator *pResult = NULL; iActual = 0; hr = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery); swprintf(szTmp, L"select * from %s", (const wchar_t *)sClassName); pQuery->Parse(L"SQL", szTmp, 0); tBegin = time(0); hr = pSession->ExecQuery(pScope, pQuery, dwFlags, dwType, NULL, &pResult); if (SUCCEEDED(hr)) { while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA) { // Iterator int iNum = 20; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; hr = pResult->NextBatch(iNum, 0, 0, dwType, IID_IWmiDbHandle, &dwNumRet, (void **)ppHandle); for (i = 0; i < (int)dwNumRet; i++) ppHandle[i]->Release(); delete ppHandle; iActual += dwNumRet; if (hr == WBEM_S_NO_MORE_DATA) break; } pResult->Release(); } tEnd = time(0); swprintf(wTemp, L"Retrieved %ld instances", iActual); RecordResult(hr, wTemp, (DWORD)(tEnd-tBegin)*1000); dwTime = (tEnd-tBegin); if (iActual && dwTime) printf("Average ExecQuery (handle) time (%S): %ld ms\n", lpClassName, ((dwTime)*1000)/iActual); else printf("Average ExecQuery (handle) time (%S): 0 ms\n", lpClassName); swprintf(szTmp, L"select * from %s", (const wchar_t *)sClassName); pQuery->Parse(L"SQL", szTmp, 0); iActual = 0; tBegin = time(0); hr = pSession->ExecQuery(pScope, pQuery, dwFlags, dwType, NULL, &pResult); if (SUCCEEDED(hr)) { while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA) { // Iterator int iNum = 20; DWORD dwNumRet = 0; IUnknown **ppHandle = new IUnknown *[iNum]; hr = pResult->NextBatch(iNum, 0, 0, dwType, IID_IWbemClassObject, &dwNumRet, (void **)ppHandle); for (i = 0; i < (int)dwNumRet; i++) { IWbemClassObject *pTemp2 = NULL; IUnknown *pHand = ppHandle[i]; if (pHand) { hr = pHand->QueryInterface(IID_IWbemClassObject, (void **)&pTemp2); if (SUCCEEDED(hr)) { iActual++; pTemp2->Release(); } pHand->Release(); } } delete ppHandle; if (hr == WBEM_S_NO_MORE_DATA) break; } pResult->Release(); } pQuery->Release(); tEnd = time(0); swprintf(wTemp, L"Retrieving %ld populated instances", iActual); RecordResult(hr, wTemp, (DWORD)(tEnd-tBegin)*1000); dwTime = (tEnd-tBegin); if (dwTime && iActual) printf("Average ExecQuery (object) time (%S): %ld ms\n", lpClassName, ((dwTime)*1000)/iActual); else printf("Average ExecQuery (object) time (%S): 0 ms\n", lpClassName); IWbemPath*pPath = NULL; hr = CoCreateInstance(CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, IID_IWbemPath, (void **)&pPath); iActual = 0; tBegin = time(0); for (i = 0; i < arrPaths.Size(); i++) { pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, arrPaths.GetAt(i)); IWmiDbHandle *pTemp2 = NULL; hr = pSession->GetObject(pScope, pPath, 0, WMIDB_HANDLE_TYPE_VERSIONED|WMIDB_HANDLE_TYPE_NO_CACHE, &pTemp2); RecordResult(hr, L"Retrieving %s", 0, lpClassName); if (SUCCEEDED(hr)) { pTemp2->Release(); iActual++; } } pPath->Release(); tEnd = time(0); dwTime = (tEnd-tBegin); if (dwTime && iActual) printf("Average GetObject time (%S): %ld ms\n", lpClassName, ((dwTime)*1000)/iActual); else printf("Average GetObject (handle) time (%S): 0 ms\n", lpClassName); swprintf(wTemp, L"Retrieving %ld handles by path", iActual); RecordResult(hr, wTemp, (DWORD)(tEnd-tBegin)*1000); } pClass->Release(); } pHandle->Release(); } return hr; } // ***************************************************** HRESULT TestSuiteStressTest::CreateNamespaces() { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; int iTotal = 0; IWmiDbHandle *pNamespace = NULL; IWbemClassObject *pClass = NULL; hr = GetObject(pScope, L"__Namespace", WMIDB_HANDLE_TYPE_COOKIE, 1, &pNamespace, &pClass); RecordResult(hr, L"Retrieving __Namespace", 0); if (SUCCEEDED(hr)) { pNamespace->Release(); for (int i = 0; i < GetNumNamespaces(iObjs); i++) { // This doesn't need to be random, since we // want all threads to be working in the same namespaces. IWbemClassObject *pNs1 = NULL; pClass->SpawnInstance(0, &pNs1); wchar_t wTemp[500]; swprintf(wTemp, L"Namespace%ld", i+1); SetStringProp(pNs1, L"Name", wTemp); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pNs1, 0, WMIDB_HANDLE_TYPE_PROTECTED, &pNamespace); GetLocalTime(&tEndTime); iTotal += GetDiff(tEndTime,tStartTime); RecordResult(hr, L"IWmiDbSession::PutObject (__Namespace = Namespace%ld) THREAD %ld", GetDiff(tEndTime,tStartTime), GetCurrentThreadId()); if (SUCCEEDED(hr)) hr = CreateClasses(pNamespace, NULL, 1); } iTotal = iTotal/i; RecordResult(0, L"Average create time for namespaces: %ld ms", 0, iTotal); } wprintf(L"Thread %ld is done\n", GetCurrentThreadId()); return hr; } // ***************************************************** int TrimNumber( int iMin, int iMax, int iLen, int iNumber) { int iTemp = iNumber; int iOrigWidth = 0; while (iTemp > 0) { iTemp = iTemp/10; iOrigWidth++; } while (iOrigWidth > iLen) { iNumber = iNumber/10; iOrigWidth--; } if (iNumber > iMax) { if (iNumber > 10) iNumber = iNumber/10; else iNumber = iMax; } if (iNumber < iMin) iNumber = iMin; return iNumber; } // ***************************************************** _bstr_t GetRandomDate() { _bstr_t sRet; int iYear=1,iMonth=1,iDay=1,iHour=1,iMinute=0,iSecond=0,iMs=0; iYear = TrimNumber(0, 9999, 4, rand()); iMonth = TrimNumber(1, 12, 2, rand()); iDay = TrimNumber(1, 29, 2, rand()); iHour = TrimNumber(1, 23, 2, rand()); iMinute = TrimNumber(0, 59, 2, rand()); iSecond = TrimNumber(0, 59, 2, rand()); iMs = TrimNumber(0, 999, 3, rand()); wchar_t wTemp[30]; swprintf(wTemp, L"%04ld%02ld%02ld%02ld%02ld%02ld.%06ld+000", iYear, iMonth, iDay, iHour, iMinute, iSecond, iMs); sRet = wTemp; return sRet; } // ***************************************************** _bstr_t GetRandomString() { _bstr_t sRet; int iLen = TrimNumber(2, 999, 3, rand()); char szTmp[1000]; // Load it with a bunch of random characters. for (int i = 0; i < iLen/2; i++) szTmp[i] = (char)TrimNumber(48, 154, 3, rand()); wchar_t *pNew = new wchar_t[iLen+1]; swprintf(pNew, L"%S", szTmp); sRet = pNew; delete pNew; return sRet; } // ***************************************************** void SetClassProperties(IWbemClassObject *pClass) { // Randomly select from all datatypes. // We need at least one key property // Some properties may be indexed // There need to be anywhere from 1 to 99 properties // If there's a superclass, we won't bother adding more keys. CIMTYPE alltypes[] = {CIM_SINT8, CIM_UINT8, CIM_SINT16, CIM_UINT16, CIM_SINT32, CIM_UINT32, CIM_DATETIME, CIM_REFERENCE, CIM_CHAR16, CIM_STRING, CIM_REAL32, CIM_REAL64}; bool bKeySet = false; if (GetStringValue(pClass, L"__SuperClass").length()) bKeySet = true; int iTotalProps = TrimNumber(1, 9, 1, rand()); // 9 will allow room for growth. for (int i = 0; i < iTotalProps; i++) { wchar_t sPropName[100]; CIMTYPE ct = alltypes[TrimNumber(0,11,1,rand())]; swprintf(sPropName, L"Prop_%ld_%ld_%ld", ct, i, rand()); pClass->Put(sPropName, 0, NULL, ct); // no defaults. if (!bKeySet) { pClass->Put(L"Key1", 0, NULL, CIM_UINT32); SetAsKey(pClass, L"Key1"); if (ct == CIM_UINT32) SetAsKey(pClass, sPropName); if (TrimNumber(0,1,1,rand())) bKeySet = true; } if (!TrimNumber(0, 1, 1, rand()) && (ct == CIM_UINT32 || ct == CIM_STRING)) SetBoolQualifier(pClass, L"indexed", sPropName); } } // ***************************************************** void TestSuiteStressTest::SetInstanceProperties(IWbemClassObject *pInstance) { // Enumerate all properties // and set each one with an appropriate value HRESULT hr; BSTR strName; VARIANT vTemp; VariantInit(&vTemp); CIMTYPE cimtype; long lPropFlavor; IWbemClassObject *pEmbedClass = NULL; IWbemClassObject *pEmbedInstance = NULL; IWmiDbHandle *pRet = NULL; pInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY); while (pInstance->Next(0, &strName, &vTemp, &cimtype, &lPropFlavor) == S_OK) { switch(cimtype) { case CIM_BOOLEAN: V_BOOL(&vTemp) = (BOOL)rand(); vTemp.vt = VT_BOOL; break; case CIM_SINT8: case CIM_UINT8: case CIM_CHAR16: V_UI1(&vTemp) = (unsigned char)rand(); vTemp.vt = VT_UI1; break; case CIM_SINT16: V_I2(&vTemp) = (short)rand(); vTemp.vt = VT_I2; break; case CIM_UINT16: V_I4(&vTemp) = rand()/100; vTemp.vt = VT_I4; break; case CIM_SINT32: case CIM_UINT32: V_I4(&vTemp) = rand(); vTemp.vt = VT_I4; break; case CIM_SINT64: case CIM_UINT64: case CIM_REAL64: V_R8(&vTemp) = (double)rand(); vTemp.vt = VT_R8; break; case CIM_REAL32: V_R4(&vTemp) = (float)rand(); vTemp.vt = VT_R4; break; case CIM_STRING: // Randomly generate a string. V_BSTR(&vTemp) = SysAllocString(GetRandomString()); vTemp.vt = VT_BSTR; break; case CIM_REFERENCE: V_BSTR(&vTemp) = SysAllocString(L"Parent1=2"); vTemp.vt = VT_BSTR; break; case CIM_DATETIME: // Randomly generate a date. V_BSTR(&vTemp) = SysAllocString(GetRandomDate()); vTemp.vt = VT_BSTR; break; case CIM_OBJECT: // Use an instance of Parent1. hr = GetObject(pScope, L"Parent1", WMIDB_HANDLE_TYPE_COOKIE, -1, &pRet, &pEmbedClass); RecordResult(hr, L"Retrieving Parent1", 0); if (SUCCEEDED(hr)) { pRet->Release(); pEmbedClass->SpawnInstance(0, &pEmbedInstance); SetIntProp(pEmbedInstance, L"Key1", rand(), TRUE); V_UNKNOWN(&vTemp) = (IUnknown *)pEmbedInstance; vTemp.vt = VT_UNKNOWN; } break; } hr = pInstance->Put(strName, 0, &vTemp, cimtype); if (FAILED(hr)) wprintf(L"Failed to set property %s\n", strName); SysFreeString(strName); VariantClear(&vTemp); } } // ***************************************************** _bstr_t GetCIMType (CIMTYPE cimtype) { _bstr_t sRet; bool bArray = false; if (cimtype & 0x2000) bArray = true; cimtype &= ~0x2000; switch(cimtype) { case CIM_STRING: sRet = L"string"; break; case CIM_DATETIME: sRet = L"datetime"; break; case CIM_BOOLEAN: sRet = L"boolean"; break; case CIM_CHAR16: sRet = L"char16"; break; case CIM_UINT8: sRet = L"uint8"; break; case CIM_SINT8: sRet = L"sint8"; break; case CIM_UINT16: sRet = L"uint16"; break; case CIM_SINT16: sRet = L"sint16"; break; case CIM_UINT32: sRet = L"uint32"; break; case CIM_SINT32: sRet = L"sint32"; break; case CIM_UINT64: sRet = L"uint64"; break; case CIM_SINT64: sRet = L"sint64"; break; case CIM_REAL32: sRet = L"real32"; break; case CIM_REAL64: sRet = L"real64"; break; case CIM_OBJECT: sRet = L"object"; break; case CIM_REFERENCE: sRet = L"ref"; break; default: sRet = L"string"; break; } if (bArray) sRet += L"[]"; return sRet; } // ***************************************************** _bstr_t GetBstr (DWORD dwValue) { wchar_t szTmp[30]; swprintf(szTmp, L"%ld", dwValue); return szTmp; } _bstr_t GetBstr (double dValue) { wchar_t szTmp[30]; swprintf(szTmp, L"%lG", dValue); return szTmp; } _bstr_t GetBstr (VARIANT &vValue) { _bstr_t sRet; long i = 0; long lUBound = 0; long lTemp; double dTemp; BOOL bTemp; SAFEARRAY* psaArray = NULL; BSTR sTemp; HRESULT hr = 0; if (vValue.vt & CIM_FLAG_ARRAY) { DWORD dwType = vValue.vt & 0xFF; psaArray = V_ARRAY(&vValue); if (psaArray) { hr = SafeArrayGetUBound(psaArray, 1, &lUBound); lUBound += 1; for (i = 0; i < lUBound; i++) { _bstr_t sTemp1; if (dwType == VT_BOOL) { hr = SafeArrayGetElement(psaArray, &i, &bTemp); sTemp1 = GetBstr((DWORD)bTemp); } else if (dwType == VT_BSTR) { hr = SafeArrayGetElement(psaArray, &i, &sTemp); if (wcslen(sTemp) == 0) break; sTemp1 = sTemp; } else if (dwType == VT_R8) { hr = SafeArrayGetElement(psaArray, &i, &dTemp); if (!dTemp) break; sTemp1 = GetBstr(dTemp); } else { hr = SafeArrayGetElement(psaArray, &i, &lTemp); if (!lTemp) break; sTemp1 = GetBstr((DWORD)lTemp); } if (i > 0) sRet += L","; sRet += sTemp1; } } } else { switch( (vValue.vt & 0xFF)) { case VT_I1: sRet = GetBstr((DWORD)vValue.cVal); break; case VT_UI1: sRet = GetBstr((DWORD)vValue.bVal); break; case VT_I2: sRet = GetBstr((DWORD)vValue.iVal); break; case VT_I4: sRet = GetBstr((DWORD)vValue.lVal); break; case VT_BOOL: sRet = GetBstr((DWORD)vValue.boolVal); break; case VT_R4: sRet = GetBstr((double)vValue.fltVal); break; case VT_R8: sRet = GetBstr((double)vValue.dblVal); break; case VT_NULL: case VT_EMPTY: sRet = ""; break; case VT_BSTR: sRet = vValue.bstrVal; break; case VT_UNKNOWN: sRet = ""; break; default: // TO DO: Add all the other datatypes... sRet = ""; } } return sRet; } // ***************************************************** void DumpObject(IWbemClassObject *pIn) { BSTR strName; VARIANT vTemp; CIMTYPE cimtype; long lPropFlavor; wprintf(L"*** FAILED OBJECT ***\n"); wprintf(L"instance of %s\n{\n", (const wchar_t *)GetStringValue(pIn, L"__Class")); pIn->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY); while (pIn->Next(0, &strName, &vTemp, &cimtype, &lPropFlavor) == S_OK) { wprintf(L"\t%s %s = %s\n", (const wchar_t *)GetCIMType(cimtype), (const wchar_t *)strName, (const wchar_t *)GetBstr(vTemp)); SysFreeString(strName); VariantClear(&vTemp); } pIn->EndEnumeration(); wprintf(L"}\n\n"); } // ***************************************************** HRESULT TestSuiteStressTest::CreateClasses(IWmiDbHandle *pNamespace, IWbemClassObject *pParent, int iCurrDepth) { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; int iTotal = 0; srand((unsigned)time(NULL)); for (int j = 0; j < GetNumClasses(iObjs)/iDepth; j++) { IWmiDbHandle *pClass = NULL; IWbemClassObject *pNewClass = NULL; if (pParent) hr = pParent->SpawnDerivedClass(0, &pNewClass); else { hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER, IID_IWbemClassObject, (void **)&pNewClass); } if (SUCCEEDED(hr)) { int iRand = rand(); wchar_t wClassName[255]; swprintf(wClassName, L"Class%ld_%ld", iRand, GetCurrentThreadId()); // Random classes. We can find them later by querying __Class. SetStringProp(pNewClass, L"__Class", wClassName); // Generate a class of random type with // random property types. SetClassProperties(pNewClass); GetLocalTime(&tStartTime); hr = pSession->PutObject(pNamespace, IID_IWbemClassObject, pNewClass, 0, WMIDB_HANDLE_TYPE_COOKIE, &pClass); GetLocalTime(&tEndTime); iTotal += GetDiff(tEndTime,tStartTime); RecordResult(hr, L"IWmiDbSession::PutObject (%s) THREAD %ld", GetDiff(tEndTime,tStartTime), (const wchar_t *)wClassName, GetCurrentThreadId()); if (hr == WBEM_E_RERUN_COMMAND) { int iTimes = 0; printf("WARNING: Encountered a deadlock. Will attempt to rerun command.\n"); DumpObject(pNewClass); while (hr == WBEM_E_RERUN_COMMAND && iTimes < 5) { hr = pSession->PutObject(pNamespace, IID_IWbemClassObject, pNewClass, 0, WMIDB_HANDLE_TYPE_COOKIE, &pClass); RecordResult(hr, L"IWmiDbSession::PutObject (%s) THREAD %ld", 0, (const wchar_t *)wClassName, GetCurrentThreadId()); if (SUCCEEDED(hr)) break; iTimes++; } } if (SUCCEEDED(hr)) { hr = CreateInstances(pNamespace, pNewClass ); if (iDepth < iCurrDepth) hr = CreateClasses(pNamespace, pNewClass, iCurrDepth+1); pClass->Release(); hr = GetObjects(pNamespace, wClassName); } else { IErrorInfo *pInfo = NULL; hr = GetErrorInfo(0, &pInfo); if (pInfo) { BSTR sDescr = NULL; pInfo->GetDescription(&sDescr); wprintf(L"SQL Error: %s\n", (const wchar_t *)sDescr); SysFreeString(sDescr); pInfo->Release(); } DumpObject(pNewClass); } pNewClass->Release(); } } if (j) iTotal = iTotal/j; RecordResult(hr, L"Average create time for classes: %ld ms", 0, iTotal); return hr; } // ***************************************************** HRESULT TestSuiteStressTest::CreateInstances(IWmiDbHandle *pNamespace, IWbemClassObject *pClass) { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; int iTotal = 0; for (int k = 0; k < GetNumInstances(iObjs); k++) { IWmiDbHandle *pHandle = NULL; IWbemClassObject *pInst = NULL; hr = pClass->SpawnInstance(0, &pInst); if (SUCCEEDED(hr)) { // Populate the instance. Choose // random data based on the datatypes // of the properties. SetInstanceProperties(pInst); GetLocalTime(&tStartTime); hr = pSession->PutObject(pNamespace, IID_IWbemClassObject, pInst, 0, WMIDB_HANDLE_TYPE_COOKIE, &pHandle); GetLocalTime(&tEndTime); iTotal += GetDiff(tEndTime,tStartTime); RecordResult(hr, L"IWmiDbSession::PutObject (%s) THREAD %ld", GetDiff(tEndTime,tStartTime), (const wchar_t *)GetStringValue(pInst, L"__RelPath"), GetCurrentThreadId()); if (FAILED(hr)) { int iTimes = 0; if (hr == WBEM_E_RERUN_COMMAND) printf("WARNING: Encountered a deadlock. Will attempt to rerun command.\n"); DumpObject(pInst); while (hr == WBEM_E_RERUN_COMMAND && iTimes < 5) { hr = pSession->PutObject(pNamespace, IID_IWbemClassObject, pInst, 0, WMIDB_HANDLE_TYPE_COOKIE, &pHandle); if (SUCCEEDED(hr)) pHandle->Release(); iTimes++; } } else pHandle->Release(); pInst->Release(); } } if (k) iTotal = iTotal/k; RecordResult(hr, L"Average create time for instances: %ld ms", 0, iTotal); return hr; } // ***************************************************** HRESULT TestSuiteStressTest::GetObjects(IWmiDbHandle *pScope, LPWSTR lpClassName) { HRESULT hr = WBEM_S_NO_ERROR; SYSTEMTIME tStartTime, tEndTime; if (Interfaces[IWbemQuery_pos]) { IWmiDbIterator *pIt = NULL; IWbemQuery *pQuery = NULL; hr = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery); wchar_t wQuery[100]; swprintf(wQuery, L"select * from %s", lpClassName); pQuery->Parse(L"SQL", wQuery, 0); GetLocalTime(&tStartTime); hr = pSession->ExecQuery(pScope, pQuery, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pIt); if (SUCCEEDED(hr)) pIt->Release(); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::ExecQuery (%s)", GetDiff(tEndTime,tStartTime), wQuery); } IWmiDbHandle *pRet = NULL; IWbemClassObject *pTemp = NULL; GetLocalTime(&tStartTime); hr = GetObject(pScope, lpClassName, WMIDB_HANDLE_TYPE_COOKIE, -1, &pRet, &pTemp); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::GetObject (%s)", GetDiff(tEndTime,tStartTime), lpClassName); if (SUCCEEDED(hr)) { pRet->Release(); if (pTemp) { // Set a bunch of values and update the class. SetInstanceProperties(pTemp); GetLocalTime(&tStartTime); hr = pSession->PutObject(pScope, IID_IWbemClassObject, pTemp, 0, 0, NULL); GetLocalTime(&tEndTime); RecordResult(hr, L"IWmiDbSession::PutObject (%s)", GetDiff(tEndTime,tStartTime), lpClassName); pTemp->Release(); } } return hr; }