How Do I Read Raw Input in C++/CLI - c++

Here's my problem.
I am trying to get raw input from attached devices. I am using the information on MSDN to figure it out, but it's been very difficult for me to make sense of some of it.
I believe I have successfully created a RAWINPUTDEVICE object and registered a device with RegisterRawInputDevices(). Now I am trying to figure out how to use the GetRawInputDeviceList() and GetRawInputDeviceInfo() functions. The big trouble is trying to understand the parameters they take, which includes a RAWINPUTDEVICELIST object, a HANDLE, a LPVOID, and a PUINT.
What are those variables and how do I use them?
Here's what I've gotten to work:
Important stuff in the header file:
#include <Windows.h>
#include <Winuser.h>
Important thing in the CPP file:
// I do not know where I found this not what it does, but it fixed some errors
// that I could not solve. MSDN did not mention it.
#pragma comment(lib, "user32.lib")
And the stuff that works, and the thing that does not:
RAWINPUTDEVICE rid[1];
rid[0].usUsagePage = 1;
rid[0].usUsage = 6;
rid[0].dwFlags = 0;
rid[0].hwndTarget = NULL;
// awesomeSauce returned true, so it works
bool awesomeSauce = RegisterRawInputDevices(rid, 1, sizeof(RAWINPUTDEVICE) );
// Nothing past this point works
UINT numDevices = GetRawInputDeviceList(NULL, NULL, sizeof(RAWINPUTDEVICELIST));
How do continue?
I am a little bit rusty at C++, and what you see here is pretty much the sum of my knowledge with raw input. I do not know if it will effect anything, but I am using C++/CLI, not regular C++. How do I go from this, to getting some kind of unbuffered raw input (preferably from the keyboard)?
Edit:
Most examples I find have a switch statement. I don't understand how it works though. I have something like this:
UINT msg; // How does this work?
switch(msg)
{
case WM_CREATE:
executeCase = 1;
break;
case WM_INPUT:
executeCase = 2;
break;
}
How does the msg variable work? How can I create and assign one correctly?

According to the MSDN page for GetRawInputDeviceList, here's the documentation for the first parameter (which you're passing as null):
An array of RAWINPUTDEVICELIST structures for the devices attached to the system. If NULL, the number of devices are returned in *puiNumDevices.
And here's the documentation for the return value:
If the function is successful, the return value is the number of devices stored in the buffer pointed to by pRawInputDeviceList.
You're passing null for the first parameter, and expecting the number of devices to be present in the return from the method. The documentation doesn't say it will do that.
Pass an actual variable for the second parameter, and read that instead of the return code.
If that doesn't solve your problem, please be more specific with "this is the thing that doesn't work". Tell us how it doesn't work: does it throw an exception, is there an error return code, does a black hole open up and swallow your computer whole?
Edit
In your comment, you're still storing the return value in numDevices. Also, you're using the second parameter as an array. An array of length 1 is basically the same thing, but it'd be better to think of it as a pointer to an integer.
Here's a copy of the sample code from the MSDN page, with my comments added in. Give this a try.
UINT nDevices;
PRAWINPUTDEVICELIST pRawInputDeviceList;
// Pass a null pointer to find out how many devices there are.
if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVCELIST)) != 0) { Error();}
// Now, malloc the needed storage, based on the output parameter, NOT the return value.
if ((pRawInputDeviceList = malloc(sizeof(RAWINPUTDEVICELIST) * nDevices)) == NULL) {Error();}
// Finally, call for real, passing in the newly allocated buffer.
if (GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST)) == (-1) {Error();}
// after the job, free the RAWINPUTDEVICELIST
free(pRawInputDeviceList);

Related

BluetoothGATTSetCharacteristicValue returns E_INVALIDARG or ERROR_INVALID_FUNCTION

I have build a set C++ containing classes on top of the BluetoothAPIs apis.
I can enumerate open handles to services, characteristics and descriptors. I can read characteristic values. The issue that I have is that I cannot write to a characteristic value.
Below is the code use to write the characteristic value
void BleGattCharacteristic::setValue(UCHAR * data, ULONG size){
if (pGattCharacteristic->IsSignedWritable || pGattCharacteristic->IsWritable || pGattCharacteristic->IsWritableWithoutResponse)
{
size_t required_size = sizeof(BTH_LE_GATT_CHARACTERISTIC_VALUE) + size;
PBTH_LE_GATT_CHARACTERISTIC_VALUE gatt_value = (PBTH_LE_GATT_CHARACTERISTIC_VALUE)malloc(required_size);
ZeroMemory(gatt_value, required_size);
gatt_value->DataSize = (ULONG)size;
memcpy(gatt_value->Data, data, size);
HRESULT hr = BluetoothGATTSetCharacteristicValue(bleDeviceContext.getBleServiceHandle(), pGattCharacteristic, gatt_value, NULL, BLUETOOTH_GATT_FLAG_NONE);
free(gatt_value);
if (HRESULT_FROM_WIN32(S_OK) != hr)
{
stringstream msg;
msg << "Unable to write the characeristic value. Reason: ["
<< Util.getLastError(hr) << "]";
throw BleException(msg.str());
}
}
else
{
throw BleException("characteristic is not writable");
}}
The call to bleDeviceContext.getBleServiceHandle() returns the open handle to the device info service.
pGattCharacteristics is the pointer to the characteristic to write too. It was opened with a call to BluetoothGATTGetCharacteristics.
I have tried different combinations of the flags with no difference in the return code.
I have also tried using the handle to the device not to the service. In that case I get an ERROR_INVALID_FUNCTION return error code.
I would appreciate any pointers as to what I am doing wrong or what other possible options I could try.
1- You have to use the Service Handle, right.
2- I don't know how you designed your class, and then how you allocate some memory for the Characteristic's Value itself.
What I do (to be sure to have enough and proper memory for Value's data):
a) at init of the Value object, call ::BluetoothGATTGetCharacteristicValue twice, to get the needed size and then actually allocate some internal memory for it.
b) when using it, set the inner memory to what it may , then call ::BluetoothGATTSetCharacteristicValue
hr=::BluetoothGATTSetCharacteristicValue(
handle,
(PBTH_LE_GATT_CHARACTERISTIC)Characteristic,
value,//actually a (PBTH_LE_GATT_CHARACTERISTIC_VALUE) to allocated memory
0,//BTH_LE_GATT_RELIABLE_WRITE_CONTEXT ReliableWriteContext,
BLUETOOTH_GATT_FLAG_NONE)
So a few things:
typedef struct _BTH_LE_GATT_CHARACTERISTIC_VALUE {
ULONG DataSize;
UCHAR Data[];
} BTH_LE_GATT_CHARACTERISTIC_VALUE, *PBTH_LE_GATT_CHARACTERISTIC_VALUE;
is how the data structure used in the parameter CharacteristicValue is defined. Please note that Data is NOT an allocated array, but rather a pointer. So accessing Data[0] is undefined behavior and could be accessing anywhere in memory. Rather you need to do gatt_value.Data = &data; setting the pointer to the address of the input parameter.
Secondly the documentation is quite clear as to why you might get ERROR_INVALID_FUNCTION; if another reliable write is already pending then this write will fail. You should consider retry logic in that case.
As for E_INVALIDARG I'd assume it's related to the undefined behavior but I'd check after fixing the other issues previously mentioned.

NVIDIA Unhandled exception at 0x002a2da2 in <work.exe>0xC0000005: Access violation reading location 0x00000000

I am currently trying to make two arms on a character and use NxRevoluteJoint for their movement. I have these working perfectly in another program that has been given as an example and I have used the same code in this new project however I am getting an error (the one in the title) and I am struggling how to fix it. I understand that the pointers is reference to NULL at some place but I can't see how to sort it out.
The variables are set globally:
NxRevoluteJoint* playerLeftJoint= 0;
NxRevoluteJoint* playerRightJoint= 0;
This is the code in the seperate function where the player is being built as a compound object:
NxVec3 globalAnchor(0,1,0);
NxVec3 globalAxis(0,0,1);
playerLeftJoint= CreateRevoluteJoint(0,actor2,globalAnchor,globalAxis);
playerRightJoint= CreateRevoluteJoint(0,actor2,globalAnchor,globalAxis);
//set joint limits
NxJointLimitPairDesc limit1;
limit1.low.value = -0.3f;
limit1.high.value = 0.0f;
playerLeftJoint->setLimits(limit1);
NxJointLimitPairDesc limit2;
limit2.low.value = 0.0f;
limit2.high.value = 0.3f;
playerRightJoint->setLimits(limit2);
NxMotorDesc motorDesc1;
motorDesc1.velTarget = 0.15;
motorDesc1.maxForce = 1000;
motorDesc1.freeSpin = true;
playerLeftJoint->setMotor(motorDesc1);
NxMotorDesc motorDesc2;
motorDesc2.velTarget = -0.15;
motorDesc2.maxForce = 1000;
motorDesc2.freeSpin = true;
playerRightJoint->setMotor(motorDesc2);
The line where I am getting the error is at the playerLeftJoint->setLimits(limit1);
CreateRevoluteJoint is returning a null pointer, simple as that. The error message makes it very clear that the pointer has a value of 0. Of course, you didn't post that function, so that's the best information I can give you. As such, this line;
playerLeftJoint->setLimits(limit1);
dereferences the pointer playerLeftJoint, which is an invalid pointer. You need to initialize your pointers. I can't see your entire program structure, so in this case the most simple fix would be something like;
if(!playerLeftJoint)
playerLeftJoint = new NxRevoluteJoint();
// same for the other pointer, now they are valid
Additionally, as this is C++ and not C, use a smart pointer to handle memory for you, i.e.,
#include <memory>
std::unique_ptr<NxRevoluteJoint> playerLeftJoint;
// or, if you have a custom deallocater...
std::unique_ptr<NxRevoluteJoint, RevoluteJointDeleter> playerLeftJoint;
// ...
playerLeftJoint.reset(new NxRevoluteJoint(...));

ATL C++ memory leak with safearray of ccomobjects

I find myself in need of help. Now, I'm not all that unfamiliar with C++, but combining it with ATL provides a whole new level of confusion. Anyways, my problem: I (finally) managed to return an array of objects in my COM method to C# caller. But upon 'testing' (running said function a number of times repeatedly) I recognized a small memory leak.
IDL excerpt:
...
interface IDISControl : IDispatch{
...
[id(12)] HRESULT GetNets([out,retval] VARIANT* nets);
};
Header excerpt:
...
STDMETHOD(GetNets)(VARIANT* nets);
...
Code:
STDMETHODIMP CDISControl::GetNets(VARIANT* nets)
{
SNet *netz;
int32_t num;
int result, i;
result = DIS_GetNetNum(securityHandle, &num);
netz = new SNet[num];
result = DIS_GetNet(securityHandle, netz, num); //getting some data
CComSafeArray<IDispatch*> netArray;
CComObject<CDISNet> *net;
CComVariant *var;
netArray.Create(num, 0);
for (i = 0;i<num;i++){
CComObject<CDISNet>::CreateInstance(&net);
if (net == NULL)
return S_FALSE;
net->AddRef();
net->Convert(netz[i]);
netArray[i] = net;
net->Release();
net = NULL;
}
CComVariant val(netArray.Detach());
val.Detach(nets);
delete [] netz;
netArray.Destroy();
return S_OK;
}
I instantiate CDISNet objects and put some data in them (Convert()). I put them in my safearray and release. As I understand it, the responsibility for destroying them is transferred to safearray. Afterwards, I box the array in a VARIANT so I can fill my [out, retval] parameter. Since it's an out parameter, the responsibility for destruction should be transferred to caller (in my case C#, i.e. its GarbageCollector). I dispose of my dynamic array 'netz' and I destroy safearray wrapper.
So what am I missing? What is left allocated? (This project is really making me appreciate all the comforts of .net).
Help. Please.
EDIT: Further debugging revealed to me that the problem is certainely in my CComObject objects. They aren't being deallocated. If I delete net; in each iteration the array also looses data. I'm unsure as how to rectify that...
EDIT2:
Ok, I poked around this code for a bit, and the leak seems to go away when I comment out variant boxing. The problem is that I borrowed this piece of code from Visual Studio sample on safearrays. So, does anyone have any idea what's up with:
CComVariant val(netArray.Detach());
val.Detach(nets);
...and what to do about it?
Most, if not all, of ATL's wrappers follow COM conventions -- they copy/addref incoming data, as their destructor will destroy/release.
So when you pass your detached SAFEARRAY to CComVariant's constructor, it will make a copy of the SAFEARRAY, which means nobody releases the result from CComSafeArray::Detach.
In cases like this, I always found it easier to forego the wrapper for the return value entirely;
nets->vt = VT_ARRAY | VT_DISPATCH;
nets->parray = netArray.Detach();
The alternative would be to pass your CComSafeArray directly to CComVariant's constructor, without calling Detach, but that would cost you an extra copy. I'd prefer the raw access presented above, as it is most straightforward and cheapest.
As to your first edit, what you're doing with AddRef/Release is fine, if somewhat unnecessary. CComObject::CreateInstance returns an object with reference count 0, so the AddRef will bring it to 1, and then assigning it to the CComSafeArray will bump it to 2, and the following Release back down to 1.
Unless the Convert method does anything with the object's reference count (e.g. QueryInterface itself or pass itself to another COM method), you could skip the AddRef/Release pair, and let Convert execute with refcount == 0. Then adding it to the array would increase it, and it would stay alive until released.

Querying extensions on X509 certificates using OpenSSL

I am working with the OpenSSL library's X509 certificate class, and I need to query the "key usage" extension.
After abandoning OpenSSL's vapourware "documentation", some shot-in-the-dark web searching eventually revealed that I needed to call
X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
and searching through the objects.h header revealed the proper NID.
Problem is, this call returns a pointer to void, which apparently can point to a variety of structs depending upon what extension one has asked for.
Since none of these appear to be documented, one is left without a way to figure out how to parse what the function returns.
Can anyone point me to a document that actually talks about this, instead of just listing things I can find out for myself (the function profile, which file it comes from, etc)?
The easiest solutions to read the key usage seems to be
X509* x509_cert = ...
// without X509_check_ca x509_cert->ex_kusage always returns 0 (no idea why)
int ca = X509_check_ca(x509_cert);
unsigned long usage = x509_cert->ex_kusage;
The resulting values are defined in opensc/pkcs15-init.h
SC_PKCS15INIT_X509_DIGITAL_SIGNATURE 0x0080UL
SC_PKCS15INIT_X509_NON_REPUDIATION 0x0040UL
SC_PKCS15INIT_X509_KEY_ENCIPHERMENT 0x0020UL
SC_PKCS15INIT_X509_DATA_ENCIPHERMENT 0x0010UL
SC_PKCS15INIT_X509_KEY_AGREEMENT 0x0008UL
SC_PKCS15INIT_X509_KEY_CERT_SIGN 0x0004UL
SC_PKCS15INIT_X509_CRL_SIGN 0x0002UL
I came to that soultion by finding the following code of an openssl source file
/* Handle key usage */
if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
if(usage->length > 0) {
x->ex_kusage = usage->data[0];
if(usage->length > 1)
x->ex_kusage |= usage->data[1] << 8;
} else x->ex_kusage = 0;
x->ex_flags |= EXFLAG_KUSAGE;
ASN1_BIT_STRING_free(usage);
}
The second parameter (nid) determines the returned type.
Looking at this code:
http://opengrok.creo.hu/dragonfly/xref/src/crypto/openssl-0.9/crypto/x509v3/v3_purp.c#X509_check_purpose
It appears that for the key usage NID, it returns a ASN1_BIT_STRING. (line 361).

Passing an array using COM?

I am a COM object written in ATL that is used from a C++ application, and I want to pass an array of BYTEs between the two. My experience of COM/IDL so far is limited to passing simple types (BSTRs, LONGs, etc.).
Is there a relatively easy way to have the COM object pass an array to the caller? For example, I want to pass a raw image (TIFF) instead of messing with temporary files.
Try passing a safearray variant to the COM Object. Something like this to put a BYTE array inside a safearray variant....
bool ArrayToVariant(CArray<BYTE, BYTE>& array, VARIANT& vtResult)
{
SAFEARRAY FAR* psarray;
SAFEARRAYBOUND sabounds[1];
sabounds[0].lLbound=0;
sabounds[0].cElements = (ULONG)array.GetSize();
long nLbound;
psarray = SafeArrayCreate(VT_UI1, 1, sabounds);
if(psarray == NULL)
return false;
for(nLbound = 0; nLbound < (long)sabounds[0].cElements ; nLbound++){
if(FAILED(SafeArrayPutElement(psarray, &nLbound, &array[nLbound]))){
SafeArrayDestroy(psarray);
return false;
}
}
VariantFree(vtResult);
vtResult.vt = VT_ARRAY|VT_UI1;
vtResult.parray = psarray;
return true;
}
SAFEARRAYs are the way to go if you want OLE-Automation compliance, and maybe use the COM interface from other languages such as VB6. But there is an alternative in IDL, for example: -
void Fx([in] long cItems, [in, size_is(cItems)] BYTE aItems[]);
This describes a method where the marshalling code can infer the number of bytes to be transfered by inspecting the value of the first parameter.
This is fine if your clients are all written in C/C++, but i think that an interface containing this would not be automation-compliant, so not usable from VB6, and possibly the standard marshaler will not be able to do the marshaling, so you'd need to generate your own proxy/stub DLL from the IDL. Not hard to do, but a bit harder than using SAFEARRAYs.
Check out using safearrays. Here's some example code:
The safearray is returned as a pointer to a VARIANT
[id(1), helpstring("LogCache")] HRESULT LogCache([out,retval] VARIANT* logCache);
Safearrays are pretty easy to use. Here's some example code which is a cache of the latest 1000 log messages of some application:
safearray_t<bstr_t> m_logCache;
...
if (m_logCache.size() > 1000)
{
m_logCache.pop_back();
}
m_logCache.push_front(Msg.str(), 0);
variant_t LogCache()
{
if (!m_logCache.is_empty())
{
variant_t cache(m_logCache);
return cache;
}
}
Note that the syntax in your case is almost certainly going to be different since I'm using the comet COM library, but the ideas/concepts are the same.
You can use BSTR to pass an array of bytes.
BYTE array[buffer_size];
...
BSTR toBePassed = SysAllocStringByteLen((OLECHAR*)array,length);
YourCOMMethod(toBePassed);
SysFreeString(toBePassed);
In your method:
BYTE* pData = (BYTE*)bstrPassed;
DWORD dataLength = SysStringByteLen(bstrPassed);