AllocateCommonBuffer is causing PC to reset

Hello,

The following code runs in the routine: PLxEvtDeviceAdd in the the file
Pci9656.c right after calling to: WdfDeviceCreate

The goal of this code is to allocate 4096 bytes (one page) of continuous
physical memory.

As explained to me in a previous question there is chance that the kernel
will not find even one continuous page.

Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer

is causing a crash and reset to the PC ?

it should only set the variable ‘p’ to 0x0.

After the crash windows boots with the device disabled.

I analyzed the dmp file created. It shows that this line caused the crash.

Can you tell what is wrong with my code ?

I also printed the values of ‘DmaAdapterObject’ and
‘deviceContext->AllocateCommonBuffer’.

Those variables are not NULL.


RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));

#if defined(DMA_VER2)
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2;
#else
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
#endif

deviceDescription.Master = TRUE;
deviceDescription.ScatterGather = FALSE;
deviceDescription.Dma32BitAddresses = FALSE;
deviceDescription.Dma64BitAddresses = TRUE;
deviceDescription.InterfaceType = PCIBus;
deviceDescription.MaximumLength = 4*4096;

DmaAdapterObject = IoGetDmaAdapter(DeviceObject,
&deviceDescription,
&NumberOfMapRegisters);

deviceContext->AllocateCommonBuffer =
*DmaAdapterObject->DmaOperations->AllocateCommonBuffer;

p=deviceContext->AllocateCommonBuffer
(DmaAdapterObject,4096,&LogicalAddress,FALSE);

Thanks,
Zvika.

How is p defined ? Even though this looks like a case of wrong indirection,
deviceContext->AllocateCommonBuffer =
*DmaAdapterObject->DmaOperations->AllocateCommonBuffer;
how is deviceContext defined ?

Were you thinking ? What were you thinking ?

Post your !analyze-v output

Regards,

Daniel Terhell
Resplendence Software Projects Sp
xxxxx@resplendence.com
http://www.resplendence.com

“Zvi Vered” wrote in message news:xxxxx@ntdev…
> Hello,
>
> The following code runs in the routine: PLxEvtDeviceAdd in the the file
> Pci9656.c right after calling to: WdfDeviceCreate
>
> The goal of this code is to allocate 4096 bytes (one page) of continuous
> physical memory.
>
> As explained to me in a previous question there is chance that the kernel
> will not find even one continuous page.
>
> Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer
>
> is causing a crash and reset to the PC ?
>
> it should only set the variable ‘p’ to 0x0.
>
> After the crash windows boots with the device disabled.
>
> I analyzed the dmp file created. It shows that this line caused the crash.
>
> Can you tell what is wrong with my code ?
>
> I also printed the values of ‘DmaAdapterObject’ and
> ‘deviceContext->AllocateCommonBuffer’.
>
> Those variables are not NULL.
>
> -------------------------------------------------------------------------------------------------------
> RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
>
> #if defined(DMA_VER2)
> deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2;
> #else
> deviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
> #endif
>
> deviceDescription.Master = TRUE;
> deviceDescription.ScatterGather = FALSE;
> deviceDescription.Dma32BitAddresses = FALSE;
> deviceDescription.Dma64BitAddresses = TRUE;
> deviceDescription.InterfaceType = PCIBus;
> deviceDescription.MaximumLength = 4*4096;
>
> DmaAdapterObject = IoGetDmaAdapter(DeviceObject,
> &deviceDescription,
> &NumberOfMapRegisters);
>
> deviceContext->AllocateCommonBuffer =
> *DmaAdapterObject->DmaOperations->AllocateCommonBuffer;
>
> p=deviceContext->AllocateCommonBuffer
> (DmaAdapterObject,4096,&LogicalAddress,FALSE);
> -------------------------------------------------------------------------------------------------------
>
> Thanks,
> Zvika.
>
>

Hello,

Sorry, here are the variables definitions.

DEVICE_DESCRIPTION deviceDescription;
PDMA_ADAPTER DmaAdapterObject;
PDEVICE_OBJECT DeviceObject;
ULONG NumberOfMapRegisters;
PVOID p;
PHYSICAL_ADDRESS LogicalAddress;
PDEVICE_CONTEXT deviceContext;

status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);

DeviceObject = WdfDeviceWdmGetPhysicalDevice(device);

At this point the code I sent starts.

Thanks,
Zvika.

----- Original Message -----
From:
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Sunday, October 02, 2011 22:05
Subject: Re:[ntdev] AllocateCommonBuffer is causing PC to reset

> How is p defined ? Even though this looks like a case of wrong
> indirection,
> deviceContext->AllocateCommonBuffer =
> DmaAdapterObject->DmaOperations->AllocateCommonBuffer;
> how is deviceContext defined ?
>
> Were you thinking ? What were you thinking ?
>
> Post your !analyze-v output
>
> Regards,
>
> Daniel Terhell
> Resplendence Software Projects Sp
> xxxxx@resplendence.com
> http://www.resplendence.com
>
>
>
>
>
>
> “Zvi Vered” wrote in message news:xxxxx@ntdev…
>> Hello,
>>
>> The following code runs in the routine: PLxEvtDeviceAdd in the the file
>> Pci9656.c right after calling to: WdfDeviceCreate
>>
>> The goal of this code is to allocate 4096 bytes (one page) of continuous
>> physical memory.
>>
>> As explained to me in a previous question there is chance that the kernel
>> will not find even one continuous page.
>>
>> Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer
>>
>> is causing a crash and reset to the PC ?
>>
>> it should only set the variable ‘p’ to 0x0.
>>
>> After the crash windows boots with the device disabled.
>>
>> I analyzed the dmp file created. It shows that this line caused the
>> crash.
>>
>> Can you tell what is wrong with my code ?
>>
>> I also printed the values of ‘DmaAdapterObject’ and
>> ‘deviceContext->AllocateCommonBuffer’.
>>
>> Those variables are not NULL.
>>
>> -------------------------------------------------------------------------------------------------------
>> RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
>>
>> #if defined(DMA_VER2)
>> deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2;
>> #else
>> deviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
>> #endif
>>
>> deviceDescription.Master = TRUE;
>> deviceDescription.ScatterGather = FALSE;
>> deviceDescription.Dma32BitAddresses = FALSE;
>> deviceDescription.Dma64BitAddresses = TRUE;
>> deviceDescription.InterfaceType = PCIBus;
>> deviceDescription.MaximumLength = 4
4096;
>>
>> DmaAdapterObject = IoGetDmaAdapter(DeviceObject,
>> &deviceDescription,
>> &NumberOfMapRegisters);
>>
>> deviceContext->AllocateCommonBuffer =
>> *DmaAdapterObject->DmaOperations->AllocateCommonBuffer;
>>
>> p=deviceContext->AllocateCommonBuffer
>> (DmaAdapterObject,4096,&LogicalAddress,FALSE);
>> -------------------------------------------------------------------------------------------------------
>>
>> Thanks,
>> Zvika.
>>
>>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> 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

On 02-Oct-2011 21:27, Zvi Vered wrote:


As explained to me in a previous question there is chance that the
kernel will not find even one continuous page.

Wait, wait, are you serious? No one told you this. I didn’t.
One page is always continuous so this much is available almost
always - unless there is absolutely no memory.

Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer

is causing a crash and reset to the PC ?

it should only set the variable ‘p’ to 0x0.

Because your AllocateCommonBuffer is a pointer variable!
you get it from:
*DmaAdapterObject->DmaOperations->AllocateCommonBuffer

So test it for NULL before calling thru it.
What IoGetDmaAdapter() returned?

– pa

Try :

deviceContext->AllocateCommonBuffer = DmaAdapterObject->DmaOperations->AllocateCommonBuffer ;

instead of :

deviceContext->AllocateCommonBuffer = *DmaAdapterObject->DmaOperations->AllocateCommonBuffer ;

Who knows … :slight_smile:

----- Original Message -----
From: “Zvi Vered”
To: “Windows System Software Devs Interest List”
Sent: Sunday, October 02, 2011 9:27 PM
Subject: [ntdev] AllocateCommonBuffer is causing PC to reset

@Christiaan:

Function pointers have a funny property that applying ‘*’ operator to them returns the same unchanged type.

@OP:

How did you declare deviceContext->AllocateCommonBuffer?

Also, I hope you’re saving DmaAdapterObject somewhere (for example, in deviceContext), to delete it when appropriate. In this case, why copy the function pointer at all?

I see several things wrong here. For example, I didn’t see where you
store the pointer to the DMA Adapter object for later use. I see code to
extract a function pointer and store it somewhere else, which doesn’t make
much sense. I see you dereferencing this pointer, which makes even less
sense.

You act SHOCKED that your program fails, yet you apparently have done
nothing as trivial as setting a breakpoint on the failing line and looking
at the values you are using, or looking at the generated code that fails.
This is always your first step.

Now you are allocating a “contiguous” one page buffer. Contiguous with
WHAT??? Since the allocation of any paged-size or larger buffer is
necessarily page-aligned (this is part of the spec–RTFM, e.g.
ExAllocateWithTag). You even seem to assume, without any evidence, that a
page is 4096 bytes. Presumably you have some reason to believe that a
one-page allocation could be DIScontiguous. Although how a single page
cannot be a contiguous page escapes me.

Hello,

The following code runs in the routine: PLxEvtDeviceAdd in the the file
Pci9656.c right after calling to: WdfDeviceCreate

The goal of this code is to allocate 4096 bytes (one page) of continuous
physical memory.

As explained to me in a previous question there is chance that the kernel
will not find even one continuous page.

Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer

is causing a crash and reset to the PC ?

it should only set the variable ‘p’ to 0x0.

After the crash windows boots with the device disabled.

I analyzed the dmp file created. It shows that this line caused the crash.

Can you tell what is wrong with my code ?

I also printed the values of ‘DmaAdapterObject’ and
‘deviceContext->AllocateCommonBuffer’.

Those variables are not NULL.


RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));

#if defined(DMA_VER2)
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2;
#else
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
#endif

deviceDescription.Master = TRUE;
deviceDescription.ScatterGather = FALSE;
deviceDescription.Dma32BitAddresses = FALSE;
deviceDescription.Dma64BitAddresses = TRUE;
deviceDescription.InterfaceType = PCIBus;
deviceDescription.MaximumLength = 4*4096;
*******
Where did the number 4096 come from? There have been some Windows
architectures with 8192-byte pages
*******

DmaAdapterObject = IoGetDmaAdapter(DeviceObject,
&deviceDescription,
&NumberOfMapRegisters);

deviceContext->AllocateCommonBuffer =
*DmaAdapterObject->DmaOperations->AllocateCommonBuffer;
********
(a) why do you extract this pointer here?
(b) why the * to dereference the pointer?
********

p=deviceContext->AllocateCommonBuffer
(DmaAdapterObject,4096,&LogicalAddress,FALSE);
******
Why do you use a pointer you stored insted of directly using the one in
the DmaAdapter->DmaOperations vector? Why do you think making a copy of
it is the right way to do this?

Did you consider looking at the structures to make sure the pointer you
are making the call with is the same value that was. found in the
DmaOperations structure?

Did you look at the generated code?
******


Thanks,
Zvika.


NTDEV is sponsored by OSR

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

How is it that elementary concepts such as examining the values of
variables seem incomprehensible? Instead, we get questions requiring
psychic powers and time machines, and perhaps teleportation. I see at
least one of these a week in the C++ groups, so it is not unique to kernel
programmers.
joe

On 02-Oct-2011 21:27, Zvi Vered wrote:
> …
> As explained to me in a previous question there is chance that the
> kernel will not find even one continuous page.
>

Wait, wait, are you serious? No one told you this. I didn’t.
One page is always continuous so this much is available almost
always - unless there is absolutely no memory.

> Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer
>
> is causing a crash and reset to the PC ?
>
> it should only set the variable ‘p’ to 0x0.

Because your AllocateCommonBuffer is a pointer variable!
you get it from:
*DmaAdapterObject->DmaOperations->AllocateCommonBuffer

So test it for NULL before calling thru it.
What IoGetDmaAdapter() returned?

– pa


NTDEV is sponsored by OSR

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

A less hyperbolic response might be to look at ObRegisterCallbacks() and
only grant read handles to processes you wish to deny write too. Please
do note that ‘*’ is not a viable set of processes to deny write too.
FsRtlAcquireForSectionSynchronization via
FsRtlRegisterFilteSystemFilterCallbacks() (i.e. the non-IRP
IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZTION in mini-filter land) is also
good to watch since various things within win32 can be used to ‘self
inject’.

Ob callbacks do not exist until Vista Sp1, so you are left with far
hackier solutions prior that that, but I would adopt the same basic
semantics of the Ob filter there as well.

t.

On Sun, 2 Oct 2011, xxxxx@flounder.com wrote:

How is it that elementary concepts such as examining the values of
variables seem incomprehensible? Instead, we get questions requiring
psychic powers and time machines, and perhaps teleportation. I see at
least one of these a week in the C++ groups, so it is not unique to kernel
programmers.
joe

> On 02-Oct-2011 21:27, Zvi Vered wrote:
>> …
>> As explained to me in a previous question there is chance that the
>> kernel will not find even one continuous page.
>>
>
> Wait, wait, are you serious? No one told you this. I didn’t.
> One page is always continuous so this much is available almost
> always - unless there is absolutely no memory.
>
>> Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer
>>
>> is causing a crash and reset to the PC ?
>>
>> it should only set the variable ‘p’ to 0x0.
>
> Because your AllocateCommonBuffer is a pointer variable!
> you get it from:
> *DmaAdapterObject->DmaOperations->AllocateCommonBuffer
>
> So test it for NULL before calling thru it.
> What IoGetDmaAdapter() returned?
>
> – pa
>
> —
> NTDEV is sponsored by OSR
>
> 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
>


NTDEV is sponsored by OSR

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

Dear Paval,

DmaAdapterObject which is the return value of IoGetDmaAdapter is not NULL.

Thanks,
Zvika.

----- Original Message -----
From: “Pavel A”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Sunday, October 02, 2011 23:55
Subject: Re:[ntdev] AllocateCommonBuffer is causing PC to reset

> On 02-Oct-2011 21:27, Zvi Vered wrote:
>> …
>> As explained to me in a previous question there is chance that the
>> kernel will not find even one continuous page.
>>
>
> Wait, wait, are you serious? No one told you this. I didn’t.
> One page is always continuous so this much is available almost
> always - unless there is absolutely no memory.
>
>> Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer
>>
>> is causing a crash and reset to the PC ?
>>
>> it should only set the variable ‘p’ to 0x0.
>
> Because your AllocateCommonBuffer is a pointer variable!
> you get it from:
> *DmaAdapterObject->DmaOperations->AllocateCommonBuffer
>
> So test it for NULL before calling thru it.
> What IoGetDmaAdapter() returned?
>
> – pa
>
> —
> NTDEV is sponsored by OSR
>
> 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,

Here is the definition of AllocateCommonBuffer :

typedef struct _DEVICE_CONTEXT
{
ULONG PrivateDeviceData; // just a placeholder
PALLOCATE_COMMON_BUFFER AllocateCommonBuffer;
} DEVICE_CONTEXT, *PDEVICE_CONTEXT;

Thanks,
Zvika.

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Monday, October 03, 2011 02:15
Subject: RE:[ntdev] AllocateCommonBuffer is causing PC to reset

> @Christiaan:
>
> Function pointers have a funny property that applying ‘*’ operator to them
> returns the same unchanged type.
>
> @OP:
>
> How did you declare deviceContext->AllocateCommonBuffer?
>
> Also, I hope you’re saving DmaAdapterObject somewhere (for example, in
> deviceContext), to delete it when appropriate. In this case, why copy the
> function pointer at all?
>
>
> —
> NTDEV is sponsored by OSR
>
> 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

You said “crash” we said “show us the !analyze -v output”

What we say that’ll convince you that a crash dump will help US diagnose this problem for you?

Peter
OSR

Why not use a WDF DMA enabler?

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Zvi Vered
Sent: Sunday, October 02, 2011 12:27 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] AllocateCommonBuffer is causing PC to reset

Hello,

The following code runs in the routine: PLxEvtDeviceAdd in the the file Pci9656.c right after calling to: WdfDeviceCreate

The goal of this code is to allocate 4096 bytes (one page) of continuous physical memory.

As explained to me in a previous question there is chance that the kernel will not find even one continuous page.

Buy why (on earth) the line: p=deviceContext->AllocateCommonBuffer

is causing a crash and reset to the PC ?

it should only set the variable ‘p’ to 0x0.

After the crash windows boots with the device disabled.

I analyzed the dmp file created. It shows that this line caused the crash.

Can you tell what is wrong with my code ?

I also printed the values of ‘DmaAdapterObject’ and ‘deviceContext->AllocateCommonBuffer’.

Those variables are not NULL.


RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));

#if defined(DMA_VER2)
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2; #else
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION; #endif

deviceDescription.Master = TRUE;
deviceDescription.ScatterGather = FALSE; deviceDescription.Dma32BitAddresses = FALSE; deviceDescription.Dma64BitAddresses = TRUE; deviceDescription.InterfaceType = PCIBus; deviceDescription.MaximumLength = 4*4096;

DmaAdapterObject = IoGetDmaAdapter(DeviceObject,
&deviceDescription,
&NumberOfMapRegisters);

deviceContext->AllocateCommonBuffer =
*DmaAdapterObject->DmaOperations->AllocateCommonBuffer;

p=deviceContext->AllocateCommonBuffer
(DmaAdapterObject,4096,&LogicalAddress,FALSE);

Thanks,
Zvika.


NTDEV is sponsored by OSR

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

Dear Mr. Ghijselinck,

You are right !

When I declared AllocateCommonBuffer locally and called to:

PDMA_ADAPTER DmaAdapterObject;
PALLOCATE_COMMON_BUFFER AllocateCommonBuffer;

DmaAdapterObject = IoGetDmaAdapter(FdoData->UnderlyingPDO,
&deviceDescription,
&MapRegisters);

AllocateCommonBuffer =
DmaAdapterObject->DmaOperations->AllocateCommonBuffer

It worked fine.

Thank you for your help !
Zvika.

----- Original Message -----
From: “Christiaan Ghijselinck”
To: “Windows System Software Devs Interest List”
Sent: Monday, October 03, 2011 00:12
Subject: Re: [ntdev] AllocateCommonBuffer is causing PC to reset

>
> Try :
>
> deviceContext->AllocateCommonBuffer =
> DmaAdapterObject->DmaOperations->AllocateCommonBuffer ;
>
> instead of :
>
> deviceContext->AllocateCommonBuffer =
> *DmaAdapterObject->DmaOperations->AllocateCommonBuffer ;
>
> Who knows … :slight_smile:
>
>
>
> ----- Original Message -----
> From: “Zvi Vered”
> To: “Windows System Software Devs Interest List”
> Sent: Sunday, October 02, 2011 9:27 PM
> Subject: [ntdev] AllocateCommonBuffer is causing PC to reset
>
>
>
> —
> NTDEV is sponsored by OSR
>
> 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

Zvi Vered wrote:

You are right !

When I declared AllocateCommonBuffer locally and called to:

PDMA_ADAPTER DmaAdapterObject;
PALLOCATE_COMMON_BUFFER AllocateCommonBuffer;

DmaAdapterObject = IoGetDmaAdapter(FdoData->UnderlyingPDO,
&deviceDescription,
&MapRegisters);

AllocateCommonBuffer =
DmaAdapterObject->DmaOperations->AllocateCommonBuffer

It worked fine.

That’s good, but even that extra step is unnecessary. Just do:

DmaAdapterObject->DmaOperations->AllocateCommonBuffer(DmaAdapterObject,
12345, &phys, TRUE);


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