ExAllocatePoolWithTag Problem

Hello,
I am trying to investigate a special function of a USB device. For that I use the following KMDF1.0 code (winXP SP3):

outBuffer = ExAllocatePoolWithTag(NonPagedPool,((length-8) * sizeof(BYTE)), pooltag);
status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES,
outBuffer,
((length-8) * sizeof(BYTE)),
&outMemory);
outChar = WdfMemoryGetBuffer(outMemory, &lengthOut);

//here I generate some code which is then put into ?outChar?

//here I manually generate a controlPacket using controlPacket.Generic.Bytes[0] etc.

WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptorOut, outBuffer, NULL);

status = WdfUsbTargetDeviceSendControlTransferSynchronously(
devCtx->UsbDevice,
NULL,
NULL,
&controlPacket,
&memDescriptorOut,
NULL);

ExFreePoolWithInformation(outBuffer, pooltag);

Unfortunately the function ?WdfUsbTargetDeviceSendControlTransferSynchronously? produces a BSOD. !Analyze ?v says:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced
memory at “0x%08lx”. The memory could not be “%s”.

In that case I am at beginner- level, which means that I don?t know how to correctly allocate memory which I could then use to send a control transfer. If I use input buffer, which was allocated using WdfRequestRetrieveInputMemory, than it works fine ? so the USB hardware is not causing this error.

I would be very happy if someone could tell me, how I have to rewrite my code to send data from allocated memory without causing a BSOD.

Best Regards,
Matthias

Post the output of !analyze -v

Make sure your symbols are set properly

d

Bent from my phone


From: xxxxx@alumni.tu-berlin.demailto:xxxxx
Sent: ?4/?7/?2013 7:48 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: [ntdev] ExAllocatePoolWithTag Problem

Hello,
I am trying to investigate a special function of a USB device. For that I use the following KMDF1.0 code (winXP SP3):

outBuffer = ExAllocatePoolWithTag(NonPagedPool,((length-8) * sizeof(BYTE)), pooltag);
status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES,
outBuffer,
((length-8) * sizeof(BYTE)),
&outMemory);
outChar = WdfMemoryGetBuffer(outMemory, &lengthOut);

//here I generate some code which is then put into ?outChar?

//here I manually generate a controlPacket using controlPacket.Generic.Bytes[0] etc.

WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptorOut, outBuffer, NULL);

status = WdfUsbTargetDeviceSendControlTransferSynchronously(
devCtx->UsbDevice,
NULL,
NULL,
&controlPacket,
&memDescriptorOut,
NULL);

ExFreePoolWithInformation(outBuffer, pooltag);

Unfortunately the function ?WdfUsbTargetDeviceSendControlTransferSynchronously? produces a BSOD. !Analyze ?v says:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced
memory at “0x%08lx”. The memory could not be “%s”.

In that case I am at beginner- level, which means that I don?t know how to correctly allocate memory which I could then use to send a control transfer. If I use input buffer, which was allocated using WdfRequestRetrieveInputMemory, than it works fine ? so the USB hardware is not causing this error.

I would be very happy if someone could tell me, how I have to rewrite my code to send data from allocated memory without causing a BSOD.

Best Regards,
Matthias


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

Hello Doran,
thank you for your reply - here is the whole output that !analyze ?v has generated:

Windows XP Kernel Version 2600 (Service Pack 3) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp3_gdr.080814-1236
Machine Name:
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055b1c0
Debug session time: xxxxxxxxxxxxxxxxxxxxxxx
System Uptime: 0 days 0:05:22.343
**********************************************
* Bugcheck Analysis *
**********************************************
KERNEL_MODE_EXCEPTION_NOT_HANDLED_M (1000008e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but ...
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: f7eae213, The address that the exception occurred at
Arg3: f1b3e874, Trap Frame
Arg4: 00000000

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".

FAULTING_IP:
Wdf01000+1e213
f7eae213 66395f04 cmp word ptr [edi+4],bx

TRAP_FRAME: f1b3e874 -- (.trap 0xfffffffff1b3e874)
ErrCode = 00000000
eax=7ded7210
ebx=f1b3100a
ecx=00000000
edx=00000000
esi=f1b3e930
edi=7ded7210
eip=f7eae213
esp=f1b3e8e8
ebp=f1b3e8fc
iopl=0
nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
Wdf01000+0x1e213:
f7eae213 66395f04 cmp word ptr [edi+4],bx ds:0023:7ded7214=????

Resetting default scope

DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0x8E
PROCESS_NAME: USB_test1.exe
LAST_CONTROL_TRANSFER: from f7eed9b8 to f7eae213
STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
f1b3e8fc f7eed9b8 82165008 82128de8 0000100a Wdf01000+0x1e213
f1b3e924 f7ea06e0 82165008 00000000 00000003 Wdf01000+0x5d9b8
f1b3eab0 f88966e9 00000000 f88966e9 821650c8 Wdf01000+0x106e0
f1b3eadc f8898007 7dfc1fe8 00000000 00000000 wdf_usb+0x6e9
f1b3eb48 f8897bf4 7dea96b8 7decb560 00000000 wdf_usb+0x2007
f1b3eb68 f7ecb7e3 7dea96b8 7decb560 00000000 wdf_usb+0x1bf4
f1b3eb8c f7ecca23 7dea96b8 7decb560 00000000 Wdf01000+0x3b7e3
f1b3ebc4 f7ece6ba 82134a98 82134a98 82156940 Wdf01000+0x3ca23
f1b3ebe4 f7ecf9af 82156900 81f10548 82156940 Wdf01000+0x3e6ba
f1b3ec00 f7ed1a37 00000000 81f81588 8201bc80 Wdf01000+0x3f9af
f1b3ec28 f7ec0df7 82134a98 f1b3ec58 804e37f7 Wdf01000+0x41a37
f1b3ec34 804e37f7 821ac858 8221dc00 806f12d0 Wdf01000+0x30df7
f1b3ec44 80567f81 8221dcb8 81f81588 8221dc00 nt!IopfCallDriver+0x31
f1b3ec58 8057aa9f 821ac858 8221dc00 81f81588 nt!IopSynchronousServiceTail+0x70
f1b3ed00 8058efe3 000001ac 00000000 00000000 nt!IopXxxControlFile+0x611
f1b3ed34 804de7ec 000001ac 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
f1b3ed34 7c91e4f4 000001ac 00000000 00000000 nt!KiFastCallEntry+0xf8
0012ef48 00000000 00000000 00000000 00000000 0x7c91e4f4

STACK_COMMAND: kb

FOLLOWUP_IP:
wdf_usb+6e9
f88966e9 ?? ???

SYMBOL_STACK_INDEX: 3

SYMBOL_NAME: wdf_usb+6e9

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: wdf_usb

IMAGE_NAME: wdf_usb.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 50f6b5d3

FAILURE_BUCKET_ID: 0x8E_wdf_usb+6e9

BUCKET_ID: 0x8E_wdf_usb+6e9

Followup: MachineOwner

Hope this can help to analyze the source of my problem.
Best Regards,
Matthias

Fix you symbols path (.symfix) and repost when you have a good call stack

d

Bent from my phone


From: xxxxx@alumni.tu-berlin.demailto:xxxxx
Sent: ?4/?7/?2013 10:05 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] ExAllocatePoolWithTag Problem

Hello Doran,
thank you for your reply - here is the whole output that !analyze ?v has generated:

Windows XP Kernel Version 2600 (Service Pack 3) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp3_gdr.080814-1236
Machine Name:
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055b1c0
Debug session time: xxxxxxxxxxxxxxxxxxxxxxx
System Uptime: 0 days 0:05:22.343

Bugcheck Analysis

KERNEL_MODE_EXCEPTION_NOT_HANDLED_M (1000008e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but …
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: f7eae213, The address that the exception occurred at
Arg3: f1b3e874, Trap Frame
Arg4: 00000000

Debugging Details:
------------------

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced memory at “0x%08lx”. The memory could not be “%s”.

FAULTING_IP:
Wdf01000+1e213
f7eae213 66395f04 cmp word ptr [edi+4],bx

TRAP_FRAME: f1b3e874 – (.trap 0xfffffffff1b3e874)
ErrCode = 00000000
eax=7ded7210
ebx=f1b3100a
ecx=00000000
edx=00000000
esi=f1b3e930
edi=7ded7210
eip=f7eae213
esp=f1b3e8e8
ebp=f1b3e8fc
iopl=0
nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
Wdf01000+0x1e213:
f7eae213 66395f04 cmp word ptr [edi+4],bx ds:0023:7ded7214=???

Resetting default scope

DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0x8E
PROCESS_NAME: USB_test1.exe
LAST_CONTROL_TRANSFER: from f7eed9b8 to f7eae213
STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
f1b3e8fc f7eed9b8 82165008 82128de8 0000100a Wdf01000+0x1e213
f1b3e924 f7ea06e0 82165008 00000000 00000003 Wdf01000+0x5d9b8
f1b3eab0 f88966e9 00000000 f88966e9 821650c8 Wdf01000+0x106e0
f1b3eadc f8898007 7dfc1fe8 00000000 00000000 wdf_usb+0x6e9
f1b3eb48 f8897bf4 7dea96b8 7decb560 00000000 wdf_usb+0x2007
f1b3eb68 f7ecb7e3 7dea96b8 7decb560 00000000 wdf_usb+0x1bf4
f1b3eb8c f7ecca23 7dea96b8 7decb560 00000000 Wdf01000+0x3b7e3
f1b3ebc4 f7ece6ba 82134a98 82134a98 82156940 Wdf01000+0x3ca23
f1b3ebe4 f7ecf9af 82156900 81f10548 82156940 Wdf01000+0x3e6ba
f1b3ec00 f7ed1a37 00000000 81f81588 8201bc80 Wdf01000+0x3f9af
f1b3ec28 f7ec0df7 82134a98 f1b3ec58 804e37f7 Wdf01000+0x41a37
f1b3ec34 804e37f7 821ac858 8221dc00 806f12d0 Wdf01000+0x30df7
f1b3ec44 80567f81 8221dcb8 81f81588 8221dc00 nt!IopfCallDriver+0x31
f1b3ec58 8057aa9f 821ac858 8221dc00 81f81588 nt!IopSynchronousServiceTail+0x70
f1b3ed00 8058efe3 000001ac 00000000 00000000 nt!IopXxxControlFile+0x611
f1b3ed34 804de7ec 000001ac 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
f1b3ed34 7c91e4f4 000001ac 00000000 00000000 nt!KiFastCallEntry+0xf8
0012ef48 00000000 00000000 00000000 00000000 0x7c91e4f4

STACK_COMMAND: kb

FOLLOWUP_IP:
wdf_usb+6e9
f88966e9 ?? ???

SYMBOL_STACK_INDEX: 3

SYMBOL_NAME: wdf_usb+6e9

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: wdf_usb

IMAGE_NAME: wdf_usb.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 50f6b5d3

FAILURE_BUCKET_ID: 0x8E_wdf_usb+6e9

BUCKET_ID: 0x8E_wdf_usb+6e9

Followup: MachineOwner
---------

Hope this can help to analyze the source of my problem.
Best Regards,
Matthias


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

Your first post eliminated all but one of the most useles lines in the
dump. So you’re making progress. As Doron pointed out, the stack
backtrace is useless until you get the right symbols…

That said, there are some things that can be readily deduced from this
output. For example, the fact that you have an illegal memory access.
While it is uncertain where it might have come from until you get proper
symbols, the instruction tells you that
cmp word ptr [edi+4], bx
is trying to compare the memory location 4 higher than the value in edi to
a vale in a register. So, let’s look at what is in edi
edi=7ded7210

Now that actually tells you something. In a normal Win32 boot, the
address spaces splits ar the 2GB boundary. All addresses with the
high-order bit (0x80000000) set to 1 are kernel addresses, and all
addresses with the high-order bit set to 0 are user-space addressed. In
general, the kernel should not be trying to access a user-mode address (as
a beginner, you can accept this as a True Fact; subtleties such as Mode
Neither and APCs are outside your needs). So the question is: how did I
get a user-mode address there?

Once you have correct symbols, you will find it easier to answer that
question.

You are asking the wrong question, by the way. You are asking about
ExAllocatePoolWithTag, but to really answer that question you need to have
used the debugger to verity that all the values you are developing make
sense. By the time you get to the call from your code that fails, you
should be able to tell us exactly what every parameter to every preceding
call was. And if you see that 0x7??? address, that’s a giveaway; that
would in general NOT be a valid address to most kernel calls. So then you
have to trace back where that came from.
joe

Hello Doran,
thank you for your reply - here is the whole output that !analyze ?v has
generated:

Windows XP Kernel Version 2600 (Service Pack 3) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp3_gdr.080814-1236
Machine Name:
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055b1c0
Debug session time: xxxxxxxxxxxxxxxxxxxxxxx
System Uptime: 0 days 0:05:22.343
**********************************************
* Bugcheck Analysis
*
**********************************************
KERNEL_MODE_EXCEPTION_NOT_HANDLED_M (1000008e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but …
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: f7eae213, The address that the exception occurred at
Arg3: f1b3e874, Trap Frame
Arg4: 00000000

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx”
referenced memory at “0x%08lx”. The memory could not be “%s”.

FAULTING_IP:
Wdf01000+1e213
f7eae213 66395f04 cmp word ptr [edi+4],bx

TRAP_FRAME: f1b3e874 – (.trap 0xfffffffff1b3e874)
ErrCode = 00000000
eax=7ded7210
ebx=f1b3100a
ecx=00000000
edx=00000000
esi=f1b3e930
edi=7ded7210
eip=f7eae213
esp=f1b3e8e8
ebp=f1b3e8fc
iopl=0
nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
Wdf01000+0x1e213:
f7eae213 66395f04 cmp word ptr [edi+4],bx
ds:0023:7ded7214=???

Resetting default scope

DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0x8E
PROCESS_NAME: USB_test1.exe
LAST_CONTROL_TRANSFER: from f7eed9b8 to f7eae213
STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be
wrong.
f1b3e8fc f7eed9b8 82165008 82128de8 0000100a Wdf01000+0x1e213
f1b3e924 f7ea06e0 82165008 00000000 00000003 Wdf01000+0x5d9b8
f1b3eab0 f88966e9 00000000 f88966e9 821650c8 Wdf01000+0x106e0
f1b3eadc f8898007 7dfc1fe8 00000000 00000000 wdf_usb+0x6e9
f1b3eb48 f8897bf4 7dea96b8 7decb560 00000000 wdf_usb+0x2007
f1b3eb68 f7ecb7e3 7dea96b8 7decb560 00000000 wdf_usb+0x1bf4
f1b3eb8c f7ecca23 7dea96b8 7decb560 00000000 Wdf01000+0x3b7e3
f1b3ebc4 f7ece6ba 82134a98 82134a98 82156940 Wdf01000+0x3ca23
f1b3ebe4 f7ecf9af 82156900 81f10548 82156940 Wdf01000+0x3e6ba
f1b3ec00 f7ed1a37 00000000 81f81588 8201bc80 Wdf01000+0x3f9af
f1b3ec28 f7ec0df7 82134a98 f1b3ec58 804e37f7 Wdf01000+0x41a37
f1b3ec34 804e37f7 821ac858 8221dc00 806f12d0 Wdf01000+0x30df7
f1b3ec44 80567f81 8221dcb8 81f81588 8221dc00 nt!IopfCallDriver+0x31
f1b3ec58 8057aa9f 821ac858 8221dc00 81f81588
nt!IopSynchronousServiceTail+0x70
f1b3ed00 8058efe3 000001ac 00000000 00000000 nt!IopXxxControlFile+0x611
f1b3ed34 804de7ec 000001ac 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
f1b3ed34 7c91e4f4 000001ac 00000000 00000000 nt!KiFastCallEntry+0xf8
0012ef48 00000000 00000000 00000000 00000000 0x7c91e4f4

STACK_COMMAND: kb

FOLLOWUP_IP:
wdf_usb+6e9
f88966e9 ?? ???

SYMBOL_STACK_INDEX: 3

SYMBOL_NAME: wdf_usb+6e9

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: wdf_usb

IMAGE_NAME: wdf_usb.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 50f6b5d3

FAILURE_BUCKET_ID: 0x8E_wdf_usb+6e9

BUCKET_ID: 0x8E_wdf_usb+6e9

Followup: MachineOwner

Hope this can help to analyze the source of my problem.
Best Regards,
Matthias


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

xxxxx@alumni.tu-berlin.de wrote:

I am trying to investigate a special function of a USB device. For that I use the following KMDF1.0 code (winXP SP3):

outBuffer = ExAllocatePoolWithTag(NonPagedPool,((length-8) * sizeof(BYTE)), pooltag);
status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES,
outBuffer,
((length-8) * sizeof(BYTE)),
&outMemory);
outChar = WdfMemoryGetBuffer(outMemory, &lengthOut);

//here I generate some code which is then put into ?outChar?

That code is silly. Since YOU allocated the buffer, you don’t have to
use WdfMemoryGetBuffer to get the address, because you already HAVE the
address. outBuffer and outChar will always be identical. You should
either use ExAllocatePool and WdfMemoryCreatePreallocated, OR
WdfMemoryCreate and WdfMemoryGetBuffer. One or the other.

//here I manually generate a controlPacket using controlPacket.Generic.Bytes[0] etc.

WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptorOut, outBuffer, NULL);

If this is actually your code, then this the cause of your problem.
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE expects to receive a KMDF memory
object – a WDFMEMORY. You are passing it the virtual address of your
buffer. You need to pass “outMemory” here, not outBuffer.

The WDFMEMORY object is, to me, one of the more confusing ones in KMDF.
I do have a grasp of why it was introduced, but it seems to me that it
very often introduces another level of indirection where none was really
needed.


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

It was introduced so that you could not free memory while it was in use with another object (dma, iotarget). In other words, it was supposed to stop you from sending a hand grenade and pulling the pin in mid flight (Think freeing an urb while pending with the host controller).

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, April 8, 2013 10:11 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] ExAllocatePoolWithTag Problem

xxxxx@alumni.tu-berlin.de wrote:

I am trying to investigate a special function of a USB device. For that I use the following KMDF1.0 code (winXP SP3):

outBuffer = ExAllocatePoolWithTag(NonPagedPool,((length-8) * sizeof(BYTE)), pooltag);
status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES,
outBuffer,
((length-8) * sizeof(BYTE)),
&outMemory);
outChar = WdfMemoryGetBuffer(outMemory, &lengthOut);

//here I generate some code which is then put into ?outChar?

That code is silly. Since YOU allocated the buffer, you don’t have to use WdfMemoryGetBuffer to get the address, because you already HAVE the address. outBuffer and outChar will always be identical. You should either use ExAllocatePool and WdfMemoryCreatePreallocated, OR WdfMemoryCreate and WdfMemoryGetBuffer. One or the other.

//here I manually generate a controlPacket using controlPacket.Generic.Bytes[0] etc.

WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptorOut, outBuffer,
NULL);

If this is actually your code, then this the cause of your problem.
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE expects to receive a KMDF memory object – a WDFMEMORY. You are passing it the virtual address of your buffer. You need to pass “outMemory” here, not outBuffer.

The WDFMEMORY object is, to me, one of the more confusing ones in KMDF.
I do have a grasp of why it was introduced, but it seems to me that it very often introduces another level of indirection where none was really needed.


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


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

If YOU find it slightly confusing, I’m SURE other members of the community find it confusing as well. I’ll add an item to our queue for The NT Insider, but in the meantime, let me hold forth a bit, and tell you how I explain this in class. It might not help, or maybe it’ll help one person. If that’s the case, at least I’ve tried:

There are three ways of describing allocated memory in WDF: Buffers, Memory Objects, and MDLs.

A memory buffer in WDF is just want it is in any system: A pointer and a length. You get a “buffer” directly when you call functions such as WdfRequestRetrieveInputBuffer (or friends) or when you use one of the WDM (M) functions such as ExAllocatePoolWithTag.

A buffer isn’t an object. It’s just some allocated memory. The buffer itself is not managed by the Framework. Now, don’t confuse this with an object (such as a WDFREQUEST) which might own a buffer and therefore manage its lifetime. But, if you consider JUST THE BUFFER, the buffer itself is not Framework managed.

Contrast this with a WDFMemory object. A WDFMemory object is an opaque object that is used to describe a buffer. That buffer might be associated with a Request, in which case you can call WdfRequestRetrieveInputMemory (or friends) or it may simply be a private allocation from one of the Pools (created with WdfMemoryCreate).

Just like with any WDF Object, Memory objects are managed by the Framework. They have a reference count, they can have a context, they can have cleanup callback methods… anything that any other WDF Object has.

Because it’s simple to get a buffer (pointer and length) from a WDF Memory object, in many cases a WDFMEMORY object merely offers a convenient way to allocate and track memory allocations using the same pattern by which you do ANY work in the Framework.

WDF Memory Objects also provide a handy way to pass along a description of a buffer for use by another WDF method. An added bonus is that if the function does something with a lifetime, the function can reference the WDF Memory object to ensure it’s not deallocated while being accessed.

By the way… a related structure that folks often find confusing is the WDF_MEMORY_DESCRIPTOR. This is just a data structure, and is used to provide a uniform way to describe a memory area… regardless of whether you have a buffer, a WDF Memory Object, or and MDL that describes that area of memory. While folks often see this structure as an annoyance (like when building USB Requests) it’s *really* a convenience, because you’re allowed to use ANY of the three possible types of memory descriptors to describe a data area, instead of having to use a specific one.

I hope that helps… at least some.

Peter
OSR

WDF_MEMORY_DESCRIPTOR was a tough one. It took me quite a while to get this to its current state. What we wanted to do with memory lifetime management was

  1. for async requests, require the use of WDFMEMORY so we could manage the lifetime of the buffer. BUT, to help with porting and interacting with other parts of the OS that might allocate on your behalf, we have the Preallocated version which is a veneer object that lets you opt into the model

  2. for sync requests, use any type of memory that the caller has on hand. Lifetime isn’t a problem since it is scoped to the callsite. In this case, WDFMEMORY / PVOID / PMDL are all valid. Either we created N*N sync APIs that could take any combination (C++ would have made that slightly more palatable, but not by much) or we created one version of the API that took all options for each buffer (WDF_MEMORY_DESCRIPTOR) and kept things relatively straightforward (and expandable if we ever needed more memory types)

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Monday, April 8, 2013 10:34 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ExAllocatePoolWithTag Problem

If YOU find it slightly confusing, I’m SURE other members of the community find it confusing as well. I’ll add an item to our queue for The NT Insider, but in the meantime, let me hold forth a bit, and tell you how I explain this in class. It might not help, or maybe it’ll help one person. If that’s the case, at least I’ve tried:

There are three ways of describing allocated memory in WDF: Buffers, Memory Objects, and MDLs.

A memory buffer in WDF is just want it is in any system: A pointer and a length. You get a “buffer” directly when you call functions such as WdfRequestRetrieveInputBuffer (or friends) or when you use one of the WDM (M) functions such as ExAllocatePoolWithTag.

A buffer isn’t an object. It’s just some allocated memory. The buffer itself is not managed by the Framework. Now, don’t confuse this with an object (such as a WDFREQUEST) which might own a buffer and therefore manage its lifetime. But, if you consider JUST THE BUFFER, the buffer itself is not Framework managed.

Contrast this with a WDFMemory object. A WDFMemory object is an opaque object that is used to describe a buffer. That buffer might be associated with a Request, in which case you can call WdfRequestRetrieveInputMemory (or friends) or it may simply be a private allocation from one of the Pools (created with WdfMemoryCreate).

Just like with any WDF Object, Memory objects are managed by the Framework. They have a reference count, they can have a context, they can have cleanup callback methods… anything that any other WDF Object has.

Because it’s simple to get a buffer (pointer and length) from a WDF Memory object, in many cases a WDFMEMORY object merely offers a convenient way to allocate and track memory allocations using the same pattern by which you do ANY work in the Framework.

WDF Memory Objects also provide a handy way to pass along a description of a buffer for use by another WDF method. An added bonus is that if the function does something with a lifetime, the function can reference the WDF Memory object to ensure it’s not deallocated while being accessed.

By the way… a related structure that folks often find confusing is the WDF_MEMORY_DESCRIPTOR. This is just a data structure, and is used to provide a uniform way to describe a memory area… regardless of whether you have a buffer, a WDF Memory Object, or and MDL that describes that area of memory. While folks often see this structure as an annoyance (like when building USB Requests) it’s *really* a convenience, because you’re allowed to use ANY of the three possible types of memory descriptors to describe a data area, instead of having to use a specific one.

I hope that helps… at least some.

Peter
OSR


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hello,

Thank you all for your support.

@Tim Roberts
I double checked your suggestion by commenting out WdfUsbTarget?.Synchronously to later on observe that that WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptorOut, outBuffer, NULL) is really causing the BSOD. Thank you very much.
I also tried your suggestion to use outMemory instead but unfortunately WdfUsbTargetDeviceSendControlTransferSynchronously fails with NTSTATUS 0xc0000001.

If I use WdfMemoryCreatePreallocated to ?allocate? memory which is already defined inside the device context then WdfUsbTargetDeviceSendControlTransferSynchronously succeeds. However this is not what I want because it is very inflexible.

Is there a kind of memory, which I could allocate to successfully send its content via WdfUsbTargetDeviceSendControlTransferSynchronously ?

@Doron Holan
Before I post my next call stack I will fix my symbols ? thank you very much for your suggestion.

Best Regards,
Matthias

xxxxx@alumni.tu-berlin.de wrote:

I double checked your suggestion by commenting out WdfUsbTarget?.Synchronously to later on observe that that WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptorOut, outBuffer, NULL) is really causing the BSOD. Thank you very much.
I also tried your suggestion to use outMemory instead but unfortunately WdfUsbTargetDeviceSendControlTransferSynchronously fails with NTSTATUS 0xc0000001.

If I use WdfMemoryCreatePreallocated to ?allocate? memory which is already defined inside the device context then WdfUsbTargetDeviceSendControlTransferSynchronously succeeds. However this is not what I want because it is very inflexible.

Is there a kind of memory, which I could allocate to successfully send its content via WdfUsbTargetDeviceSendControlTransferSynchronously ?

It’s not the kind of memory. It’s how you are using it.

You need exactly two things. You need a chunk memory, and you need a
WDFMEMORY object that describes that memory. You can either allocate
the memory yourself (using ExAllocatePool, perhaps) and then call
WdfMemoryCreatePreallocated to wrap a WDFMEMORY around it, or you can
use WdfMemoryCreate to allow KMDF to allocate the memory, and ask the
object to tell you the virtual address it allocated.

Whichever way you do it, you use the virtual address in your code to
write to the memory, but you must pass the WDFMEMORY object to
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE.

I’m fairly sure that your problem is still that you are confusing the
two. You are passing an address where you need a WDFMEMORY, or vice versa.


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

Dear Tim,
Maybe ? but I also found another mistake in my code (hopefully the last one). Obviously WdfUsbTargetDeviceSendControlTransferSynchronously produces a NTSTATUS 0xc0000001 if the 7th byte of controlpaket does not match with the size of outBuffer. I saw this by coincidence.

To save memory I decided to reuse a part of the memory -object which I have retrieved with the WdfRequestRetrieveInputMemory function. Using WdfMemoryGetBuffer I obtained the buffer address to get access to the buffer content.
Because of:
?Since YOU allocated the buffer, you don’t have to use WdfMemoryGetBuffer to get the address, because you already HAVE the address.?
it is surprisingly possible to reallocate this buffer using WdfMemoryCreatePreallocted to assign a new WDFMEMORY object which has e.g. a smaller buffer size. Fortunately it is also possible to access this new WDFMEMORY object to e.g. overwrite the ?old? buffer content. Subsequently I passed this new WDFMEMORY object to WDF_MEMORY_DESCRIPTOR_INIT_HANDLE to obtain a descriptor. Using this descriptor the function WdfUsbTargetDeviceSendControlTransferSynchronously has send successfully the content of the new WDFMEMORY to my USB hardware ( I observed this using a USB monitor)

Thank you again for your help .

Best Regards,
Matthias