//***************************************************************************** // Copyright (c) 2012 - 2018, Hefei LCFC Information Technology Co.Ltd. // And/or its affiliates. All rights reserved. // Hefei LCFC Information Technology Co.Ltd. PROPRIETARY/CONFIDENTIAL. // Use is subject to license terms. //****************************************************************************** /*++ Abstract: This sample application is used for execute WMI method Lfc_Tools_Wmi_Service->SetDataUlongAndPackage with one input package type parameter,one output parameter. History: Date Name Version Change Notes 2018.11.16 Steven Wang V1.00 Initial release. Module Name: SampleSetPackage.cpp */ #include "stdafx.h" //#define _WIN32_DCOM #include using namespace std; #include #include #include // for wcstombs #include // for towlower #include // for wchar_t #pragma comment(lib, "wbemuuid.lib") int main() { HRESULT hres; bool STATUS = FALSE; // Step 1: -------------------------------------------------- // Initialize COM. ------------------------------------------ hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { printf("Failed to initialize COM library. Error code = 0x%x\n", hres); return FALSE; // Program has failed. } // Step 2: -------------------------------------------------- // Set general COM security levels -------------------------- hres = CoInitializeSecurity( NULL, -1, // COM authentication NULL, // Authentication services NULL, // Reserved RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication info EOAC_NONE, // Additional capabilities NULL // Reserved ); if (FAILED(hres)) { printf("Failed to initialize security. Error code = 0x%x\n",hres); CoUninitialize(); return FALSE; // Program has failed. } // Step 3: --------------------------------------------------- // Obtain the initial locator to WMI ------------------------- IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (FAILED(hres)) { printf("Failed to create IWbemLocator object.Err code = 0x%x\n", hres); CoUninitialize(); return FALSE; // Program has failed. } // Step 4: ----------------------------------------------------- // Connect to WMI through the IWbemLocator::ConnectServer method IWbemServices *pSvc = NULL; // Connect to the root\cimv2 namespace with // the current user and obtain pointer pSvc // to make IWbemServices calls. hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\WMI"), // Object path of WMI namespace NULL, // User name. NULL = current user NULL, // User password. NULL = current 0, // Locale. NULL indicates current NULL, // Security flags. 0, // Authority (for example, Kerberos) 0, // Context object &pSvc // pointer to IWbemServices proxy ); if (FAILED(hres)) { printf("Could not connect. Error code = 0x%x\n",hres); pLoc->Release(); CoUninitialize(); return FALSE; // Program has failed. } // Step 5: -------------------------------------------------- // Set security levels on the proxy ------------------------- hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { printf("Could not set proxy blanket. Error code = 0x%x\n",hres); pSvc->Release(); pLoc->Release(); CoUninitialize(); return FALSE; // Program has failed. } CComPtr pClassObj = NULL; CComPtr pInClass = NULL; CComPtr pInParam = NULL; CComPtr pInParamA = NULL; CComPtr ppiWmiOutSetPackage = NULL; CComPtr ppiWmiOutGetPackage = NULL; CComPtr PackageObj = NULL; //====================================================== // SetPackage "Package" type input parameter preparation //====================================================== //Step0: 初始化 VARIANT; VARIANT arrVarInArg; VariantInit(&arrVarInArg); CComVariant varData; //Step1: 定义变量 int uIsRead = 16; BYTE bVal[] = {0x50,0x51,0x52,0x53,0x54,0x35,0x36,0x37,0x38,0x39,0x40,0x41,0x42,0x43,0x44,0x45}; //Step2: 创建SafeArray描述符 SAFEARRAY *psa; SAFEARRAYBOUND rgsabound[1] = {0};//16 rgsabound[0].cElements =uIsRead; rgsabound[0].lLbound = 0; VARTYPE vt = VT_UI1; psa = SafeArrayCreate(vt,1,rgsabound); //Step3: 放置数据元素到SafeArray //@)(@: The below code can also works. //for(long index=0;index < uIsRead; index++){ // SafeArrayPutElement(psa, &index, &bVal[index]); //} BYTE *pDataArray = NULL; SafeArrayAccessData(psa,(void**)&pDataArray); ZeroMemory(pDataArray, 16); CopyMemory(pDataArray, bVal,16); SafeArrayUnaccessData(psa); //Step4: 封装到VARIANT内: //@)(@: The below code can also works. //arrVarInArg.vt = vt|VT_ARRAY; //arrVarInArg.parray = psa; V_VT(&arrVarInArg) = vt | VT_ARRAY; V_ARRAY(&arrVarInArg) = psa; //@)(@: The below code just for SafeArray data verification #if 0 { LONG lUBound = 0; LONG lLBound = 0; LONG cElements = 0; SafeArrayGetLBound(arrVarInArg.parray, 1, &lLBound); SafeArrayGetUBound(arrVarInArg.parray, 1, &lUBound); cElements = lUBound - lLBound + 1; printf("lUBound = %d\n", lUBound); printf("lLBound = %d\n", lLBound); printf("cElements = %d\n", cElements); VARTYPE InputVtType; SafeArrayGetVartype(arrVarInArg.parray, &InputVtType); printf("InputVtType type = %d\n", InputVtType); UINT8 buf[16]; UINT8 ValueOut = 0; for(long ind=0; ind < cElements; ind++) { SafeArrayGetElement(arrVarInArg.parray, &ind, buf + ind); } printf("SafeArray Data : \n"); for (long i = 0;i< 16;i++) { ValueOut = buf[i]; printf("%x ",ValueOut); } printf("\n"); } #endif //@)(@: Exectute SetDataUlongAndPackage Method //Step1: Get Lfc_Tools_Wmi_Service object hres = pSvc->GetObject(L"Lfc_Tools_Wmi_Service", 0, NULL, &pClassObj, NULL); if (FAILED(hres)) { printf("Failed to get Lfc_Tools_Wmi_Service object: %x\n", hres); goto ErrorExit; } //Step2: Get SetDataUlongAndPackage method from Lfc_Tools_Wmi_Service hres = pClassObj->GetMethod(L"SetDataUlongAndPackage", 0, &pInClass, NULL); if (WBEM_S_NO_ERROR == hres) { printf("WMI:Get SetDataUlongAndPackage method successfully\n"); if (pInClass != NULL) { //create instance copy if(WBEM_S_NO_ERROR == (hres=pInClass->SpawnInstance(0, &pInParam)) ) { //Step3: Get GetDataUlongAndPackage method out parameter IUnknown instance hres = pClassObj->GetMethod(L"GetDataUlongAndPackage", 0, &pInClass, NULL); if (WBEM_S_NO_ERROR == hres) { printf("WMI:Get GetDataUlongAndPackage method successfully\n"); if(pInClass != NULL) { #if 0 { //TODO: Check if have input paramter, if yes, need put parameter here // create instance copy if(WBEM_S_NO_ERROR == (hres=pInClass->SpawnInstance(0, &pInParamA)) ) { // set each property hres = pInParamA->Put("parameter", 0, &SafeArrayData, 0); if (WBEM_S_NO_ERROR != hres) { DBG_PRINTF_FL((L"WMI:ExecMethodWMI put var failed! error=0x%x\n", hres)); // Put failed, check the properties and their types } } else { DBG_PRINTF_FL((L"WMI:ExecMethodWMI SpawnInstance failed! error=0x%x\n", hres)); } } #endif } //@)(@: Run GetDataUlongAndPackage method to get the VT_UNKNOWN type instance, this is the key point hres = pSvc->ExecMethod(L"Lfc_Tools_Wmi_Service.InstanceName='ACPI\\PNP0C14\\WM00_0'",L"GetDataUlongAndPackage",0, NULL, NULL, &ppiWmiOutGetPackage, NULL); if (WBEM_S_NO_ERROR == hres) { printf("WMI:ExecMethodWMI GetDataUlongAndPackage Success! error=0x%x\n", hres); } hres = ppiWmiOutGetPackage->Get(L"return", 0, &varData, NULL,0); if (WBEM_S_NO_ERROR != hres) { printf("WMI:ExecMethodWMI GetDataUlongAndPackage get out parameter [return] failed! error=0x%x\n", hres); goto ErrorExit; } //@)(@: GetDataUlongAndPackage out parameter should be a VT_UNKNOWN type if (varData.vt != VT_UNKNOWN) { goto ErrorExit; } //@)(@: Modify varData package member "Bytes" for SetDataUlongAndPackage in parameter IUnknown *Package = NULL; Package = (IUnknown*)varData.punkVal; hres = Package->QueryInterface(IID_IWbemClassObject, reinterpret_cast(&PackageObj)); if (FAILED(hres)) { goto ErrorExit; } //@)(@: Put the prepared SetDataUlongAndPackage input parameter "UINT8 array data: arrVarInArg" to // "Bytes" of varData' package part hres = PackageObj->Put(L"Bytes", 0, &arrVarInArg, CIM_UINT8 | CIM_FLAG_ARRAY); if (FAILED(hres)) { goto ErrorExit; } //Step4: Put parameter to SetDataUlongAndPackage input parameter //@)(@: Put the prepared IUnknow varData to SetDataUlongAndPackage input parameter "parameter" hres = pInParam->Put(L"parameter", 0, &varData, 0); if (WBEM_S_NO_ERROR != hres) { printf("WMI:ExecMethodWMI SetDataUlongAndPackage put input parameter failed! error=0x%x\n", hres); goto ErrorExit; // Put failed, check the properties and their types // WBEM_E_TYPE_MISMATCH } } else { printf("WMI:Get GetDataUlongAndPackage method failed error=0x%x\n", hres); goto ErrorExit; } } //Step5: Everything is ok, now execute the "SetPackage" method hres = pSvc->ExecMethod(L"Lfc_Tools_Wmi_Service.InstanceName='ACPI\\PNP0C14\\WM00_0'",L"SetDataUlongAndPackage",0, NULL, pInParam, &ppiWmiOutSetPackage, NULL); if (WBEM_S_NO_ERROR != hres) { printf("WMI:ExecMethodWMI SetDataUlongAndPackage Fail! error=0x%x\n", hres); goto ErrorExit; } } } // Cleanup // ======== ErrorExit: VariantClear(&arrVarInArg); if (pClassObj) { pClassObj.Release(); pClassObj = NULL; } if (pInClass) { pInClass.Release(); pInClass = NULL; } if (pInParam) { pInParam.Release(); pInParam = NULL; } if (pInParamA) { pInParamA.Release(); pInParamA = NULL; } if (ppiWmiOutSetPackage) { ppiWmiOutSetPackage.Release(); ppiWmiOutSetPackage = NULL; } if (ppiWmiOutGetPackage) { ppiWmiOutGetPackage.Release(); ppiWmiOutGetPackage = NULL; } if (PackageObj) { PackageObj.Release(); PackageObj = NULL; } pSvc->Release(); pLoc->Release(); return FALSE; }