Re: DeviceIoControl getting error 50

Let?s keep this discussion on the mailing list, so others can benefit from the exchange.

On Feb 27, 2015, at 7:52 PM, Nelson Kon (Singapore) > wrote:

I did read the document. But it doesn’t mention how IWDFMemory is related to which DeviceIoControl parameter.

Sure it did. When you call GetInputMemory, you get a copy of the DeviceIoControl input buffer. When you call GetOutputMemory, you get a copy of the DeviceIoControl output buffer.

After I put my value to the USHORT buffer and to IWDFMemory in the driver, I thought I can retrieve it from

lpInBuffer
lpOutBuffer
lpBytesReturned

All 3 don’t contain my data which is put in the USHORT buffer in the driver.

Think about it If you are trying to send data back to the application, then you are sending OUTPUT. So, you need to call GetOutputMemory, and copy the data into it. You also need to call CompleteWithInformation to tell the I/O system how much data you are returning. The data you write will be copied to lpOutBuffer, and the size is returned in lpBytesReturned.
?
Tim Roberts, xxxxx@probo.commailto:xxxxx
Providenza & Boekelheide, Inc.</mailto:xxxxx>

Nelson Kon (Singapore) wrote:

Do you mean this way?

Look at your code without the error handling:

if (ControlCode== IOCTL_BUTTON_RD_PS) {

pRequest->GetOutputMemory(&outputMemory);

hr = outputMemory->CopyFromBuffer(0,
(void*)&prox_val, sizeof(prox_val));

prox_val = 100;

You are copying your data to the memory region BEFORE you put anything
into the buffer! Of course it didn’t work. In addition, as I told you,
you have to TELL the I/O system how much data you are returning.
Remember that your buffers here are COPIES of the original application
buffers. The I/O system has to copy your output back to the
application, but it will only copy as many bytes as it needs to. So:

pRequest->GetOutputMemory(&outputMemory);
prox_val = 100;
hr = outputMemory->CopyFromBuffer(0, (void*)&prox_val, sizeof(prox_val);
pRequest->CompleteWithInformation(STATUS_SUCCESS, sizeof(prox_val));

or, if you already have a generic Complete call that completes the request:
pRequest->SetInformation(sizeof(prox_val));

In the application side I wrote like this

DeviceIoControl(hDevice,

IOCTL_BUTTON_RD_PS,

hardware, bytes,

&value1, sizeof(value1),

&bytes, NULL));

LPVOIDdispStr;

LPTSTRdispBuffer = TEXT("Value = ");

dispStr = (LPVOID)LocalAlloc(LMEM_ZEROINIT,

(lstrlen((LPCTSTR)dispBuffer) + 40)
* sizeof(TCHAR));

StringCchPrintf((LPTSTR)dispStr,

LocalSize(dispStr) / sizeof(TCHAR),

TEXT(“%s%d”),

dispBuffer, value1);

SetWindowText(txtBox_display_reading,
(LPCTSTR)dispStr);

Those last 10 lines would be a lot simpler as:
CString disp;
disp.Format( “Value = %d”, value1 );
SetWindowText(txtBox_display_reading, disp);


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.