Re: Can't logon workstation after enabling file read during IRP_MJ_CREATE

Thank you so much, Ryan.

The InternalReadFile routine is copied from my codes.

My filter is loaded at system start up, and will hook all file creations for
all volumes.

And in the IRP_MJ_CREATE handle, my codes do as the following, after
IRP_CREATE is returned from lower driver, just check the
filestandardinformation and read the file content. If the read operation is
skipped, I can logon to the system, otherwise the system will report error.

Codes in handler of IRP_MJ_CREATE:

SaveFileObject = IrpStack->FileObject;

// send IRP_MJ_CREATE to lower driver and get the result
status = IssueCreateIrp(DeviceObject, IRP);

if( NT_SUCCESS(status) ){
//check the file’s content , and fill myfcb
status = CheckFilePostCreate(DeviceObject, SafeFileObject, &MyFcb);

if( !NT_SUCCESS(status)){
IoCancelFileOpen(DeviceObject, SaveFileObject );
RC = Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
}
}
return status;

NTSTATUS
CheckFilePostCreate(
DEVICEOBJECT DeviceObject,
PFILE_OBJECT SafeFileObject,
PMYFCB pMyFcb)
{
// get file info
status = IoQueryFileInformation(FileObject,
FileStandardInformation,
sizeof( fileinfo ),
&fileinfo,
&ReturnedLength);

if( !NT_SUCCESS(status))
return status;

// copy some filestandardinfo into myFCB here

//Check: is file a directory?

// try to read my filehead , only for files
if( fileinfo.EndOfFile.QuadPart > SIZE_FILE_HEAD){
readoffset.QuadPart = 0;

status = InternalReadFile( DeviceObject,
FileObject,
&FileHead,
SIZE_FILE_HEAD,
&readoffset);

if(NT_SUCCESS( status ) ){
//copy data from FileHead into myFCB

}
}

return status;
}

“Nick Ryan” wrote :xxxxx@ntfsd…
>
> No, a read won’t increase the reference on a file object. There’s
> nothing wrong with what you are trying to do that I can see. Can you
> post your code?
>
> SXW wrote:
>
> > More info about this error:
> >
> > Some creations will return STATUS_SHARING_VIOLATION, and there are also
some
> > creations failed with STATUS_NO_SUCH_LOGON_SESSION error.
> >
> > Does the internal read operation hold reference of the file object?
> >
> > Thanks in advanced.
> >
> >
> >>Hi,
> >>
> >>My filter will read file content during the the MJ_CREATE, only when
this
> >>creation return successfully from lower driver. After the iocalldriver
> >>returned,sending a new IRP built with IoBuildSynchronousFsdRequest will
> >>cause the winlogon report the domain(actually the local machine) can’t
be
> >>accessed. If the internal routine InternalReadFile is simply skipped ,
> >>everything is ok.
> >>
> >>What’s wrong with the winlogon? At this time, my filter hooks all files’
> >>creations.
> >>
> >>Appreciate for any advise,
> >>
> >>Xinwei
> >>
> >>
> >>
> >>NTSTATUS
> >>InternalReadFile(
> >> IN PDEVICE_OBJECT DeviceObject,
> >> IN PFILE_OBJECT FileObject,
> >> OUT PVOID Buffer,
> >> IN ULONG Length,
> >> IN PLARGE_INTEGER StartingOffset
> >>)
> >>{
> >> PIRP irpRead;
> >> KEVENT syncevent;
> >> NTSTATUS status;
> >> IO_STATUS_BLOCK iostatus;
> >> PIO_STACK_LOCATION pIrpStackNext ;
> >> PDEVICE_OBJECT pLowerDriver;
> >>
> >> pLowerDriver =
> >>((PDeviceExtension)(DeviceObject->DeviceExtension))->TargetDeviceObject;
> >>
> >> RtlZeroMemory( &iostatus, sizeof( iostatus ) );
> >>
> >> KeInitializeEvent( &syncevent, SynchronizationEvent, FALSE );
> >>
> >> irpRead = IoBuildSynchronousFsdRequest(
> >> IRP_MJ_READ,
> >> pLowerDriver,
> >> Buffer ,
> >> Length ,
> >> StartingOffset ,
> >> &syncevent,
> >> &iostatus);
> >>
> >> if( irpRead ){
> >>
> >> pIrpStackNext = IoGetNextIrpStackLocation( irpRead );
> >>
> >> pIrpStackNext->FileObject = FileObject;
> >>
> >> status = IoCallDriver( pLowerDriver, irpRead );
> >>
> >> if( STATUS_PENDING == status ){
> >>
> >>KeWaitForSingleObject(&syncevent,Executive,KernelMode,FALSE,NULL);
> >> status = iostatus.Status;
> >> }
> >> }else{
> >> status = STATUS_INSUFFICIENT_RESOURCES;
> >> }
> >>
> >> return status ;
> >>}
> >>
> >>
> >>
> >>
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@nryan.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
> –
> - Nick Ryan (MVP for DDK)
>
>
>
>

“SXW” wrote in message news:xxxxx@ntfsd…
>
> Thank you so much, Ryan.
>
> The InternalReadFile routine is copied from my codes.
>
> My filter is loaded at system start up, and will hook all file creations
for
> all volumes.
>
> And in the IRP_MJ_CREATE handle, my codes do as the following, after
> IRP_CREATE is returned from lower driver, just check the
> filestandardinformation and read the file content. If the read operation
is
> skipped, I can logon to the system, otherwise the system will report
error.
>
> Codes in handler of IRP_MJ_CREATE:
>
> SaveFileObject = IrpStack->FileObject;
>
> // send IRP_MJ_CREATE to lower driver and get the result
> status = IssueCreateIrp(DeviceObject, IRP);
>

If you want to keep using original IRP after this point you need to set
completion routine that returns STATUS_MORE_PROCESSING_REQUIERED. You can’t
call IoCancelFileOpen if you didn’t done this.

> if( NT_SUCCESS(status) ){
> //check the file’s content , and fill myfcb
> status = CheckFilePostCreate(DeviceObject, SafeFileObject, &MyFcb);
>
> if( !NT_SUCCESS(status)){
> IoCancelFileOpen(DeviceObject, SaveFileObject );
> RC = Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
> Irp->IoStatus.Information = 0;
> }
> }

Here you need to call IoCompleteRequest, assuming that you interrupted
completion of the IRP by returning STATUS_MORE_PROCESSING_REQUIERED from the
completion routine.

> return status;
>

The value you return here MUST be the same as Irp->IoStatus.Status. In
particular if you set Irp->IoStatus.Status = STATUS_ACCESS_DENIED, you have
to return STATUS_ACCESS_DENIED.

There is another problem with your approach. It is not safe to read file
using NonCachedIo and then call IoCancelFileOpen. If you read file using
cached IO and then call IoCancelFileOpen system WILL bug check when cache
dereference the file object that is no longer valid because you failed the
create request. osronline web site has an article discussing this issue, you
need to read it.

Alexei.