Good afternoon, I am writing a program that will extract pixels from the desktop, but unfortunately I ran into a problem, Map gives an error "Access Violation". Help me please.
I've divided all the code by function to make it clear to you.
I hope you can help me because I have little experience with directx and dxgi so far.
ID3D11Device *m_pDevice;
ID3D11DeviceContext *m_pDeviceContext;
IDXGIDevice *m_pDXGIDevice;
ID3D11Texture2D* m_pDesktopTexture;
ID3D11Texture2D* m_pCompatibleTexture;
//ID3D11Device* m_pDevice;
IDXGIAdapter* m_pDXGIAdapter;
IDXGIOutput* m_pDXGIOutput;
IDXGIOutput1* m_pDXGIOutput1;
IDXGIOutputDuplication* m_pOutputDuplication = nullptr;
DXGI_OUTDUPL_DESC m_OutputDuplicationDescription;
DXGI_OUTPUT_DESC m_OutputDescription;
D3D11_MAPPED_SUBRESOURCE m_mappedResource;
HRESULT CreateD3DDevice()
{
HRESULT hResult = S_OK;
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_9_1;
hResult = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr,
0, &featureLevel, (UINT)(1), D3D11_SDK_VERSION, &m_pDevice, 0, &m_pDeviceContext);
return hResult;
}
HRESULT CreateDXGIDevice()
{
return m_pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&m_pDXGIDevice));;
}
HRESULT CreateCompatibleTexture()
{
D3D11_TEXTURE2D_DESC textureDescription;
textureDescription.Width = m_OutputDuplicationDescription.ModeDesc.Width;
textureDescription.Height = m_OutputDuplicationDescription.ModeDesc.Height;
textureDescription.Format = m_OutputDuplicationDescription.ModeDesc.Format;
textureDescription.ArraySize = 1;
textureDescription.BindFlags = 0;
textureDescription.MiscFlags = 0;
textureDescription.SampleDesc.Count = 1;
textureDescription.SampleDesc.Quality = 0;
textureDescription.MipLevels = 1;
textureDescription.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
textureDescription.Usage = D3D11_USAGE_STAGING;
return m_pDevice->CreateTexture2D(&textureDescription, 0, &m_pCompatibleTexture);
}
HRESULT CreateDXGIOutput()
{
return m_pDXGIAdapter->EnumOutputs((UINT)(0), &m_pDXGIOutput);
}
HRESULT DuplicateOutput()
{
return m_pDXGIOutput1->DuplicateOutput(m_pDevice, &m_pOutputDuplication);
}
HRESULT CreateDXGIAdapter()
{
return m_pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_pDXGIAdapter));
}
HRESULT CreateDXGIOutput1()
{
return m_pDXGIOutput->QueryInterface(__uuidof(m_pDXGIOutput1), reinterpret_cast<void**>(&m_pDXGIOutput1));
}
HRESULT GetOutputDescription()
{
return m_pDXGIOutput->GetDesc(&m_OutputDescription);
}
HRESULT CaptureScreen()
{
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
IDXGIResource* DesktopResource = nullptr;
HRESULT hResult = m_pOutputDuplication->AcquireNextFrame(9999, &FrameInfo, &DesktopResource);
if (FAILED(hResult))
{
return hResult;
}
hResult = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&m_pDesktopTexture));
DesktopResource->Release();
DesktopResource = nullptr;
if (FAILED(hResult))
{
return hResult;
}
m_pDeviceContext->CopyResource(m_pCompatibleTexture, m_pDesktopTexture);
m_pDeviceContext->Map(m_pCompatibleTexture, D3D11CalcSubresource(0, 0, 0), D3D11_MAP_READ_WRITE, 0, &m_mappedResource);
BYTE* sptr = reinterpret_cast<BYTE*>(m_mappedResource.pData);
m_pDeviceContext->Unmap(m_pCompatibleTexture, 0);
m_pOutputDuplication->ReleaseFrame();
return hResult;
}
int main()
{
HRESULT hr;
hr = CreateD3DDevice();
std::cout << hr << std::endl;
hr = CreateDXGIDevice();
std::cout << hr << std::endl;
hr = CreateDXGIAdapter();
std::cout << hr << std::endl;
hr = CreateDXGIOutput();
std::cout << hr << std::endl;
hr = GetOutputDescription();
std::cout << hr << std::endl;
hr = CreateDXGIOutput1();
std::cout << hr << std::endl;
hr = DuplicateOutput();
std::cout << hr << std::endl;
m_pOutputDuplication->GetDesc(&m_OutputDuplicationDescription);
hr = CaptureScreen();
std::cout << hr << std::endl;
}
I'm using Window's Core Audio API (https://learn.microsoft.com/en-us/windows/desktop/CoreAudio/core-audio-apis-in-windows-vista) for controlling audio settings for my audio processing/analysis application. Below is my modified version of WalkTreeBackwardsFromPart. I can control the sidetone setting from the API, but I don't know what it actually does. If it does what I think it does, it could be useful to me. It does not seem to do the exact same thing as "listen to this device" setting. See line 204 for where I turn off the setting. Thanks.
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <mmdeviceapi.h>
#include <devicetopology.h>
#include <vector>
using namespace std;
struct AudioNode
{
LPWSTR name;
AudioNode *parent;
vector<AudioNode *>children;
};
AudioNode *newAudioNode(LPWSTR name) {
AudioNode *temp = new AudioNode;
temp->name = name;
temp->parent = NULL;
return temp;
}
AudioNode *audioTreeHead;
//AudioNode *audioTreeCurrNode;
HRESULT WalkTreeBackwardsFromPart(IPart *pPart, EDataFlow deviceType, AudioNode *audioTreeCurrNode, int iTabLevel = 0);
//HRESULT DisplayVolume(IAudioVolumeLevel *pVolume, int iTabLevel);
HRESULT DisplayMute(IAudioMute *pMute, int iTabLevel);
int SetDeviceVolume(EDataFlow deviceType, float vol);
void Tab(int iTabLevel);
int __cdecl main(void) {
//float volumes[] = {0, 5, 10, 15}
printf("capture\n");
int result = SetDeviceVolume(eCapture, -20);
printf("render\n");
result = SetDeviceVolume(eRender, -20);
system("pause");
return 0;
}
//HRESULT DisplayVolume(IAudioVolumeLevel *pVolume, int iTabLevel) {
//
//}
int SetDeviceVolume(EDataFlow deviceType, float vol) {
audioTreeHead = newAudioNode(L"");
AudioNode *audioTreeCurrNode = audioTreeHead;
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
printf("Failed CoInitializeEx: hr = 0x%08x\n", hr);
return __LINE__;
}
// get default render endpoint
IMMDeviceEnumerator *pEnum = NULL;
hr = CoCreateInstance(
__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
(void**)&pEnum
);
if (FAILED(hr)) {
printf("Couldn't get device enumerator: hr = 0x%08x\n", hr);
CoUninitialize();
return __LINE__;
}
IMMDevice *pDevice = NULL;
hr = pEnum->GetDefaultAudioEndpoint(deviceType, eConsole, &pDevice);
if (FAILED(hr)) {
printf("Couldn't get default capture device: hr = 0x%08x\n", hr);
pEnum->Release();
CoUninitialize();
return __LINE__;
}
pEnum->Release();
// get device topology object for that endpoint
IDeviceTopology *pDT = NULL;
hr = pDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&pDT);
if (FAILED(hr)) {
printf("Couldn't get device topology object: hr = 0x%08x\n", hr);
pDevice->Release();
CoUninitialize();
return __LINE__;
}
pDevice->Release();
// get the single connector for that endpoint
IConnector *pConnEndpoint = NULL;
hr = pDT->GetConnector(0, &pConnEndpoint);
if (FAILED(hr)) {
printf("Couldn't get the connector on the endpoint: hr = 0x%08x\n", hr);
pDT->Release();
CoUninitialize();
return __LINE__;
}
pDT->Release();
// get the connector on the device that is
// connected to
// the connector on the endpoint
IConnector *pConnDevice = NULL;
hr = pConnEndpoint->GetConnectedTo(&pConnDevice);
if (FAILED(hr)) {
printf("Couldn't get the connector on the device: hr = 0x%08x\n", hr);
pConnEndpoint->Release();
CoUninitialize();
return __LINE__;
}
pConnEndpoint->Release();
// QI on the device's connector for IPart
IPart *pPart = NULL;
hr = pConnDevice->QueryInterface(__uuidof(IPart), (void**)&pPart);
if (FAILED(hr)) {
printf("Couldn't get the part: hr = 0x%08x\n", hr);
pConnDevice->Release();
CoUninitialize();
return __LINE__;
}
pConnDevice->Release();
// all the real work is done in this function
hr = WalkTreeBackwardsFromPart(pPart, deviceType, audioTreeCurrNode);
if (FAILED(hr)) {
printf("Couldn't walk the tree: hr = 0x%08x\n", hr);
pPart->Release();
CoUninitialize();
return __LINE__;
}
pPart->Release();
CoUninitialize();
return 0;
}
HRESULT WalkTreeBackwardsFromPart(IPart *pPart, EDataFlow deviceType, AudioNode *audioTreeCurrNode, int iTabLevel /* = 0 */) {
HRESULT hr = S_OK;
LPWSTR pwszPartName = NULL;
hr = pPart->GetName(&pwszPartName);
if (FAILED(hr)) {
Tab(iTabLevel);
printf("Could not get part name: hr = 0x%08x\n", hr);
return hr;
}
Tab(iTabLevel);
printf("Part name: %ws\n", *pwszPartName ? pwszPartName : L"(Unnamed)");
AudioNode * tempNode = newAudioNode(pwszPartName);
//CoTaskMemFree(pwszPartName);
tempNode->parent = audioTreeCurrNode;
audioTreeCurrNode->children.push_back(tempNode);
audioTreeCurrNode = tempNode;
audioTreeCurrNode->name = pwszPartName;
if (audioTreeCurrNode->parent != NULL) {
Tab(iTabLevel);
printf("my parent: %ws\n", audioTreeCurrNode->parent->name);
if (audioTreeCurrNode->parent->parent != NULL) {
Tab(iTabLevel);
printf("my parent of parent: %ws\n", audioTreeCurrNode->parent->parent->name);
}
}
else {
Tab(iTabLevel);
printf("parent is NULL!\n");
}
if (wcscmp(audioTreeCurrNode->name, L"Mute") == 0 &&
audioTreeCurrNode->parent != NULL && audioTreeCurrNode->parent->parent != NULL &&
wcscmp(audioTreeCurrNode->parent->name, L"Volume") == 0 &&
wcscmp(audioTreeCurrNode->parent->parent->name, L"SuperMix") == 0) {
Tab(iTabLevel);
printf("found the mute I want!\n");
Tab(iTabLevel);
printf("parent: %ws\n", audioTreeCurrNode->parent->name);
Tab(iTabLevel);
printf("parent of parent: %ws\n", audioTreeCurrNode->parent->parent->name);
Tab(iTabLevel);
printf("muting passthrough...\n");
const IID IID_IAudioMute = __uuidof(IAudioMute);
IAudioMute *muteControl = NULL;
hr = pPart->Activate(CLSCTX_ALL, IID_IAudioMute, (void**)&muteControl);
if (E_NOINTERFACE == hr) {
Tab(iTabLevel);
printf("NO MUTE CONTROL\n");
}
else if (FAILED(hr)) {
Tab(iTabLevel);
printf("Unexpected failure trying to activate IAudioMute : hr = 0x%08x\n", hr);
return hr;
}
else {
Tab(iTabLevel);
printf("HAS MUTE CONTROL\n");
//LPCGUID pguidEventContext;
BOOL muted;
muteControl->SetMute(TRUE, NULL);
muteControl->GetMute(&muted);
Tab(iTabLevel);
printf("%s\n", muted ? "MUTED" : "NOT MUTED");
}
}
// Check AGC settings
const IID IID_IAudioAutoGainControl = __uuidof(IAudioAutoGainControl);
IAudioAutoGainControl *aGCcontrol = NULL;
hr = pPart->Activate(CLSCTX_ALL, IID_IAudioAutoGainControl, (void**)&aGCcontrol);
if (E_NOINTERFACE == hr) {
Tab(iTabLevel);
printf("NO AGC CONTROL\n");
// not a Microphone node
}
else if (FAILED(hr)) {
Tab(iTabLevel);
printf("Unexpected failure trying to activate IAudioAutoGainControl : hr = 0x%08x\n", hr);
return hr;
}
else {
// it's an AGC node...
Tab(iTabLevel);
printf("HAS AGC CONTROL\n");
aGCcontrol->SetEnabled(0, NULL); //Disable it
if (FAILED(hr)) {
Tab(iTabLevel);
printf("AGC Failed: hr = 0x%08x", hr);
aGCcontrol->Release();
return hr;
}
aGCcontrol->Release();
}
// Check Volume Settings
const IID IID_IAudioVolumeLevel = __uuidof(IAudioVolumeLevel);
IAudioVolumeLevel *volControl = NULL;
hr = pPart->Activate(CLSCTX_ALL, IID_IAudioVolumeLevel, (void**)&volControl);
if (E_NOINTERFACE == hr) {
Tab(iTabLevel);
printf("NO VOLUME CONTROL\n");
// not a volume control
}
else if (FAILED(hr)) {
Tab(iTabLevel);
printf("Unexpected failure trying to activate IAudioVolumeLevel : hr = 0x%08x\n", hr);
return hr;
}
else {
// it's a volume control node
Tab(iTabLevel);
printf("HAS VOLUME CONTROL\n");
UINT numChannels;
float pfLevelDB;
float minLevel;
float maxLevel;
float stepLevel;
volControl->GetChannelCount(&numChannels);
for (int i = 0; i < numChannels; i++) {
volControl->GetLevel(i + 1, &pfLevelDB);
volControl->GetLevelRange(i, &minLevel, &maxLevel, &stepLevel);
Tab(iTabLevel);
printf("Volume Level on %d: %f\n", i, pfLevelDB);
Tab(iTabLevel);
printf("Volume range: %f to %f steps of %f\n", minLevel, maxLevel, stepLevel);
}
}
// get the list of incoming parts
IPartsList *pOutgoingParts = NULL;
if (deviceType == eCapture) {
hr = pPart->EnumPartsOutgoing(&pOutgoingParts);
}
else {
hr = pPart->EnumPartsIncoming(&pOutgoingParts);
}
if (E_NOTFOUND == hr) {
return hr;
// not an error... we've just reached the end of the path
//MessageBox("No incoming parts at this part\n", MB_OK);
}
if (FAILED(hr)) {
return hr;
//MessageBox("Couldn't enum outgoing parts", MB_OK);
}
UINT nParts = 0;
hr = pOutgoingParts->GetCount(&nParts);
if (FAILED(hr)) {
//MessageBox("Couldn't get count of outgoing parts", MB_OK);
pOutgoingParts->Release();
return hr;
}
// walk the tree on each incoming part recursively
for (UINT n = 0; n < nParts; n++) {
IPart *pOutgoingPart = NULL;
hr = pOutgoingParts->GetPart(n, &pOutgoingPart);
if (FAILED(hr)) {
//MessageBox("Couldn't get part ", MB_OK);
pOutgoingParts->Release();
return hr;
}
hr = WalkTreeBackwardsFromPart(pOutgoingPart, deviceType, audioTreeCurrNode, iTabLevel + 1);
if (FAILED(hr)) {
//MessageBox("Couldn't walk tree on part", MB_OK);
pOutgoingPart->Release();
pOutgoingParts->Release();
return hr;
}
pOutgoingPart->Release();
}
pOutgoingParts->Release();
return S_OK;
}
void Tab(int iTabLevel) {
if (0 >= iTabLevel) { return; }
printf("\t");
Tab(iTabLevel - 1);
}
Here is my original post: (What Is This Sidetone Setting on My Playback Device?)
It was flagged for not being on topic because it's not programming related.
In an application I've been using the piece of code below to automatically set the 'Default Format' of the microphone to '2 channel, 16 bit, 48000Hz'.
This code works in Windows 7 an 8 en until recently also in Windows 10. Since some update of Windows 10 this year the code doesn't work anymore as expected. When I manually set the format to another value, like 44.1KHz in Sound - Mic - Advanced and I run the code, then the format is changed to '2 channel, 16 bit, 48000Hz', but I get no sound from the microphone. When I set the format manually to the correct value, then there are no problems.
Here is the piece of code:
IMMDevice* pEndpointRead = NULL;
IMMDevice* pEndpointWrite = NULL;
IMMDeviceEnumerator* pEnumerator = NULL;
IPropertyStore* propertyStoreRead = NULL;
IPropertyStore* propertyStoreWrite = NULL;
IAudioClient *audioClient = NULL;
PROPVARIANT propRead;
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pEnumerator);
hr = pEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &pEndpointRead);
hr = pEndpointRead->OpenPropertyStore(STGM_READ, &propertyStoreRead);
if (FAILED(hr))
{
std::cout << "OpenPropertyStore failed!" << std::endl;
}
hr = propertyStoreRead->GetValue(PKEY_AudioEngine_DeviceFormat, &propRead);
if (FAILED(hr))
{
std::cout << "GetValue failed!" << std::endl;
}
deviceFormatProperties =(WAVEFORMATEXTENSIBLE *)propRead.blob.pBlobData;
deviceFormatProperties->Format.nChannels = 2;
deviceFormatProperties->Format.nSamplesPerSec = 48000;
deviceFormatProperties->Format.wBitsPerSample = 16;
deviceFormatProperties->Samples.wValidBitsPerSample = deviceFormatProperties->Format.wBitsPerSample;
deviceFormatProperties->Format.nBlockAlign = (deviceFormatProperties->Format.nChannels*deviceFormatProperties->Format.wBitsPerSample) / 8;
deviceFormatProperties->Format.nAvgBytesPerSec = deviceFormatProperties->Format.nSamplesPerSec*deviceFormatProperties->Format.nBlockAlign;
deviceFormatProperties->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
deviceFormatProperties->Format.cbSize = 22;
deviceFormatProperties->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
hr = pEndpointRead->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&audioClient);
if (FAILED(hr))
{
std::cout << "pDevice->Activate failed!" << std::endl;
}
hr = audioClient->IsFormatSupported(/*AUDCLNT_SHAREMODE_SHARED*/AUDCLNT_SHAREMODE_EXCLUSIVE, (PWAVEFORMATEX)&deviceFormatProperties->Format, NULL);
if (FAILED(hr))
{
std::cout << "IsFormatSupported failed" << std::endl;
}
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pEnumerator);
hr = pEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &pEndpointWrite);
hr= pEndpointWrite->OpenPropertyStore(STGM_WRITE, &propertyStoreWrite);
if (FAILED(hr))
{
std::cout << "OpenPropertyStore failed!" << std::endl;
}
hr = propertyStoreWrite->SetValue(PKEY_AudioEngine_DeviceFormat, propRead);
if (FAILED(hr))
{
std::cout << "SetValue failed!" << std::endl;
}
hr = propertyStoreWrite->Commit();
pEndpointWrite->Release();
pEnumerator->Release();
propertyStoreWrite->Release();
pEndpointRead->Release();
propertyStoreRead->Release();
pEndpointRead = NULL;
PropVariantClear(&propRead);
Any idea what could be the problem?
I have read most questions like this .But there are still some problems when try get the value of cpu usage in WMI using c++.
I have tried two ways to solve this problem:
query the value of PercentProcessorTime in Win32_PerfFormattedData_PerfOS_Processor.But the value is much bigger than I want . It can reach 10802692. some pieces of my codeļ¼
hres = m_pWbemSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor where Name='_Total' "),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&m_pEnumClsObj
);
hres = m_pWbemClsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
wcout << "CPU Usage : " << vtProp.ullVal << endl;
VariantClear(&vtProp);
get the some data form Win32_PerfRawData_PerfOS_Processor,then using the formula.However,when I try this method , I always get same value about PercentProcessorTime and TimeStamp_Sys100NS.That is to say N1=N2 and D1=D2.I think there must be some wrong in my code
Formula - (1- ((N2 - N1) / (D2 - D1))) x 100
unsigned __int64 N1;
unsigned __int64 D1;
unsigned __int64 N2;
unsigned __int64 D2;
bool result = false;
if (getCPUData(&N1, &D1))
{
Sleep(1000);
if (getCPUData(&N2, &D2))
{
result = true;
}
}
//(1 - ((N2 - N1) / (D2 - D1))) * 100;
bool WMI_Util::getCPUData(unsigned __int64 *N, unsigned __int64 *D)
{
HRESULT hres;
ULONG uReturn = 0;
VARIANT vtProp;
m_pEnumClsObj = NULL;
bool result = false;
hres = m_pWbemSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_PerfRawData_PerfOS_Processor where Name='_Total' "),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&m_pEnumClsObj
);
if (FAILED(hres))
{
wcout << L"Query for operating system name failed."
<< L" Error code = 0x"
<< hex << hres << endl;
m_pWbemSvc->Release();
m_pWbemLoc->Release();
CoUninitialize();
}
else{
m_pWbemClsObj = NULL;
while (m_pEnumClsObj)
{
hres = m_pEnumClsObj->Next(WBEM_INFINITE, 1, &m_pWbemClsObj, &uReturn);
if (0 == uReturn)
break;
hres = m_pWbemClsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
*N = vtProp.ullVal;
VariantClear(&vtProp);
hres = m_pWbemClsObj->Get(L"TimeStamp_Sys100NS", 0, &vtProp, 0, 0);
*D = vtProp.ullVal;
VariantClear(&vtProp);
m_pWbemClsObj->Release();
}
result = true;
}
return result;
ReleaseWMI();
}
As for initialization of WMI, I followed the step1-5 in MSDN. Do I need to get the value of them in two different WMI connection? In current situation , I just query the class in two different time .Is this reason why I always get the same value?
My advice is to use 'vtProp.bstrVal' instead of 'vtProp.ullVal'.
I implemented very similar function and as you said got constant values in numeric fields but I got correct value in string field.
Here is my method (without debug printings):
HRESULT WMI_sdk_services::GetCpuUsage(int &cpuUsage)
{
bool shouldUninitializeComAfterWmiRequest; //out parameter
HRESULT hres = PrepareEnumWbemClassObject(true, shouldUninitializeComAfterWmiRequest, L"SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor where Name='_Total'");
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(SUCCEEDED(hres)){
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
VARIANT vtProp;
// Get the value of the 'PercentProcessorTime' property
hr = pclsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
if (WBEM_S_NO_ERROR != hr) {
if(pclsObj){
VariantClear(&vtProp);
pclsObj->Release(); pclsObj = NULL;
}
break;
}
cpuUsage = std::stoi(vtProp.bstrVal);
VariantClear(&vtProp);
pclsObj->Release(); pclsObj = NULL;
}
}
return hres;
}
Another remark: You get here total CPU usage not your process CPU usage.
i'm writting a C++ WMI utility class which wraps the WMI stuff to help my further WMI query. i encountered a problem when accessing a Win32_SecurityDescriptor instance.
i used the WQL query "Select * from Win32_LogicalShareSecuritySetting" to get all the Win32_LogicalShareSecuritySetting instances. then called the GetSecurityDescriptor method of Win32_LogicalShareSecuritySetting instance to get a Win32_SecurityDescriptor instance. But when i attempted to retrieve some property like "__PATH" from the Win32_SecurityDescriptor instance, i got a 0xC0000005 Access Violation messagebox.
i wrote my code in C++, but i think the problem should be common.
I also used the wbemtest tool by Microsoft for test but didn't find a way to display a Win32_SecurityDescriptor instance. Why is Win32_SecurityDescriptor so special?
here's all my code, you can try it in your VC, mine is 6. Windows SDK maybe needed.
Access Violation found in the caller code:
CString strSDInstancePath = wmiSearcher->getStringFromObject(pSDInstance, "__PATH");
ADWMISearch.cpp
#include "StdAfx.h"
#include "ADWMISearch.h"
#include <comdef.h>
# pragma comment(lib, "wbemuuid.lib")
# pragma comment(lib, "credui.lib")
# pragma comment(lib, "comsupp.lib")
#include <wincred.h>
#include <strsafe.h>
#include <iostream>
using namespace std;
DWORD ADWMISearch::WIN32_FROM_HRESULT_alternate(HRESULT hr)
{
DWORD dwResult;
if (hr < 0)
{
dwResult = (DWORD) hr;
return dwResult;
}
else
{
MyMessageBox_Error(_T("WIN32_FROM_HRESULT_alternate Error."), _T("Error"));
return -1;
}
}
IWbemServices* ADWMISearch::connect(CString strServerName, CString strServerIP, CString strDomainName, CString strUsername,
CString strPassword)
{
CString strComputerName = strServerName;
CString strFullUsername; //_T("adtest\\Administrator")
if (strDomainName == _T(""))
{
strUsername = _T("");
strFullUsername = _T("");
strPassword = _T("");
}
else
{
strFullUsername = strDomainName + _T("\\") + strUsername;
}
HRESULT hres;
// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
//cout << "Failed to initialize COM library. Error code = 0x"
// << hex << hres << endl;
MyMessageBox_Error(_T("connect"));
return NULL; // 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_IDENTIFY, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
//char aaa[100];
//sprintf(aaa, "%x", hres);
if (FAILED(hres) && hres != RPC_E_TOO_LATE)
{
//cout << "Failed to initialize security. Error code = 0x"
// << hex << hres << endl;
CoUninitialize();
MyMessageBox_Error(_T("connect"));
return NULL; // 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))
{
CoUninitialize();
MyMessageBox_Error(_T("connect"));
return NULL; // Program has failed.
}
// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
bool useToken = TRUE;
bool useNTLM = FALSE;
// Get the user name and password for the remote computer
/*
CREDUI_INFO cui;
bool useToken = TRUE;
bool useNTLM = FALSE;
TCHAR pszName[CREDUI_MAX_USERNAME_LENGTH+1] = {0};
TCHAR pszPwd[CREDUI_MAX_PASSWORD_LENGTH+1] = {0};
TCHAR pszDomain[CREDUI_MAX_USERNAME_LENGTH+1];
TCHAR pszUserName[CREDUI_MAX_USERNAME_LENGTH+1];
TCHAR pszAuthority[CREDUI_MAX_USERNAME_LENGTH+1];
BOOL fSave;
DWORD dwErr;
memset(&cui,0,sizeof(CREDUI_INFO));
cui.cbSize = sizeof(CREDUI_INFO);
cui.hwndParent = NULL;
// Ensure that MessageText and CaptionText identify
// what credentials to use and which application requires them.
cui.pszMessageText = _T("Press cancel to use process token");
cui.pszCaptionText = _T("Enter Account Information");
cui.hbmBanner = NULL;
fSave = FALSE;
dwErr = CredUIPromptForCredentials(
&cui, // CREDUI_INFO structure
_T(""), // Target for credentials
NULL, // Reserved
0, // Reason
pszName, // User name
CREDUI_MAX_USERNAME_LENGTH+1, // Max number for user name
pszPwd, // Password
CREDUI_MAX_PASSWORD_LENGTH+1, // Max number for password
&fSave, // State of save check box
CREDUI_FLAGS_GENERIC_CREDENTIALS |// flags
CREDUI_FLAGS_ALWAYS_SHOW_UI |
CREDUI_FLAGS_DO_NOT_PERSIST);
if(dwErr == ERROR_CANCELLED)
{
useToken = true;
}
else if (dwErr)
{
cout << "Did not get credentials " << dwErr << endl;
pLoc->Release();
CoUninitialize();
return 1;
}
*/
// change the computerName strings below to the full computer name
// of the remote computer
CString strAuthority;
if(!useNTLM)
{
//StringCchPrintf(pszAuthority, CREDUI_MAX_USERNAME_LENGTH+1, _T("kERBEROS:%s"), strComputerName);
strAuthority = _T("kERBEROS:") + strComputerName;
}
// Connect to the remote root\cimv2 namespace
// and obtain pointer pSvc to make IWbemServices calls.
//---------------------------------------------------------
CString strNetworkResource = _T("\\\\") + strComputerName + _T("\\root\\cimv2");
if (strFullUsername == _T(""))
{
hres = pLoc->ConnectServer(
_bstr_t(strNetworkResource),
NULL, // User name
NULL, // User password
NULL, // Locale
WBEM_FLAG_CONNECT_USE_MAX_WAIT, // Security flags
_bstr_t(strAuthority), // Authority
NULL, // Context object
&pSvc // IWbemServices proxy
);
}
else
{
hres = pLoc->ConnectServer(
_bstr_t(strNetworkResource),
_bstr_t(strFullUsername), // User name
_bstr_t(strPassword), // User password
NULL, // Locale
WBEM_FLAG_CONNECT_USE_MAX_WAIT, // Security flags
_bstr_t(strAuthority), // Authority
NULL, // Context object
&pSvc // IWbemServices proxy
);
}
if (FAILED(hres))
{
DWORD aaa = WIN32_FROM_HRESULT_alternate(hres);
//cout << "Could not connect. Error code = 0x"
// << hex << hres << endl;
pLoc->Release();
CoUninitialize();
MyMessageBox_Error(_T("connect"));
return NULL; // Program has failed.
}
//cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
// step 5: --------------------------------------------------
// Create COAUTHIDENTITY that can be used for setting security on proxy
COAUTHIDENTITY *userAcct = NULL;
COAUTHIDENTITY authIdent;
if(!useToken)
{
memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
authIdent.PasswordLength = strPassword.GetLength();
authIdent.Password = (USHORT*) _bstr_t(strPassword);
authIdent.Domain = (USHORT*) _bstr_t(strDomainName);
authIdent.DomainLength = strDomainName.GetLength();
authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
userAcct = &authIdent;
}
// Step 6: --------------------------------------------------
// Set security levels on a WMI connection ------------------
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_DEFAULT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_DEFAULT, // RPC_C_AUTHZ_xxx
COLE_DEFAULT_PRINCIPAL, // Server principal name
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
userAcct, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
//cout << "Could not set proxy blanket. Error code = 0x"
// << hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
MyMessageBox_Error(_T("connect"));
return NULL; // Program has failed.
}
// Cleanup
// ========
pLoc->Release();
return pSvc;
}
vector<IWbemClassObject*> ADWMISearch::query(IWbemServices *pSvc, CString strDomainName, CString strPassword, CString strWQL)
{
vector<IWbemClassObject*> npResultObjects;
BOOL useToken = TRUE;
// step 5: --------------------------------------------------
// Create COAUTHIDENTITY that can be used for setting security on proxy
COAUTHIDENTITY *userAcct = NULL;
COAUTHIDENTITY authIdent;
if(!useToken)
{
memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
authIdent.PasswordLength = strPassword.GetLength();
authIdent.Password = (USHORT*) _bstr_t(strPassword);
/*
LPTSTR slash = _tcschr(pszName, _T('\\'));
if( slash == NULL )
{
//cout << _T("Could not create Auth identity. No domain specified\n") ;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
StringCchCopy(pszUserName, CREDUI_MAX_USERNAME_LENGTH+1, slash+1);
authIdent.User = (USHORT*)pszUserName;
authIdent.UserLength = _tcslen(pszUserName);
StringCchCopyN(pszDomain, CREDUI_MAX_USERNAME_LENGTH+1, pszName, slash - pszName);
*/
authIdent.Domain = (USHORT*) _bstr_t(strDomainName);
authIdent.DomainLength = strDomainName.GetLength();
authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
userAcct = &authIdent;
}
// Step 7: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----
// For example, get the name of the operating system
IEnumWbemClassObject* pEnumerator = NULL;
HRESULT hResult;
hResult = pSvc->ExecQuery(
_bstr_t(_T("WQL")),
_bstr_t(strWQL), //_T("Select * from Win32_Share")
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hResult))
{
//cout << "Query for operating system name failed."
// << " Error code = 0x"
// << hex << hres << endl;
MyMessageBox_Error(_T("query"));
return npResultObjects; // Program has failed.
}
// Step 8: -------------------------------------------------
// Secure the enumerator proxy
hResult = CoSetProxyBlanket(
pEnumerator, // Indicates the proxy to set
RPC_C_AUTHN_DEFAULT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_DEFAULT, // RPC_C_AUTHZ_xxx
COLE_DEFAULT_PRINCIPAL, // Server principal name
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
userAcct, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hResult))
{
//cout << "Could not set proxy blanket on enumerator. Error code = 0x"
// << hex << hres << endl;
pEnumerator->Release();
MyMessageBox_Error(_T("query"));
return npResultObjects; // Program has failed.
}
// When you have finished using the credentials,
// erase them from memory.
// Step 9: -------------------------------------------------
// Get the data from the query in step 7 -------------------
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
npResultObjects.push_back(pclsObj);
/*
VARIANT vtProp;
// Get the value of the Name property
hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
cout << _T("OS Name: ") << vtProp.bstrVal << endl;
// Get the value of the FreePhysicalMemory property
hr = pclsObj->Get(L"FreePhysicalMemory", 0, &vtProp, 0, 0);
cout << "Free physical memory(in kilobytes): " << vtProp.uintVal << endl;
VariantClear(&vtProp);
pclsObj->Release();
pclsObj = NULL;
*/
}
// Cleanup
// ========
pEnumerator->Release();
return npResultObjects;
}
CString ADWMISearch::getStringFromObject(IWbemClassObject* pObject, CString strPropertyName)
{
_bstr_t bstrPropertyName = strPropertyName;
VARIANT vtProperty;
CString strProperty;
// Get the value of the property
VariantInit(&vtProperty);
HRESULT hResult = pObject->Get(bstrPropertyName, 0, &vtProperty, 0, 0);
if (SUCCEEDED(hResult) && V_VT(&vtProperty) == VT_BSTR)
{
strProperty = vtProperty.bstrVal;
VariantClear(&vtProperty);
return strProperty;
}
else
{
VariantClear(&vtProperty);
MyMessageBox_Error(_T("getStringsFromObjects"));
return _T("");
}
}
vector<CString> ADWMISearch::getStringsFromObjects(vector<IWbemClassObject*> npObjects, CString strPropertyName)
{
_bstr_t bstrPropertyName = strPropertyName;
vector<CString> nstrProperties;
for (int i = 0; i < npObjects.size(); i ++)
{
VARIANT vtProperty;
CString strProperty;
// Get the value of the property
VariantInit(&vtProperty);
HRESULT hResult = npObjects[i]->Get(bstrPropertyName, 0, &vtProperty, 0, 0);
if (SUCCEEDED(hResult) && V_VT(&vtProperty) == VT_BSTR)
{
CString strProperty = vtProperty.bstrVal;
nstrProperties.push_back(strProperty);
VariantClear(&vtProperty);
}
else
{
VariantClear(&vtProperty);
MyMessageBox_Error(_T("getStringsFromObjects"));
return nstrProperties;
}
}
return nstrProperties;
}
void ADWMISearch::clearObjects(vector<IWbemClassObject*> npObjects)
{
for (int i = 0; i < npObjects.size(); i ++)
{
npObjects[i]->Release();
npObjects[i] = NULL;
}
npObjects.clear();
}
IWbemClassObject* ADWMISearch::getWMIClass(IWbemServices *pSvc, CString strClassName)
{
HRESULT hResult;
IWbemClassObject* pClass = NULL;
hResult = pSvc->GetObject(_bstr_t(strClassName), 0, NULL, &pClass, NULL); //_T("Win32_Share")
if (!SUCCEEDED(hResult))
{
MyMessageBox_Error(_T("getWMIClass"));
return NULL;
}
else
{
return pClass;
}
}
IWbemClassObject* ADWMISearch::getObjectFromObject(IWbemClassObject *pObject, CString strArgumentName)
{
if (!pObject)
{
MyMessageBox_Error(_T("getObjectFromObject"));
return NULL;
}
HRESULT hResult;
VARIANT varArgument;
hResult = pObject->Get(_bstr_t(strArgumentName), 0, &varArgument, NULL, 0);
if (!SUCCEEDED(hResult))
{
VariantClear(&varArgument);
MyMessageBox_Error(_T("getObjectFromObject"));
return NULL;
}
//IWbemClassObject **ppResultObject;
IWbemClassObject *pResultObject2;
if (V_VT(&varArgument) == VT_UNKNOWN)
{
//ppResultObject = (IWbemClassObject **)varArgument.ppunkVal;
pResultObject2 = (IWbemClassObject *)varArgument.punkVal;
}
else if (V_VT(&varArgument) == VT_DISPATCH)
{
//ppResultObject = (IWbemClassObject **)varArgument.ppdispVal;
pResultObject2 = (IWbemClassObject *)varArgument.pdispVal;
}
else
{
VariantClear(&varArgument);
MyMessageBox_Error(_T("getObjectFromObject"));
return NULL;
}
VariantClear(&varArgument);
//IWbemClassObject *pResultObject = *ppResultObject;
//return pResultObject;
return pResultObject2;
}
IWbemClassObject* ADWMISearch::getObjectFromObjectWithCheck(IWbemClassObject *pOutParams, CString strArgumentName)
{
if (!pOutParams)
{
MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
return NULL;
}
HRESULT hResult;
VARIANT varReturnValue;
VARIANT varArgument;
hResult = pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
if (!SUCCEEDED(hResult))
{
VariantClear(&varReturnValue);
VariantClear(&varArgument);
MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
return NULL;
}
DWORD dwResult = varReturnValue.lVal;
hResult = pOutParams->Get(_bstr_t(strArgumentName), 0, &varArgument, NULL, 0);
if (!SUCCEEDED(hResult))
{
VariantClear(&varReturnValue);
VariantClear(&varArgument);
MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
return NULL;
}
//IWbemClassObject **ppResultObject;
IWbemClassObject *pResultObject2;
if (V_VT(&varArgument) == VT_UNKNOWN)
{
//ppResultObject = (IWbemClassObject **)varArgument.ppunkVal;
pResultObject2 = (IWbemClassObject *)varArgument.punkVal;
}
else if (V_VT(&varArgument) == VT_DISPATCH)
{
//ppResultObject = (IWbemClassObject **)varArgument.ppdispVal;
pResultObject2 = (IWbemClassObject *)varArgument.pdispVal;
}
else
{
VariantClear(&varReturnValue);
VariantClear(&varArgument);
MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
return NULL;
}
VariantClear(&varReturnValue);
VariantClear(&varArgument);
//IWbemClassObject *pResultObject = *ppResultObject;
//return pResultObject;
return pResultObject2;
}
vector<ADWMIParam> ADWMISearch::genObjectArguments(CString strArgName, IWbemClassObject *pObject)
{
vector<ADWMIParam> resultArgs;
resultArgs.push_back(ADWMIParam(strArgName, pObject));
return resultArgs;
}
IWbemClassObject* ADWMISearch::callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strMethodName)
{
return callStaticMethod(pSvc, pClass, strClassName, strMethodName, vector<ADWMIParam>());
}
IWbemClassObject* ADWMISearch::callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strMethodName, vector<ADWMIParam> &arguments)
{
_bstr_t bstrClassName = _bstr_t(strClassName);
_bstr_t bstrMethodName = _bstr_t(strMethodName);
BOOL bInParams;
BOOL bOutParams;
HRESULT hResult;
IWbemClassObject* pClass2 = getWMIClass(pSvc, strClassName);
IWbemClassObject* pInParamsDefinition = NULL;
IWbemClassObject* pOutParamsDefinition = NULL;
hResult = pClass2->GetMethod(bstrMethodName, 0, &pInParamsDefinition, &pOutParamsDefinition);
if (hResult != WBEM_S_NO_ERROR)
{
//pClass->Release();
MyMessageBox_Error(_T("callStaticMethod"));
return NULL;
}
if (pInParamsDefinition == NULL)
{
bInParams = FALSE;
}
else
{
bInParams = TRUE;
}
if (pOutParamsDefinition == NULL)
{
bOutParams = FALSE;
}
else
{
bOutParams = TRUE;
}
IWbemClassObject* pInParamsInstance = NULL;
if (bInParams)
{
hResult = pInParamsDefinition->SpawnInstance(0, &pInParamsInstance);
for (int i = 0; i < arguments.size(); i ++)
{
_variant_t varArg;
VariantCopy(&varArg, &(arguments[i].value));
hResult = pInParamsInstance->Put(_bstr_t(arguments[i].key), 0, &varArg, 0);
//hResult = pInParamsInstance->Put(_bstr_t(arguments[i].key), 0, &(arguments[i].value), 0);
}
}
IWbemClassObject* pOutParams = NULL;
hResult = pSvc->ExecMethod(bstrClassName, bstrMethodName, 0, NULL, pInParamsInstance, &pOutParams, NULL);
if (hResult != WBEM_S_NO_ERROR)
{
//pClass->Release();
if (pInParamsDefinition != NULL)
{
pInParamsDefinition->Release();
}
if (pOutParamsDefinition != NULL)
{
pOutParamsDefinition->Release();
}
if (pInParamsInstance != NULL)
{
pInParamsInstance->Release();
}
MyMessageBox_Error(_T("callStaticMethod"));
return NULL;
}
if (pInParamsDefinition != NULL)
{
pInParamsDefinition->Release();
}
if (pOutParamsDefinition != NULL)
{
pOutParamsDefinition->Release();
}
if (pInParamsInstance != NULL)
{
pInParamsInstance->Release();
}
if (bOutParams)
{
return pOutParams;
}
else
{
return NULL;
}
}
IWbemClassObject* ADWMISearch::callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strInstancePath, CString strMethodName)
{
return callMethod(pSvc, pClass, strClassName, strInstancePath, strMethodName, vector<ADWMIParam>());
}
IWbemClassObject* ADWMISearch::callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strInstancePath, CString strMethodName, vector<ADWMIParam> &arguments)
{
_bstr_t bstrClassName = _bstr_t(strClassName);
_bstr_t bstrMethodName = _bstr_t(strMethodName);
BOOL bInParams;
BOOL bOutParams;
HRESULT hResult;
//IWbemClassObject* pClass = getWMIClass(pSvc, strClassName);
IWbemClassObject* pInParamsDefinition = NULL;
IWbemClassObject* pOutParamsDefinition = NULL;
hResult = pClass->GetMethod(bstrMethodName, 0, &pInParamsDefinition, &pOutParamsDefinition);
if (hResult != WBEM_S_NO_ERROR)
{
//pClass->Release();
MyMessageBox_Error(_T("callMethod"));
return NULL;
}
if (pInParamsDefinition == NULL)
{
bInParams = FALSE;
}
else
{
bInParams = TRUE;
}
if (pOutParamsDefinition == NULL)
{
bOutParams = FALSE;
}
else
{
bOutParams = TRUE;
}
IWbemClassObject* pInParamsInstance = NULL;
if (bInParams)
{
hResult = pInParamsDefinition->SpawnInstance(0, &pInParamsInstance);
for (int i = 0; i < arguments.size(); i ++)
{
_variant_t varArg;
VariantCopy(&varArg, &(arguments[i].value));
hResult = pInParamsInstance->Put(_bstr_t(arguments[i].key), 0, &varArg, 0);
//hResult = pInParamsInstance->Put(_bstr_t(arguments[i].key), 0, &(arguments[i].value), 0);
}
}
IWbemClassObject* pOutParams = NULL;
hResult = pSvc->ExecMethod(_bstr_t(strInstancePath), bstrMethodName, 0, NULL, pInParamsInstance, &pOutParams, NULL);
if (hResult != WBEM_S_NO_ERROR)
{
//pClass->Release();
if (pInParamsDefinition != NULL)
{
pInParamsDefinition->Release();
}
if (pOutParamsDefinition != NULL)
{
pOutParamsDefinition->Release();
}
if (pInParamsInstance != NULL)
{
pInParamsInstance->Release();
}
MyMessageBox_Error(_T("callMethod"));
return NULL;
}
if (pInParamsDefinition != NULL)
{
pInParamsDefinition->Release();
}
if (pOutParamsDefinition != NULL)
{
pOutParamsDefinition->Release();
}
if (pInParamsInstance != NULL)
{
pInParamsInstance->Release();
}
if (bOutParams)
{
return pOutParams;
}
else
{
return NULL;
}
}
void ADWMISearch::disconnect(IWbemServices *pSvc)
{
pSvc->Release();
CoUninitialize();
}
ADWMISearch.h
#include <Wbemidl.h>
#include <vector>
#include <map>
using namespace std;
class ADWMIParam
{
public:
CString key;
_variant_t value;
public:
ADWMIParam(CString strKey, CString strValue)
{
key = strKey;
VariantInit(&value);
value.vt = VT_BSTR;
value.bstrVal = _bstr_t(strValue);
}
ADWMIParam(CString strKey, IWbemClassObject *pValue)
{
key = strKey;
VariantInit(&value);
value.vt = VT_UNKNOWN;
value.punkVal = pValue;
}
};
class ADWMISearch
{
public:
DWORD WIN32_FROM_HRESULT_alternate(HRESULT hr);
IWbemServices* connect(CString strServerName, CString strServerIP, CString strDomainName,
CString strUsername, CString strPassword);
vector<IWbemClassObject*> query(IWbemServices *pSvc, CString strDomainName, CString strPassword, CString strWQL);
CString getStringFromObject(IWbemClassObject* pObject, CString strPropertyName);
vector<CString> getStringsFromObjects(vector<IWbemClassObject*> npObjects, CString strPropertyName);
void clearObjects(vector<IWbemClassObject*> npObjects);
IWbemClassObject* getWMIClass(IWbemServices *pSvc, CString strClassName);
IWbemClassObject* getObjectFromObject(IWbemClassObject *pObject, CString strArgumentName);
IWbemClassObject* getObjectFromObjectWithCheck(IWbemClassObject *pOutParams, CString strArgumentName);
vector<ADWMIParam> genObjectArguments(CString strArgName, IWbemClassObject *pObject);
IWbemClassObject* callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strMethodName);
IWbemClassObject* callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strMethodName, vector<ADWMIParam> &arguments);
IWbemClassObject* callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strInstancePath, CString strMethodName);
IWbemClassObject* callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
CString strInstancePath, CString strMethodName, vector<ADWMIParam> &arguments);
void disconnect(IWbemServices *pSvc);
};
the call code(a place like main is ok)
ADWMISearch *wmiSearcher = new ADWMISearch();
IWbemServices *pSvc = wmiSearcher->connect("luo-pc", "127.0.0.1", "", "", "");
IWbemClassObject *pLSSSClass = wmiSearcher->getWMIClass(pSvc, "Win32_LogicalShareSecuritySetting");
vector<IWbemClassObject*> npObjects = wmiSearcher->query(pSvc, "", "", "Select * from Win32_Log