Hi all,
We are writing a filter driver and are having problems ( like many before by
the looks of it )
We are trying to read from file in a completion routine when we receive
IRP_MJ_CREATE requests,
so that we can identify files we need to decrypt. (we have a header on our
files)
In the completion routine for the create we queue a work item to try and do
the read from and return STATUS_MORE_PROCESSING_REQUIRED.
In the worker function we use IoBuildSynchronousFsdRequest to create an IRP
for the read and send it on.
This all works fine in almost every circumstanceā¦ except when filtering
LanmanRedirector.
Sometimes the read fails with STATUS_ACCESS_DENIED (0xC0000022).
Helpā¦ does anyone have any ideas? Possibly something to do with security?
We have tried SeCreateClientSecurity & SeImpersonateClient to no avail.
We have pasted the offending chunk of code below.
Thanks for any assitanceā¦
Rob Linegar & Duncan Hume
Software Engineers
Data Encryption Systems Limited
// Running in the context of a worker thread - using ExInitializeWorkItem &
ExQueueWorkItem
void FSFil_FileCreateWorker( PFILE_CREATE_CONTEXT pContext )
{
PDEVICE_OBJECT pTargetDeviceObject;
char *pBuffer;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER ByteOffset;
LARGE_INTEGER OrigByteOffset;
PFILE_OBJECT pFileObject;
pFileObject = IoGetCurrentIrpStackLocation( pContext->pOriginalIrp
)->FileObject;
// Get the Previous filtered device object
pTargetDeviceObject =
((PFSFIL_DEVICEEXTENSION)pContext->pDeviceObject->DeviceExtension)->pPrevDev
iceObject;
// No point in continuing if there is no FileObject
if (pFileObject)
{
// Allocate memory for our Buffer
pBuffer = ExAllocatePool( NonPagedPool, 10 );
if (pBuffer)
{
ByteOffset.QuadPart = 0;
// Store the original byte offset
OrigByteOffset = pFileObject->CurrentByteOffset;
FO_ReadFile( pContext->pOriginalIrp,
pTargetDeviceObject, pFileObject, &ByteOffset, 5, pBuffer, &IoStatusBlock );
// Restore the original byte offset
pFileObject->CurrentByteOffset = OrigByteOffset;
if (NT_SUCCESS(IoStatusBlock.Status))
{
}
else
{
///FAILS
}
// Free our read buffer
ExFreePool( pBuffer );
}
}
// Complete the Create Request
IoCompleteRequest( pContext->pOriginalIrp, IO_NO_INCREMENT );
// Free the create context data
ExFreePool( pContext );
}
VOID FO_ReadFile( PIRP pIrp, PDEVICE_OBJECT pDeviceObject, PFILE_OBJECT
pFileObject, PLARGE_INTEGER Offset, ULONG Length, char * pBuffer,
PIO_STATUS_BLOCK IoStatusBlock )
{
KEVENT kEvent;
PIRP pReadIrp;
NTSTATUS ntStatus;
// Initialise an event to wait for after calling the previous driver
KeInitializeEvent( &kEvent, NotificationEvent, FALSE );
// Build an Irp for the read
pReadIrp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, pDeviceObject,
pBuffer, Length, Offset, &kEvent, IoStatusBlock );
if (pReadIrp)
{
PIO_STACK_LOCATION pReadStack = IoGetNextIrpStackLocation(
pReadIrp );
// Caching? no thank you maam!
pReadIrp->Flags = IRP_NOCACHE | IRP_READ_OPERATION;
pReadIrp->Tail.Overlay.Thread = pIrp->Tail.Overlay.Thread;
pReadIrp->RequestorMode = KernelMode;
// We need a FileObject to identify the file we are reading
pReadStack->FileObject = pFileObject;
pReadStack->DeviceObject = pDeviceObject;
// Call on to the previous driver
ntStatus = IoCallDriver( pDeviceObject, pReadIrp );
if (ntStatus == STATUS_PENDING)
{
// Wait for the Irp to complete if it is pending
KeWaitForSingleObject( &kEvent, Executive,
KernelMode, FALSE, NULL );
}
else
IoStatusBlock->Status = ntStatus;
}
else
{
IoStatusBlock->Status =
STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
}
}
// Copyright Dunk & Rob aka DES Massive