Article - Emerging Issues in IoCancelFileOpen -

Didn’t quite understand the logic of the operations, when creating, initializing and passing down the StreamFileObject IRP.

As I can see from the code, the original IRP and Stack must be altered so that we custom the stream create request.
After the create request succeds with the stream file object, do, the processing needed with the object.

Now is the tricky part. I see there, reinitialize the original IRP.
I can think of many ways to do it. But what is the good way. Should I pass down the first IRP, and in my CompletionRoutine, return STATUS_MORE_PROCESSING_REQ and the then not call IoCompleteRequest, but get The current IRP_STACK_LOCATION for the IRP, replace it’s file object with the original file object and resend it. Should I use IoReuseIrp or IoInitializeIrp on the Irp to reuse it ?

Why is it not possible, after Creating the StreamFileObjectLite, initialize different parameters, and send it down as a create request ?

Why do I need the same IRP ?
If I missunderstood please correct me.
Thanks.

PS:
I forgot to mention, another issue. After calling ObDereferenceObject() on the stream I get BadPoolHeader exception.
The tricky part is that on XP SP2 32 Bit, this issue can be handled if allocating the FileName Buffer without tag and let ObDereferenceObject free it.
On XP 64 Bit on the other hand, I see on the stack that ObDereferenceObject calls ExFreePoolWithTag, and now even if I free the memory befor calling ObDereferenceObject, and point the Name Buffer to NULL, even if I let ObDereferenceObect free it, I get blue screen with Bad Pool Header exception ?
How should I handle this issue ?
Thanks again

->FileName.Buffer must be freed by ExFreePool, not by ObDereferenceObject.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntfsd…
> PS:
> I forgot to mention, another issue. After calling ObDereferenceObject() on
the stream I get BadPoolHeader exception.
> The tricky part is that on XP SP2 32 Bit, this issue can be handled if
allocating the FileName Buffer without tag and let ObDereferenceObject free it.
> On XP 64 Bit on the other hand, I see on the stack that ObDereferenceObject
calls ExFreePoolWithTag, and now even if I free the memory befor calling
ObDereferenceObject, and point the Name Buffer to NULL, even if I let
ObDereferenceObect free it, I get blue screen with Bad Pool Header exception ?
> How should I handle this issue ?
> Thanks again
>
>

But if I call ExFreePool then ObDereferenceObject gives me BadPoolCaller exception.
Here is the logic of my implementation:

MyCreate(DeviceObject, Irp)
{

if(some_condition)
{
StreamFileObject = IoCreateStreamFileObjectLite(irpSp->FileObject, NULL);

RtlCopyMemory(StreamFileObject, irpSp->FileObject, sizeof(FILE_OBJECT));
StreamFileObject->RelatedFileObject = NULL;

SetFlag(StreamFileObject->Flags,FO_STREAM_FILE);

StreamFileObject->FileName.Buffer = ExAllocatePool(irpSp->FileObject->FileName.MaximumLength)
RtlCopyMemory(StreamFileObject->FileName.Buffer,irpSp->FileObject->FileName.Buffer,length);

OriginalFileObject = irpSp->FileObject;

irpSp->FileObject = StreamFileObject;

KeInitializeEvent(&CreateStreamFinish);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp)
Status = IoCallDriver(NextDeviceObject, Irp);
if (Status == STATUS_PENDING)
KeWaitForSingleObject(&CreateStreamFinish);
if (NT_SUCCESS(Irp->IoStatus.Status))
{
SetFlag(StreamFileObject->Flags,FO_CLEANUP_COMPLETE);

/*
* untill here everything goes smoothly
*/

/* . . . . */
/*
Do I/O processing with StreamFileObject
*/

if (CreatedFileObject->PrivateCacheMap != NULL)
CcUninitializeCacheMap(CreatedFileObject,NULL,NULL);

}

/*
* now to go on with my original request
*/
//these values where originally saved before making the stream

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->Tail.Overlay.Thread = IrpOriginalThread;
Irp->RequestorMode = IrpProcessorMode;
Irp->Flags = IrpFlags;
Irp->Type = IrpType;

irpSp = IoGetCurrentIrpStackLocation(Irp);
irpSp->FileObject = OriginalFileObject;
irpSp->Flags = OriginalSlFlags;

etc.
KeInitializeEvent(&CreateEnded)
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine()
status = IoCallDriver(NextDevObject,Irp);
if (status == STATUS_PENDING) KeWaitForSingleObject()
status = Irp->IoStatus.Status;

IoCompleteRequest(Irp);

/*
* now to dereference my stream file object
* if I try to dereference it before I call IoCompleteRequest I get BSOD
*/

ExFreePool(StreamFileObject->FileName.Buffer); //if I comment out these 2 lines it works on XP SP 2 32 bit but not 64 bit
StreamFileObject->FileName.Buffer = NULL;
ObDereferenceObject( CreatedFileObject); // this blue screens
}

else
return PassThrough(DeviceObject, Irp);

}

This is the stack after ObDereferenceObject:

STACK_TEXT:
fffffadff08e9b48 fffff800010c8ede : 0000000000000020 0000000000000000 0000000000000019 fffff8000106144e : nt!DbgBreakPointWithStatus
fffffadff08e9b50 fffff800010ca4c4 : fffff80000000003 0000000000000019 0000000000000020 fffffadff3e9f3b0 : nt!KeDisconnectInterrupt+0x48e
fffffadff08e9bb0 fffff800010502d4 : fffffadff3c5e900 fffffadff3e9f440 fffffadff3c5e900 fffffadff3a4e940 : nt!KeDisconnectInterrupt+0x1a74
fffffadff08ea200 fffff8000118444c : 0000000000000019 0000000000000020 fffffadff3e9f3b0 fffffadff3e9f500 : nt!KeBugCheckEx+0x104

fffffadff08ea240 fffff8000105a92b : fffffadff3e9f410 fffff80001295740 fffffadff3e9f410 fffff80001295740 : nt!ExFreePoolWithTag+0xdfc //vezi imediat
dupa asta ai bugcheck, deci asta nu da free la ce trebuie

fffffadff08ea300 fffffadfeff04c48 : fffffadff3dd68c0 fffffadff3dd68c0 fffffadff3aa23a0 fffffadff3aa2358 : nt!PsReturnPoolQuota+0x22b
fffffadff08ea330 fffff80001295ede : fffffadff3c5e900 fffffadff3aa2010 fffffadff08ea950 fffffadff3a70270 : FSMonitor!Create+0x6e8
fffffadff08ea460 fffff8000128ea00 : fffffadff3dd68c0 fffffadff3dd6850 fffffadff08ea790 0000000000000001 : nt!RtlAreAllAccessesGranted+0xd5e
fffffadff08ea610 fffff800012909a7 : 0000000000000000 fffffadff08ea780 0000000000000040 0000000000000000 : nt!SeAccessCheck+0x540
fffffadff08ea720 fffff80001296a14 : fffff680003c6c08 fffff8000109aaea 0000000000000000 0000000000040400 : nt!ObOpenObjectByName+0x167
fffffadff08ea910 fffff80001296bb7 : 0000000000000000 0000000000000000 fffffa8000000000 fffffadff3d27c20 : nt!CcMapData+0x714
fffffadff08eaaa0 fffff80001298479 : 0000000078d81258 fffff680003c6c08 0000000000000000 fffff800010596a6 : nt!IoCreateFile+0xe7
fffffadff08eab80 fffff8000104fce2 : fffffa80006f5278 0000000000000000 fffff6fb7dbed000 0000000000000001 : nt!NtCreateFile+0x69
fffffadff08eac00 0000000078ef17ba : 0000000078d6f729 0000000000000000 0000000002529890 0000000000000001 : nt!ZwUnloadKey+0x2092
000000000374fb08 0000000078d6f729 : 0000000000000000 0000000002529890 0000000000000001 0000000000000000 : ntdll!NtCreateFile+0xa
000000000374fb10 0000000000000000 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : kernel32!CreateFileW+0x279

PS: I rerecorrect:

ExFreePool(StreamFileObject->FileName.Buffer); //if I comment out these 2 lines
it works on XP SP 2 32 bit but not 64 bit
StreamFileObject->FileName.Buffer = NULL;
>ObDereferenceObject( CreatedFileObject); // this blue screens

Doesn’t work on neither 32 bit version nor 64