Re: Encrypting buffer from IRP_MJ_WRITE

You should complete in the I/O completion routine.

Le Thu, 29 Nov 2007 08:20:37 -0500 (EST), xxxxx@inocentric.com a
ecrit:

Hi,
I have a storage filter driver and i am trying to encrypt the buffer from
IRP_MJ_WRITE. After searching this forum i’ve found 2 way to do this.

    • Sending my IRP
  • Intercept IRP_MJ_WRITE
  • get the buffer
  • encrypt the buffer
  • build my irp
  • send irp down
  • wait to complet
  • Complete original irp
    • Replace original buffer
  • Intercept IRP_MJ_WRITE
  • get and store Buffer
  • copy original buffer into my buffer and encrypt it
  • set io completion for irp
  • send irp down
  • IN io completion put back the original buffer

If i use the first method, i don’t get the bsod, but windows isn’t
starting.
here is the code:

NTSTATUS
FilterDriver_Write( PDEVICE_OBJECT pDeviceObject, PIRP Irp )
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = pDeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
LPBYTE pBuffer = NULL;
LPBYTE pBuffer2 = NULL;
PIRP pIrp;
//--------------------------------------------

if( Irp->Flags & IRP_NOCACHE )
{

ULONG Length = currentIrpStack->Parameters.Write.Length;
LARGE_INTEGER Offset = currentIrpStack->Parameters.Write.ByteOffset;
IO_STATUS_BLOCK iosb;
KEVENT kEvent;
PMDL pMdl;

PAGED_CODE();

// get buffer from received irp and build ours
pBuffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
NormalPoolPriority );
pBuffer2 = (LPBYTE)core_mem_alloc( NonPagedPool,
currentIrpStack->Parameters.Write.Length);
core_mem_copy(
pBuffer2,
pBuffer,
currentIrpStack->Parameters.Write.Length
);

// init event
KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
// BUILD IRP
pIrp = IoBuildSynchronousFsdRequest(
IRP_MJ_WRITE,
deviceExtension->pNextDeviceInChain,
pBuffer2,
Length,
&Offset,
&kEvent,
&iosb
);
if( NULL == pIrp )
return STATUS_INSUFFICIENT_RESOURCES;

status = IoCallDriver( deviceExtension->pNextDeviceInChain, pIrp );
if( STATUS_PENDING == status )
KeWaitForSingleObject(
&kEvent,
Executive,
KernelMode,
TRUE,
0
);

//core_mem_free( pBuffer2 );
}

Irp->IoStatus.Information = pIrp->IoStatus.Information;
Irp->IoStatus.Status = pIrp->IoStatus.Status;

IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;

}

If i use the second method, i get IRQL_NOT_LESS_OR_EQUAL.
here is the code:
NTSTATUS
FilterDriver_Write( PDEVICE_OBJECT pDeviceObject, PIRP Irp )
{

NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = pDeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
LPBYTE pBuffer = NULL;
LPBYTE pBuffer2 = NULL;
PIRP pIrp;
//--------------------------------------------

*nextIrpStack = *currentIrpStack;
if( Irp->Flags & IRP_NOCACHE )
{

ULONG Length = currentIrpStack->Parameters.Write.Length;
LARGE_INTEGER Offset = currentIrpStack->Parameters.Write.ByteOffset;
IO_STATUS_BLOCK iosb;
PMDL pMdl;
PMDL pOldMdl;

PAGED_CODE();

// get buffer from received irp and build ours
pBuffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
NormalPoolPriority );
pBuffer2 = (LPBYTE)core_mem_alloc( NonPagedPool,
currentIrpStack->Parameters.Write.Length);
core_mem_copy(
pBuffer2,
pBuffer,
currentIrpStack->Parameters.Write.Length
);

// BUILD MDL TRY

// build Mdl
pMdl = IoAllocateMdl(
pBuffer2,
currentIrpStack->Parameters.Write.Length,
FALSE,
TRUE,
Irp
);
//MmProbeAndLockPages( pMdl, KernelMode, IoReadAccess );

pOldMdl = Irp->MdlAddress;
Irp->MdlAddress = pMdl;
// set the completion routine
IoSetCompletionRoutine(
Irp,
FilterDriver_IoCompletion,
(PVOID)pOldMdl,
TRUE,
TRUE,
TRUE
);
//
////MmUnlockPages( pMdl );
IoFreeMdl( pMdl );
core_mem_free( pBuffer2 );
}

IoCallDriver( deviceExtension->pNextDeviceInChain ,
Irp );

return status;

}

NTSTATUS
FilterDriver_IoCompletion( PDEVICE_OBJECT pDeviceObject, PIRP Irp, PVOID
Context )
{
PDEVICE_EXTENSION deviceExtension = pDeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
// check what irp is coming back
if (currentIrpStack->MajorFunction == IRP_MJ_READ)
{
}

else
{
Irp->MdlAddress = (PMDL)Context;
}

if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
return STATUS_SUCCESS;
}

I’m new to driver developing and i know that there must be something
wrong
with my functions but i can’t figure it out. Any help would be
appreciated.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars 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

EA