RE: Question on preventing my driver from filtering i- t's own transactions...

Actually, an IRP_MJ_CLEANUP is issued (on Win2k, at least). Maybe
ObDereferenceObject, seeing the handle count is zero, issues the cleanup
event though it has never been > 0? Any ideas?

[Smith, Joel] -----Original Message-----
From: Rob Fuller [mailto:xxxxx@NSISW.COM]
Sent: Wednesday, February 14, 2001 5:39 PM
To: File Systems Developers
Subject: [ntfsd] RE: Question on preventing my driver from filtering i t’s
own transactions…

Actually, IRP_MJ_CLEANUP will not be issued with this scheme, although
IRP_MJ_CLOSE will. You may want to poof up a handle with the
quasi-documented ObOpenObjectByPointer, then close the handle to generate
the IRP_MJ_CLEANUP. Alternatively, you could send IRP_MJ_CLEANUP yourself
if you already have such code.

-----Original Message-----
From: Smith, Joel [mailto:xxxxx@ntpsoftware.com]
Sent: Wednesday, February 14, 2001 4:16 PM
To: File Systems Developers
Subject: [ntfsd] RE: Question on preventing my driver from filtering i t’s
own transactions…

Here’s my version of rolling your own create. Credit goes to Hrdina
Pavel; I derived this code from an old post of his. Any bugs in THIS
version are probably mine, not Mr. Pavel’s! Note the pAuxData variable.
Obviously, a 1k nonpaged buffer is overkill, but I haven’t yet bothered to
try to figure out what SeCreateAccessState puts in here.

I must warn you any others who are considering using this code that
this code has never been rigorously tested and several of the referenced
routines are undocumented. I have run it only on WIn2k, and for very simple
applications. USE AT YOUR OWN RISK! This is alpha code at best! I
hesitate to disseminate this code, but perhaps the routine can be improved
through the collaborative medium of this list, for all of our benefit.

Note that this routine is not very flexible. The sort of ‘open’
that can be performed with this routine are limited. I wanted to keep the
code simple. Also note that you ‘close’ a file object created with the
routine by calling ObDereferenceObject on it. This will cause a cleanup to
be issued to the top of the FSD stack.

Here are some declarations you will need (you will probably want to
pull my ‘CLEANUP’ macros):

NTSTATUS
ObCreateObject(
IN KPROCESSOR_MODE ProbeMode,
IN POBJECT_TYPE ObjectType,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN KPROCESSOR_MODE OwnershipMode,
IN OUT PVOID ParseContext OPTIONAL,
IN ULONG ObjectBodySize,
IN ULONG PagedPoolCharge,
IN ULONG NonPagedPoolCharge,
OUT PVOID *Object
);

NTSTATUS
SeCreateAccessState(PACCESS_STATE pAccessState,
PVOID pAuxData,
ACCESS_MASK AccessMask,
PGENERIC_MAPPING pMapping);

NTSTATUS FsSimpleOpen(PUNICODE_STRING pstrName, ACCESS_MASK DesiredAccess,
PDEVICE_OBJECT pVolume, PDEVICE_OBJECT pRealDevice, PFILE_OBJECT pParent,
PFILE_OBJECT *ppFile)

{
PIRP pIrp = NULL;
PIO_STACK_LOCATION pStack;
KEVENT event;
IO_STATUS_BLOCK stat;
NTSTATUS ntRet;
PFILE_OBJECT pFile = NULL;
OBJECT_ATTRIBUTES oa;
ACCESS_STATE AccessState;
HANDLE hFile = NULL;
IO_SECURITY_CONTEXT ctx;
ULONG *pAuxData = ExAllocatePool(NonPagedPool, 1024);

if (pAuxData == NULL)
{
ntRet = STATUS_INSUFFICIENT_RESOURCES;
CLEANUP();
}

ASSERT(pVolume != NULL);
ASSERT(pRealDevice != NULL);
ASSERT(ppFile != NULL);
ASSERT(pstrName != NULL);

memset(pAuxData, 0, 1024);

//initialize an event and an IRP to send to the fsd
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
pIrp = IoAllocateIrp(pVolume->StackSize, FALSE);
IF_OUTOFMEMORY_CLEANUP(pIrp, &ntRet);

InitializeObjectAttributes(&oa,
NULL,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);

//create a file object for the irp
ntRet = ObCreateObject(KernelMode,
*IoFileObjectType,
&oa,
KernelMode,
0,
sizeof(FILE_OBJECT),
0,
0,
&pFile);

IF_FAIL_CLEANUP(ntRet);

//initialize the file object
RtlZeroMemory(pFile, sizeof(FILE_OBJECT));
pFile->Type = IO_TYPE_FILE;
pFile->Size = sizeof(FILE_OBJECT);
pFile->DeviceObject = pRealDevice;
pFile->Flags = FO_SYNCHRONOUS_IO;
pFile->RelatedFileObject = pParent;

//initialize embedded synch objects
KeInitializeEvent(&pFile->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&pFile->Event, NotificationEvent, FALSE);

//copy the file name into the buffer
pFile->FileName.Buffer = ExAllocatePool(NonPagedPool,
pstrName->MaximumLength);
if (pFile->FileName.Buffer == NULL)
{
ntRet = STATUS_INSUFFICIENT_RESOURCES;
CLEANUP();
}

pFile->FileName.MaximumLength = pstrName->MaximumLength;
pFile->FileName.Length = pstrName->Length;
RtlCopyMemory(pFile->FileName.Buffer, pstrName->Buffer,
pstrName->Length);

//setup the irp
pIrp->UserEvent = &event;
pIrp->UserIosb = &stat;
pIrp->Tail.Overlay.Thread = KeGetCurrentThread();
pIrp->Tail.Overlay.OriginalFileObject = pFile;
pIrp->RequestorMode = KernelMode;
pIrp->Flags |= (IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API);
pIrp->MdlAddress = NULL;
pIrp->PendingReturned = FALSE;
pIrp->Cancel = FALSE;
pIrp->CancelRoutine = NULL;
pIrp->Tail.Overlay.AuxiliaryBuffer = NULL;

//Set up the I/O stack location.
pStack = IoGetNextIrpStackLocation(pIrp);
pStack->MajorFunction = IRP_MJ_CREATE;
pStack->DeviceObject = pVolume;
pStack->FileObject = pFile;

//create an access state for the sd
ntRet = SeCreateAccessState(&AccessState, pAuxData, DesiredAccess,
IoGetFileObjectGenericMapping());
IF_FAIL_CLEANUP(ntRet);

//fill out the create’s security context
ctx.AccessState = &AccessState;
ctx.DesiredAccess = DesiredAccess;
ctx.SecurityQos = NULL;
ctx.FullCreateOptions = 0;

//fill out the the create parameter
pStack->Parameters.Create.SecurityContext = &ctx;
pStack->Parameters.Create.Options = FILE_OPEN << 24;
pStack->Parameters.Create.FileAttributes = FILE_ATTRIBUTE_NORMAL;
pStack->Parameters.Create.ShareAccess = FILE_SHARE_READ |
FILE_SHARE_WRITE;
pStack->Parameters.Create.EaLength = 0;

//set the completion routine (that will free the irp)
IoSetCompletionRoutine(pIrp, FsDefaultComplete, 0, TRUE, TRUE, TRUE);

//Send it to the FSD
ntRet = IoCallDriver(pVolume, pIrp);
pIrp = NULL;

if (ntRet == STATUS_PENDING)
{
//wait for the io to complete
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
ntRet = stat.Status;
}

CLEANUP:

SAFE_FREE_POOL(pAuxData);

if (!NT_SUCCESS(ntRet))
{
if (pIrp != NULL)
{
IoFreeIrp(pIrp);
}
if (pFile)
{
SAFE_FREE_POOL(pFile->FileName.Buffer);
pFile->DeviceObject = NULL;
ObDereferenceObject(pFile);
}
}
else
{
FsReferenceDeviceAndVpb(pFile);

//set the out param
*ppFile = pFile;
}
return ntRet;
}

VOID FsReferenceDeviceAndVpb(PFILE_OBJECT pFile)
{
NTSTATUS ntRet;

ASSERT(pFile->Vpb != NULL ? pFile->DeviceObject->Vpb != NULL :
pFile->DeviceObject->Vpb == NULL);

//Increment RealDevice’s reference count.
InterlockedIncrement(&pFile->DeviceObject->ReferenceCount);

//Increment Vpb’s reference count, if one exists.
if (pFile->Vpb)
{
ASSERT((pFile->Vpb->Flags & VPB_MOUNTED) && !(pFile->Vpb->Flags &
VPB_LOCKED));
InterlockedIncrement(&pFile->Vpb->ReferenceCount);
}
}

-----Original Message-----
From: Edward Mandac [mailto:xxxxx@texar.com mailto:xxxxx]
Sent: Wednesday, February 14, 2001 3:51 PM
To: xxxxx@ntpsoftware.com
Subject: Re: [ntfsd] RE: Question on preventing my driver from filtering
it’s own transactions…

I’d like to see the code for rolling one’s own IRPs as I have not been able
to do it and have resorted to using ZwCreateFile, ZwQueryDirectoryFile, etc.

Post it either to me or to the list. Thanks!

----- Original Message -----
From: “Smith, Joel”
To: “File Systems Developers”
Sent: Wednesday, February 14, 2001 3:30 PM
Subject: [ntfsd] RE: Question on preventing my driver from filtering it’s
own transactions…

> If you need any code for the first two techniques, reply to the
> list and I’ll send it up (In exchange for others critiquing it and
> pointing out its flaws!)
>
> -Joel


You are currently subscribed to ntfsd as: xxxxx@nsisw.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: xxxxx@ntpsoftware.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com</mailto:xxxxx>