I’ve been trying to redo parts of my legacy FSFD driver the “right” way, even though they were working fine before.
I am having the devil of a time using IoBuildSynchronousFsdRequest inside an IRP_MJ_CREATE Completion routine.
If I include IoCompleteRequest below, I get PAGE_FAULT_IN_FREED_SPECIAL_POOL inside IoCompeteRequest.
If I omit IoCompleteRequest I get Verifier error 0x226 (IRP dispatch handler returned without passing down / completing IRP).
Streamlined code below. Any ideas?
Thanks.
KeInitializeEvent(&completionEvent, NotificationEvent, FALSE);
myIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
deviceExtension->FileSystemDeviceObject,
fileHeader,length,&offset,
&completionEvent,
&ioStatusBlock);
nextSp = IoGetNextIrpStackLocation(myIrp);
nextSp->FileObject = irpSp->FileObject;
if ((ntStatus = IoCallDriver(devext->FileSystemDeviceObject, myIrp)) == STATUS_PENDING)
{
KeWaitForSingleObject(&completionEvent, Executive, KernelMode, TRUE, NULL);
ntStatus = ioStatusBlock.Status;
}
IoCompleteRequest(myIrp,IO_NO_INCREMENT); // bsod with or without
Show your completion routine as well.
Tony
OSR
“Tony Mason” wrote in message news:xxxxx@ntfsd…
> Show your completion routine as well.
Tony, IoBuildSynchronousFsdRequest doesn’t require a completion routine,
just an event. Am I mistaken?
Thanks for the reply.
“Tony Mason” wrote in message news:xxxxx@ntfsd…
> Show your completion routine as well.
Oops - sorry. You mean my Create Completion routine? Ok, I stripped it down to the bare essentials. I omitted any internal logic.
Also omitted the fail logic for things like ExAllocatePoolWithTag and IoQueryFileInformation since that is not what is happening here.
I also omitted the logic for creating new files, since it is never getting that far.
Incidentally, IoSetCompletionRoutine for the IRP_MJ_CREATE is set to TRUE, FALSE, FALSE;
Please let me know if you need any additional information.
Thanks.
NTSTATUS CreateCompletion
(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
void* contextFlags
)
{
NTSTATUS ntStatus;
PFILE_HEADER fileHeader = NULL;
PIRP hdrIrp = NULL;
LARGE_INTEGER offset = {0};
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
UCHAR CreateResult;
long len = 0;
PIO_STACK_LOCATION irpSp, nextSp;
IO_STATUS_BLOCK ioStatusBlock = {STATUS_ACCESS_DENIED};
ULONG_PTR CreateOptions;
KEVENT completionEvent;
FILE_BASIC_INFORMATION basicInformation;
PFILE_OBJECT fileObject;
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
irpSp = IoGetCurrentIrpStackLocation(Irp);
fileObject = irpSp->FileObject;
CreateOptions = (irpSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS);
CreateCreateDispositionsition = (UCHAR)((irpSp->Parameters.Create.Options >> 24) & 0xFF);
ntStatus = Irp->IoStatus.Status;
if (!NT_SUCCESS(ntStatus)) goto ignore; // ignore if error
if (fileObject->Flags & (FO_NAMED_PIPE|FO_MAILSLOT)) goto ignore; // ignore special cases
ntStatus = IoQueryFileInformation
(
fileObject,
FileBasicInformation,
sizeof (FILE_BASIC_INFORMATION),
&basicInformation,
&len
);
if (basicInformation.FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM))
goto ignore; // ignore special cases
CreateResult = (UCHAR)(Irp->IoStatus.Information & 0xFF);
if (!opening an existing file)
goto ignore; // ignore new file creation for now
fileHeader = ExAllocatePoolWithTag(NonPagedPool, SECTOR_SIZE,‘NETL’);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent(&completionEvent, NotificationEvent, FALSE);
hdrIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
deviceExtension->FileSystemDeviceObject,
fileHeader,
SECTOR_SIZE,
&offset,
&completionEvent,
&ioStatusBlock );
nextSp = IoGetNextIrpStackLocation(hdrIrp);
hdrIrp->Flags |= IRP_NOCACHE;
nextSp->FileObject = fileObject;
nextSp->MajorFunction = IRP_MJ_READ;
if ((ntStatus = IoCallDriver(deviceExtension->FileSystemDeviceObject, hdrIrp)) == STATUS_PENDING)
{
KeWaitForSingleObject(&completionEvent, Executive, KernelMode, TRUE, NULL);
ntStatus = ioStatusBlock.Status;
}
IoCompleteRequest(hdrIrp,IO_NO_INCREMENT);
len = ioStatusBlock.Information;
if (!NT_SUCCESS(ntStatus))
goto ignore;
if (len != SECTOR_SIZE)
goto ignore;
// do some internal logic
ignore:
if (fileHeader != NULL)
ExFreePool(fileHeader);
return (STATUS_SUCCESS);
}
You should not call??? IoCompleteRequest(hdrIrp,IO_NO_INCREMENT);
?
In this case, the IRP should have been completed by the lower driver.
?
Are you sure the IRP verifier complains about not being sent down or completed is the IRP you allocated using IoBuildSynchronousFsdRequest?
?
From: Neil Weicher
To: Windows File Systems Devs Interest List
Sent: Mon, January 25, 2010 6:14:50 PM
Subject: Re:[ntfsd] IoBuildSynchronousFsdRequest inside Create completion routine
“Tony Mason” wrote in message news:xxxxx@ntfsd…
> Show your completion routine as well.
Oops - sorry. You mean my Create Completion routine???Ok, I stripped it down to the?bare essentials.?I omitted any?internal logic.
Also omitted the fail?logic for things like?ExAllocatePoolWithTag and?IoQueryFileInformation since that is not what is happening here.
I also omitted the logic for creating new files,?since it is never?getting that far.?
?
Incidentally, IoSetCompletionRoutine for the IRP_MJ_CREATE is set to TRUE, FALSE, FALSE;
?
Please let me know if you need any additional information.?
?
Thanks.
NTSTATUS CreateCompletion
(
??? PDEVICE_OBJECT DeviceObject,
??? PIRP Irp,
??? void* contextFlags
)
{
??? NTSTATUS ntStatus;
??? PFILE_HEADER fileHeader = NULL;
??? PIRP hdrIrp = NULL;
??? LARGE_INTEGER offset = {0};
??? PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
??? UCHAR CreateResult;
??? long len = 0;
??? PIO_STACK_LOCATION irpSp, nextSp;
??? IO_STATUS_BLOCK ioStatusBlock = {STATUS_ACCESS_DENIED};
??? ULONG_PTR CreateOptions;
??? KEVENT completionEvent;
??? FILE_BASIC_INFORMATION basicInformation;
??? PFILE_OBJECT fileObject;
??? if (Irp->PendingReturned)
??? IoMarkIrpPending(Irp);
??? irpSp = IoGetCurrentIrpStackLocation(Irp);
??? fileObject = irpSp->FileObject;
??? CreateOptions = (irpSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS);
??? CreateCreateDispositionsition = (UCHAR)((irpSp->Parameters.Create.Options >> 24) & 0xFF);
??? ntStatus = Irp->IoStatus.Status;
??? if (!NT_SUCCESS(ntStatus)) goto ignore;??? // ignore if error
??? if (fileObject->Flags & (FO_NAMED_PIPE|FO_MAILSLOT)) goto ignore; // ignore special cases
??? ntStatus = IoQueryFileInformation
??? (
??? fileObject,
??? FileBasicInformation,
??? sizeof (FILE_BASIC_INFORMATION),
??? &basicInformation,
??? &len
??? );
??? if (basicInformation.FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM))
??? goto ignore;??? // ignore special cases
??? CreateResult = (UCHAR)(Irp->IoStatus.Information & 0xFF);
??? if (!opening an existing file)
??? goto ignore;??? // ignore new file creation for now
??? fileHeader = ExAllocatePoolWithTag(NonPagedPool, SECTOR_SIZE,‘NETL’);
??? ntStatus = STATUS_INSUFFICIENT_RESOURCES;
???
??? KeInitializeEvent(&completionEvent, NotificationEvent, FALSE);
??? hdrIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
??? deviceExtension->FileSystemDeviceObject,
??? fileHeader,
??? SECTOR_SIZE,
??? &offset,
??? &completionEvent,
??? &ioStatusBlock );
??? nextSp = IoGetNextIrpStackLocation(hdrIrp);
??? hdrIrp->Flags |= IRP_NOCACHE;
??? nextSp->FileObject = fileObject;
??? nextSp->MajorFunction = IRP_MJ_READ;
??? if ((ntStatus = IoCallDriver(deviceExtension->FileSystemDeviceObject, hdrIrp)) == STATUS_PENDING)
??? {
??? KeWaitForSingleObject(&completionEvent, Executive, KernelMode, TRUE, NULL);
??? ntStatus = ioStatusBlock.Status;
??? }
??? IoCompleteRequest(hdrIrp,IO_NO_INCREMENT);
??? len = ioStatusBlock.Information;
??? if (!NT_SUCCESS(ntStatus))
??? goto ignore;
??? if (len != SECTOR_SIZE)
??? goto ignore;
?
??? // do some internal logic
?
ignore:
??? if (fileHeader != NULL)???
??? ExFreePool(fileHeader);
??? return (STATUS_SUCCESS);
}
?
?
?
?
?
—
NTFSD is sponsored by OSR
For our schedule of debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>Incidentally, IoSetCompletionRoutine for the IRP_MJ_CREATE is set to TRUE, FALSE, FALSE;
I always set the completion routines to TRUE, TRUE, TRUE.
A good way to avoid bugs.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
“Maxim S. Shatskih” wrote in message
news:xxxxx@ntfsd…
>>Incidentally, IoSetCompletionRoutine for the IRP_MJ_CREATE is set to TRUE,
>>FALSE, FALSE;
> I always set the completion routines to TRUE, TRUE, TRUE.
> A good way to avoid bugs.
Max, I did try that, thanks. Although since it was not using a context I
didn’t think it mattered.