IoBuildSynchronousFsdRequest inside Create completion routine

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.

Neil Weicher wrote:

“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.
>

With TRUE, FALSE, FALSE the completion routine will not be called on
failure or cancellation of the request. So if you are doing something
like setting an event to synchronize back to the dispatch side then
you’ll be stuck …

Pete


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295