📄 driverentry.cpp
字号:
#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 PAGEDCODEVOID DriverUnload(IN PDRIVER_OBJECT DriverObject){ // DriverUnload PAGED_CODE(); KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject));} // DriverUnload
///////////////////////////////////////////////////////////////////////////////
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo){ // AddDevice PAGED_CODE(); NTSTATUS status;
PDEVICE_OBJECT fido; 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 LOCKEDCODENTSTATUS 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);
// 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 fcnsNTSTATUS 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 PAGEDCODEULONG 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 PAGEDCODEVOID 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 LOCKEDCODENTSTATUS 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 LOCKEDCODENTSTATUS 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -