Hallo folks,
First of all I am still a beginner at driver developement but it seems that I got a general problem at the moment that may be more about theoretical background information and not about code.
My goal summarized:
I want to be a “lower filter driver” and attach to \Device\Harddisk0\DR0 (the bootdisk) and register to IRP_MJ_SCSI request. The only thing I want to do right now is log some information about the incoming SCSI command blocks and than return to the PDO driver below.
Here is most of my code I have go so far:
extern “C” NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ntStatus;
WCHAR deviceNameBuffer = L"\Device\FLT";
UNICODE_STRING deviceNameUnicodeString = {0};
//WCHAR physicalDevice = L"\DosDevices\PhysicalDrive0";
WCHAR physicalDevice = L"\Device\Harddisk0\DR0";
UNICODE_STRING physicalDeviceUnicodeString = {0};
PFILE_OBJECT fileObject;
PDEVICE_OBJECT targetDevice;
PDEVICE_OBJECT attachedTargetDevice;
NTGuardDriver = DriverObject;
WriteLogFile(“DriverEntry”);
RtlInitUnicodeString (&deviceNameUnicodeString,deviceNameBuffer);
ntStatus = IoCreateDevice (DriverObject,
DEVICE_EXTENSION_SIZE,
&deviceNameUnicodeString,
FILE_DEVICE_NTGUARD,
0,
FALSE,
&NTGuardDevice);
if(!NT_SUCCESS(ntStatus))
return ntStatus;
WriteLogFile(“Device created”);
RtlInitUnicodeString(&physicalDeviceUnicodeString,physicalDevice);
ntStatus = IoGetDeviceObjectPointer(&physicalDeviceUnicodeString,
FILE_READ_ACCESS,
&fileObject,
&targetDevice);
if(!NT_SUCCESS(ntStatus)) {
ObDereferenceObject(fileObject);
return ntStatus;
}
//targetDevice = IoGetDeviceAttachmentBaseRef(fileObject->DeviceObject);
WriteLogFile(“Target”);
PrintDeviceName(targetDevice);
if( ((PDEVICE_EXTENSION)NTGuardDevice->DeviceExtension)->TargetDeviceObject = attachedTargetDevice = IoAttachDeviceToDeviceStack(NTGuardDevice, fileObject->DeviceObject)) {
WriteLogFile("Attaching to ");
PrintDeviceName(attachedTargetDevice);
}
//DriverObject->MajorFunction[IRP_MJ_CREATE] = Guard_Irp_Mj_Create;
//DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Guard_Irp_Mj_Cleanup;
//DriverObject->MajorFunction[IRP_MJ_WRITE] = Guard_Irp_Mj_Write;
//DriverObject->MajorFunction[IRP_MJ_READ] = Guard_Irp_Mj_Read;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = Guard_Irp_Mj_SCSI;
//DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Guard_Irp_Mj_DevCntrl;
//ObDereferenceObject(fileObject);
return ntStatus;
}
NTSTATUS Guard_Irp_Mj_SCSI(PDEVICE_OBJECT HookDevice, IN PIRP Irp) {
WriteLogFile(“SCSI”);
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Srb = IrpStack->Parameters.Scsi.Srb;
PDEVICE_EXTENSION ext = (PDEVICE_EXTENSION)HookDevice->DeviceExtension;
UCHAR CdbOpCode = ((PCDB)Srb->Cdb)->CDB6GENERIC.OperationCode;
if (CdbOpCode == SCSIOP_READ) {
WriteLogFile(“SCSIOP_READ”);
} else if(CdbOpCode == SCSIOP_WRITE) {
WriteLogFile(“SCSIOP_WRITE”);
} else if(CdbOpCode == SCSIOP_READ_DATA_BUFF) {
WriteLogFile(“SCSIOP_READ_DATA_BUFF”);
} else if(CdbOpCode == SCSIOP_WRITE_DATA_BUFF) {
WriteLogFile(“SCSIOP_WRITE_DATA_BUFF”);
} else {
WriteLogFile(“Unknown SCSIOP”);
}
// some more code to be written when i finally get here ![]()
return IoCallDriver(ext->TargetDeviceObject, Irp);
}
From what I read this should be enough to get me started but my problem is that I never get into Guard_Irp_Mj_SCSI function.
For testings purpose I was also registering to READ, WRITE, CLEANUP and CREATE but the only functions I got inside where CREATE and CLEANUP.
So actually I got three questions except from why my code is not working:
1.) How can i actually determine to be an upper or a lower filter? The only thing I found on the internet so far was specifiyng by an .inf file.
I always thought it depends on the device I am attaching too, where I get in the stack and therefore lower and upper is just a naming convention where I get attached too.
2.) Is there some general guideline which requests should/can be handled bei either an upper or lower filter?
3.) I had a look at the DiskPerf sample from DDK. Someone said that this example can be either used as volume filter (so I guess upper level) or disk filter (so I guess lower level). This question is probably related to my first and second one but how can the same driver be used for different purposes?