C++ code: Logical error in finding the Kinect sensor - c++

I want to get depth and RGB data from Kinect V2 by Windows SDK 2.0 in Viual Studio 2013. So I write these codes:
#include <Kinect.h>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <Windows.h>
#include <iostream>
using namespace std;
const int width = 512;
const int height = 424;
const int colorwidth = 1920;
const int colorheight = 1080;
// Kinect Variables
IKinectSensor* sensor; // Kinect sensor
IMultiSourceFrameReader* reader; // Kinect data source
ICoordinateMapper* mapper;
int main(int argc, char* argv[]) {
if (FAILED(GetDefaultKinectSensor(&sensor))) {
printf("not found sensor");
getchar();
return -100;
}
if (sensor) {
sensor->get_CoordinateMapper(&mapper);
sensor->Open();
sensor->OpenMultiSourceFrameReader(
FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Color,
&reader);
IMultiSourceFrame* framesource;
cout << "Find!!!";
getchar();
return 100;
}
else {
return -100;
}
getchar();
return 10;
}
Logically, when I do not plug Kinect sensor to my Laptop, in Console should be printed: "not found sensor",isn't it? But, in console printed: "Find!!!". what is the problem?

No, Since SDK v2, You can debug an application by using KinectStudio, even without a physical kinect is connected to the system. If you want to check whether the actual Kinect is connected, you need to use IsAvailable property of the sensor itself. GetDefaultKinectSensor will always give you S_OK unless you have runtime or installation issues. GetDefaultKinectSensor won't check whether is this stream comes from actual physical kinect sensor or from KinectStudio.
The following is a code snippet from my project. If you want more examples about Kinect, please refer my project in github https://github.com/shanilfernando/VRInteraction or comment here. I'm more than happy to help you.
HRESULT CDepthBasics::InitializeDefaultSensor()
{
HRESULT hr;
hr = GetDefaultKinectSensor(&m_pKinectSensor);
if (FAILED(hr))
{
return hr;
}
if (m_pKinectSensor)
{
if (SUCCEEDED(hr))
{
hr = m_pKinectSensor->get_CoordinateMapper(&m_pCoordinateMapper);
}
if (SUCCEEDED(hr))
{
hr = m_pKinectSensor->Open();
}
if (SUCCEEDED(hr))
{
hr = m_pKinectSensor->OpenMultiSourceFrameReader(
FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Color | FrameSourceTypes::FrameSourceTypes_Body | FrameSourceTypes::FrameSourceTypes_BodyIndex,
&m_pMultiSourceFrameReader);
}
}
if (!m_pKinectSensor || FAILED(hr))
{
std::cout << "No ready Kinect found!" << std::endl;
return E_FAIL;
}
else
{
std::cout << "Kinect found!" << std::endl;
}
return hr;
}
https://github.com/shanilfernando/VRInteraction/blob/master/DepthBasics.cpp
Edit
I didn't use IsAvailable since it doesn't matter for me where that stream comes from. Sometimes I used KinectStudio to get the streams while Kinect is not with me. I said GetDefaultKinectSensor will return S_OK unless you have runtime or installation issues, I did NOT said GetDefaultKinectSensor will always give you a valid m_pKinectSensor. Since we don't have access to the implementation of the GetDefaultKinectSensor and as a good practice, it is better to check it null or not before using it. This is the official answer for your question from the Microsoft

Related

How to get a human readable process name (like in the task manager) via Win32 API? [duplicate]

I want to get the description of a process (the description that is seen in task manager) in Windows using C++.
You most likely want to get the FileDesription field from the version resources of the main .exe file of the program, using the VerQueryValue() API call. Here is an example from that document:
The following example shows how to enumerate the available version languages and retrieve the FileDescription string-value for each language.
Be sure to call the GetFileVersionInfoSize and GetFileVersionInfo functions before calling VerQueryValue to properly initialize the pBlock buffer.
// Structure used to store enumerated languages and code pages.
HRESULT hr;
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
// Read the list of languages and code pages.
VerQueryValue(pBlock,
TEXT("\\VarFileInfo\\Translation"),
(LPVOID*)&lpTranslate,
&cbTranslate);
// Read the file description for each language and code page.
for( i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ )
{
hr = StringCchPrintf(SubBlock, 50,
TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
if (FAILED(hr))
{
// TODO: write error handler.
}
// Retrieve file description for language and code page "i".
VerQueryValue(pBlock,
SubBlock,
&lpBuffer,
&dwBytes);
}
Although I read this question, the accepted answer, and the documentation for VerQueryValue, I spent quite a while to understand how to use that VerQueryValue function (since the code example in the docs has no declarations of variables and isn't clear for me at all).
So I decided to put here the code that can be easily run as a working example of the usage of VerQueryValue to get a process description.
#pragma comment(lib,"Version.lib")
#include <iostream>
#include <windows.h>
#include <winver.h>
using namespace std;
int printFileDescriptions(const wchar_t* filename)
{
int versionInfoSize = GetFileVersionInfoSize(filename, NULL);
if (!versionInfoSize) {
return 0;
}
auto versionInfo = new BYTE[versionInfoSize];
std::unique_ptr<BYTE[]> versionInfo_automatic_cleanup(versionInfo);
if (!GetFileVersionInfo(filename, NULL, versionInfoSize, versionInfo)) {
return 0;
}
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *translationArray;
UINT translationArrayByteLength = 0;
if (!VerQueryValue(versionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayByteLength)) {
return 0;
}
// You may check GetSystemDefaultUILanguage() == translationArray[i].wLanguage
// if only the system language required
for (unsigned int i = 0; i < (translationArrayByteLength / sizeof(LANGANDCODEPAGE)); i++) {
wchar_t fileDescriptionKey[256];
wsprintf(
fileDescriptionKey,
L"\\StringFileInfo\\%04x%04x\\FileDescription",
translationArray[i].wLanguage,
translationArray[i].wCodePage
);
wchar_t* fileDescription = NULL;
UINT fileDescriptionSize;
if (VerQueryValue(versionInfo, fileDescriptionKey, (LPVOID*)&fileDescription, &fileDescriptionSize)) {
wcout << endl << fileDescription << endl;
}
}
return TRUE;
}
int main()
{
// Set locale of the console to print non-ASCII symbols
SetConsoleOutputCP(GetACP());
SetConsoleCP(GetACP());
wcout.imbue(std::locale("")); // set default global locale
// ----------------------------------------------------
auto path = L"C:\\Windows\\explorer.exe";
printFileDescriptions(path);
wcin.get(); // to prevent console close
}
It's supposed that all WinAPI functions on your system use wchar_t, that is VerQueryValueW is actually used.
The initial version of the code I took here Retrieve File Description an Application VerQueryValue

How to know if a device has been explicitly been disabled by user?

Using device manager a user can explicitly enable/disable a device, as can be seen in the following image.
For a given device I want to know if it's currently in a user disabled/enabled state.
I have tried the following approaches
CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); I was hoping that presence of DN_STARTED, or DN_DRIVER_LOADED would tell me that. But these can be zero even when a driver is being loaded/unloaded by the OS, when the device connects/disconnects. For example, a device which is enabled, and for which driver is loaded. DN_STARTED will be 1, but when we disconnect device it is set to zero before the device's entry is removed from device manager.
SetupDiGetDeviceRegistryProperty(..., SPDRP_INSTALL_STATE, ...) I though a state of CM_INSTALL_STATE_INSTALLED should mean that the device is enabled. But the function returns this state even for disabled devices.
Using WMI I was able to get the required information, but I used wmi in PowerShell. I do not want to use wmi, as it is quite difficult to implement in native c++. I used the following query.
Select Name, Availability, ConfigManagerErrorCode, ConfigManagerUserConfig from Win32_PnPEntity where Name = 'NVIDIA Quadro M1000M'
ConfigManagerErrorCode in above query, if set to 22, means that device has been disabled, 21 means that windows is removing the device
I am looking for a non wmi solution.
The information can be obtained from a device's problem code. There are two ways which I could find to get it.
Use SetupDiGetDeviceProperty() to query DEVPKEY_Device_ProblemCode.
Use CM_Get_DevNode_Status() the problem code will be present in the second argument after the call.
A problem code of 22 (CM_PROB_DISABLED) means that the device has been explicitly disabled by a user by either using device manager, or other such utility.
Sample code
#include "stdafx.h"
#include <Windows.h>
#include <SetupAPI.h>
#include <Cfgmgr32.h>
#include <devguid.h>
#include <initguid.h>
#include "devpkey.h"
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0); //only getting for GPUs on the machine
if (INVALID_HANDLE_VALUE != hDevInfo)
{
SP_DEVINFO_DATA data;
data.cbSize = (DWORD)sizeof(data);
for (unsigned int nIndex = 0; ::SetupDiEnumDeviceInfo(hDevInfo, nIndex, &data); nIndex++)
{
ULONG status = 0, problem = 0;
CONFIGRET cr = ::CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); //after the call 'problem' variable will have the problem code
if (CR_SUCCESS == cr)
{
cout << " problem " << problem <<endl;
if(problem == CM_PROB_DISABLED)
{ /*Do Something*/ }
DEVPROPTYPE propertyType;
const DWORD propertyBufferSize = 100;
BYTE propertyBuffer[propertyBufferSize];
std::fill(begin(propertyBuffer), end(propertyBuffer), BYTE(0));
DWORD requiredSize = 0;
if (SetupDiGetDeviceProperty(hDevInfo, &data, &DEVPKEY_Device_ProblemCode, &propertyType, propertyBuffer, propertyBufferSize, &requiredSize, 0)) //after the call 'propertyBuffer' will have error codes
{
unsigned long deviceProblemCode = *((unsigned long*)propertyBuffer);
cout << " deviceProblemCode " << deviceProblemCode << endl;
if(problem == CM_PROB_DISABLED)
{ /*Do Something*/ }
}
}
}
}
return 0;
}
Sample Output
problem 0
deviceProblemCode 0
problem 22
deviceProblemCode 22
In the question it can be seen that Intel(R) HD Graphics 530 was enabled, and NVIDIA Quadro M1000M was disabled. Hence in the output we got a problem code of 0, and a problem code of 22 (CM_PROB_DISABLED).

Getting BLE Beacons in C++ Windows 10 Desktop Application

Has someone already figured out how to get BLE Beacons into a c++ desktop apps?
I have some code from the following websites to get it done in c#:
msdn sozial site
and
codefest.at post. Sorry, it's in german but the code is code
but that'for C# and not c++
I also have the example from MS (msdn.microsoft.com/en-us/library/hh973459.aspx) how to use the WinRL
For now I have the following code:
#include "stdafx.h"
#include <iostream>
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>
#include <../winrt/windows.devices.bluetooth.h>
#include <../winrt/windows.devices.bluetooth.advertisement.h>
using namespace std;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Devices::Bluetooth::Advertisement;
/* http://www.codefest.at/post/2015/09/07/Bluetooth-Beacons-Windows-10.aspx
private async void WatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
_beaconManager.ReceivedAdvertisement(eventArgs);
}
var watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active };
watcher.Received += WatcherOnReceived;
watcher.Stopped += WatcherOnStopped;
watcher.Start();
*/
// Prints an error string for the provided source code line and HRESULT
// value and returns the HRESULT value as an int.
int PrintError(unsigned int line, HRESULT hr)
{
wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
return hr;
}
EventRegistrationToken watcherToken;
int main()
{
// Initialize the Windows Runtime.
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
{
return PrintError(__LINE__, initialize);
}
// Get the activation factory for the IBluetoothLEAdvertisementWatcherFactory interface.
ComPtr<IBluetoothLEAdvertisementWatcherFactory> bleAdvWatcherFactory;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Devices_Bluetooth_Advertisement_BluetoothLEAdvertisementWatcher).Get(), &bleAdvWatcherFactory);
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
IBluetoothLEAdvertisementWatcher* bleWatcher;
IBluetoothLEAdvertisementFilter* bleFilter;
hr = bleAdvWatcherFactory->Create(bleFilter, &bleWatcher);
if (bleWatcher == NULL)
{
cout << "bleWatcher is NULL, err is " << hex << hr;
}
else
{
bleWatcher->Start();
while (1)
Sleep(1000);
}
return 0;
}
my problem is that the Watcher Factory complains ( hr = E_INVALIDARG "One or more arguments are not valid" 0x80070057) that one of the variables is not valid (I suspect the filter because it has no valid content).
And even on the same level of severity, I have no idea how to register the event handler for the incoming beacons.
msdn.microsoft.com/en-us/library/windows/apps/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher.received?cs-save-lang=1&cs-lang=cpp
is telling me something about the Received event. But I don't have it in my autocomplete from VS and also not by manually looking into the header file.
The next best thing I have is the "add_Received" but I can't find any documentation about it how to use. And I don't get that much wiser from the header file.
Thanks in advance for tips and tricks or even a working solution.
Markus
You have few problems in your code. First of all All I* classes should be wrapped around ComPtr<I*>
ComPtr<IBluetoothLEAdvertisementWatcher> bleWatcher;
ComPtr<IBluetoothLEAdvertisementFilter> bleFilter;
In function bleAdvWatcherFactory->Create(bleFilter, &bleWatcher); parameter bleFilter is undefined and it will lead to undefined behaviour (In Debug version it might be initialized as nullptr).
You can create it by using:
Wrappers::HStringReference
Wrappers::HStringReference class_id_filter(RuntimeClass_Windows_Devices_Bluetooth_Advertisement_BluetoothLEAdvertisementFilter);
hr = RoActivateInstance(class_id_filter.Get(), reinterpret_cast<IInspectable**>(bleFilter.GetAddressOf()));
Then you are allowed to call:
hr = bleAdvWatcherFactory->Create(bleFilter.Get(), &bleWatcher.GetAddressOf());

Visual C++, Windows Update Interface (IUpdate) <wuapi.h>, get_MsrcSeverity

I'm probably just blind, but I cannot see any errors here (and I am looking on this issue already for days now...)
I am trying to get the Patch Priority (Severity) from the Windows Update Interface using the following piece of code in Visual Studio:
#include "stdafx.h"
#include <wuapi.h>
#include <iostream>
#include <ATLComTime.h>
#include <wuerror.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr;
hr = CoInitialize(NULL);
IUpdateSession* iUpdate;
IUpdateSearcher* searcher;
ISearchResult* results;
BSTR criteria = SysAllocString(L"IsInstalled=0");
hr = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&iUpdate);
hr = iUpdate->CreateUpdateSearcher(&searcher);
wcout << L"Searching for updates ..."<<endl;
hr = searcher->Search(criteria, &results);
SysFreeString(criteria);
switch(hr)
{
case S_OK:
wcout<<L"List of applicable items on the machine:"<<endl;
break;
case WU_E_LEGACYSERVER:
wcout<<L"No server selection enabled"<<endl;
return 0;
case WU_E_INVALID_CRITERIA:
wcout<<L"Invalid search criteria"<<endl;
return 0;
}
IUpdateCollection *updateList;
IUpdateCollection *bundledUpdates;
IUpdate *updateItem;
IUpdate *bundledUpdateItem;
LONG updateSize;
LONG bundledUpdateSize;
BSTR updateName;
BSTR severity;
results->get_Updates(&updateList);
updateList->get_Count(&updateSize);
if (updateSize == 0)
{
wcout << L"No updates found"<<endl;
}
for (LONG i = 0; i < updateSize; i++)
{
updateList->get_Item(i,&updateItem);
updateItem->get_Title(&updateName);
severity = NULL;
updateItem->get_MsrcSeverity(&severity);
if (severity != NULL)
{
wcout << L"update severity: " << severity << endl;
}
wcout<<i+1<<" - " << updateName << endl;
// bundled updates
updateItem->get_BundledUpdates(&bundledUpdates);
bundledUpdates->get_Count(&bundledUpdateSize);
if (bundledUpdateSize != 0)
{
// iterate through bundled updates
for (LONG ii = 0; ii < bundledUpdateSize; ii++)
{
bundledUpdates->get_Item(ii, &bundledUpdateItem);
severity = NULL;
bundledUpdateItem->get_MsrcSeverity(&severity);
if (severity != NULL)
{
wcout << L" bundled update severity: " << severity << endl;
}
}
}
}
::CoUninitialize();
wcin.get();
return 0;
}
So here's the issue: updateItem->get_MsrcSeverity(&severity); is not returning anything. If I catch the result code with an HRESULT it always returns S_OK.
Link to MSDN IUpdate MsrcSeverity: http://msdn.microsoft.com/en-us/library/windows/desktop/aa386906(v=vs.85).aspx
Can you see what I am doing obviously wrong or is the get_MsrcSeverity function currently broken?
#EDIT: Changed the code to iterate through "BundledUpdates" as suggested.
#EDIT2: the code now outputs the severity value of the updateItem as well as the bundledUpdatesItem, but it's always NULL.
I also know there is one important update waiting for my computer - regarding to Windows Update in the control panel. It is KB2858725.
#EDIT3: Okay, it turns out, KB2858725 is no security update and therefore has no severity rating by Microsoft. But how does Microsoft Windows Update now categorize the updates in "important" and "optional" like you can see it in control panel's update?
Thank you for any hints!
// Markus
I've been struggling with the exact same problem for hours now... I finally figured out that Microsoft only seems to set the MsrcSeverity value on some updates. For general Windows updates, it's usually null. For most security updates it's set to one of:
"Critical"
"Moderate"
"Important"
"Low"
It seems as though the "Unspecified" value is never used, though it is documented in MSDN (http://msdn.microsoft.com/en-us/library/microsoft.updateservices.administration.msrcseverity(v=vs.85).aspx).
I wrote a small C# program to list all available updates and their reported severity. It requires a reference to WUApiLib:
using System;
using WUApiLib;
namespace EnumerateUpdates
{
class Program
{
static void Main(string[] args)
{
var session = new UpdateSession();
var searcher = session.CreateUpdateSearcher();
searcher.Online = false;
// Find all updates that have not yet been installed
var result = searcher.Search("IsInstalled=0 And IsHidden=0");
foreach (dynamic update in result.Updates)
{
Console.WriteLine(update.Title + ": " + update.Description);
Console.WriteLine("Severity is " + update.MsrcSeverity);
Console.WriteLine();
}
Console.ReadLine();
}
}
}
Hope this helps someone!
Look for bundled updates in the list. The bundled updates does not have some properties or methods as described on this page.
Remarks
If the BundledUpdates property contains an IUpdateCollection, some
properties and methods of the update may only be available on the
bundled updates, for example, DownloadContents or CopyFromCache.
The update you are processing in is a bundled update. Extract the individual updates from this bundle, it will have the property you are looking out for.
The IUpdate interface has a method get_BundledUpdates which gets you a IUpdateCollection if the size of this collection is greater then 0, this is a bundled update.

How to get process description?

I want to get the description of a process (the description that is seen in task manager) in Windows using C++.
You most likely want to get the FileDesription field from the version resources of the main .exe file of the program, using the VerQueryValue() API call. Here is an example from that document:
The following example shows how to enumerate the available version languages and retrieve the FileDescription string-value for each language.
Be sure to call the GetFileVersionInfoSize and GetFileVersionInfo functions before calling VerQueryValue to properly initialize the pBlock buffer.
// Structure used to store enumerated languages and code pages.
HRESULT hr;
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
// Read the list of languages and code pages.
VerQueryValue(pBlock,
TEXT("\\VarFileInfo\\Translation"),
(LPVOID*)&lpTranslate,
&cbTranslate);
// Read the file description for each language and code page.
for( i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ )
{
hr = StringCchPrintf(SubBlock, 50,
TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
if (FAILED(hr))
{
// TODO: write error handler.
}
// Retrieve file description for language and code page "i".
VerQueryValue(pBlock,
SubBlock,
&lpBuffer,
&dwBytes);
}
Although I read this question, the accepted answer, and the documentation for VerQueryValue, I spent quite a while to understand how to use that VerQueryValue function (since the code example in the docs has no declarations of variables and isn't clear for me at all).
So I decided to put here the code that can be easily run as a working example of the usage of VerQueryValue to get a process description.
#pragma comment(lib,"Version.lib")
#include <iostream>
#include <windows.h>
#include <winver.h>
using namespace std;
int printFileDescriptions(const wchar_t* filename)
{
int versionInfoSize = GetFileVersionInfoSize(filename, NULL);
if (!versionInfoSize) {
return 0;
}
auto versionInfo = new BYTE[versionInfoSize];
std::unique_ptr<BYTE[]> versionInfo_automatic_cleanup(versionInfo);
if (!GetFileVersionInfo(filename, NULL, versionInfoSize, versionInfo)) {
return 0;
}
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *translationArray;
UINT translationArrayByteLength = 0;
if (!VerQueryValue(versionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayByteLength)) {
return 0;
}
// You may check GetSystemDefaultUILanguage() == translationArray[i].wLanguage
// if only the system language required
for (unsigned int i = 0; i < (translationArrayByteLength / sizeof(LANGANDCODEPAGE)); i++) {
wchar_t fileDescriptionKey[256];
wsprintf(
fileDescriptionKey,
L"\\StringFileInfo\\%04x%04x\\FileDescription",
translationArray[i].wLanguage,
translationArray[i].wCodePage
);
wchar_t* fileDescription = NULL;
UINT fileDescriptionSize;
if (VerQueryValue(versionInfo, fileDescriptionKey, (LPVOID*)&fileDescription, &fileDescriptionSize)) {
wcout << endl << fileDescription << endl;
}
}
return TRUE;
}
int main()
{
// Set locale of the console to print non-ASCII symbols
SetConsoleOutputCP(GetACP());
SetConsoleCP(GetACP());
wcout.imbue(std::locale("")); // set default global locale
// ----------------------------------------------------
auto path = L"C:\\Windows\\explorer.exe";
printFileDescriptions(path);
wcin.get(); // to prevent console close
}
It's supposed that all WinAPI functions on your system use wchar_t, that is VerQueryValueW is actually used.
The initial version of the code I took here Retrieve File Description an Application VerQueryValue