⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driverentry.cpp

📁 文件过滤驱动程序
💻 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 + -