Confirmation

Hi,

Can I confirm this is correct?

Inside a Callback:

NtStatus = WdfIoQueueGetState(gWdfQueue, &QueueCount, NULL);

if(QueueCount > 1)
{
NtStatus = WdfIoQueueRetrieveNextRequest(gWdfQueue, &WdfRequest);

// I need more than one entry.

if(!NT_SUCCESS(NtStatus))
{
goto done;
}

NtStatus = WdfRequestRetrieveOutputMemory(WdfRequest, &WdfMemory);
if(!NT_SUCCESS(NtStatus))
{
goto done;
}

{
ULONG sOutputWdfMemoryLength;
ULONG data;

data = 0x00003A4B; // As Example.
DbgPrint(“data = 0x%08X.\n”, data);
NtStatus = WdfMemoryCopyFromWdfMemory(WdfMemory, 0, (PVOID) &data, sizeof(ULONG));

if (!NT_SUCCESS(NtStatus))
{
goto done;
}

WdfRequestSetInformation(WdfRequest, sizeof(ULONG));
WdfRequestComplete(WdfRequest, STATUS_SUCCESS);
}

Inside a EvtIoRawPdoDeviceControl

switch(uIoControlCode)
{
case IOCTL_CONTROL_CODE:
{
NtStatus = WdfIoQueueGetState(gWdfQueue, &QueueCount, NULL);
if(WDF_IO_QUEUE_STOPPED(NtStatus))
{
WdfIoQueueStart(gWdfQueue);
}

NtStatus = WdfRequestForwardToIoQueue(WdfRequest, gWdfQueue);

if(!NT_SUCCESS(NtStatus))
{
WdfRequestComplete(WdfRequest, NtStatus);
}

return;
}
}

Inside DeviceAdd.

WDF_IO_QUEUE_CONFIG_INIT(&WdfIoQueueConfig, WdfIoQueueDispatchManual);

NtStatus = WdfIoQueueCreate(WdfDevice, &WdfIoQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &gWdfQueue);

“Is this correct” is a bit of a silly question…

You don’t tell us what you want this to DO, so it’s hard to tell if it’s “correct”…

And MY main question would be: Does it WORK for you? Why not just RUN it, and single-step through it?

Is this real code that you’ve compiled? I’d guess not:

… as I don’t think there’s any such DDI as WdfMemoryCopyFromWdfMemory.

Help us help you… ask a SPECIFIC question, supplying all the necessary details, and we can give you a real answer.

Peter
OSR

Hi,

It was a reply to a previous post, Doron suggested that I used the debug to check the queue. The ioqueues are there. He also suggested a manual queue.

The situation is: I run a driver with a ManualQueue, a usermode application sends a custom IOCTL to the driver and if no data is present forwards it to a queue, when a callback is given in the driver the request is completed and data is returned to the usermode application.

However, the usermode application says that multiple data is being returned, for example the first sizeof(ULONG) is the correct data. The next two are invalid, seemingly random, so I believe I am reading the wrong piece of memory. Again the fourth is correct and so is the seventh. After n number of IOCTL requests, all IOCTL’s are dropped and I have a GetLastError() of 998. The application quits. The code is correct however I mistakingly ran ‘replace’ on Buffer which turned the function to another name. This is actual code. Inside the driver it is perfectly correct displaying all the correct information, however the usermode application is being sent the wrong code before I deduce that the error is in the program I just wanted to make sure my code is absolutely correct and I am completing it correctly before I begin debugging. Hence the check.

The second and only reason I want to know whether it is the driver is every other IOCTL works with success. So I am left wondering if it is the driver or usermode application.


Hi,

Can I confirm this is correct?

Inside a Callback:

NtStatus = WdfIoQueueGetState(gWdfQueue, &QueueCount, NULL);

if(QueueCount > 1)
{
NtStatus = WdfIoQueueRetrieveNextRequest(gWdfQueue, &WdfRequest);

// I need more than one entry.

if(!NT_SUCCESS(NtStatus))
{
goto done;
}

NtStatus = WdfRequestRetrieveOutputMemory(WdfRequest, &WdfMemory);
if(!NT_SUCCESS(NtStatus))
{
goto done;
}

{
ULONG sOutputWdfMemoryLength;
ULONG data;

data = 0x00003A4B; // As Example.
DbgPrint(“data = 0x%08X.\n”, data);
NtStatus = WdfMemoryCopyFromWdfMemory(WdfMemory, 0, (PVOID) &data,
sizeof(ULONG));

if (!NT_SUCCESS(NtStatus))
{
goto done;
}

WdfRequestSetInformation(WdfRequest, sizeof(ULONG));
WdfRequestComplete(WdfRequest, STATUS_SUCCESS);
}

Inside a EvtIoRawPdoDeviceControl

switch(uIoControlCode)
{
case IOCTL_CONTROL_CODE:
{
NtStatus = WdfIoQueueGetState(gWdfQueue, &QueueCount, NULL);
if(WDF_IO_QUEUE_STOPPED(NtStatus))
{
WdfIoQueueStart(gWdfQueue);
}

NtStatus = WdfRequestForwardToIoQueue(WdfRequest, gWdfQueue);

if(!NT_SUCCESS(NtStatus))
{
WdfRequestComplete(WdfRequest, NtStatus);
}

return;
}
}

Inside DeviceAdd.

WDF_IO_QUEUE_CONFIG_INIT(&WdfIoQueueConfig, WdfIoQueueDispatchManual);

NtStatus = WdfIoQueueCreate(WdfDevice, &WdfIoQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES, &gWdfQueue);

“Is this correct” is a bit of a silly question…

You don’t tell us what you want this to DO, so it’s hard to tell if it’s
“correct”…

And MY main question would be: Does it WORK for you? Why not just RUN it, and
single-step through it?

Is this real code that you’ve compiled? I’d guess not:

… as I don’t think there’s any such DDI as WdfMemoryCopyFromWdfMemory.

Help us help you… ask a SPECIFIC question, supplying all the necessary
details, and we can give you a real answer.

Peter
OSR

OK. So, I admit it: I didn’t understand a word of that reply.

Best of luck with your driver. Sorry I can’t be more helpful,

Peter
OSR

xxxxx@hotmail.com wrote:

Can I confirm this is correct?

Inside a Callback:

NtStatus = WdfIoQueueGetState(gWdfQueue, &QueueCount, NULL);

if(QueueCount > 1)
{
NtStatus = WdfIoQueueRetrieveNextRequest(gWdfQueue, &WdfRequest);

You go to a lot of extra trouble in this code. Why check the count at
all? Why just just try to retrieve a request, and bail out if it
fails? No need to do in two steps what can be accomplished in one step.

NtStatus = WdfRequestRetrieveOutputMemory(WdfRequest, &WdfMemory);
if(!NT_SUCCESS(NtStatus))
{
goto done;
}

{
ULONG sOutputWdfMemoryLength;
ULONG data;

data = 0x00003A4B; // As Example.
DbgPrint(“data = 0x%08X.\n”, data);
NtStatus = WdfMemoryCopyFromWdfMemory(WdfMemory, 0, (PVOID) &data, sizeof(ULONG));

Again, you are using two APIs to do something that can be done in one
call. Why fetch the WDFMEMORY and use an API to call it? Why not just
fetch the buffer and copy into it directly?

PULONG pul;
WdfRequestRetrieveOutputBuffer( WdfRequest, sizeof(ULONG),
(PULONG)&pul, NULL );
*pul = 0x00003A4B;

WdfRequestSetInformation(WdfRequest, sizeof(ULONG));
WdfRequestComplete(WdfRequest, STATUS_SUCCESS);

Again, two calls where one would do. Are you not aware of
WdfRequestCompleteWithInformation?


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

WdfRequestCompleteWithInformation, I did but only after I wrote the two other subroutines. In either case the result is exactly the same and while I can improve the code at a later date I am just trying to fix a problem - I unfortuately need at least one IOCTL for another operation which is why I need to check to make sure there is at least one.

Since you don’t seem to think there is a problem with the code I will being debugging the UMDF because there is a problem somewhere.


xxxxx@hotmail.com wrote:

Can I confirm this is correct?

Inside a Callback:

NtStatus = WdfIoQueueGetState(gWdfQueue, &QueueCount, NULL);

if(QueueCount > 1)
{
NtStatus = WdfIoQueueRetrieveNextRequest(gWdfQueue, &WdfRequest);

You go to a lot of extra trouble in this code. Why check the count at
all? Why just just try to retrieve a request, and bail out if it
fails? No need to do in two steps what can be accomplished in one step.

NtStatus = WdfRequestRetrieveOutputMemory(WdfRequest, &WdfMemory);
if(!NT_SUCCESS(NtStatus))
{
goto done;
}

{
ULONG sOutputWdfMemoryLength;
ULONG data;

<…excess quoted lines suppressed…>

Again, you are using two APIs to do something that can be done in one
call. Why fetch the WDFMEMORY and use an API to call it? Why not just
fetch the buffer and copy into it directly?

PULONG pul;
WdfRequestRetrieveOutputBuffer( WdfRequest, sizeof(ULONG),
(PULONG)&pul, NULL );
*pul = 0x00003A4B;

WdfRequestSetInformation(WdfRequest, sizeof(ULONG));
WdfRequestComplete(WdfRequest, STATUS_SUCCESS);

Again, two calls where one would do. Are you not aware of
WdfRequestCompleteWithInformation?


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