From: Daniel Zhang on
I get this error log in windbg

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

INACCESSIBLE_BOOT_DEVICE (7b)
During the initialization of the I/O system, it is possible that the
driver
for the boot device failed to initialize the device that the system is
attempting to boot from, or it is possible for the file system that is
supposed to read that device to either fail its initialization or to
simply
not recognize the data on the boot device as a file system structure
that
it recognizes. In the former case, the argument (#1) is the address
of a
Unicode string data structure that is the ARC name of the device from
which
the boot was being attempted. In the latter case, the argument (#1)
is the
address of the device object that could not be mounted.
If this is the initial setup of the system, then this error can occur
if
the system was installed on an unsupported disk or SCSI controller.
Note
that some controllers are supported only by drivers which are in the
Windows
Driver Library (WDL) which requires the user to do a custom install.
See
the Windows Driver Library for more information.
This error can also be caused by the installation of a new SCSI
adapter or
disk controller or repartitioning the disk with the system partition.
If
this is the case, on x86 systems the boot.ini file must be edited or
on ARC
systems setup must be run. See the "Advanced Server System
Administrator's
User Guide" for information on changing boot.ini.
If the argument is a pointer to an ARC name string, then the format of
the
first two (and in this case only) longwords will be:
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
That is, the first longword will contain something like 00800020 where
20
is the actual length of the Unicode string, and the next longword will
contain the address of buffer. This address will be in system space,
so
the high order bit will be set.
If the argument is a pointer to a device object, then the format of
the first
word will be:
USHORT Type;
That is, the first word will contain a 0003, where the Type code will
ALWAYS
be 0003.
Note that this makes it immediately obvious whether the argument is a
pointer
to an ARC name string or a device object, since a Unicode string can
never
have an odd number of bytes, and a device object will always have a
Type
code of 3.
Arguments:
Arg1: f9bfa528, Pointer to the device object or Unicode string of ARC
name
Arg2: c0000034
Arg3: 00000000
Arg4: 00000000

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


DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x7B

PROCESS_NAME: System

LAST_CONTROL_TRANSFER: from 804f880d to 80527da8

STACK_TEXT:
f9bfa090 804f880d 00000003 f9bfa3ec 00000000 nt!
RtlpBreakWithStatusInstruction
f9bfa0dc 804f93fa 00000003 00000000 80087000 nt!KiBugCheckDebugBreak
+0x19
f9bfa4bc 804f9925 0000007b f9bfa528 c0000034 nt!KeBugCheck2+0x574
f9bfa4dc 80685be9 0000007b f9bfa528 c0000034 nt!KeBugCheckEx+0x1b
f9bfa644 80689d06 80087000 00000000 80087000 nt!IopMarkBootPartition
+0xf5
f9bfa694 80686a48 80087000 f9bfa6b0 00043000 nt!
IopInitializeBootDrivers+0x4ba
f9bfa83c 80684edd 80087000 00000000 819965b8 nt!IoInitSystem+0x712
f9bfadac 805c5a06 80087000 00000000 00000000 nt!Phase1Initialization
+0x9b5
f9bfaddc 80541fa2 80684528 80087000 00000000 nt!PspSystemThreadStartup
+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16


STACK_COMMAND: kb

FOLLOWUP_IP:
nt!IopMarkBootPartition+f5
80685be9 8d85e0feffff lea eax,[ebp-120h]

SYMBOL_STACK_INDEX: 4

SYMBOL_NAME: nt!IopMarkBootPartition+f5

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: nt

IMAGE_NAME: ntkrnlpa.exe

DEBUG_FLR_IMAGE_TIMESTAMP: 42250a1d

FAILURE_BUCKET_ID: 0x7B_nt!IopMarkBootPartition+f5

BUCKET_ID: 0x7B_nt!IopMarkBootPartition+f5

Followup: MachineOwner
From: Wayne on
That means you have done something wrong for the system boot device. Since
you are writing a disk filter driver, I think you should check whether you
pass all IRPs to lower driver that you don't/ cannot care about.

--
Thanks
Wayne

From: Daniel Zhang on
Wayne,Thank you for your help. But I think I have already passed all
the irp to the lower driver. Through the infomation from the core dump
file, I felt that the system was not crashed at my filter driver.
Below is my code,could you please find some error for me?


#include "stddcls.h"
#include "driver.h"

#include <srb.h>
#include <scsi.h>

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT
pdo);
VOID DriverUnload(IN PDRIVER_OBJECT fido);
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fido, IN PIRP Irp);
ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo);
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp,
PDEVICE_EXTENSION pdx);
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP
Irp, PDEVICE_EXTENSION pdx);

///////////////////////////////////////////////////////////////////////////////
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{ // DriverEntry
KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n",
DriverObject));

// Initialize function pointers
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
for (int i = 0; i < arraysize(DriverObject->MajorFunction); ++i)
DriverObject->MajorFunction[i] = DispatchAny;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_SCSI] = DispatchForSCSI;

return STATUS_SUCCESS;
} // DriverEntry


#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{ // DriverUnload
PAGED_CODE();
KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX
\n", DriverObject));
} // DriverUnload


BOOLEAN USB_Disk(IN PDEVICE_OBJECT pDevice)
{
UNICODE_STRING usb_disk_name;
RtlInitUnicodeString(&usb_disk_name,L"\\driver\\usbstor");

PDRIVER_OBJECT pDriver = pDevice->DriverObject;
KdPrint(("driver name:%wZ\n",&pDriver->DriverName));
if (!RtlCompareUnicodeString(&pDriver-
>DriverName,&usb_disk_name,TRUE))
{
KdPrint(("Find a USB disk device!\n"));
return TRUE;
}
KdPrint(("This is not a USB disk device!"));
return FALSE;
}

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT
pdo)
{ // AddDevice
PAGED_CODE();
NTSTATUS status;

PDEVICE_OBJECT fido;

if (!USB_Disk(pdo))
{
return STATUS_SUCCESS;
}

status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
GetDeviceTypeToUse(pdo), 0, FALSE, &fido);
if (!NT_SUCCESS(status))
{ // can't create device object
KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
return status;
} // can't create device object
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

do
{ // finish initialization
IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);
pdx->DeviceObject = fido;
pdx->Pdo = pdo;
//½«¹ýÂËÇý¶¯¸½¼ÓÔڵײãÇý¶¯Ö®ÉÏ
PDEVICE_OBJECT fdo = IoAttachDeviceToDeviceStack(fido, pdo);
if (!fdo)
{ // can't attach
KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
status = STATUS_DEVICE_REMOVED;
break;
} // can't attach
//¼Ç¼µ×²ãÇý¶¯
pdx->LowerDeviceObject = fdo;
//ÓÉÓÚ²»ÖªµÀµ×²ãÇý¶¯ÊÇÖ±½ÓIO»¹ÊÇBufferIO£¬Òò´Ë½«±êÖ¾¶¼ÖÃÉÏ
fido->Flags |= fdo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO |
DO_POWER_PAGABLE);
// Clear the "initializing" flag so that we can get IRPs
fido->Flags &= ~DO_DEVICE_INITIALIZING;
} while (FALSE); // finish initialization

if (!NT_SUCCESS(status))
{ // need to cleanup
if (pdx->LowerDeviceObject)
IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fido);
} // need to cleanup

return status;
} // AddDevice


///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR
info)
{ // CompleteRequest
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest

NTSTATUS
USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context )
{
PDEVICE_EXTENSION pdx = ( PDEVICE_EXTENSION )
DeviceObject->DeviceExtension;

IoAcquireRemoveLock(&pdx->RemoveLock,Irp);

PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );

PSCSI_REQUEST_BLOCK CurSrb=irpStack->Parameters.Scsi.Srb;
PCDB cdb = (PCDB)CurSrb->Cdb;
UCHAR opCode=cdb->CDB6GENERIC.OperationCode;

if(opCode==SCSIOP_MODE_SENSE && CurSrb->DataBuffer
&& CurSrb->DataTransferLength >=
sizeof(MODE_PARAMETER_HEADER))
{
KdPrint(("SCSIOP_MODE_SENSE comming!\n"));

PMODE_PARAMETER_HEADER modeData = (PMODE_PARAMETER_HEADER)CurSrb-
>DataBuffer;

modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
}

if ( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}

IoReleaseRemoveLock(&pdx->RemoveLock,Irp);

return Irp->IoStatus.Status ;
}

#pragma LOCKEDCODE
NTSTATUS DispatchForSCSI(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
// KdPrint((DRIVERNAME " - Enter DispatchForSCSI \n"));

PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

ULONG IoControlCode = irpStack-
>Parameters.DeviceIoControl.IoControlCode;

KdPrint((DRIVERNAME " - Enter DispatchForSCSI :%x\n",IoControlCode));

// Pass request down without additional processing
NTSTATUS status;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine( Irp,
USBSCSICompletion,
NULL,
TRUE,
TRUE,
TRUE );
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
}
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE // make no assumptions about pageability of
dispatch fcns
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchAny
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
#if DBG
static char* irpname[] =
{
"IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE",
"IRP_MJ_READ",
"IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP",
};

UCHAR type = stack->MajorFunction;
// if (type >= arraysize(irpname))
// KdPrint((DRIVERNAME " - Unknown IRP, major type %X\n", type));
// else
// KdPrint((DRIVERNAME " - %s\n", irpname[type]));

#endif

// Pass request down without additional processing
NTSTATUS status;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
} // DispatchAny


///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchPower
#if DBG
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG fcn = stack->MinorFunction;
static char* fcnname[] =
{
"IRP_MN_WAIT_WAKE",
"IRP_MN_POWER_SEQUENCE",
"IRP_MN_SET_POWER",
"IRP_MN_QUERY_POWER",
};

if (fcn == IRP_MN_SET_POWER || fcn == IRP_MN_QUERY_POWER)
{
static char* sysstate[] =
{
"PowerSystemUnspecified",
"PowerSystemWorking",
"PowerSystemSleeping1",
"PowerSystemSleeping2",
"PowerSystemSleeping3",
"PowerSystemHibernate",
"PowerSystemShutdown",
"PowerSystemMaximum",
};

static char* devstate[] =
{
"PowerDeviceUnspecified",
"PowerDeviceD0",
"PowerDeviceD1",
"PowerDeviceD2",
"PowerDeviceD3",
"PowerDeviceMaximum",
};

ULONG context = stack->Parameters.Power.SystemContext;
POWER_STATE_TYPE type = stack->Parameters.Power.Type;
KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)", fcnname[fcn]));
if (type == SystemPowerState)
KdPrint((", SystemPowerState = %s\n", sysstate[stack-
>Parameters.Power.State.SystemState]));
else
KdPrint((", DevicePowerState = %s\n", devstate[stack-
>Parameters.Power.State.DeviceState]));
}
else if (fcn < arraysize(fcnname))
KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)\n", fcnname[fcn]));
else
KdPrint((DRIVERNAME " - IRP_MJ_POWER (%2.2X)\n", fcn));
#endif // DBG

PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
PoStartNextPowerIrp(Irp); // must be done while we own the IRP
NTSTATUS status;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
} // DispatchPower


///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchPnp
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG fcn = stack->MinorFunction;
NTSTATUS status;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
#if DBG
static char* pnpname[] =
{
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
"IRP_MN_QUERY_LEGACY_BUS_INFORMATION",
};

if (fcn < arraysize(pnpname))
KdPrint((DRIVERNAME " - IRP_MJ_PNP (%s)\n", pnpname[fcn]));
else
KdPrint((DRIVERNAME " - IRP_MJ_PNP (%2.2X)\n", fcn));
#endif // DBG

// Handle usage notification specially in order to track power
pageable
// flag correctly. We need to avoid allowing a non-pageable handler
to be
// layered on top of a pageable handler.
if (fcn == IRP_MN_DEVICE_USAGE_NOTIFICATION)
{ // usage notification
if (!fido->AttachedDevice || (fido->AttachedDevice->Flags &
DO_POWER_PAGABLE))
fido->Flags |= DO_POWER_PAGABLE;
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
UsageNotificationCompletionRoutine,
(PVOID) pdx, TRUE, TRUE, TRUE);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
} // usage notification

// Handle start device specially in order to correctly inherit
// FILE_REMOVABLE_MEDIA
if (fcn == IRP_MN_START_DEVICE)
{ // device start
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
StartDeviceCompletionRoutine,
(PVOID) pdx, TRUE, TRUE, TRUE);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
} // device start

// Handle remove device specially in order to cleanup device stack
if (fcn == IRP_MN_REMOVE_DEVICE)
{ // remove device
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
RemoveDevice(fido);
return status;
} // remove device

// Simply forward any other type of PnP request
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
} // DispatchPnp

///////////////////////////////////////////////////////////////////////////////
// GetDeviceTypeToUse returns the device object type of the next lower
device
// object. This helps overcome a bug in some Win2K file systems which
expect the
// topmost FiDO in a storage stack to have a VPB and, hence, to have
been created
// with a type such as FILE_DEVICE_DISK.
#pragma PAGEDCODE
ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo)
{ // GetDeviceTypeToUse
PDEVICE_OBJECT ldo = IoGetAttachedDeviceReference(pdo);
if (!ldo)
return FILE_DEVICE_UNKNOWN;
ULONG devtype = ldo->DeviceType;
ObDereferenceObject(ldo);
return devtype;
} // GetDeviceTypeToUse

///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID RemoveDevice(IN PDEVICE_OBJECT fido)
{ // RemoveDevice
KdPrint(("Enter RemoveDevice"));
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
if (pdx->LowerDeviceObject)
IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fido);
} // RemoveDevice

///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp,
PDEVICE_EXTENSION pdx)
{ // StartDeviceCompletionRoutine
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
// Inherit FILE_REMOVABLE_MEDIA flag from lower object. This is
necessary
// for a disk filter, but it isn't available until start-device time.
Drivers
// above us may examine the flag as part of their own start-device
processing, too.
if (pdx->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
fido->Characteristics |= FILE_REMOVABLE_MEDIA;
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return STATUS_SUCCESS;
} // StartDeviceCompletionRoutine

///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP
Irp, PDEVICE_EXTENSION pdx)
{ // UsageNotificationCompletionRoutine
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
// If lower driver cleared pageable flag, we must do the same
if (!(pdx->LowerDeviceObject->Flags & DO_POWER_PAGABLE))
fido->Flags &= ~DO_POWER_PAGABLE;
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return STATUS_SUCCESS;
} // UsageNotificationCompletionRoutine

#pragma LOCKEDCODE // force inline functions into nonpaged code

From: Wayne Gong on
>
> BOOLEAN USB_Disk(IN PDEVICE_OBJECT pDevice)
> {
> UNICODE_STRING usb_disk_name;
> RtlInitUnicodeString(&usb_disk_name,L"\\driver\\usbstor");
>
> PDRIVER_OBJECT pDriver = pDevice->DriverObject;
> KdPrint(("driver name:%wZ\n",&pDriver->DriverName));
> if (!RtlCompareUnicodeString(&pDriver-
>>DriverName,&usb_disk_name,TRUE))
> {
> KdPrint(("Find a USB disk device!\n"));
> return TRUE;
> }
> KdPrint(("This is not a USB disk device!"));
> return FALSE;
> }
>


Sorry, I still doubt that this routine can work fine. Please use Windbg to
check it. And then you can trace fido which you create to filter system disk
object to find is some IRPs doesn't process properly. 0x7B BSOD code always
happen when the system disk cannot work fine.

Thanks
Wayne

From: Doron Holan [MSFT] on
instead of looking at the driver name (in USB_Disk) of the PDO to determine
if it is a usb disk, get the enumerator name by calling
IoGetDeviceProperty(DevicePropertyEnumeratorName) and looks for "USBSTOR" or
"USB" depending on which usbstor devobj you are filtering

http://msdn.microsoft.com/en-us/library/ms801223.aspx

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.



"Daniel Zhang" <fanzier(a)gmail.com> wrote in message
news:5240f735-2ee7-4979-91a8-0e31fd94e7e8(a)p2g2000prf.googlegroups.com...
> Wayne,Thank you for your help. But I think I have already passed all
> the irp to the lower driver. Through the infomation from the core dump
> file, I felt that the system was not crashed at my filter driver.
> Below is my code,could you please find some error for me?
>
>
> #include "stddcls.h"
> #include "driver.h"
>
> #include <srb.h>
> #include <scsi.h>
>
> NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT
> pdo);
> VOID DriverUnload(IN PDRIVER_OBJECT fido);
> NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp);
> NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp);
> NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp);
> NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fido, IN PIRP Irp);
> ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo);
> NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp,
> PDEVICE_EXTENSION pdx);
> NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP
> Irp, PDEVICE_EXTENSION pdx);
>
> ///////////////////////////////////////////////////////////////////////////////
> #pragma INITCODE
> extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath)
> { // DriverEntry
> KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n",
> DriverObject));
>
> // Initialize function pointers
> DriverObject->DriverUnload = DriverUnload;
> DriverObject->DriverExtension->AddDevice = AddDevice;
> for (int i = 0; i < arraysize(DriverObject->MajorFunction); ++i)
> DriverObject->MajorFunction[i] = DispatchAny;
> DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
> DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
> DriverObject->MajorFunction[IRP_MJ_SCSI] = DispatchForSCSI;
>
> return STATUS_SUCCESS;
> } // DriverEntry
>
>
> #pragma PAGEDCODE
> VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
> { // DriverUnload
> PAGED_CODE();
> KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX
> \n", DriverObject));
> } // DriverUnload
>
>
> BOOLEAN USB_Disk(IN PDEVICE_OBJECT pDevice)
> {
> UNICODE_STRING usb_disk_name;
> RtlInitUnicodeString(&usb_disk_name,L"\\driver\\usbstor");
>
> PDRIVER_OBJECT pDriver = pDevice->DriverObject;
> KdPrint(("driver name:%wZ\n",&pDriver->DriverName));
> if (!RtlCompareUnicodeString(&pDriver-
>>DriverName,&usb_disk_name,TRUE))
> {
> KdPrint(("Find a USB disk device!\n"));
> return TRUE;
> }
> KdPrint(("This is not a USB disk device!"));
> return FALSE;
> }
>
> NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT
> pdo)
> { // AddDevice
> PAGED_CODE();
> NTSTATUS status;
>
> PDEVICE_OBJECT fido;
>
> if (!USB_Disk(pdo))
> {
> return STATUS_SUCCESS;
> }
>
> status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
> GetDeviceTypeToUse(pdo), 0, FALSE, &fido);
> if (!NT_SUCCESS(status))
> { // can't create device object
> KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
> return status;
> } // can't create device object
> PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
>
> do
> { // finish initialization
> IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);
> pdx->DeviceObject = fido;
> pdx->Pdo = pdo;
> //����������ڵײ���֮��
> PDEVICE_OBJECT fdo = IoAttachDeviceToDeviceStack(fido, pdo);
> if (!fdo)
> { // can't attach
> KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
> status = STATUS_DEVICE_REMOVED;
> break;
> } // can't attach
> //��¼�ײ���
> pdx->LowerDeviceObject = fdo;
> //���ڲ�֪���ײ�����ֱ��IO����BufferIO����˽���־������
> fido->Flags |= fdo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO |
> DO_POWER_PAGABLE);
> // Clear the "initializing" flag so that we can get IRPs
> fido->Flags &= ~DO_DEVICE_INITIALIZING;
> } while (FALSE); // finish initialization
>
> if (!NT_SUCCESS(status))
> { // need to cleanup
> if (pdx->LowerDeviceObject)
> IoDetachDevice(pdx->LowerDeviceObject);
> IoDeleteDevice(fido);
> } // need to cleanup
>
> return status;
> } // AddDevice
>
>
> ///////////////////////////////////////////////////////////////////////////////
> #pragma LOCKEDCODE
> NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR
> info)
> { // CompleteRequest
> Irp->IoStatus.Status = status;
> Irp->IoStatus.Information = info;
> IoCompleteRequest(Irp, IO_NO_INCREMENT);
> return status;
> } // CompleteRequest
>
> NTSTATUS
> USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp,
> IN PVOID Context )
> {
> PDEVICE_EXTENSION pdx = ( PDEVICE_EXTENSION )
> DeviceObject->DeviceExtension;
>
> IoAcquireRemoveLock(&pdx->RemoveLock,Irp);
>
> PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
>
> PSCSI_REQUEST_BLOCK CurSrb=irpStack->Parameters.Scsi.Srb;
> PCDB cdb = (PCDB)CurSrb->Cdb;
> UCHAR opCode=cdb->CDB6GENERIC.OperationCode;
>
> if(opCode==SCSIOP_MODE_SENSE && CurSrb->DataBuffer
> && CurSrb->DataTransferLength >=
> sizeof(MODE_PARAMETER_HEADER))
> {
> KdPrint(("SCSIOP_MODE_SENSE comming!\n"));
>
> PMODE_PARAMETER_HEADER modeData = (PMODE_PARAMETER_HEADER)CurSrb-
>>DataBuffer;
>
> modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
> }
>
> if ( Irp->PendingReturned )
> {
> IoMarkIrpPending( Irp );
> }
>
> IoReleaseRemoveLock(&pdx->RemoveLock,Irp);
>
> return Irp->IoStatus.Status ;
> }
>
> #pragma LOCKEDCODE
> NTSTATUS DispatchForSCSI(IN PDEVICE_OBJECT fido, IN PIRP Irp)
> {
> // KdPrint((DRIVERNAME " - Enter DispatchForSCSI \n"));
>
> PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
>
> PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
>
> ULONG IoControlCode = irpStack-
>>Parameters.DeviceIoControl.IoControlCode;
>
> KdPrint((DRIVERNAME " - Enter DispatchForSCSI :%x\n",IoControlCode));
>
> // Pass request down without additional processing
> NTSTATUS status;
> status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
> if (!NT_SUCCESS(status))
> return CompleteRequest(Irp, status, 0);
>
> IoCopyCurrentIrpStackLocationToNext(Irp);
>
> IoSetCompletionRoutine( Irp,
> USBSCSICompletion,
> NULL,
> TRUE,
> TRUE,
> TRUE );
> status = IoCallDriver(pdx->LowerDeviceObject, Irp);
> IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
> return status;
> }
> ///////////////////////////////////////////////////////////////////////////////
> #pragma LOCKEDCODE // make no assumptions about pageability of
> dispatch fcns
> NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
> { // DispatchAny
> PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
> PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
> #if DBG
> static char* irpname[] =
> {
> "IRP_MJ_CREATE",
> "IRP_MJ_CREATE_NAMED_PIPE",
> "IRP_MJ_CLOSE",
> "IRP_MJ_READ",
> "IRP_MJ_WRITE",
> "IRP_MJ_QUERY_INFORMATION",
> "IRP_MJ_SET_INFORMATION",
> "IRP_MJ_QUERY_EA",
> "IRP_MJ_SET_EA",
> "IRP_MJ_FLUSH_BUFFERS",
> "IRP_MJ_QUERY_VOLUME_INFORMATION",
> "IRP_MJ_SET_VOLUME_INFORMATION",
> "IRP_MJ_DIRECTORY_CONTROL",
> "IRP_MJ_FILE_SYSTEM_CONTROL",
> "IRP_MJ_DEVICE_CONTROL",
> "IRP_MJ_INTERNAL_DEVICE_CONTROL",
> "IRP_MJ_SHUTDOWN",
> "IRP_MJ_LOCK_CONTROL",
> "IRP_MJ_CLEANUP",
> "IRP_MJ_CREATE_MAILSLOT",
> "IRP_MJ_QUERY_SECURITY",
> "IRP_MJ_SET_SECURITY",
> "IRP_MJ_POWER",
> "IRP_MJ_SYSTEM_CONTROL",
> "IRP_MJ_DEVICE_CHANGE",
> "IRP_MJ_QUERY_QUOTA",
> "IRP_MJ_SET_QUOTA",
> "IRP_MJ_PNP",
> };
>
> UCHAR type = stack->MajorFunction;
> // if (type >= arraysize(irpname))
> // KdPrint((DRIVERNAME " - Unknown IRP, major type %X\n", type));
> // else
> // KdPrint((DRIVERNAME " - %s\n", irpname[type]));
>
> #endif
>
> // Pass request down without additional processing
> NTSTATUS status;
> status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
> if (!NT_SUCCESS(status))
> return CompleteRequest(Irp, status, 0);
> IoSkipCurrentIrpStackLocation(Irp);
> status = IoCallDriver(pdx->LowerDeviceObject, Irp);
> IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
> return status;
> } // DispatchAny
>
>
> ///////////////////////////////////////////////////////////////////////////////
> NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
> { // DispatchPower
> #if DBG
> PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
> ULONG fcn = stack->MinorFunction;
> static char* fcnname[] =
> {
> "IRP_MN_WAIT_WAKE",
> "IRP_MN_POWER_SEQUENCE",
> "IRP_MN_SET_POWER",
> "IRP_MN_QUERY_POWER",
> };
>
> if (fcn == IRP_MN_SET_POWER || fcn == IRP_MN_QUERY_POWER)
> {
> static char* sysstate[] =
> {
> "PowerSystemUnspecified",
> "PowerSystemWorking",
> "PowerSystemSleeping1",
> "PowerSystemSleeping2",
> "PowerSystemSleeping3",
> "PowerSystemHibernate",
> "PowerSystemShutdown",
> "PowerSystemMaximum",
> };
>
> static char* devstate[] =
> {
> "PowerDeviceUnspecified",
> "PowerDeviceD0",
> "PowerDeviceD1",
> "PowerDeviceD2",
> "PowerDeviceD3",
> "PowerDeviceMaximum",
> };
>
> ULONG context = stack->Parameters.Power.SystemContext;
> POWER_STATE_TYPE type = stack->Parameters.Power.Type;
> KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)", fcnname[fcn]));
> if (type == SystemPowerState)
> KdPrint((", SystemPowerState = %s\n", sysstate[stack-
>>Parameters.Power.State.SystemState]));
> else
> KdPrint((", DevicePowerState = %s\n", devstate[stack-
>>Parameters.Power.State.DeviceState]));
> }
> else if (fcn < arraysize(fcnname))
> KdPrint((DRIVERNAME " - IRP_MJ_POWER (%s)\n", fcnname[fcn]));
> else
> KdPrint((DRIVERNAME " - IRP_MJ_POWER (%2.2X)\n", fcn));
> #endif // DBG
>
> PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
> PoStartNextPowerIrp(Irp); // must be done while we own the IRP
> NTSTATUS status;
> status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
> if (!NT_SUCCESS(status))
> return CompleteRequest(Irp, status, 0);
> IoSkipCurrentIrpStackLocation(Irp);
> status = PoCallDriver(pdx->LowerDeviceObject, Irp);
> IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
> return status;
> } // DispatchPower
>
>
> ///////////////////////////////////////////////////////////////////////////////
> NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
> { // DispatchPnp
> PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
> ULONG fcn = stack->MinorFunction;
> NTSTATUS status;
> PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
> status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
> if (!NT_SUCCESS(status))
> return CompleteRequest(Irp, status, 0);
> #if DBG
> static char* pnpname[] =
> {
> "IRP_MN_START_DEVICE",
> "IRP_MN_QUERY_REMOVE_DEVICE",
> "IRP_MN_REMOVE_DEVICE",
> "IRP_MN_CANCEL_REMOVE_DEVICE",
> "IRP_MN_STOP_DEVICE",
> "IRP_MN_QUERY_STOP_DEVICE",
> "IRP_MN_CANCEL_STOP_DEVICE",
> "IRP_MN_QUERY_DEVICE_RELATIONS",
> "IRP_MN_QUERY_INTERFACE",
> "IRP_MN_QUERY_CAPABILITIES",
> "IRP_MN_QUERY_RESOURCES",
> "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
> "IRP_MN_QUERY_DEVICE_TEXT",
> "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
> "",
> "IRP_MN_READ_CONFIG",
> "IRP_MN_WRITE_CONFIG",
> "IRP_MN_EJECT",
> "IRP_MN_SET_LOCK",
> "IRP_MN_QUERY_ID",
> "IRP_MN_QUERY_PNP_DEVICE_STATE",
> "IRP_MN_QUERY_BUS_INFORMATION",
> "IRP_MN_DEVICE_USAGE_NOTIFICATION",
> "IRP_MN_SURPRISE_REMOVAL",
> "IRP_MN_QUERY_LEGACY_BUS_INFORMATION",
> };
>
> if (fcn < arraysize(pnpname))
> KdPrint((DRIVERNAME " - IRP_MJ_PNP (%s)\n", pnpname[fcn]));
> else
> KdPrint((DRIVERNAME " - IRP_MJ_PNP (%2.2X)\n", fcn));
> #endif // DBG
>
> // Handle usage notification specially in order to track power
> pageable
> // flag correctly. We need to avoid allowing a non-pageable handler
> to be
> // layered on top of a pageable handler.
> if (fcn == IRP_MN_DEVICE_USAGE_NOTIFICATION)
> { // usage notification
> if (!fido->AttachedDevice || (fido->AttachedDevice->Flags &
> DO_POWER_PAGABLE))
> fido->Flags |= DO_POWER_PAGABLE;
> IoCopyCurrentIrpStackLocationToNext(Irp);
> IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
> UsageNotificationCompletionRoutine,
> (PVOID) pdx, TRUE, TRUE, TRUE);
> return IoCallDriver(pdx->LowerDeviceObject, Irp);
> } // usage notification
>
> // Handle start device specially in order to correctly inherit
> // FILE_REMOVABLE_MEDIA
> if (fcn == IRP_MN_START_DEVICE)
> { // device start
> IoCopyCurrentIrpStackLocationToNext(Irp);
> IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
> StartDeviceCompletionRoutine,
> (PVOID) pdx, TRUE, TRUE, TRUE);
> return IoCallDriver(pdx->LowerDeviceObject, Irp);
> } // device start
>
> // Handle remove device specially in order to cleanup device stack
> if (fcn == IRP_MN_REMOVE_DEVICE)
> { // remove device
> IoSkipCurrentIrpStackLocation(Irp);
> status = IoCallDriver(pdx->LowerDeviceObject, Irp);
> IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
> RemoveDevice(fido);
> return status;
> } // remove device
>
> // Simply forward any other type of PnP request
> IoSkipCurrentIrpStackLocation(Irp);
> status = IoCallDriver(pdx->LowerDeviceObject, Irp);
> IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
> return status;
> } // DispatchPnp
>
> ///////////////////////////////////////////////////////////////////////////////
> // GetDeviceTypeToUse returns the device object type of the next lower
> device
> // object. This helps overcome a bug in some Win2K file systems which
> expect the
> // topmost FiDO in a storage stack to have a VPB and, hence, to have
> been created
> // with a type such as FILE_DEVICE_DISK.
> #pragma PAGEDCODE
> ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo)
> { // GetDeviceTypeToUse
> PDEVICE_OBJECT ldo = IoGetAttachedDeviceReference(pdo);
> if (!ldo)
> return FILE_DEVICE_UNKNOWN;
> ULONG devtype = ldo->DeviceType;
> ObDereferenceObject(ldo);
> return devtype;
> } // GetDeviceTypeToUse
>
> ///////////////////////////////////////////////////////////////////////////////
> #pragma PAGEDCODE
> VOID RemoveDevice(IN PDEVICE_OBJECT fido)
> { // RemoveDevice
> KdPrint(("Enter RemoveDevice"));
> PAGED_CODE();
> PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
> if (pdx->LowerDeviceObject)
> IoDetachDevice(pdx->LowerDeviceObject);
> IoDeleteDevice(fido);
> } // RemoveDevice
>
> ///////////////////////////////////////////////////////////////////////////////
> #pragma LOCKEDCODE
> NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp,
> PDEVICE_EXTENSION pdx)
> { // StartDeviceCompletionRoutine
> if (Irp->PendingReturned)
> IoMarkIrpPending(Irp);
> // Inherit FILE_REMOVABLE_MEDIA flag from lower object. This is
> necessary
> // for a disk filter, but it isn't available until start-device time.
> Drivers
> // above us may examine the flag as part of their own start-device
> processing, too.
> if (pdx->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
> fido->Characteristics |= FILE_REMOVABLE_MEDIA;
> IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
> return STATUS_SUCCESS;
> } // StartDeviceCompletionRoutine
>
> ///////////////////////////////////////////////////////////////////////////////
> #pragma LOCKEDCODE
> NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP
> Irp, PDEVICE_EXTENSION pdx)
> { // UsageNotificationCompletionRoutine
> if (Irp->PendingReturned)
> IoMarkIrpPending(Irp);
> // If lower driver cleared pageable flag, we must do the same
> if (!(pdx->LowerDeviceObject->Flags & DO_POWER_PAGABLE))
> fido->Flags &= ~DO_POWER_PAGABLE;
> IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
> return STATUS_SUCCESS;
> } // UsageNotificationCompletionRoutine
>
> #pragma LOCKEDCODE // force inline functions into nonpaged code
>