373 lines
12 KiB
C++
373 lines
12 KiB
C++
//*****************************************************************************
|
||
// 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 <iostream>
|
||
using namespace std;
|
||
#include <comdef.h>
|
||
#include <Wbemidl.h>
|
||
#include <stdlib.h> // for wcstombs
|
||
#include <wctype.h> // for towlower
|
||
#include <wchar.h> // 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<IWbemClassObject> pClassObj = NULL;
|
||
CComPtr<IWbemClassObject> pInClass = NULL;
|
||
CComPtr<IWbemClassObject> pInParam = NULL;
|
||
CComPtr<IWbemClassObject> pInParamA = NULL;
|
||
CComPtr<IWbemClassObject> ppiWmiOutSetPackage = NULL;
|
||
CComPtr<IWbemClassObject> ppiWmiOutGetPackage = NULL;
|
||
CComPtr<IWbemClassObject> PackageObj = NULL;
|
||
|
||
//======================================================
|
||
// SetPackage "Package" type input parameter preparation
|
||
//======================================================
|
||
//Step0: <20><>ʼ<EFBFBD><CABC> VARIANT;
|
||
VARIANT arrVarInArg;
|
||
VariantInit(&arrVarInArg);
|
||
CComVariant varData;
|
||
|
||
//Step1: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int uIsRead = 16;
|
||
BYTE bVal[] = {0x50,0x51,0x52,0x53,0x54,0x35,0x36,0x37,0x38,0x39,0x40,0x41,0x42,0x43,0x44,0x45};
|
||
|
||
//Step2: <20><><EFBFBD><EFBFBD>SafeArray<61><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
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: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>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: <20><>װ<EFBFBD><D7B0>VARIANT<4E>ڣ<EFBFBD>
|
||
//@)(@: 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<void**>(&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;
|
||
}
|
||
|