How do I lock/unlock access to modify IRP's data buffers?

Hello, all!

Please, help me with follow problem: i’m write filter driver, but when I’m touch data buffers in the completion routines for IRP_MJ_READ and IRP_MJ_WRITE, even if don’t change this buffers, system is crashes!
I’ve tryed spin locks like a follow:

KIRQL oldirql;
KeAcquireSpinLock( &DataMutex, &oldirql );
//do xor twice, data in the buffer is unchanged!
for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
KeReleaseSpinLock( &DataMutex, oldirql );

But it not helps…I’m don’t know how to syncronize access to IRP’s data buffer, should I create one spinclock for each opened file? if you know, please, give me a source sample how to do this right.

Any help will be very appreciated

Regards,

Valery A. Boronin,
System Software Engineer, Novosoft
http://www.novosoft.ru

You need to synchronize access by having you completion routine set and
event and having you dispatch routine wait on the event. Then, you can
access the buffer after the completion routine sets the event.

Jamey
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Valery A. Boronin
Sent: Thursday, August 10, 2000 12:30 PM
To: File Systems Developers
Subject: [ntfsd] How do I lock/unlock access to modify IRP’s data buffers?

Hello, all!

Please, help me with follow problem: i’m write filter driver, but when I’m
touch data buffers in the completion routines for IRP_MJ_READ and
IRP_MJ_WRITE, even if don’t change this buffers, system is crashes!
I’ve tryed spin locks like a follow:

KIRQL oldirql;
KeAcquireSpinLock( &DataMutex, &oldirql );
//do xor twice, data in the buffer is unchanged!
for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
KeReleaseSpinLock( &DataMutex, oldirql );

But it not helps…I’m don’t know how to syncronize access to IRP’s data
buffer, should I create one spinclock for each opened file? if you know,
please, give me a source sample how to do this right.

Any help will be very appreciated

Regards,

Valery A. Boronin,
System Software Engineer, Novosoft
http://www.novosoft.ru

first, it seems that the xor is done twice with the same result, ie the
buffer will be changed.

second, are you touching the buffer irp->userbuffer? if so, well, you cannot
touch it in the completion routine as the thread context is arbitruary. you
have to lock done the buffer with a mdl first in the dispatch.

Ho Mun Chuen
xxxxx@pmail.ntu.edu.sg
@@ “Not everything that counts can be counted;
<” )~ and not everything that can be counted counts"
//\ … Albert Einstein
----- Original Message -----
From: Valery A. Boronin
To: File Systems Developers
Sent: Friday, August 11, 2000 3:30 AM
Subject: [ntfsd] How do I lock/unlock access to modify IRP’s data buffers?

Hello, all!

Please, help me with follow problem: i’m write filter driver, but when
I’m touch data buffers in the completion routines for IRP_MJ_READ and
IRP_MJ_WRITE, even if don’t change this buffers, system is crashes!
I’ve tryed spin locks like a follow:

KIRQL oldirql;
KeAcquireSpinLock( &DataMutex, &oldirql );
file://do xor twice, data in the buffer is unchanged!
for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
KeReleaseSpinLock( &DataMutex, oldirql );

But it not helps…I’m don’t know how to syncronize access to IRP’s data
buffer, should I create one spinclock for each opened file? if you know,
please, give me a source sample how to do this right.

Any help will be very appreciated

Regards,

Valery A. Boronin,
System Software Engineer, Novosoft
http://www.novosoft.ru http:</http:>

Thanks for answer

On 08/10/00, ““Ho Mun Chuen” ” wrote:
> first, it seems that the xor is done twice with the same result, ie the
> buffer will be changed.
no, buffer won’t changed because pOutBuff always the same as pInBuff.

>
> second, are you touching the buffer irp->userbuffer? if so, well, you cannot
> touch it in the completion routine as the thread context is arbitruary. you
> have to lock done the buffer with a mdl first in the dispatch.
yes, i’m touching irp->userbuffer sometimes
you are right, just what I want, the very thing I want is how to lock done
the buffer with a mdl first in the dispatch? If possible, may be a short
source example or what’s API calls do that?

I’m not sure, but now I’m don’t touch buffers in the completion routines,
I’m set and wait event in the hook routine as follow:

On 08/10/00, ““Jamey Kirby” ” wrote:
>
> You need to synchronize access by having you completion routine set and
> event and having you dispatch routine wait on the event. Then, you can
> access the buffer after the completion routine sets the event.
Jamey, The problem is I do as you written above!
This is sample of code from hook routine:
if (currentIrpStack->MajorFunction==IRP_MJ_READ)
{
NTSTATUS ntStatus;
KEVENT event;
// Initialize the event used to signla request completion.
KeInitializeEvent(&event, NotificationEvent, FALSE);
// Copy the stack to the next location for the target to use.
IoCopyCurrentIrpStackLocationToNext(Irp);
// Set the completion routine to make aperation synchronous.
IoSetCompletionRoutine(Irp, EfsHookReadDone, &event, TRUE, TRUE, TRUE);
// Call the target device with the request.
ntStatus = IoCallDriver( hookExt->FileSystem, Irp );
if (ntStatus == STATUS_PENDING)
{
// Wait for it to complete.
KeWaitForSingleObject(&event, UserRequest, KernelMode, TRUE, NULL);
// Reload local status with request status.
ntStatus = Irp->IoStatus.Status;
}

ioBuffer = EfsMapUserBuffer(Irp);
bufferLength = currentIrpStack->Parameters.Read.Length;

//!!! Here is I’m touching buffers !!!
if (ioBuffer) Decrypt(ioBuffer,ioBuffer,bufferLength);

// Complete the hi-jacked request.
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
// Maybe do some stuff.
// Maybe do even more stuff.
return ntStatus;
}

This code should work, IMHO, but it isn’t! Any ideas?

Valery

>
> Ho Mun Chuen
> xxxxx@pmail.ntu.edu.sg
> @@ “Not everything that counts can be counted;
> <” )~ and not everything that can be counted counts"
> //\ … Albert Einstein
> ----- Original Message -----
> From: Valery A. Boronin
> To: File Systems Developers
> Sent: Friday, August 11, 2000 3:30 AM
> Subject: [ntfsd] How do I lock/unlock access to modify IRP’s data buffers?
>
>
> Hello, all!
>
> Please, help me with follow problem: i’m write filter driver, but when
> I’m touch data buffers in the completion routines for IRP_MJ_READ and
> IRP_MJ_WRITE, even if don’t change this buffers, system is crashes!
> I’ve tryed spin locks like a follow:
>
> KIRQL oldirql;
> KeAcquireSpinLock( &DataMutex, &oldirql );
> file://do xor twice, data in the buffer is unchanged!
> for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
> for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
> KeReleaseSpinLock( &DataMutex, oldirql );
>
> But it not helps…I’m don’t know how to syncronize access to IRP’s data
> buffer, should I create one spinclock for each opened file? if you know,
> please, give me a source sample how to do this right.
>
> Any help will be very appreciated
>
> Regards,
>
> Valery A. Boronin,
> System Software Engineer, Novosoft
> http://www.novosoft.ru http:</http:>

Thanks for answer

On 08/10/00, ““Jamey Kirby” ” wrote:
>
> You need to synchronize access by having you completion routine set and
> event and having you dispatch routine wait on the event. Then, you can
> access the buffer after the completion routine sets the event.
Jamey, The problem is I do as you written above!
This is sample of code from hook routine:
if (currentIrpStack->MajorFunction==IRP_MJ_READ)
{
NTSTATUS ntStatus;
KEVENT event;
// Initialize the event used to signla request completion.
KeInitializeEvent(&event, NotificationEvent, FALSE);
// Copy the stack to the next location for the target to use.
IoCopyCurrentIrpStackLocationToNext(Irp);
// Set the completion routine to make aperation synchronous.
IoSetCompletionRoutine(Irp, EfsHookReadDone, &event, TRUE, TRUE, TRUE);
// Call the target device with the request.
ntStatus = IoCallDriver( hookExt->FileSystem, Irp );
if (ntStatus == STATUS_PENDING)
{
// Wait for it to complete.
KeWaitForSingleObject(&event, UserRequest, KernelMode, TRUE, NULL);
// Reload local status with request status.
ntStatus = Irp->IoStatus.Status;
}

ioBuffer = EfsMapUserBuffer(Irp);
bufferLength = currentIrpStack->Parameters.Read.Length;

//!!! Here is I’m touching buffers !!!
if (ioBuffer) Decrypt(ioBuffer,ioBuffer,bufferLength);

// Complete the hi-jacked request.
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
// Maybe do some stuff.
// Maybe do even more stuff.
return ntStatus;
}

This code should work, IMHO, but it isn’t! Any ideas?

Valery

>
> Jamey
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Valery A. Boronin
> Sent: Thursday, August 10, 2000 12:30 PM
> To: File Systems Developers
> Subject: [ntfsd] How do I lock/unlock access to modify IRP’s data buffers?
>
>
> Hello, all!
>
> Please, help me with follow problem: i’m write filter driver, but when I’m
> touch data buffers in the completion routines for IRP_MJ_READ and
> IRP_MJ_WRITE, even if don’t change this buffers, system is crashes!
> I’ve tryed spin locks like a follow:
>
> KIRQL oldirql;
> KeAcquireSpinLock( &DataMutex, &oldirql );
> //do xor twice, data in the buffer is unchanged!
> for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
> for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
> KeReleaseSpinLock( &DataMutex, oldirql );
>
> But it not helps…I’m don’t know how to syncronize access to IRP’s data
> buffer, should I create one spinclock for each opened file? if you know,
> please, give me a source sample how to do this right.
>
> Any help will be very appreciated
>
> Regards,
>
> Valery A. Boronin,
> System Software Engineer, Novosoft
> http://www.novosoft.ru
>

in dispatch, use IoAllocateMdl to allocate a mdl for irp->userbuffer. then
lock it with MmProbeAndLockPages. u will then be able to access the buffer
in completion by calling MmGetSystemAddressForMdl to get a system level
address equivalent for the buffer. after use, unlock with MmUnlockPages, and
then free the mdl with IoFreeMdl.

Ho Mun Chuen
xxxxx@pmail.ntu.edu.sg
@@ “Not everything that counts can be counted;
<” )~ and not everything that can be counted counts"
//\ … Albert Einstein
----- Original Message -----
From:
To: File Systems Developers
Sent: Friday, August 11, 2000 8:43 AM
Subject: [ntfsd] Re: How do I lock/unlock access to modify IRP’s data
buffers?

Thanks for answer

On 08/10/00, ““Ho Mun Chuen” ” wrote:
> first, it seems that the xor is done twice with the same result, ie the
> buffer will be changed.
no, buffer won’t changed because pOutBuff always the same as pInBuff.

>
> second, are you touching the buffer irp->userbuffer? if so, well, you
cannot
> touch it in the completion routine as the thread context is arbitruary.
you
> have to lock done the buffer with a mdl first in the dispatch.
yes, i’m touching irp->userbuffer sometimes
you are right, just what I want, the very thing I want is how to lock done
the buffer with a mdl first in the dispatch? If possible, may be a short
source example or what’s API calls do that?

I’m not sure, but now I’m don’t touch buffers in the completion routines,
I’m set and wait event in the hook routine as follow:

On 08/10/00, ““Jamey Kirby” ” wrote:
>
> You need to synchronize access by having you completion routine set and
> event and having you dispatch routine wait on the event. Then, you can
> access the buffer after the completion routine sets the event.
Jamey, The problem is I do as you written above!
This is sample of code from hook routine:
if (currentIrpStack->MajorFunction==IRP_MJ_READ)
{
NTSTATUS ntStatus;
KEVENT event;
// Initialize the event used to signla request completion.
KeInitializeEvent(&event, NotificationEvent, FALSE);
// Copy the stack to the next location for the target to use.
IoCopyCurrentIrpStackLocationToNext(Irp);
// Set the completion routine to make aperation synchronous.
IoSetCompletionRoutine(Irp, EfsHookReadDone, &event, TRUE, TRUE, TRUE);
// Call the target device with the request.
ntStatus = IoCallDriver( hookExt->FileSystem, Irp );
if (ntStatus == STATUS_PENDING)
{
// Wait for it to complete.
KeWaitForSingleObject(&event, UserRequest, KernelMode, TRUE, NULL);
// Reload local status with request status.
ntStatus = Irp->IoStatus.Status;
}

ioBuffer = EfsMapUserBuffer(Irp);
bufferLength = currentIrpStack->Parameters.Read.Length;

file://!!! Here is I’m touching buffers !!!
if (ioBuffer) Decrypt(ioBuffer,ioBuffer,bufferLength);

// Complete the hi-jacked request.
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
// Maybe do some stuff.
// Maybe do even more stuff.
return ntStatus;
}

This code should work, IMHO, but it isn’t! Any ideas?

Valery

>
> Ho Mun Chuen
> xxxxx@pmail.ntu.edu.sg
> @@ “Not everything that counts can be counted;
> <” )~ and not everything that can be counted counts"
> //\ … Albert Einstein
> ----- Original Message -----
> From: Valery A. Boronin
> To: File Systems Developers
> Sent: Friday, August 11, 2000 3:30 AM
> Subject: [ntfsd] How do I lock/unlock access to modify IRP’s data buffers?
>
>
> Hello, all!
>
> Please, help me with follow problem: i’m write filter driver, but when
> I’m touch data buffers in the completion routines for IRP_MJ_READ and
> IRP_MJ_WRITE, even if don’t change this buffers, system is crashes!
> I’ve tryed spin locks like a follow:
>
> KIRQL oldirql;
> KeAcquireSpinLock( &DataMutex, &oldirql );
> file://do xor twice, data in the buffer is unchanged!
> for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
> for (i=0; i < len; i++) pOutBuff[i] = ~pInBuff[i];
> KeReleaseSpinLock( &DataMutex, oldirql );
>
> But it not helps…I’m don’t know how to syncronize access to IRP’s data
> buffer, should I create one spinclock for each opened file? if you know,
> please, give me a source sample how to do this right.
>
> Any help will be very appreciated
>
> Regards,
>
> Valery A. Boronin,
> System Software Engineer, Novosoft
> http://www.novosoft.ru http:


You are currently subscribed to ntfsd as: xxxxx@pmail.ntu.edu.sg
To unsubscribe send a blank email to $subst(‘Email.Unsub’)</http:>