0

Currently, I am trying hard to get a safearray of variants to work in my c++ code below. As you can see I call QueueInputReport which has a signature of (SAFEARRAY * psainputreport, UNIT timeoutduration):

    CComSafeArray<VARIANT> savt;  
     //LONG j[5];
    LONG length = 4;
    //SafeArrayLock(psaValues);

        for(LONG i = 0; i <= length; ++i)
     {
        //j[i] = i;
     MessageBox(NULL,L"inputreport assigned to variable",NULL,NULL);

     //VariantInit(&pDescriptorData[i]);
        //pDescriptorData[i].vt = VT_UI1;
        //pDescriptorData[i].bVal = inputreport[i];
        //SafeArrayPutElement(psaValues,&i,&pDescriptorData[i]);
       //  VariantClear(&pDescriptorData[i]);

       savt.Add(CComVariant(inputreport[i]));  
    }

    //SafeArrayUnlock(psaValues);

MessageBox(NULL,L"data is successfully assigned to safearray",L"correct data format",NULL);
//FADF_STATIC+FADF_FIXEDSIZE+FADF_HAVEVARTYPE+FADF_VARIANT;
/* _TCHAR szBuffer2[100];
_stprintf_s(szBuffer2, _T("%i"),&psaValues->fFeatures);
MessageBox(NULL,L"safe array type",szBuffer2,NULL);*/

piSoftHidDevice1[devindex]->QueueInputReport(savt,8);
piSoftHidDevice1[devindex]->StartProcessing();
piSoftHidDevice1[devindex]->StopProcessing();

Edit: below is the code for queueinputreport which I needed to pass data to.

 STDMETHODIMP CHIDDevice::QueueInputReport( SAFEARRAY* psaInputReport, UINT timeoutDuration )
/*++
Routine Description: Queues additional input reports

Arguments:
IdleTimeout - used to set the value of the log level

Return value:
S_OK
--*/
{

VARIANT *  pArrayData  = NULL;
UINT               cbData      = 5;
LONG                lLBound     = 0;
LONG                lUBound     = 0;
HRESULT             hr          = S_OK;
HID_INPUT_REPORT    inputReport;
BOOLEAN             result      = TRUE;

// Initialize Structure
inputReport.timeout = timeoutDuration;
inputReport.cbInputReport = 0;
inputReport.pbInputReport = NULL;
    MessageBox(NULL,L"report initialized",L"initial report",NULL);
// Get SAFEARRAY size
IfFailHrGo(SafeArrayGetLBound(psaInputReport, 1, &lLBound));
IfFailHrGo(SafeArrayGetUBound(psaInputReport, 1, &lUBound));
IfFalseHrGo(lUBound > lLBound, E_UNEXPECTED);
cbData = lUBound - lLBound + 1;
//psaInputReport->fFeatures = 0x892;
//psaInputReport->fFeatures = 0x892;
inputReport.pbInputReport = (BYTE*)CoTaskMemAlloc( cbData * sizeof(BYTE) );
 _TCHAR szBuffer3[100];
_stprintf_s(szBuffer3, _T("%i"), &psaInputReport->fFeatures);
MessageBox(NULL,L"array content features",szBuffer3,NULL);
// If the memory Allocation fails, then fail and exit
if( inputReport.pbInputReport == NULL )
{
    hr = E_UNEXPECTED;
    goto Exit;
}
//void HUGEP** cast orginally
IfFailHrGo( SafeArrayAccessData( psaInputReport, 
                                 reinterpret_cast<void HUGEP**>(&pArrayData) ) );

// Step through the SAFEARRAY and populating only BYTE input report
// and bail out if the type is not correct
for( LONG i = 0; i <= lUBound; ++i )
{
    if (pArrayData[i].vt == VT_UI1)
    {

        inputReport.pbInputReport[i] = pArrayData[i].bVal;

    }
    else
    {
        hr = E_FAIL;
        goto Exit;
    }
}
  SafeArrayUnaccessData(psaInputReport);
inputReport.cbInputReport = cbData;
    //MessageBox(NULL,L"report being sent next",L"sent report",NULL);
// Add the report to the input queue (does a shallow copy so no need to free the array data)
result = m_InputReportQueue.insert( inputReport );

if (result == FALSE)
{
    MessageBox(NULL,L"failed to queue the input",NULL,NULL);
    hr = E_FAIL;
}
return hr;
Exit:
SafeArrayUnaccessData(psaInputReport);
if( FAILED(hr) )
{
    CoTaskMemFree(inputReport.pbInputReport);
}
return hr;
}

Edit: The problem is I need the fFeatures to equal 2194 and it is currently its a very high number. What could I be doing wrong?

In vbscript, I have some working code for the queueinputreport:

........(too numerous code to list here but it represents the device I am sending input to (i.e. device #1,#2,#3)) Here's some more information on the fFeatures Iam talking about: http://msdn.microsoft.com/en-us/library/cc237824.aspx

     Dim inputreport(5)
     inputreport(0) = CByte(0)
     inputreport(1) = CByte(100)
     inputreport(2) = CByte(100)
     inputreport(3) = CByte(0)
     inputreport(4) = Cbyte(0)
     pisofthiddevice1(i).QueueInputReport(inputreport, 8)

However, when I try replicating this in C++ above it does not work.

starman
  • 1
  • 4
  • You have three different spellings of what I presume is meant to be the same identifier: `ffeatures`, `fFeatures`, and `Ffeatures`. – Keith Thompson Feb 28 '14 at 00:32
  • Yes, I am using Device Simulation Framework and need to pass an input report to the queueinputreport function. It's so annoying because it works correctly as long as the Ffeatures of passed data is 2197 (FADF_FIXEDSIZE,FADF_STATIC,FADF_HAVEVARTYPE,and I think FADF_VARIANT). Also, in hex i think it would be 892. – starman Feb 28 '14 at 01:04
  • 1
    `2197` in hex is `0x895`. – Keith Thompson Feb 28 '14 at 01:06
  • My bad its 0x892 in hex and 2194 in decimal. I know I need a safe array of variants though with a VT_UI1 subtype. – starman Feb 28 '14 at 03:04
  • What's the significance of the number 2194? It sounds like this `ffeatures` thing may be a bitfield, so have you looked at its binary representation to see which unwanted bits are set? What do those bits signify (per the bitfield's documentation)? – Wyzard Feb 28 '14 at 22:08
  • Nothing, its some odd value like 4XXXXXXXXXX which is really high right now. I might have had a memory leak somewhere or improperly defined or used a variable somewhere because that seems too high. – starman Feb 28 '14 at 23:25
  • Here is what I am referring to by fFeatures above:http://msdn.microsoft.com/en-us/library/cc237824.aspx – starman Feb 28 '14 at 23:29
  • I think the closest I got was every bit field for Ffeatures set besides static. Note: I will be calling this c++ library from vb.net passing data. I have a fixed binary array passing data right now. – starman Feb 28 '14 at 23:34
  • Is it called `ffeatures` (as in your title), `fFeatures` (as in your code), or `Ffeatures` (as in the body of your question)? Those are three distinct identifiers. If they refer to the same thing, please update your question to make them consistent. It looks like this is specific to Windows; if so, please add the "windows" tag. You should probably also add the MSDN link to your question, since a lot of readers won't see it buried in the comments. I'd edit your question myself, but I'm not familiar enough with this stuff. – Keith Thompson Mar 01 '14 at 00:22
  • its fFeatures as mdsn docs says and yes its windows specific and a com/ATL based question mostly. – starman Mar 01 '14 at 03:05
  • I will add that on the unmanaged c++ function queueinputreport function with some changes I have the data correct yet the end result is that the function fails to work. It passes data to another function down in the chain which requires bytes so I know the safearray requires bytes somewhere in it. In addition, I will add that I pass an array of bytes from vb.net to the c++ function that the above code is in. It maybe that data is being passed wrong or I have my safearray in the incorrect format but that is the problem I cannot figure out. – starman Mar 19 '14 at 13:50
  • note: the queueinputreport function is written by Microsoft. I only added the messagebox's and maybe changed fFeatures a few times. – starman Mar 19 '14 at 14:02
  • `_stprintf_s(szBuffer3, _T("%i"), &psaInputReport->fFeatures)` does not do what you think. – Raymond Chen Mar 19 '14 at 14:18
  • Do you know if you could correct it Raymond or propose a solution? I was displaying the fFeatures in a message box. I used it to display safearray values too. – starman Mar 20 '14 at 16:44

0 Answers0