How to get CPU usage in WMI using C++? - c++

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.

Related

DXGI got an error in func Map "Access Violation"

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;
}

CreateSnapshot() does not generate a hyper-v virtual machine snapshot?

HRESULT hr;
IWbemClassObject *pInClass = NULL;
IWbemClassObject *pOutClass = NULL;
IWbemContext *pCtx = 0;
IWbemCallResult *pResult = 0;
BSTR snapshotClassPath = SysAllocString(L"Msvm_VirtualSystemSnapshotService");
hr = m_pWbemServices->GetObject(
snapshotClassPath,
0,
NULL,
&m_pWbemClassObject,
NULL);
if (FAILED(hr))
{
std::cout << "Failed to get class object(Msvm_VirtualSystemSnapshotService). Error code = 0x" << hex << hr << std::endl;
return;
}
// Create snapshot method
BSTR MethodNameOne = SysAllocString(L"CreateSnapshot");
hr = m_pWbemClassObject->GetMethod(
MethodNameOne,
0,
&pInClass,
&pOutClass
);
if (FAILED(hr))
{
std::cout << "Failed to get method(CreateSnapshot). Error code = 0x" << hex << hr << endl;
}
cout << "Succeeded to get method(CreateSnapshot)." << endl;
BSTR virtualSystemSnaphotSettingData = SysAllocString(L"Msvm_VirtualSystemSnapshotSettingData");
// Get the Msvm_VirtualSystemSnapshotSettingData Class object
IWbemClassObject * pvirtualSystemSnaphotSettingData = NULL;
hr = m_pWbemServices->GetObject(
virtualSystemSnaphotSettingData,
0,
pCtx,
&pvirtualSystemSnaphotSettingData,
&pResult
);
if (FAILED(hr))
{
wprintf(L"Error GetObject Msvm_VirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
std::cout << "Succeeded to get object(Msvm_VirtualSystemSnapshotSettingData)." << std::endl;
// Create instance of Msvm_VirtualSystemSnapshotSettingData class
IWbemClassObject * pInpInstOfSnapshotSettingData = NULL;
hr = pvirtualSystemSnaphotSettingData->SpawnInstance(
0,
&pInpInstOfSnapshotSettingData);
if (FAILED(hr))
{
wprintf(L"Error SpawnInstance Msvm_VirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
std::cout << "Succeeded to created instance(Msvm_VirtualSystemSnapshotSettingData )." << std::endl;
// Set the property(Consistency Level)
BSTR memberOneForVirtualSystemSnapshotSettingData = SysAllocString(L"ConsistencyLevel");
VARIANT consistencyLevel;
VariantInit(&consistencyLevel);
V_VT(&consistencyLevel) = VT_BSTR;
V_BSTR(&consistencyLevel) = SysAllocString(L"1");
hr = pInpInstOfSnapshotSettingData->Put(
memberOneForVirtualSystemSnapshotSettingData,
0,
&consistencyLevel,
0);
if (FAILED(hr))
{
wprintf(L"Error memberOneForVirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(ConsistencyLevel), Consistency level:%s\n", consistencyLevel.bstrVal);
VariantClear(&consistencyLevel);
The CreateSnapshot method was called on Windows Hyper-V 2016 and the execution was successful, but the generated virtual machine snapshot was not visible in the Hyper-V GUI.
// Set the property(ElementName)
BSTR memberThreeForVirtualSystemSnapshotSettingData = SysAllocString(L"ElementName");
VARIANT elementName;
VariantInit(&elementName);
V_VT(&elementName) = VT_BSTR;
V_BSTR(&elementName) = SysAllocString(vmName);
hr = pInpInstOfSnapshotSettingData->Put(
memberThreeForVirtualSystemSnapshotSettingData,
0,
&elementName,
0);
if (FAILED(hr))
{
wprintf(L"Failed to set property(ElementName), Erorr code:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(ElementName):%s\n", elementName.bstrVal);
VariantClear(&elementName);
// Set the property(ignore disks that aren't compatible with snapshots)
BSTR memberTwoForVirtualSystemSnapshotSettingData = SysAllocString(L"IgnoreNonSnapshottableDisks");
VARIANT ignoreNonSnapshottableDisks;
ignoreNonSnapshottableDisks.vt = VT_BOOL;
ignoreNonSnapshottableDisks.boolVal = true;
hr = pInpInstOfSnapshotSettingData->Put(
memberTwoForVirtualSystemSnapshotSettingData,
0,
&ignoreNonSnapshottableDisks,
0);
if (FAILED(hr))
{
wprintf(L"Error memberTwoForVirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(IgnoreNonSnapshottableDisks):%d\n", ignoreNonSnapshottableDisks.boolVal);
VariantClear(&ignoreNonSnapshottableDisks);
// Create or update instance
hr = m_pWbemServices->PutInstance(
pInpInstOfSnapshotSettingData,
0,
pCtx,
&pResult);
if (FAILED(hr))
{
wprintf(L"Error PutInstance:0x%08lx\n", hr);
}
wprintf(L"Succeeded to update the instance.\n");
// Get textual rendering of the object in the MOF syntax
BSTR objString = NULL;
hr = pInpInstOfSnapshotSettingData->GetObjectText(0, &objString);
if (FAILED(hr))
{
wprintf(L"Error GetObjectText:0x%08lx\n", hr);
}
wprintf(L"Succeeded to get textual rendering.\n");
BSTR ArgNameTwo = SysAllocString(L"SnapshotSettings");
VARIANT v;
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = objString;
wprintf(L"Object text: %s\n", objString);
// Pass the second Argument to CreateSnapshot method
hr = pInClass->Put(ArgNameTwo, 0, &v, 0);
if (FAILED(hr))
{
wprintf(L"Error ArgNameTwo:0x%08lx\n", hr);
}
VariantClear(&v);
wprintf(L"Succeeded to set property(SnapshotSettings).\n");
// set property(AffectedSystem)
VARIANT vtProp;
m_pWbemClassObject->Get(L"__Path", 0, &vtProp, 0, 0);
hr = pInClass->Put(L"AffectedSystem", 0, &vtProp, NULL);
if (FAILED(hr))
{
std::cout << "Failed to set property(AffectedSystem)." << std::endl;
}
wprintf(L"AffectedSystem: %s\n", vtProp.bstrVal);
VariantClear(&vtProp);
// Pass the Third Argument to CreateSnapshot method
BSTR ArgNameThree = SysAllocString(L"SnapshotType");
VARIANT var;
VariantInit(&var);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(L"32768");
hr = pInClass->Put(ArgNameThree, 0, &var, 0);
if (FAILED(hr))
{
std::cout << "Failed to set property(SnapshotType)." << std::endl;
}
wprintf(L"SnapshotType: %s\n", var.bstrVal);
VariantClear(&var);
// Call the CreateSnapshot method.
IEnumWbemClassObject* pEnumOb1 = NULL;
hr = m_pWbemServices->ExecQuery(
BSTR(L"WQL"),
BSTR(L"SELECT * FROM Msvm_VirtualSystemSnapshotService"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumOb1
);
if (FAILED(hr)) {
std::cout << "SELECT * FROM Msvm_VirtualSystemSnapshotService, Error code:0x%08lx" << hex << hr << endl;
}
std::cout << "Succeeded to query snapshot." << std::endl;
IWbemClassObject *pclsObj1 = NULL;
ULONG uReturn1 = 0;
std::cout << "Create snapshot..." << std::endl;
while (1)
{
HRESULT hr = pEnumOb1->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn1);
if (FAILED(hr) || !uReturn1)
{
break;
}
VARIANT vt;
// Get the value of the path property from Msvm_VirtualSystemSnapshotService Class
hr = pclsObj1->Get(L"__Path", 0, &vt, 0, 0);
if (FAILED(hr))
{
std::wcout << "Failed to get vm's path." << std::endl;
break;
}
wprintf(L"__PATH:%s \n", vt.bstrVal);
//Call the CreateSnapshot method
hr = m_pWbemServices->ExecMethod(
vt.bstrVal,
MethodNameOne,
0,
NULL,
pInClass,
&pOutClass,
NULL);
if (FAILED(hr))
{
wprintf(L"Failed to execute(CreateSnapshot), Erorr code:0x%08lx\n", hr);
break;
}
wprintf(L"Succeeded to create snapshot.\n");
Sleep(10);
pclsObj1->Release();
pclsObj1 = NULL;
}
The return value of ExecMethod() is 0, that is, the call succeeds, but I did not see the snapshot just created on Hyper-V.
I use this PowerShell script and it works. The only problem is to set snapshot name:
function Create-VMSnapshot{
$vm = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Query "select * from msvm_computersystem where elementname='$VMName'"
if($vm -eq $null){
throw "Failed to get VM with display name '$VMName'"
}
$Msvm_VirtualSystemSnapshotService = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Class Msvm_VirtualSystemSnapshotService
if($Msvm_VirtualSystemSnapshotService -eq $null)
{
throw "Failed to get Msvm_VirtualSystemSnapshotService instance"
}
[WMI]$Msvm_VirtualSystemSnapshotSettingData = ([WMIClass]"\\.\root\virtualization\v2:Msvm_VirtualSystemSnapshotSettingData").CreateInstance()
if($Msvm_VirtualSystemSnapshotSettingData -eq $null)
{
throw "Failed to get Msvm_VirtualSystemSnapshotSettingData instance"
}
$Msvm_VirtualSystemSnapshotSettingData.ConsistencyLevel = 1
$Msvm_VirtualSystemSnapshotSettingData.IgnoreNonSnapshottableDisks = $true
$Msvm_VirtualSystemSnapshotSettingData.ElementName = $SnapshotName
$Msvm_VirtualSystemSnapshotSettingData.Description = $SnapshotDescription
$Msvm_VirtualSystemSnapshotSettingData
[System.Management.ManagementBaseObject]$result = $Msvm_VirtualSystemSnapshotService.CreateSnapshot(
$vm,
$Msvm_VirtualSystemSnapshotSettingData.GetText(2),
32768)
[int]$res = Job-Observation -WMIJobResult $result -JobAction "Creating snapshot" -JobProgressCaption "Create snapshot"
$snapshot = (([WMI]$result.Job).GetRelated("Msvm_VirtualSystemSettingData") | % {$_})
$snapshot
}

Setting default format on capture device via WinAPI

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?

How to get system volume level as a scalar from 0 to 100?

I'm currently working on a "Volume mixer" to control the volume of each program on my PC (Windows 10).
How do I get the volume level of each program/audio session as a scalar from 0 to 100?
As you can see, in the code below, I found the GetPeakValue function, but it returns values like 0.0812654 or 0.021352.
I'm sure that these values are the volume of each audio session in a scalar from 1.0 to 0.0. But what I want is the volume limitation, which you can set in the windows audio mixer for example, and not the current level. So if I set the program volume level to 50%, I want a value like 0.5.
In the second function (getVolume), you'll see that I already got the master volume in a 0-100 scalar, but there the endpoint device has a function for the scalar level already. So I'll need the same function at least, or a calculation, to get such a scalar for every audio session as well.
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionManager2 *pAudioSessionManager2 = NULL;
IAudioSessionEnumerator *pAudioSessionEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
std::cout << "Session Count: " << nSessionCount << std::endl;
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl = NULL;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
IAudioMeterInformation *pAudioMeterInformation = NULL;
pSessionControl->QueryInterface(&pAudioMeterInformation);
float fPeak = NULL;
pAudioMeterInformation->GetPeakValue(&fPeak);
std::cout << "fPeak Value: " << fPeak << std::endl;
}
std::cout << "\n\n";
Sleep(1000);
}
CoUninitialize();
}
double getVolume() {
float currentVolume = 0;
CoInitialize(NULL);
IMMDeviceEnumerator *deviceEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
IMMDevice *defaultDevice = NULL;
deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
deviceEnumerator->Release();
deviceEnumerator = NULL;
IAudioEndpointVolume *endpointVolume = NULL;
defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
defaultDevice->Release();
defaultDevice = NULL;
float fLevel;
endpointVolume->GetMasterVolumeLevel(&fLevel);
qDebug() << "FLevel: ";
qDebug() << fLevel;
endpointVolume->GetMasterVolumeLevelScalar(&currentVolume);
endpointVolume->Release();
CoUninitialize();
return (double)(currentVolume * 100);
}
Ok guys, I've found the solution for my problem!
I had to call QueryInterface on the SessionControl to gain access to ISimpleAudioVolume where you can use the functions GetMasterVolume and SetMasterVolume. It's a 0-1 scalar, but you can just multiply it with 100 to get a 0-100 scalar. If the system's master volume is on 50%, you get a output of 1 if the program volume is on 50% too, so the output is based on the system's master volume!
Thanks for every comment and help!
Here the working code:
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator;
IMMDevice *pDevice;
IAudioSessionManager2 *pAudioSessionManager2;
IAudioSessionEnumerator *pAudioSessionEnumerator;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
ISimpleAudioVolume *pSimpleAudioVolume;
pSessionControl->QueryInterface(&pSimpleAudioVolume);
float fLevel;
pSimpleAudioVolume->GetMasterVolume(&fLevel);
std::cout << "fLevel Value: " << fLevel << std::endl;
}
Sleep(1000);
}
CoUninitialize();
}

How to get a instance of Win32_SecurityDescriptor in WMI?

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