SYSTEM_SERVICE_EXCEPTION (3b) while running WHQL tests

Hi Guys,

we have developed virtual serial port driver. which is working fine in
general conditions.
while running WHQL test(DF-Fuzz Misc API test(Certification)) getting
system crash with with bugcheck code BugCheck 3B, {c0000005,
fffff8800456afaf, fffff880065d4d30, 0}.

in order debug this issue we have connected windgb to test machine, but we
didn’t found any system crash.
atfer that we enabled driver verifier in test machine and started
debugging. from that time onwards getting system crash with different
bugcheck BugCheck C9, {7, fffff8800464d700, fffff98004dcce10, 0} after
opening the virtual serial port form any application.

after doing more debugging on this bugcheck we got to know that
“IOCTL_SERIAL_WAIT_ON_MASK” because of this Irp system is getting crash.

i am not getting from where this Irp is completed in driver before the
cancel routine for this Irp got called by the system.

i have gone through the source of “IOCTL_SERIAL_WAIT_ON_MASK” handling
again and again but didn’t found any mistakes in sources.

please help me to resolve this issue where i am doing wrong.
here i am copying my code, please correct me where i am going wrong

if (outputBufferLength < sizeof(ULONG))
{
status = STATUS_BUFFER_TOO_SMALL;
break;
}

//Acquire SpinLock
KeAcquireSpinLock(
&SerialDevExt->SpinLock,
&OldIrql
);

// capture the current irp if any
CurrentWaitIrp = SerialDevExt->CurrentMaskIrp;
SerialDevExt->CurrentMaskIrp = NULL;
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK Previous
CurrentMaskIrp(0x%X)\n”,CurrentWaitIrp));

DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK
CurrentMaskIrp(0x%X)\n”,SerialDevExt->CurrentMaskIrp));

//Release the SpinLock
KeReleaseSpinLock(
&SerialDevExt->SpinLock,
OldIrql
);

if (CurrentWaitIrp != NULL)
{
IoSetCancelRoutine(CurrentWaitIrp, NULL);

DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,(“SerialIoControl: WAIT_ON_MASK
complete previous wait\n”));
*((PULONG)CurrentWaitIrp->AssociatedIrp.SystemBuffer) = 0;
//DbgPrint(“WOM 3 Completed\n”);
COMPLETE_REQUEST( CurrentWaitIrp, STATUS_SUCCESS, sizeof(ULONG));
CurrentWaitIrp = NULL;
}

//Acquire SpinLock
KeAcquireSpinLock(
&SerialDevExt->SpinLock,
&OldIrql
);

if (SerialDevExt->CurrentMask == 0)
{
// can only set if mask is not zero
status = STATUS_UNSUCCESSFUL;
}
else
{
//If the CurrentMask has something comman with StatusHistoryMask
//(i.e. the user mode is waiting for an event which has already
//occurred in the driver and has not been communicated to user mode till
now)
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl:StatusHistoryMask(0x%X),CurrentMask(0x%X)\n”,
SerialDevExt->StatusHistoryMask,SerialDevExt->CurrentMask));

if(pSerialQueue->Count == 0)
{
//If there are no bytes in receive queue then clear the SERIAL_EV_RXCHAR
//from the StatusHistoryMask. Because after setting this flag in
StatusHistoryMask
//Data has already been read from the buffer through serial read.
SerialDevExt->StatusHistoryMask &= ~SERIAL_EV_RXCHAR;
}

CommonMask = (SerialDevExt->StatusHistoryMask & SerialDevExt->CurrentMask);
if(CommonMask)
{
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl: 0x%X communicated to application\n”, CommonMask));
//Remove that event from StatusHistoryMask
SerialDevExt->StatusHistoryMask &= ~(CommonMask);
*((PULONG)ioBuffer) = CommonMask;
Irp->IoStatus.Information = sizeof(ULONG);
}
IoSetCancelRoutine(Irp, PendingComIrpCancelRoutine);
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl: IOCTL_SERIAL_WAIT_ON_MASK setting CurrentMaskIrp as
(0x%X)\n”,
SerialDevExt->CurrentMaskIrp) );
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl: WAIT_ON_MASK STATUS_PENDING\n”) );

if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
{
status = STATUS_CANCELLED;
}
else
{
IoMarkIrpPending(Irp);
status = Irp->IoStatus.Status = STATUS_PENDING;
SerialDevExt->CurrentMaskIrp = Irp;
}
//
/*
// is IRP to be canceled?
if (Irp->Cancel)
{
// IRP is to be cancelled
PDRIVER_CANCEL OldCancelRoutine = IoSetCancelRoutine(Irp, NULL);

// cancel routine already called?
if (OldCancelRoutine != NULL)
{
// no, then cancel IRP here
status = STATUS_CANCELLED;
SerialDevExt->CurrentMaskIrp = NULL;
}
else
{
// yes, cancel routine will complete IRP
IoMarkIrpPending(Irp);
}
}
else
{
// Irp is not being cancelled, so mark it pending
IoMarkIrpPending(Irp);
}
//
*/
//Mark the IRP pending
//IoMarkIrpPending(Irp); //removed for certification
}
//Release the SpinLock
KeReleaseSpinLock(
&SerialDevExt->SpinLock,
OldIrql
);

if (status != STATUS_PENDING)
{
//Irp->IoStatus.Status = status;
//IoCompleteRequest( Irp, IO_NO_INCREMENT ); //IO_SERIAL_INCREMENT
COMPLETE_REQUEST( Irp, status, Irp->IoStatus.Information);
}
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, (“\nSerialIoControl <==
Status(0x%X)\n”,status));

return status;

If you can’t trap the crash when winbdg is running, you should analyze the generated crash dump afterwards in windbg.

It would be more useful if you gave the windbg output from !analzye –v, but just taking a quick guess…

Your code seems to have a spinlock in the device extension, and you release that lock and execute:

if (CurrentWaitIrp != NULL)
{
IoSetCancelRoutine(CurrentWaitIrp, NULL);

Offhand it looks like there is nothing to prevent some other thread/processor from completing the irp held in CurrentWaitIrp, and when you go to call IoSetCancelRoutine, the Irp is already gone.

Jan

From: on behalf of johnny basha
Reply-To: Windows List
Date: Thursday, August 3, 2017 at 8:14 AM
To: Windows List
Subject: [ntdev] SYSTEM_SERVICE_EXCEPTION (3b) while running WHQL tests

Hi Guys,

we have developed virtual serial port driver. which is working fine in general conditions.
while running WHQL test(DF-Fuzz Misc API test(Certification)) getting system crash with with bugcheck code BugCheck 3B, {c0000005, fffff8800456afaf, fffff880065d4d30, 0}.

in order debug this issue we have connected windgb to test machine, but we didn’t found any system crash.
atfer that we enabled driver verifier in test machine and started debugging. from that time onwards getting system crash with different bugcheck BugCheck C9, {7, fffff8800464d700, fffff98004dcce10, 0} after opening the virtual serial port form any application.

after doing more debugging on this bugcheck we got to know that “IOCTL_SERIAL_WAIT_ON_MASK” because of this Irp system is getting crash.

i am not getting from where this Irp is completed in driver before the cancel routine for this Irp got called by the system.

i have gone through the source of “IOCTL_SERIAL_WAIT_ON_MASK” handling again and again but didn’t found any mistakes in sources.

please help me to resolve this issue where i am doing wrong.
here i am copying my code, please correct me where i am going wrong

if (outputBufferLength < sizeof(ULONG))
{
status = STATUS_BUFFER_TOO_SMALL;
break;
}

//Acquire SpinLock
KeAcquireSpinLock(
&SerialDevExt->SpinLock,
&OldIrql
);

// capture the current irp if any
CurrentWaitIrp = SerialDevExt->CurrentMaskIrp;
SerialDevExt->CurrentMaskIrp = NULL;
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK Previous CurrentMaskIrp(0x%X)\n”,CurrentWaitIrp));

DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK CurrentMaskIrp(0x%X)\n”,SerialDevExt->CurrentMaskIrp));

//Release the SpinLock
KeReleaseSpinLock(
&SerialDevExt->SpinLock,
OldIrql
);

if (CurrentWaitIrp != NULL)
{
IoSetCancelRoutine(CurrentWaitIrp, NULL);

DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,(“SerialIoControl: WAIT_ON_MASK complete previous wait\n”));
((PULONG)CurrentWaitIrp->AssociatedIrp.SystemBuffer) = 0;
//DbgPrint(“WOM 3 Completed\n”);
COMPLETE_REQUEST( CurrentWaitIrp, STATUS_SUCCESS, sizeof(ULONG));
CurrentWaitIrp = NULL;
}

//Acquire SpinLock
KeAcquireSpinLock(
&SerialDevExt->SpinLock,
&OldIrql
);

if (SerialDevExt->CurrentMask == 0)
{
// can only set if mask is not zero
status = STATUS_UNSUCCESSFUL;
}
else
{
//If the CurrentMask has something comman with StatusHistoryMask
//(i.e. the user mode is waiting for an event which has already
//occurred in the driver and has not been communicated to user mode till now)
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl:StatusHistoryMask(0x%X),CurrentMask(0x%X)\n”, SerialDevExt->StatusHistoryMask,SerialDevExt->CurrentMask));

if(pSerialQueue->Count == 0)
{
//If there are no bytes in receive queue then clear the SERIAL_EV_RXCHAR
//from the StatusHistoryMask. Because after setting this flag in StatusHistoryMask
//Data has already been read from the buffer through serial read.
SerialDevExt->StatusHistoryMask &= ~SERIAL_EV_RXCHAR;
}

CommonMask = (SerialDevExt->StatusHistoryMask & SerialDevExt->CurrentMask);
if(CommonMask)
{
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl: 0x%X communicated to application\n”, CommonMask));
//Remove that event from StatusHistoryMask
SerialDevExt->StatusHistoryMask &= ~(CommonMask);
((PULONG)ioBuffer) = CommonMask;
Irp->IoStatus.Information = sizeof(ULONG);
}
IoSetCancelRoutine(Irp, PendingComIrpCancelRoutine);
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl: IOCTL_SERIAL_WAIT_ON_MASK setting CurrentMaskIrp as (0x%X)\n”,
SerialDevExt->CurrentMaskIrp) );
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“SerialIoControl: WAIT_ON_MASK STATUS_PENDING\n”) );

if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
{
status = STATUS_CANCELLED;
}
else
{
IoMarkIrpPending(Irp);
status = Irp->IoStatus.Status = STATUS_PENDING;
SerialDevExt->CurrentMaskIrp = Irp;
}
//
/
// is IRP to be canceled?
if (Irp->Cancel)
{
// IRP is to be cancelled
PDRIVER_CANCEL OldCancelRoutine = IoSetCancelRoutine(Irp, NULL);

// cancel routine already called?
if (OldCancelRoutine != NULL)
{
// no, then cancel IRP here
status = STATUS_CANCELLED;
SerialDevExt->CurrentMaskIrp = NULL;
}
else
{
// yes, cancel routine will complete IRP
IoMarkIrpPending(Irp);
}
}
else
{
// Irp is not being cancelled, so mark it pending
IoMarkIrpPending(Irp);
}
//
/
//Mark the IRP pending
//IoMarkIrpPending(Irp); //removed for certification
}
//Release the SpinLock
KeReleaseSpinLock(
&SerialDevExt->SpinLock,
OldIrql
);

if (status != STATUS_PENDING)
{
//Irp->IoStatus.Status = status;
//IoCompleteRequest( Irp, IO_NO_INCREMENT ); //IO_SERIAL_INCREMENT
COMPLETE_REQUEST( Irp, status, Irp->IoStatus.Information);
}
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
(“\nSerialIoControl <== Status(0x%X)\n”,status));

return status;

— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at

0: kd> !analyze -v
*******************************************************************************
*
*
* Bugcheck Analysis
*
*
*
*******************************************************************************

DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 0000000000000007, IRP passed to IoCompleteRequest still has cancel
routine set
Arg2: fffff88000dbdc90, the cancel routine pointer
Arg3: fffff98012476e10, the IRP
Arg4: 0000000000000000

Debugging Details:

BUGCHECK_STR: 0xc9_7

DRIVER_VERIFIER_IO_VIOLATION_TYPE: 7

IRP_CANCEL_ROUTINE:
SerRdr!PendingComIrpCancelRoutine+0
[c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\dispatch.c @ 1102]
fffff880`00dbdc90 4889542410 mov qword ptr [rsp+10h],rdx

FAULTING_IP:
SerRdr!PendingComIrpCancelRoutine+0
[c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\dispatch.c @ 1102]
fffff880`00dbdc90 4889542410 mov qword ptr [rsp+10h],rdx

FOLLOWUP_IP:
SerRdr!PendingComIrpCancelRoutine+0
[c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\dispatch.c @ 1102]
fffff880`00dbdc90 4889542410 mov qword ptr [rsp+10h],rdx

IRP_ADDRESS: fffff98012476e10

DEVICE_OBJECT: fffffa8003a30060

DRIVER_OBJECT: fffffa8003ac0570

IMAGE_NAME: SerRdr.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 5983fda7

MODULE_NAME: SerRdr

FAULTING_MODULE: fffff88000db9000 SerRdr

DEFAULT_BUCKET_ID: WIN7_DRIVER_FAULT

PROCESS_NAME: SerRedir.exe

CURRENT_IRQL: 2

ANALYSIS_VERSION: 6.3.9600.17237 (debuggers(dbg).140716-0327) amd64fre

LAST_CONTROL_TRANSFER: from fffff80002db9cc2 to fffff80002cbfcf0

STACK_TEXT:
fffff88007034fa8 fffff80002db9cc2 : 0000000000000007 fffffa8004c5fb50
0000000000000065 fffff80002d037e8 : nt!RtlpBreakWithStatusInstruction
fffff88007034fb0 fffff80002dbaaae : fffff98000000003 0000000000000000
fffff80002d04040 00000000000000c9 : nt!KiBugCheckDebugBreak+0x12
fffff88007035010 fffff80002cc7fc4 : fffffa8001b43b80 fffff800031660f2
fffff88007030000 fffff88007036000 : nt!KeBugCheck2+0x71e
fffff880070356e0 fffff8000316d1a2 : 00000000000000c9 0000000000000007
fffff88000dbdc90 fffff98012476e10 : nt!KeBugCheckEx+0x104
fffff88007035720 fffff88000dca396 : fffff88000dcdbc0 0000000000000000
fffff98012514ee0 fffffa800195bcb0 : nt!IovCompleteRequest+0x72
fffff880070357f0 fffff88000dca932 : fffffa8003a301b0 fffff980166ac7ee
0000000000000001 fffffa800195bcb0 : SerRdr!PutDataInQueue+0x466
[c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\serialdevice.c @ 1870]
fffff88007035860 fffff88000dc0cc9 : fffffa800195bcb0 fffff98012514ee0
0000000000000065 0000000000000003 : SerRdr!RedirectorWrite+0x592
[c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\serialdevice.c @ 960]
fffff88007035960 fffff80003173d46 : fffffa800195bcb0 fffff98012514ee0
fffff8000302b788 0000000000000028 : SerRdr!SrlrdrDispatchWrite+0x79
[c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\dispatch.c @ 36]
fffff880070359a0 fffff80002fd3afb : 0000000000000001 fffffa8004bfcdc0
0000000000000000 fffffa8005532440 : nt!IovCallDriver+0x566
fffff88007035a00 fffff80002fdf2f3 : fffff98012514ff8 fffffa8004bfce10
fffffa8004bfcdc0 fffff80002fc4701 : nt!IopSynchronousServiceTail+0xfb
fffff88007035a70 fffff80002cc7153 : fffffa8004c5fb01 00000000000001a4
0000000000000000 000000000235f1e8 : nt!NtWriteFile+0x7e2
fffff88007035b70 0000000076f2139a : 000007fefd187871 0000000000000000
000000000235f1f8 000000000033a4ac : nt!KiSystemServiceCopyEnd+0x13
000000000235f0e8 000007fefd187871 : 0000000000000000 000000000235f1f8
000000000033a4ac 0000000000000000 : ntdll!ZwWriteFile+0xa
000000000235f0f0 0000000076cd35d6 : 0000000000000000 0000000000000000
000000000235f680 000000000235f248 : KERNELBASE!WriteFile+0xfe
000000000235f160 0000000140011227 : 000000000012fb30 000000000235f210
000000000012fb30 000000000235f210 : kernel32!WriteFileImplementation+0x36
000000000235f1a0 000000014000b966 : 000000000012fb30 00000000023b5820
0000000000000002 0000000000000000 : SerRedir+0x11227
000000000235f230 0000000140012b90 : 0000000000000004 00000001402a5178
0000000000000004 0000004600ba0013 : SerRedir+0xb966
000000000235fee0 0000000076cc652d : 0000000000000004 00000000003329c8
00000000023b5820 ffffffff0000017c : SerRedir+0x12b90
000000000235ff60 0000000076efc521 : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : kernel32!BaseThreadInitThunk+0xd
000000000235ff90 0000000000000000 : 0000000000000000 0000000000000000
0000000000000000 0000000000000000 : ntdll!RtlUserThreadStart+0x1d

STACK_COMMAND: .bugcheck ; kb

FAULTING_SOURCE_LINE:
c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\dispatch.c

FAULTING_SOURCE_FILE:
c:\sources\sourcecode_8142\mcs8140_serialserver\serialservices_adddevice
_serial_project_working_half_certify\dispatch.c

FAULTING_SOURCE_LINE_NUMBER: 1102

FAULTING_SOURCE_CODE:
1098: PSERIAL_DEVICE_EXTENSION SerDevExt = DeviceObject->DeviceExtension;
1099: // Complete the current wait irp with status cancelled
1100:
1101: DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_VERBOSE, (“\n CancelWaitIrp ==>
\n”));

1102:
1103: // Acquire our queue-specific queue lock. Note that we stayed at
DISPATCH_LEVEL
1104: // when we released the cancel spin lock
1105:
1106:
1107: KeAcquireSpinLock(&SerDevExt->SpinLock, &OldIrql);

SYMBOL_NAME: SerRdr!PendingComIrpCancelRoutine+0

FOLLOWUP_NAME: MachineOwner

FAILURE_BUCKET_ID: X64_0xc9_7_VRF_SerRdr!PendingComIrpCancelRoutine+0

BUCKET_ID: X64_0xc9_7_VRF_SerRdr!PendingComIrpCancelRoutine+0

ANALYSIS_SOURCE: KM

FAILURE_ID_HASH_STRING:
km:x64_0xc9_7_vrf_serrdr!pendingcomirpcancelroutine+0

FAILURE_ID_HASH: {38303584-0c00-00c2-8ae7-cd18d8b52061}

Followup: MachineOwner

and the Irp i found by printing debug statements are

*SerialIoControl : Irp(0x12476E10) *

SerialIoControl : IRQL(0x0)

SerialIoControl ==>
IoControlCode 1B0048
SerialIoControl: IOCTL_SERIAL_WAIT_ON_MASK
SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK Previous CurrentMaskIrp(0x0)
SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK CurrentMaskIrp(0x0)
SerialIoControl:StatusHistoryMask(0x0),CurrentMask(0x179)
SerialIoControl: IOCTL_SERIAL_WAIT_ON_MASK setting CurrentMaskIrp as (0x0)
SerialIoControl: WAIT_ON_MASK STATUS_PENDING

SerialIoControl <== Status(0x103)

This Irp "*SerialIoControl : Irp(0x12476E10) " *is causing the bug

On Thu, Aug 3, 2017 at 9:17 PM, Jan Bottorff <
xxxxx@lists.osr.com> wrote:

> If you can’t trap the crash when winbdg is running, you should analyze the
> generated crash dump afterwards in windbg.
>
>
>
> It would be more useful if you gave the windbg output from !analzye –v,
> but just taking a quick guess…
>
>
>
> Your code seems to have a spinlock in the device extension, and you
> release that lock and execute:
>
>
>
> if (CurrentWaitIrp != NULL)
>
> {
>
> IoSetCancelRoutine(CurrentWaitIrp, NULL);
>
>
>
> Offhand it looks like there is nothing to prevent some other
> thread/processor from completing the irp held in CurrentWaitIrp, and when
> you go to call IoSetCancelRoutine, the Irp is already gone.
>
>
>
> Jan
>
>
>
> *From: * on behalf of johnny basha <
> xxxxx@gmail.com>
> *Reply-To: *Windows List
> *Date: *Thursday, August 3, 2017 at 8:14 AM
> *To: *Windows List
> *Subject: *[ntdev] SYSTEM_SERVICE_EXCEPTION (3b) while running WHQL tests
>
>
>
> Hi Guys,
>
>
>
> we have developed virtual serial port driver. which is working fine in
> general conditions.
>
> while running WHQL test(DF-Fuzz Misc API test(Certification)) getting
> system crash with with bugcheck code BugCheck 3B, {c0000005,
> fffff8800456afaf, fffff880065d4d30, 0}.
>
>
>
>
>
> in order debug this issue we have connected windgb to test machine, but
> we didn’t found any system crash.
>
> atfer that we enabled driver verifier in test machine and started
> debugging. from that time onwards getting system crash with different
> bugcheck BugCheck C9, {7, fffff8800464d700, fffff98004dcce10, 0} after
> opening the virtual serial port form any application.
>
>
>
>
>
> after doing more debugging on this bugcheck we got to know that
> “IOCTL_SERIAL_WAIT_ON_MASK” because of this Irp system is getting crash.
>
>
>
> i am not getting from where this Irp is completed in driver before the
> cancel routine for this Irp got called by the system.
>
>
>
> i have gone through the source of “IOCTL_SERIAL_WAIT_ON_MASK” handling
> again and again but didn’t found any mistakes in sources.
>
>
>
> please help me to resolve this issue where i am doing wrong.
>
> here i am copying my code, please correct me where i am going wrong
>
>
>
> if (outputBufferLength < sizeof(ULONG))
>
> {
>
> status = STATUS_BUFFER_TOO_SMALL;
>
> break;
>
> }
>
>
>
> //Acquire SpinLock
>
> KeAcquireSpinLock(
>
> &SerialDevExt->SpinLock,
>
> &OldIrql
>
> );
>
>
>
> // capture the current irp if any
>
> CurrentWaitIrp = SerialDevExt->CurrentMaskIrp;
>
> SerialDevExt->CurrentMaskIrp = NULL;
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
>
> (“SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK Previous
> CurrentMaskIrp(0x%X)\n”,CurrentWaitIrp));
>
>
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
>
> (“SerialIoControl:IOCTL_SERIAL_WAIT_ON_MASK CurrentMaskIrp(0x%X)\n”,
> SerialDevExt->CurrentMaskIrp));
>
>
>
> //Release the SpinLock
>
> KeReleaseSpinLock(
>
> &SerialDevExt->SpinLock,
>
> OldIrql
>
> );
>
>
>
> if (CurrentWaitIrp != NULL)
>
> {
>
> IoSetCancelRoutine(CurrentWaitIrp, NULL);
>
>
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,(“SerialIoControl:
> WAIT_ON_MASK complete previous wait\n”));
>
> *((PULONG)CurrentWaitIrp->AssociatedIrp.SystemBuffer) = 0;
>
> //DbgPrint(“WOM 3 Completed\n”);
>
> COMPLETE_REQUEST( CurrentWaitIrp, STATUS_SUCCESS, sizeof(ULONG));
>
> CurrentWaitIrp = NULL;
>
> }
>
>
>
> //Acquire SpinLock
>
> KeAcquireSpinLock(
>
> &SerialDevExt->SpinLock,
>
> &OldIrql
>
> );
>
>
>
>
>
>
>
> if (SerialDevExt->CurrentMask == 0)
>
> {
>
> // can only set if mask is not zero
>
> status = STATUS_UNSUCCESSFUL;
>
> }
>
> else
>
> {
>
> //If the CurrentMask has something comman with StatusHistoryMask
>
> //(i.e. the user mode is waiting for an event which has already
>
> //occurred in the driver and has not been communicated to user mode till
> now)
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
>
> (“SerialIoControl:StatusHistoryMask(0x%X),CurrentMask(0x%X)\n”,
> SerialDevExt->StatusHistoryMask,SerialDevExt->CurrentMask));
>
>
>
> if(pSerialQueue->Count == 0)
>
> {
>
> //If there are no bytes in receive queue then clear the SERIAL_EV_RXCHAR
>
> //from the StatusHistoryMask. Because after setting this flag in
> StatusHistoryMask
>
> //Data has already been read from the buffer through serial read.
>
> SerialDevExt->StatusHistoryMask &= ~SERIAL_EV_RXCHAR;
>
> }
>
>
>
>
>
> CommonMask = (SerialDevExt->StatusHistoryMask &
> SerialDevExt->CurrentMask);
>
> if(CommonMask)
>
> {
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
>
> (“SerialIoControl: 0x%X communicated to application\n”, CommonMask));
>
> //Remove that event from StatusHistoryMask
>
> SerialDevExt->StatusHistoryMask &= ~(CommonMask);
>
> ((PULONG)ioBuffer) = CommonMask;
>
> Irp->IoStatus.Information = sizeof(ULONG);
>
> }
>
> IoSetCancelRoutine(Irp, PendingComIrpCancelRoutine);
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
>
> (“SerialIoControl: IOCTL_SERIAL_WAIT_ON_MASK setting CurrentMaskIrp as
> (0x%X)\n”,
>
> SerialDevExt->CurrentMaskIrp) );
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
>
> (“SerialIoControl: WAIT_ON_MASK STATUS_PENDING\n”) );
>
>
>
> if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
>
> {
>
> status = STATUS_CANCELLED;
>
> }
>
> else
>
> {
>
> IoMarkIrpPending(Irp);
>
> status = Irp->IoStatus.Status = STATUS_PENDING;
>
> SerialDevExt->CurrentMaskIrp = Irp;
>
> }
>
> //
>
> /

>
> // is IRP to be canceled?
>
> if (Irp->Cancel)
>
> {
>
> // IRP is to be cancelled
>
> PDRIVER_CANCEL OldCancelRoutine = IoSetCancelRoutine(Irp, NULL);
>
>
>
> // cancel routine already called?
>
> if (OldCancelRoutine != NULL)
>
> {
>
> // no, then cancel IRP here
>
> status = STATUS_CANCELLED;
>
> SerialDevExt->CurrentMaskIrp = NULL;
>
> }
>
> else
>
> {
>
> // yes, cancel routine will complete IRP
>
> IoMarkIrpPending(Irp);
>
> }
>
> }
>
> else
>
> {
>
> // Irp is not being cancelled, so mark it pending
>
> IoMarkIrpPending(Irp);
>
> }
>
> //
>
> */
>
> //Mark the IRP pending
>
> //IoMarkIrpPending(Irp); //removed for certification
>
> }
>
> //Release the SpinLock
>
> KeReleaseSpinLock(
>
> &SerialDevExt->SpinLock,
>
> OldIrql
>
> );
>
>
>
> if (status != STATUS_PENDING)
>
> {
>
> //Irp->IoStatus.Status = status;
>
> //IoCompleteRequest( Irp, IO_NO_INCREMENT ); //IO_SERIAL_INCREMENT
>
> COMPLETE_REQUEST( Irp, status, Irp->IoStatus.Information);
>
> }
>
> DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE,
>
> (“\nSerialIoControl <== Status(0x%X)\n”,status));
>
>
>
> return status;
>
>
>
>
>
> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars
> on crash dump analysis, WDF, Windows internals and software drivers!
> Details at To unsubscribe, visit the List Server section of OSR Online at
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

johnny basha wrote:

0: kd> !analyze -v
*******************************************************************************
*
*
* Bugcheck Analysis
*
*
*
*******************************************************************************

DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 0000000000000007, IRP passed to IoCompleteRequest still has
cancel routine set
Arg2: fffff88000dbdc90, the cancel routine pointer
Arg3: fffff98012476e10, the IRP
Arg4: 0000000000000000

Could that error message possibly be more clear? You need to look at
serialdevice.c line 1870. That line is completing a request that still
has a cancel routine.


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