KeWaitForSingleObject Hangs in IRP_MJ_CREATE

Hi,

Whenever i create a file and during create completion i call the below
function

BOOLEAN ReadHeader(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT
newFileObject, ULONG fileSize, OUT PVOID * pHeader)
{
PIRP irpRead;
KEVENT eventRead;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION OrgIoStack;
PIO_STACK_LOCATION IoStackLocation;
PVOID readBuffer = NULL;
PFILESPY_DEVICE_EXTENSION pDeviceExtension;
NTSTATUS ntStatus = 0;
BOOLEAN result = EFE_NOT_ENCRYPTED;
ULONG HeaderOffset = 0;
PCHAR pChar;

// Calculate the offset from where to get the header
HeaderOffset = fileSize - HEADER_SIZE_WITH_LEN;

//KdBreakPoint();

// Get current stack location
OrgIoStack = IoGetCurrentIrpStackLocation(Irp);

// Get Device Extension
pDeviceExtension = DeviceObject->DeviceExtension;

readBuffer = ExAllocatePool(NonPagedPool, HEADER_SIZE_WITH_LEN);
if(readBuffer == NULL)
{
DbgPrint(“Error insufficient memory…\n”);
return EFE_ACCESS_DENIED;
}

// Initialize the read event
KeInitializeEvent(&eventRead, SynchronizationEvent, FALSE);

// Allocate and create and IRP for reading data
irpRead = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(irpRead == NULL)
{
DbgPrint(“Error in allocation irp for read…\n”);
return EFE_ACCESS_DENIED;
}

IoSetNextIrpStackLocation(irpRead);
irpRead->AssociatedIrp.SystemBuffer = irpRead->UserBuffer;
irpRead->UserEvent = NULL;
irpRead->UserIosb = &IoStatusBlock;
irpRead->Tail.Overlay.Thread = PsGetCurrentThread();
irpRead->Tail.Overlay.OriginalFileObject = newFileObject;
irpRead->RequestorMode = KernelMode;
irpRead->UserBuffer = readBuffer;
irpRead->MdlAddress = NULL;
irpRead->Flags = IRP_NOCACHE;

IoStackLocation = IoGetNextIrpStackLocation(irpRead);
IoStackLocation->MajorFunction = IRP_MJ_READ;
IoStackLocation->MinorFunction = 0;
IoStackLocation->DeviceObject = pDeviceExtension->AttachedToDeviceObject;
IoStackLocation->FileObject = newFileObject;
IoStackLocation->Parameters.Read.ByteOffset.LowPart = HeaderOffset;
IoStackLocation->Parameters.Read.ByteOffset.HighPart = 0;
IoStackLocation->Parameters.Read.Length = HEADER_SIZE_WITH_LEN;

IoSetCompletionRoutine(irpRead, OurCloseCompletionRoutine, &eventRead,
TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(pDeviceExtension->AttachedToDeviceObject, irpRead);

DbgPrint(“This IoCallDriver is done…\n”);
if(ntStatus == STATUS_PENDING)
{
DbgPrint(“we are waiting for the event with IRQL…= %d\n”,
KeGetCurrentIrql());
KeWaitForSingleObject(&eventRead, Executive, KernelMode, FALSE, 0);
DbgPrint(“we are done for the event…\n”);
}

// Analyze the header to check whether the file is encrypted or not
pChar = readBuffer;
DbgPrint(“We are analyzing header now …\n”);
result = AnalyzeHeader(pChar, fileSize);
DbgPrint(“We are done analyzing header now …\n”);
if(result == EFE_ENCRYPTED)
{
// File is encrypted then send the header back to the caller
*pHeader = readBuffer;
}
else
{
// Release the memory for buffer
// if the file is not encrypted
//*pHeader = NULL;
ExFreePool(readBuffer);
}

IoFreeIrp(irpRead);
return result;
}

NTSTATUS OurCloseCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PVOID Context)
{
PRKEVENT eventC = NULL;
UNREFERENCED_PARAMETER(DeviceObject);

DbgPrint(“Setting the event …\n”);

eventC = (PKEVENT)Context;
UNREFERENCED_PARAMETER( DeviceObject );

//
// Make sure that the Irp status is copied over to the user’s
// IO_STATUS_BLOCK so that the originator of this irp will know
// the final status of this operation.
//

ASSERT( NULL != Irp->UserIosb );
*Irp->UserIosb = Irp->IoStatus;

KeSetEvent(eventC, IO_NO_INCREMENT, FALSE);

//IoFreeIrp(Irp);

DbgPrint(“Setting the event …done\n”);
return STATUS_MORE_PROCESSING_REQUIRED;
}

which creates IRP_MJ_READ Irp and send it to the below driver.
The function waits at KeWaitForSingleObject() indefinitly only when i access
the file from network and fails after some time with Access Denied error.
It works fine when i access the file locally.

Please let me know what the problem is.

Thanks
Suhail


MSN Movies - Trailers, showtimes, DVD’s, and the latest news from Hollywood!
http://movies.msn.click-url.com/go/onm00200509ave/direct/01/

Have you tried to set breakpoint into your completion routine ?
Maybe this is the problem, the completion gets never called.

Or the wrong thing is to return
STATUS_MORE_PROCESSING_REQUIRED
in your completion routine.

Anyway, you can change the approach. Don’t use the completion
at all and set the pointer to readEvent into the IrpRead->UserEvent,
this will work.

L.

Suhail,

I don’t exactly know what you are hanging but you have a serious bug in
this code. You should not be setting the “OriginalFileObject” field
when you are generating an IRP. Please immediately fix this code by
setting this field to NULL.

I said this just a few days ago. It is wrong for any component besides
the IO Manager to set this field. You will experience unusual crashes
when interoperating with DFS.

Neal Christiansen
Microsoft File System Filter Group Lead
This posting is provided “AS IS” with no warranties, and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Suhail Ansari
Sent: Wednesday, June 23, 2004 6:46 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] KeWaitForSingleObject Hangs in IRP_MJ_CREATE

Hi,

Whenever i create a file and during create completion i call the below
function

BOOLEAN ReadHeader(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT
newFileObject, ULONG fileSize, OUT PVOID * pHeader)
{
PIRP irpRead;
KEVENT eventRead;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION OrgIoStack;
PIO_STACK_LOCATION IoStackLocation;
PVOID readBuffer =
NULL;
PFILESPY_DEVICE_EXTENSION pDeviceExtension;
NTSTATUS ntStatus = 0;
BOOLEAN result =
EFE_NOT_ENCRYPTED;
ULONG HeaderOffset =
0;
PCHAR pChar;

// Calculate the offset from where to get the header
HeaderOffset = fileSize - HEADER_SIZE_WITH_LEN;

//KdBreakPoint();

// Get current stack location
OrgIoStack = IoGetCurrentIrpStackLocation(Irp);

// Get Device Extension
pDeviceExtension = DeviceObject->DeviceExtension;

readBuffer = ExAllocatePool(NonPagedPool, HEADER_SIZE_WITH_LEN);
if(readBuffer == NULL)
{
DbgPrint(“Error insufficient memory…\n”);
return EFE_ACCESS_DENIED;
}

// Initialize the read event
KeInitializeEvent(&eventRead, SynchronizationEvent, FALSE);

// Allocate and create and IRP for reading data
irpRead = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(irpRead == NULL)
{
DbgPrint(“Error in allocation irp for read…\n”);
return EFE_ACCESS_DENIED;
}

IoSetNextIrpStackLocation(irpRead);
irpRead->AssociatedIrp.SystemBuffer = irpRead->UserBuffer;
irpRead->UserEvent = NULL;
irpRead->UserIosb = &IoStatusBlock;
irpRead->Tail.Overlay.Thread = PsGetCurrentThread();
irpRead->Tail.Overlay.OriginalFileObject = newFileObject;
irpRead->RequestorMode = KernelMode;
irpRead->UserBuffer = readBuffer;
irpRead->MdlAddress = NULL;
irpRead->Flags = IRP_NOCACHE;

IoStackLocation = IoGetNextIrpStackLocation(irpRead);
IoStackLocation->MajorFunction = IRP_MJ_READ;
IoStackLocation->MinorFunction = 0;
IoStackLocation->DeviceObject =
pDeviceExtension->AttachedToDeviceObject;
IoStackLocation->FileObject = newFileObject;
IoStackLocation->Parameters.Read.ByteOffset.LowPart =
HeaderOffset;
IoStackLocation->Parameters.Read.ByteOffset.HighPart = 0;
IoStackLocation->Parameters.Read.Length = HEADER_SIZE_WITH_LEN;

IoSetCompletionRoutine(irpRead, OurCloseCompletionRoutine,
&eventRead,
TRUE, TRUE, TRUE);
ntStatus =
IoCallDriver(pDeviceExtension->AttachedToDeviceObject, irpRead);

DbgPrint(“This IoCallDriver is done…\n”);
if(ntStatus == STATUS_PENDING)
{
DbgPrint(“we are waiting for the event with IRQL…=
%d\n”,
KeGetCurrentIrql());
KeWaitForSingleObject(&eventRead, Executive, KernelMode,
FALSE, 0);
DbgPrint(“we are done for the event…\n”);
}

// Analyze the header to check whether the file is encrypted or
not
pChar = readBuffer;
DbgPrint(“We are analyzing header now …\n”);
result = AnalyzeHeader(pChar, fileSize);
DbgPrint(“We are done analyzing header now …\n”);
if(result == EFE_ENCRYPTED)
{
// File is encrypted then send the header back to the
caller
*pHeader = readBuffer;
}
else
{
// Release the memory for buffer
// if the file is not encrypted
//*pHeader = NULL;
ExFreePool(readBuffer);
}

IoFreeIrp(irpRead);
return result;
}

NTSTATUS OurCloseCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP
Irp,
PVOID Context)
{
PRKEVENT eventC = NULL;
UNREFERENCED_PARAMETER(DeviceObject);

DbgPrint(“Setting the event …\n”);

eventC = (PKEVENT)Context;
UNREFERENCED_PARAMETER( DeviceObject );

//
// Make sure that the Irp status is copied over to the user’s
// IO_STATUS_BLOCK so that the originator of this irp will know
// the final status of this operation.
//

ASSERT( NULL != Irp->UserIosb );
*Irp->UserIosb = Irp->IoStatus;

KeSetEvent(eventC, IO_NO_INCREMENT, FALSE);

//IoFreeIrp(Irp);

DbgPrint(“Setting the event …done\n”);
return STATUS_MORE_PROCESSING_REQUIRED;
}

which creates IRP_MJ_READ Irp and send it to the below driver.
The function waits at KeWaitForSingleObject() indefinitly only when i
access
the file from network and fails after some time with Access Denied
error.
It works fine when i access the file locally.

Please let me know what the problem is.

Thanks
Suhail


MSN Movies - Trailers, showtimes, DVD’s, and the latest news from
Hollywood!
http://movies.msn.click-url.com/go/onm00200509ave/direct/01/


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com