Fw: IRP_MJ_SET_INFORMATION

Hi All !
Sorry for my last mail, but my english is very bad… Perhaps, this letter is written more competently…
I have a stupid question. I’m writing the File System Filter driver for NT 2000.
My computer has FAT32 file system, provided by Microsoft native FastFat driver.
Some time ago i couldn’t write my code, to work properly with Visual C++
(i.e. MSDEV IDE). After driver starts, the system crashes during building of any project
by MSDEV IDE. I’ve found that memory crash occures after closing of thranslated file, when MSDEV calls NtGetFullAttributesFile native API. This function generates four file system actions

  1. IRP_MJ_CREATE
  2. FastIoQueryNetworkOpenInfo
  3. IRP_MJ_CLEANUP
  4. IRP_MJ_CLOSE

After generating of the last action an error occures during ExFreePoolWithTag execution when some object is being released.

In stack dump i’ve seen the ObpFreeObject, ObpRemoveObjectQueue calls, and others.

During my experiences i found, that error occures in my SetFileInformation routine. By means of this call i set the
file position to the beginning of the file after noncached reading. I’ve changed this call to native IFS function IoSetInformation(…), but it caused the problem of reenterability of my driver. In some functions I needed to set aside my old handler because of system hangover during MSDEV IDE exit. Can any smart guy tell me anything about my bug?
I’ve included the source code in this message.

BOOLEAN SetFileInfo(IN PFILE_OBJECT lpFileObject, IN PDEVICE_OBJECT lpDeviceObject,
IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG dwInfoLen, IN PVOID lpInfo)
{
PIRP Irp;
KEVENT Event;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION IrpSp;

Irp = IoAllocateIrp(lpDeviceObject->StackSize,FALSE);
if(!Irp)
return FALSE;
Irp->RequestorMode = KernelMode;
KeInitializeEvent(&Event,SynchronizationEvent,FALSE);
Irp->Flags = IRP_BUFFERED_IO;
Irp->Tail.Overlay.OriginalFileObject = lpFileObject;
Irp->UserIosb = &IoStatus;
if(FileInformationClass != FilePositionInformation)
Irp->UserEvent = &Event;
Irp->AssociatedIrp.SystemBuffer = lpInfo;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->DeviceObject = lpDeviceObject;
IrpSp->FileObject = lpFileObject;
IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
IrpSp->Parameters.SetFile.Length = dwInfoLen;
IrpSp->DeviceObject = lpDeviceObject;
Irp->Tail.Overlay.OriginalFileObject = lpFileObject;
IoSetCompletionRoutine(Irp,MyCompleteRequestHandler,((FileInformationClass ==
FilePositionInformation) ? &Event : NULL),TRUE,TRUE,TRUE);
IoCallDriver(lpDeviceObject,Irp);
KeWaitForSingleObject(&Event,Executive,KernelMode,TRUE,0);
return NT_SUCCESS(IoStatus.Status);
}

NTSTATUS MyCompleteRequestHandler(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,
IN PVOID Context)
{
if( Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
return Irp->IoStatus.Status;
}
*Irp->UserIosb = Irp->IoStatus;
if(Irp->UserEvent)
KeSetEvent(Irp->UserEvent,0,FALSE);
else if(Context)
KeSetEvent((PKEVENT)Context,0,FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}

}
Best regards.
Always grateful to you
Nikityenko Oleg.

Hi Oleg,

You might want to think at this scenario, maybe is what causes your crashes:

NT have several operations (such as query full attributtes, delete file) into very convenable packages, from the use point of view. Yet,
most of them have some more obscure optimizations, for example in our case, when the IO manager will open an file object for fasionetworkquery or for delete, it will not create a real valid file object registered with the Object Manager. Rather, the file object
will be created on the stack , as a dummy file object. This have a implication, regardless which is the reference count on this file object, when the function which created it as local returns , it will be destroyed, whithout any warning. Any further reference to that object is invalid. Errors of your kind usualy occures when someone Ref / Deref such a file object, and the ref count will reach 0, casi in whitch the Object Manager will try to free this object, but of course it will fail, since this memory is on a call stack and not in Ob allocation pools. If I where you I would check any referencing / dereferencing on those cases. Not that your FSD cannot distinguish
through normal means if a file object is a real file object , registered with OB manager, or a dummy file object.

Regards , Dan
----- Original Message -----
From: Oleg Nikityenko
To: File Systems Developers
Sent: Thursday, March 07, 2002 11:09 AM
Subject: [ntfsd] Fw: IRP_MJ_SET_INFORMATION

Hi All !
Sorry for my last mail, but my english is very bad… Perhaps, this letter is written more competently…
I have a stupid question. I’m writing the File System Filter driver for NT 2000.
My computer has FAT32 file system, provided by Microsoft native FastFat driver.
Some time ago i couldn’t write my code, to work properly with Visual C++
(i.e. MSDEV IDE). After driver starts, the system crashes during building of any project
by MSDEV IDE. I’ve found that memory crash occures after closing of thranslated file, when MSDEV calls NtGetFullAttributesFile native API. This function generates four file system actions

  1. IRP_MJ_CREATE
  2. FastIoQueryNetworkOpenInfo
  3. IRP_MJ_CLEANUP
  4. IRP_MJ_CLOSE

After generating of the last action an error occures during ExFreePoolWithTag execution when some object is being released.

In stack dump i’ve seen the ObpFreeObject, ObpRemoveObjectQueue calls, and others.

During my experiences i found, that error occures in my SetFileInformation routine. By means of this call i set the
file position to the beginning of the file after noncached reading. I’ve changed this call to native IFS function IoSetInformation(…), but it caused the problem of reenterability of my driver. In some functions I needed to set aside my old handler because of system hangover during MSDEV IDE exit. Can any smart guy tell me anything about my bug?
I’ve included the source code in this message.

BOOLEAN SetFileInfo(IN PFILE_OBJECT lpFileObject, IN PDEVICE_OBJECT lpDeviceObject,
IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG dwInfoLen, IN PVOID lpInfo)
{
PIRP Irp;
KEVENT Event;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION IrpSp;

Irp = IoAllocateIrp(lpDeviceObject->StackSize,FALSE);
if(!Irp)
return FALSE;
Irp->RequestorMode = KernelMode;
KeInitializeEvent(&Event,SynchronizationEvent,FALSE);
Irp->Flags = IRP_BUFFERED_IO;
Irp->Tail.Overlay.OriginalFileObject = lpFileObject;
Irp->UserIosb = &IoStatus;
if(FileInformationClass != FilePositionInformation)
Irp->UserEvent = &Event;
Irp->AssociatedIrp.SystemBuffer = lpInfo;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->DeviceObject = lpDeviceObject;
IrpSp->FileObject = lpFileObject;
IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
IrpSp->Parameters.SetFile.Length = dwInfoLen;
IrpSp->DeviceObject = lpDeviceObject;
Irp->Tail.Overlay.OriginalFileObject = lpFileObject;
IoSetCompletionRoutine(Irp,MyCompleteRequestHandler,((FileInformationClass ==
FilePositionInformation) ? &Event : NULL),TRUE,TRUE,TRUE);
IoCallDriver(lpDeviceObject,Irp);
KeWaitForSingleObject(&Event,Executive,KernelMode,TRUE,0);
return NT_SUCCESS(IoStatus.Status);
}

NTSTATUS MyCompleteRequestHandler(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,
IN PVOID Context)
{
if( Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
return Irp->IoStatus.Status;
}
*Irp->UserIosb = Irp->IoStatus;
if(Irp->UserEvent)
KeSetEvent(Irp->UserEvent,0,FALSE);
else if(Context)
KeSetEvent((PKEVENT)Context,0,FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}

}
Best regards.
Always grateful to you
Nikityenko Oleg.

You are currently subscribed to ntfsd as: xxxxx@rdsor.ro
To unsubscribe send a blank email to %%email.unsub%%

Hi,

NTSTATUS MyCompleteRequestHandler(IN PDEVICE_OBJECT DeviceObject,IN PIRP
=
Irp,
IN PVOID Context)
{
if( Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
return Irp->IoStatus.Status;
}

If you allocated your own IRP you should not propagate pending status and
you have to free irp and return STATUS_MORE_PROCESSING_REQUIRED from
completion routine. When this routine is called IRP was already completed
by undelying driver, so it is save to free it. You need to propagate
pending status only if you passed IRP through your filter and want IO
Manager to finish processing of this IRP.

IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}

Alexei.

For one thing I would recomend using
IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS) instead of IoAllocateIrp
Second, don’t ever return from your completion routine Irp->IoStatus.Status!
There are just two allowed ret codes: STATUS_SUCCESS
and STATUS_MORE_PROCESSING_REQUIRED. And although I/O Mgr treat them as
“STATUS_MORE_PROCESSING_REQUIRED &
everything else” (to the best of my knowledge) shit happens…

Regards,

Vladimir

-----Original Message-----
From: Oleg Nikityenko [mailto:xxxxx@guardant.ru]
Sent: Thursday, March 07, 2002 1:10 AM
To: File Systems Developers
Subject: [ntfsd] Fw: IRP_MJ_SET_INFORMATION

Hi All !
Sorry for my last mail, but my english is very bad… Perhaps, this letter
is written more competently…
I have a stupid question. I’m writing the File System Filter driver for NT
2000.
My computer has FAT32 file system, provided by Microsoft native FastFat
driver.
Some time ago i couldn’t write my code, to work properly with Visual C++
(i.e. MSDEV IDE). After driver starts, the system crashes during building of
any project
by MSDEV IDE. I’ve found that memory crash occures after closing of
thranslated file, when MSDEV calls NtGetFullAttributesFile native API. This
function generates four file system actions

  1. IRP_MJ_CREATE
  2. FastIoQueryNetworkOpenInfo
  3. IRP_MJ_CLEANUP
  4. IRP_MJ_CLOSE

After generating of the last action an error occures during
ExFreePoolWithTag execution when some object is being released.

In stack dump i’ve seen the ObpFreeObject, ObpRemoveObjectQueue calls, and
others.

During my experiences i found, that error occures in my SetFileInformation
routine. By means of this call i set the
file position to the beginning of the file after noncached reading. I’ve
changed this call to native IFS function IoSetInformation(…), but it caused
the problem of reenterability of my driver. In some functions I needed to
set aside my old handler because of system hangover during MSDEV IDE exit.
Can any smart guy tell me anything about my bug?
I’ve included the source code in this message.

BOOLEAN SetFileInfo(IN PFILE_OBJECT lpFileObject, IN PDEVICE_OBJECT
lpDeviceObject,
IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG dwInfoLen, IN
PVOID lpInfo)
{
PIRP Irp;
KEVENT Event;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION IrpSp;

Irp = IoAllocateIrp(lpDeviceObject->StackSize,FALSE);
if(!Irp)
return FALSE;
Irp->RequestorMode = KernelMode;
KeInitializeEvent(&Event,SynchronizationEvent,FALSE);
Irp->Flags = IRP_BUFFERED_IO;
Irp->Tail.Overlay.OriginalFileObject = lpFileObject;
Irp->UserIosb = &IoStatus;
if(FileInformationClass != FilePositionInformation)
Irp->UserEvent = &Event;
Irp->AssociatedIrp.SystemBuffer = lpInfo;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->DeviceObject = lpDeviceObject;
IrpSp->FileObject = lpFileObject;
IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
IrpSp->Parameters.SetFile.Length = dwInfoLen;
IrpSp->DeviceObject = lpDeviceObject;
Irp->Tail.Overlay.OriginalFileObject = lpFileObject;
IoSetCompletionRoutine(Irp,MyCompleteRequestHandler,((FileInformationClass

FilePositionInformation) ? &Event : NULL),TRUE,TRUE,TRUE);
IoCallDriver(lpDeviceObject,Irp);
KeWaitForSingleObject(&Event,Executive,KernelMode,TRUE,0);
return NT_SUCCESS(IoStatus.Status);
}

NTSTATUS MyCompleteRequestHandler(IN PDEVICE_OBJECT DeviceObject,IN PIRP
Irp,
IN PVOID Context)
{
if( Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
return Irp->IoStatus.Status;
}
*Irp->UserIosb = Irp->IoStatus;
if(Irp->UserEvent)
KeSetEvent(Irp->UserEvent,0,FALSE);
else if(Context)
KeSetEvent((PKEVENT)Context,0,FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}

}
Best regards.
Always grateful to you
Nikityenko Oleg.

You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to %%email.unsub%%