APPCRASH while Pending IRP

Hello,

I have PCIe device for which we have written a NDIS miniport driver which also interacts with a user application for some data exchange. To enable this we have creating a symbolic link which user can use in CreateFile call by registering a device using NdisRegisterDeviceEx.

The user app sends IOCTL to the driver which we handle in the DeviceIoControl dispatch routine .For data exchange we want to use pended IRP method so that the receipt of interrupt from the device can be indicated to the application. When the DeviceIoControl Receives the specific IOCTL it pends it and stores the IRP pointer in DeviceExtension received after NdisRegisterDeviceEx call as follows:

case XXX_CHECK_EVENT:
{
DbgPrint(“CHECK EVENT\n”);
NdisAcquireSpinLock(&pXXXDrvInstance->m_PendingIrpLock);
pXXXDrvInstance->m_pPendingIrp = Irp_p;
if(!Irp_p->Cancel)
{
IoMarkIrpPending(Irp_p);
IoSetCancelRoutine(Irp_p, XXXCancelIrp);

}
else
{
NdisReleaseSpinLock(&pXXXDrvInstance->m_PendingIrpLock);
Status = STATUS_CANCELLED;
break;
}

NdisReleaseSpinLock(&pHpmnDrvInstance->m_PendingIrpLock);
Status = STATUS_PENDING;
break;
}

default:

Status = STATUS_UNSUCCESSFUL;
break;
}

if (Status != STATUS_PENDING)
{
//
// complete the Irp
//
DbgPrint(“Complete \n”);
Irp_p->IoStatus.Status = Status;
IoCompleteRequest(Irp_p, IO_NO_INCREMENT);
}

The device uses MSI for signalling the receipt of data. In my driver’s DPCforISR I retreive the Pended Irp pointer copy the information in the IRP buffer and then complete it as follows:

VOID
HpmnNdisDpc(
__in NDIS_HANDLE MiniportInterruptContext_p,
__in ULONG MessageId_p,
__in PVOID MiniportDpcContext_p,
__in PULONG NdisReserved1_p,
__in PULONG NdisReserved2_p
)
{
PIRP pIrp = NULL;
BYTE bMode;
PVOID pBuff;
NTSTATUS Status = STATUS_SUCCESS;
do
{
bMode = XXXGetMode();
NdisDprAcquireSpinLock(&XXXnDrvInstance_l->m_PendingIrpLock);
if(XXXDrvInstance_l->m_pPendingIrp != NULL)
{
DbgPrint(" Mode : %x\n",bMode);

pIrp = XXXDrvInstance_l->m_pPendingIrp;

if(pIrp->Cancel)
{

Status = STATUS_CANCELLED;
break;
}
else
{

pBuff = pIrp->AssociatedIrp.SystemBuffer;

DbgPrint(" Copying \n");
NdisMoveMemory(pBuff,&bMode,sizeof(bMode));
Status = STATUS_SUCCESS;

}
}
}
while(FALSE);
NdisDprReleaseSpinLock(&XXXDrvInstance_l->m_PendingIrpLock);

if(pIrp != NULL)
{
DbgPrint(“completing the IRP\n”);
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
XXXDrvInstance_l->m_pPendingIrp = NULL;
}
}

when i call the user application with the XXX_CHECK_EVENT control code it results in a APPCRASH :

Problem Event Name: APPCRASH
Application Name: demo_App.exe
Application Version: 0.0.0.0
Application Timestamp: 502f64cd
Fault Module Name: KERNELBASE.dll
Fault Module Version: 6.1.7601.17651
Fault Module Timestamp: 4e21213c
Exception Code: c0000005
Exception Offset: 000000000000a292
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 1033
Additional Information 1: b046
Additional Information 2: b0463d6163e1702cfe7937c497a94fef
Additional Information 3: 3ca0
Additional Information 4: 3ca0db409703bf7afef063aa94280bf5

I havent used a internal queue for storring the pended IRP is that necessary? Please someone help.

Thanks in advance

You MUST replace pPendingIrp with NULL while still under spinlock. Or you can use InterlockedExchangePointer.

You need to set the length of data returned in pIrp->IoStatus.Information.

Also, you need to protect against an app issuing two pended IRPs. In your case, you will lose the first one.

Two things
1 debug the app crash too
2 instead of rolling your own cancel logic, use an IoCSQ

d

debt from my phone


From: xxxxx@broadcom.com
Sent: 8/18/2012 8:17 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] APPCRASH while Pending IRP

You MUST replace pPendingIrp with NULL while still under spinlock. Or you can use InterlockedExchangePointer.

You need to set the length of data returned in pIrp->IoStatus.Information.

Also, you need to protect against an app issuing two pended IRPs. In your case, you will lose the first one.


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

thanks for the replies

“You MUST replace pPendingIrp with NULL while still under spinlock. Or you can use InterlockedExchangePointer.”

I tried this alex but that didnt worked.

“Two things
1 debug the app crash too
2 instead of rolling your own cancel logic, use an IoCSQ”

Doron can you please tell me how i can debug the app crash

Is it your app? Attach windbg to it and see what is going wrong

d

debt from my phone


From: xxxxx@gmail.com
Sent: 8/18/2012 9:22 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] APPCRASH while Pending IRP

thanks for the replies

“You MUST replace pPendingIrp with NULL while still under spinlock. Or you can use InterlockedExchangePointer.”

I tried this alex but that didnt worked.

“Two things
1 debug the app crash too
2 instead of rolling your own cancel logic, use an IoCSQ”

Doron can you please tell me how i can debug the app crash


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

Also, IoCsqInitialize and friends , http://msdn.microsoft.com/en-us/library/windows/hardware/ff549054(v=vs.85).aspx

d

debt from my phone


From: xxxxx@gmail.com
Sent: 8/18/2012 9:22 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] APPCRASH while Pending IRP

thanks for the replies

“You MUST replace pPendingIrp with NULL while still under spinlock. Or you can use InterlockedExchangePointer.”

I tried this alex but that didnt worked.

“Two things
1 debug the app crash too
2 instead of rolling your own cancel logic, use an IoCSQ”

Doron can you please tell me how i can debug the app crash


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

I will do that. By the way i wanted to know whether being a Network device effects this in any way?

I am not used to windbg can some please interpret what is the cause of following error

I am opening my executable in windbg

Executable search path is:
ModLoad: 00000000039a0000 00000000039a6000 demo_App.exe
ModLoad: 00000000776f0000 0000000077899000 ntdll.dll
ModLoad: 0000000077160000 000000007727f000 C:\Windows\system32\kernel32.dll
ModLoad: 000007fefdeb0000 000007fefdf1c000 C:\Windows\system32\KERNELBASE.dll
ModLoad: 0000000074f50000 0000000074f95000 C:\Program Files\AVAST Software\Avast\snxhk64.dll
ModLoad: 000007feff740000 000007feff7df000 C:\Windows\system32\msvcrt.dll
(d50.c4c): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
ntdll!CsrSetPriorityClass+0x40:
00000000`7779cb60 cc int 3

You need to configure your symbols.

.symfix c:\sym
.reload -f *

You can replace c:\sym with any local directory you wish to use as a symbol
cache.

Mm
On Aug 18, 2012 11:45 PM, wrote:

> I am not used to windbg can some please interpret what is the cause of
> following error
>
> I am opening my executable in windbg
>
> Executable search path is:
> ModLoad: 00000000039a0000 00000000039a6000 demo_App.exe
> ModLoad: 00000000776f0000 0000000077899000 ntdll.dll
> ModLoad: 0000000077160000 000000007727f000
> C:\Windows\system32\kernel32.dll
> ModLoad: 000007fefdeb0000 000007fefdf1c000
> C:\Windows\system32\KERNELBASE.dll
> ModLoad: 0000000074f50000 0000000074f95000 C:\Program Files\AVAST
> Software\Avast\snxhk64.dll
> ModLoad: 000007feff740000 000007feff7df000
> C:\Windows\system32\msvcrt.dll
> (d50.c4c): Break instruction exception - code 80000003 (first chance)
> *** ERROR: Symbol file could not be found. Defaulted to export symbols
> for ntdll.dll -
> ntdll!CsrSetPriorityClass+0x40:
> 00000000`7779cb60 cc int 3
>
>
> —
> 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
>

Well, the 80000003 says that you took a breakpoint. If you take a
breakpoint in msvcrt, there’s a good chance it came from malloc/free
logic, and there has been storage damage which has corrupted a block
header.

You need to make sure you don’t have a buffer overrun. You should also
try Application Verifier with all memory options enabled.

But the bottom line in what I’ve been reading: it is nearly impossible for
a kernel error to cause an app failure. This assumes your driver is
correct, so if the user sends down a buffer of length N you do not write
more than N bytes to it; this is particularly important when using Direct
I/O. Assuming you have not done something like this, then the error is
solely in your application, and should be debugged as such.

The Visual Studio debugger is a good deal friendlier for app debugging
than windbg. If all you have is windbg, you need to have proper symbols,
you need to give a backtrace, and you need to learn to interpret the error
codes.
joe

I am not used to windbg can some please interpret what is the cause of
following error

I am opening my executable in windbg

Executable search path is:
ModLoad: 00000000039a0000 00000000039a6000 demo_App.exe
ModLoad: 00000000776f0000 0000000077899000 ntdll.dll
ModLoad: 0000000077160000 000000007727f000
C:\Windows\system32\kernel32.dll
ModLoad: 000007fefdeb0000 000007fefdf1c000
C:\Windows\system32\KERNELBASE.dll
ModLoad: 0000000074f50000 0000000074f95000 C:\Program Files\AVAST
Software\Avast\snxhk64.dll
ModLoad: 000007feff740000 000007feff7df000
C:\Windows\system32\msvcrt.dll
(d50.c4c): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols
for ntdll.dll -
ntdll!CsrSetPriorityClass+0x40:
00000000`7779cb60 cc int 3


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

Thanks all. Now its working fine the error was in my call of
DeviceIoControl() in the application. I was passing NULL to the
BytesReturned argument since the msdn description tells the it is optional
and i didnt wanted to use it now i am passing the address of the variable
to store it and its working

On Sun, Aug 19, 2012 at 1:21 PM, wrote:

> Well, the 80000003 says that you took a breakpoint. If you take a
> breakpoint in msvcrt, there’s a good chance it came from malloc/free
> logic, and there has been storage damage which has corrupted a block
> header.
>
> You need to make sure you don’t have a buffer overrun. You should also
> try Application Verifier with all memory options enabled.
>
> But the bottom line in what I’ve been reading: it is nearly impossible for
> a kernel error to cause an app failure. This assumes your driver is
> correct, so if the user sends down a buffer of length N you do not write
> more than N bytes to it; this is particularly important when using Direct
> I/O. Assuming you have not done something like this, then the error is
> solely in your application, and should be debugged as such.
>
> The Visual Studio debugger is a good deal friendlier for app debugging
> than windbg. If all you have is windbg, you need to have proper symbols,
> you need to give a backtrace, and you need to learn to interpret the error
> codes.
> joe
>
>
> > I am not used to windbg can some please interpret what is the cause of
> > following error
> >
> > I am opening my executable in windbg
> >
> > Executable search path is:
> > ModLoad: 00000000039a0000 00000000039a6000 demo_App.exe
> > ModLoad: 00000000776f0000 0000000077899000 ntdll.dll
> > ModLoad: 0000000077160000 000000007727f000
> > C:\Windows\system32\kernel32.dll
> > ModLoad: 000007fefdeb0000 000007fefdf1c000
> > C:\Windows\system32\KERNELBASE.dll
> > ModLoad: 0000000074f50000 0000000074f95000 C:\Program Files\AVAST
> > Software\Avast\snxhk64.dll
> > ModLoad: 000007feff740000 000007feff7df000
> > C:\Windows\system32\msvcrt.dll
> > (d50.c4c): Break instruction exception - code 80000003 (first chance)
> > *** ERROR: Symbol file could not be found. Defaulted to export symbols
> > for ntdll.dll -
> > ntdll!CsrSetPriorityClass+0x40:
> > 00000000`7779cb60 cc int 3
> >
> >
> > —
> > 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
>

“You MUST replace pPendingIrp with NULL while still under spinlock. Or you can
use InterlockedExchangePointer.”

I tried this alex but that didnt worked.

You still MUST do it, otherwise your driver is open to race conditions.
Also, make sure to set Irp->IoStatus.Information to the length of data returned.

Thanks Grigora i have implemented queue for storing the Pended IRP list
entry and i am also passing the size of the returned data

On Sun, Aug 19, 2012 at 7:19 PM, wrote:

> “You MUST replace pPendingIrp with NULL while still under spinlock. Or you
> can
> use InterlockedExchangePointer.”
>
> >I tried this alex but that didnt worked.
>
> You still MUST do it, otherwise your driver is open to race conditions.
> Also, make sure to set Irp->IoStatus.Information to the length of data
> returned.
>
> —
> 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
>

Cancel safe queues are hard to get right for all the little corner cases. Use IoCSQ and you have a tested, well implemented solution to use

d

debt from my phone


From: Gaurav Kumar Singh
Sent: 8/19/2012 6:54 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] APPCRASH while Pending IRP

Thanks Grigora i have implemented queue for storing the Pended IRP list entry and i am also passing the size of the returned data

On Sun, Aug 19, 2012 at 7:19 PM, > wrote:
“You MUST replace pPendingIrp with NULL while still under spinlock. Or you can
use InterlockedExchangePointer.”

>I tried this alex but that didnt worked.

You still MUST do it, otherwise your driver is open to race conditions.
Also, make sure to set Irp->IoStatus.Information to the length of data returned.


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

There is very little you can do to cause an application to crash.
However, the convoluted code that copies one byte to the user buffer
should not cause a problem, providing of course that the length was not 0.
But then you set IoStatus.Information to 0, and since you are using
buffered, I/O, this tells the I/O Manager to copy back 0 bytes to
application space, meaning whatever the app is doing, it is doing with
whatever garbage was in the buffer when the call was made.

I think your app has a bug. You should be debugging it. You are so
focused on your driver that you are thinking that a pending IRP is to
blame; instead, start looking for bugs in your app. This means you debug
IT, and get its backtrace, etc. C000005 means access fault, and you need
to identify what line of your source code is doing this…most likely an
uninitailized pointer, but there are several ways of pointer-mangling that
could result in this error, including damaging the return address from a
function.

You would be better served by showing, not your kernel code, which is
probably irrelevant, but the application code, the source line to which
the error is attributed, and the stack backtrace.
joe

Hello,

I have PCIe device for which we have written a NDIS miniport driver which
also interacts with a user application for some data exchange. To enable
this we have creating a symbolic link which user can use in CreateFile
call by registering a device using NdisRegisterDeviceEx.

The user app sends IOCTL to the driver which we handle in the
DeviceIoControl dispatch routine .For data exchange we want to use pended
IRP method so that the receipt of interrupt from the device can be
indicated to the application. When the DeviceIoControl Receives the
specific IOCTL it pends it and stores the IRP pointer in DeviceExtension
received after NdisRegisterDeviceEx call as follows:

case XXX_CHECK_EVENT:
{
DbgPrint(“CHECK EVENT\n”);
NdisAcquireSpinLock(&pXXXDrvInstance->m_PendingIrpLock);
pXXXDrvInstance->m_pPendingIrp = Irp_p;
if(!Irp_p->Cancel)
{
IoMarkIrpPending(Irp_p);
IoSetCancelRoutine(Irp_p, XXXCancelIrp);

}
else
{
NdisReleaseSpinLock(&pXXXDrvInstance->m_PendingIrpLock);
Status = STATUS_CANCELLED;
break;
}

NdisReleaseSpinLock(&pHpmnDrvInstance->m_PendingIrpLock);
Status = STATUS_PENDING;
break;
}

default:

Status = STATUS_UNSUCCESSFUL;
break;
}

if (Status != STATUS_PENDING)
{
//
// complete the Irp
//
DbgPrint(“Complete \n”);
Irp_p->IoStatus.Status = Status;
IoCompleteRequest(Irp_p, IO_NO_INCREMENT);
}

The device uses MSI for signalling the receipt of data. In my driver’s
DPCforISR I retreive the Pended Irp pointer copy the information in the
IRP buffer and then complete it as follows:

VOID
HpmnNdisDpc(
__in NDIS_HANDLE MiniportInterruptContext_p,
__in ULONG MessageId_p,
__in PVOID MiniportDpcContext_p,
__in PULONG NdisReserved1_p,
__in PULONG NdisReserved2_p
)
{
PIRP pIrp = NULL;
BYTE bMode;
PVOID pBuff;
NTSTATUS Status = STATUS_SUCCESS;
do
{
bMode = XXXGetMode();
NdisDprAcquireSpinLock(&XXXnDrvInstance_l->m_PendingIrpLock);
if(XXXDrvInstance_l->m_pPendingIrp != NULL)
{
DbgPrint(" Mode : %x\n",bMode);

pIrp = XXXDrvInstance_l->m_pPendingIrp;

if(pIrp->Cancel)
{

Status = STATUS_CANCELLED;
break;
}
else
{

pBuff = pIrp->AssociatedIrp.SystemBuffer;

DbgPrint(" Copying \n");
NdisMoveMemory(pBuff,&bMode,sizeof(bMode));
Status = STATUS_SUCCESS;

}
}
}
while(FALSE);
NdisDprReleaseSpinLock(&XXXDrvInstance_l->m_PendingIrpLock);

if(pIrp != NULL)
{
DbgPrint(“completing the IRP\n”);
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
XXXDrvInstance_l->m_pPendingIrp = NULL;
}
}

when i call the user application with the XXX_CHECK_EVENT control code it
results in a APPCRASH :

Problem Event Name: APPCRASH
Application Name: demo_App.exe
Application Version: 0.0.0.0
Application Timestamp: 502f64cd
Fault Module Name: KERNELBASE.dll
Fault Module Version: 6.1.7601.17651
Fault Module Timestamp: 4e21213c
Exception Code: c0000005
Exception Offset: 000000000000a292
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 1033
Additional Information 1: b046
Additional Information 2: b0463d6163e1702cfe7937c497a94fef
Additional Information 3: 3ca0
Additional Information 4: 3ca0db409703bf7afef063aa94280bf5

I havent used a internal queue for storring the pended IRP is that
necessary? Please someone help.

Thanks in advance


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

RTFM. You can’t just read the function prototype and assume you know what
is going on. In the description of BytesReturned, it explicitly says that
if the OVLAPPED pointer is NULL, the BytesReturned pointer cannot be NULL.
Since you were having an app crash, and didn’t show the app code (I have
no idea why you were showing kernel code to debug an application crash),
this was not obvious to anyone here. The FIRST assumption you make when
your app crashes is that your app is wrong.
joe

Thanks all. Now its working fine the error was in my call of
DeviceIoControl() in the application. I was passing NULL to the
BytesReturned argument since the msdn description tells the it is optional
and i didnt wanted to use it now i am passing the address of the variable
to store it and its working

On Sun, Aug 19, 2012 at 1:21 PM, wrote:
>
>> Well, the 80000003 says that you took a breakpoint. If you take a
>> breakpoint in msvcrt, there’s a good chance it came from malloc/free
>> logic, and there has been storage damage which has corrupted a block
>> header.
>>
>> You need to make sure you don’t have a buffer overrun. You should also
>> try Application Verifier with all memory options enabled.
>>
>> But the bottom line in what I’ve been reading: it is nearly impossible
>> for
>> a kernel error to cause an app failure. This assumes your driver is
>> correct, so if the user sends down a buffer of length N you do not write
>> more than N bytes to it; this is particularly important when using
>> Direct
>> I/O. Assuming you have not done something like this, then the error is
>> solely in your application, and should be debugged as such.
>>
>> The Visual Studio debugger is a good deal friendlier for app debugging
>> than windbg. If all you have is windbg, you need to have proper
>> symbols,
>> you need to give a backtrace, and you need to learn to interpret the
>> error
>> codes.
>> joe
>>
>>
>> > I am not used to windbg can some please interpret what is the cause of
>> > following error
>> >
>> > I am opening my executable in windbg
>> >
>> > Executable search path is:
>> > ModLoad: 00000000039a0000 00000000039a6000 demo_App.exe
>> > ModLoad: 00000000776f0000 0000000077899000 ntdll.dll
>> > ModLoad: 0000000077160000 000000007727f000
>> > C:\Windows\system32\kernel32.dll
>> > ModLoad: 000007fefdeb0000 000007fefdf1c000
>> > C:\Windows\system32\KERNELBASE.dll
>> > ModLoad: 0000000074f50000 0000000074f95000 C:\Program Files\AVAST
>> > Software\Avast\snxhk64.dll
>> > ModLoad: 000007feff740000 000007feff7df000
>> > C:\Windows\system32\msvcrt.dll
>> > (d50.c4c): Break instruction exception - code 80000003 (first chance)
>> > *** ERROR: Symbol file could not be found. Defaulted to export
>> symbols
>> > for ntdll.dll -
>> > ntdll!CsrSetPriorityClass+0x40:
>> > 00000000`7779cb60 cc int 3
>> >
>> >
>> > —
>> > 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
>>
>
> —
> 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

>In the description of BytesReturned, it explicitly says that
if the OVLAPPED pointer is NULL, the BytesReturned pointer cannot be NULL.

Even then, if DeviceIoControl completes immediately, the byte count will be placed to *BytesReturned, not to Overlapped. So one pretty much HAVE to have non-NULL BytesReturned pointer.

>>In the description of BytesReturned, it explicitly says that

if the OVLAPPED pointer is NULL, the BytesReturned pointer cannot be NULL.

Even then, if DeviceIoControl completes immediately, the byte count will
be placed to *BytesReturned, not to Overlapped. So one pretty much HAVE to
have non-NULL BytesReturned pointer.

Not true. The documentation states:

lpBytesReturned [out, optional]
A pointer to a variable that receives the size of the data stored in the
output buffer, in bytes.

If the output buffer is too small to receive any data, the call fails,
GetLastError returns ERROR_INSUFFICIENT_BUFFER, and lpBytesReturned is
zero.

If the output buffer is too small to hold all of the data but can hold
some entries, some drivers will return as much data as fits. In this case,
the call fails, GetLastError returns ERROR_MORE_DATA, and lpBytesReturned
indicates the amount of data received. Your application should call
DeviceIoControl again with the same operation, specifying a new starting
point.

If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even when an
operation returns no output data and lpOutBuffer is NULL, DeviceIoControl
makes use of lpBytesReturned. After such an operation, the value of
lpBytesReturned is meaningless.

If lpOverlapped is not NULL, lpBytesReturned can be NULL. If this
parameter is not NULL and the operation returns data, lpBytesReturned is
meaningless until the overlapped operation has completed. To retrieve the
number of bytes returned, call GetOverlappedResult. If hDevice is
associated with an I/O completion port, you can retrieve the number of
bytes returned by calling GetQueuedCompletionStatus.


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

lpBytesReturned MAY only be NULL only and ONLY if the driver is guaranteed to return STATUS_PENDING for the given IOCTL, and Overapped is non-NULL. Of course, this is up to the contract between an application and the driver. In general case, when a driver may for some IOCTLs complete the IO synchronously, lpBytesReturned MUST be non-zero.

Sometimes an application (COMCTL32.OCX, that’s you) makes unfounded assumptions about IOCTLs being completed one or another way, and that’s causing problems when these assumptions don’t hold true.

Then the documentation is incorrect, and should be fixed.
joe

lpBytesReturned MAY only be NULL only and ONLY if the driver is guaranteed
to return STATUS_PENDING for the given IOCTL, and Overapped is non-NULL.
Of course, this is up to the contract between an application and the
driver. In general case, when a driver may for some IOCTLs complete the IO
synchronously, lpBytesReturned MUST be non-zero.

Sometimes an application (COMCTL32.OCX, that’s you) makes unfounded
assumptions about IOCTLs being completed one or another way, and that’s
causing problems when these assumptions don’t hold true.


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