I have a file system filter driver and I have some problems with my dispatch read routine
As I read the read and write dispathces sould not be pageable.
this is the dispatch read:
NTSTATUS
SfRead (
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
NTSTATUS Status;
PNAME_CONTROL fileName = NULL;
PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
BOOLEAN cacheName;
NAME_LOOKUP_FLAGS LookupFlags = 0x00000000;
//KEVENT waitEvent;
NTSTATUS localStatus,freeStatus;
UNICODE_STRING DosName;
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_INVALID_DEVICE_REQUEST;
}
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
ASSERT(irpSp->MajorFunction != IRP_MJ_POWER);
Status = NLAllocateNameControl(
&fileName,
&gSfNameBufferLookasideList );
if (NT_SUCCESS( Status )) {
//
// We are okay not checking the return value here because
// the GetFullPathName function will set the Unicode String
// length to 0. So either way, in an error it will print an empty string
//
if (devExt->NLExtHeader.DosName.Length!=0)
SetFlag(LookupFlags,NLFL_USE_DOS_DEVICE_NAME);
localStatus = NLGetFullPathName(
irpSp->FileObject,
fileName,
&devExt->NLExtHeader,
LookupFlags,
&gSfNameBufferLookasideList,
&cacheName );
freeStatus=localStatus;
DosName.Buffer = ExAllocatePoolWithTag(
NonPagedPool,
255*sizeof(WCHAR),
‘dnb0’);
DosName.Length=0;
DosName.MaximumLength=255*sizeof(WCHAR);
__try
{
if (DosName.Buffer)
if (NT_SUCCESS(localStatus))
{
localStatus = GetDosNameFromDeviceNameAndFullNTPath(
&devExt->NLExtHeader.DeviceName,
&fileName->Name,
&DosName);
}
if (DosName.Buffer)
if (NT_SUCCESS(localStatus))
DbgPrint(“IRP_MJ_READ: FILE: DosName: %S\n”,DosName.Buffer);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
localStatus = GetExceptionCode();
DbgPrint(“Exception caught in sfread: 0x%x”,localStatus);
}
if (DosName.Buffer)
ExFreePoolWithTag(DosName.Buffer,‘dnb0’);
if (NT_SUCCESS(freeStatus))
NLFreeNameControl(fileName,&gSfNameBufferLookasideList);
}
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(
devExt->NLExtHeader.AttachedToDeviceObject,
Irp );
return Status;
}
NTSTATUS GetDosNameFromDeviceNameAndFullNTPath(
PUNICODE_STRING DeviceName,
PUNICODE_STRING FullNTPath,
PUNICODE_STRING DosName)
{
UNICODE_STRING VolumeDosName;
NTSTATUS Status;
// PAGED_CODE();
Status = GetDriveLetterFromDeviceName(
DeviceName,
&VolumeDosName);
if (!NT_SUCCESS(Status))
return Status;
if (DosName->MaximumLength< VolumeDosName.Length + (FullNTPath->Length-56))
{
ExFreePool(VolumeDosName.Buffer);
return STATUS_BUFFER_OVERFLOW;
}
RtlCopyMemory(
DosName->Buffer,
VolumeDosName.Buffer,
VolumeDosName.Length);
DosName->Length=VolumeDosName.Length;
ExFreePool(VolumeDosName.Buffer);
RtlAppendUnicodeToString(
DosName,
&FullNTPath->Buffer[23]);
return STATUS_SUCCESS;
}
NTSTATUS GetDriveLetterFromDeviceName(
PUNICODE_STRING DeviceName,
PUNICODE_STRING DriveLetter)
{
NTSTATUS Status;
PFILE_OBJECT VolumeFileObject;
PDEVICE_OBJECT VolumeDevice;
// PAGED_CODE();
Status=IoGetDeviceObjectPointer(DeviceName,
FILE_READ_ATTRIBUTES,
&VolumeFileObject,
&VolumeDevice);
if (!NT_SUCCESS(Status))
{
DbgPrint("Error get device pointer: 0x%x , Name: %S ",Status,DeviceName->Buffer);
return Status;
}
Status=IoVolumeDeviceToDosName(VolumeDevice,DriveLetter);
if (!NT_SUCCESS(Status))
{
DbgPrint(“Error volume device to dos name: 0x%x Name: %S”,Status, DeviceName->Buffer);
ObDereferenceObject(VolumeFileObject);
return Status;
}
ObDereferenceObject(VolumeFileObject);
return Status;
}
the problem is that I get blue screen. I have the same code for IRP_MJ_WRITE but it works OK.
How should I handle this. What is the issue I am missing.
Windbg says that the problem is improper addresing at IRQL = 2 (DISPATCH_LEVEL)
how do I control code execution at proper IRQL (< 2) , should I create a system thread and execute code there ?
please help .