808 lines
27 KiB
C
808 lines
27 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
Misc.c
|
||
|
||
Abstract:
|
||
|
||
This module implements the dirctrl, fileinfo and volinfo routines for the local minirdr.
|
||
|
||
Author:
|
||
|
||
Joe Linn [JoeLinn] 4-dec-1994
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "precomp.h"
|
||
#pragma hdrstop
|
||
//#include "fsctlbuf.h"
|
||
//#include "NtDdNfs2.h"
|
||
//#include "stdio.h"
|
||
|
||
//
|
||
// The Bug check file id for this module
|
||
//
|
||
|
||
#define BugCheckFileId (RDBSS_BUG_CHECK_LOCAL_MISC)
|
||
|
||
//
|
||
// The local debug trace level
|
||
//
|
||
|
||
#undef Dbg
|
||
#define Dbg (DEBUG_TRACE_DIRCTRL)
|
||
|
||
|
||
|
||
|
||
PIRP
|
||
MRxLocalBuildCoreOfSyncIoRequest (
|
||
IN PFILE_OBJECT FileObject,
|
||
IN BOOLEAN ForceSyncApi,
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
|
||
IN PVOID Context
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This (local) function builds the request-independent portion of
|
||
an I/O request packet for an I/O operation that will be performed
|
||
synchronously. It initializes a kernel event object, references
|
||
the target file object, and allocates and initializes an IRP.
|
||
|
||
Arguments:
|
||
|
||
FileObject - supplies a pointer to the target file object.
|
||
|
||
Event - Supplies a pointer to a kernel event object. This routine
|
||
initializes the event.
|
||
|
||
IoStatusBlock - Supplies a pointer to an I/O status block. This
|
||
pointer is placed in the IRP.
|
||
|
||
DeviceObject - Supplies or receives the address of the device object
|
||
associated with the target file object. This address is
|
||
subsequently used by StartIoAndWait. *DeviceObject must be
|
||
valid or NULL on entry if FileObject != NULL.
|
||
|
||
CompletionRoutine - the IrpCompletionRoutine
|
||
Context - context of the completion routine
|
||
|
||
Return Value:
|
||
|
||
PIRP - Returns a pointer to the constructed IRP.
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS status;
|
||
PIRP irp;
|
||
PIO_STACK_LOCATION irpSp;
|
||
|
||
PAGED_CODE( );
|
||
|
||
irp = IoAllocateIrp( DeviceObject->StackSize, TRUE );
|
||
if ( irp == NULL ) {
|
||
return NULL;
|
||
}
|
||
|
||
//
|
||
// Fill in the service independent parameters in the IRP.
|
||
|
||
if (ForceSyncApi) {
|
||
irp->Flags = (LONG)IRP_SYNCHRONOUS_API;
|
||
}
|
||
|
||
//
|
||
// Put the file object pointer in the stack location.
|
||
|
||
irpSp = IoGetNextIrpStackLocation( irp ); //ok4ioget
|
||
irpSp->FileObject = FileObject; //ok4->FileObj
|
||
irpSp->DeviceObject = DeviceObject;
|
||
|
||
{ BOOLEAN EnableCalls = CompletionRoutine!=NULL;
|
||
|
||
IoSetCompletionRoutine(irp, CompletionRoutine, Context,
|
||
EnableCalls,EnableCalls,EnableCalls);
|
||
}
|
||
|
||
return irp;
|
||
|
||
} // BuildCoreOfSyncIoRequest
|
||
|
||
|
||
RXSTATUS
|
||
MRxLocalStartIoAndWait (
|
||
IN PRX_CONTEXT RxContext,
|
||
IN PIRP CalldownIrp,
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN OUT PULONG pLengthRemaining
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This (local) function passes a fully built I/O request packet to the
|
||
target driver, then waits for the driver to complete the request.
|
||
|
||
Arguments:
|
||
|
||
RxContext - Supplies a pointer operation context.
|
||
|
||
CalldownIrp - Supplies a pointer to the I/O request packet.
|
||
|
||
DeviceObject - Supplies a pointer to the target device object.
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - Either an error status returned by the driver from
|
||
IoCallDriver, indicating that the driver rejected the request,
|
||
or the I/O status placed in the I/O status block by the driver
|
||
at I/O completion.
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS Status;
|
||
RxCaptureRequestPacket;
|
||
PKEVENT Event;
|
||
PMRX_SYNCIO_CONTEXT SyncIoContext = (PMRX_SYNCIO_CONTEXT)&RxContext->LowIoContext;
|
||
BOOLEAN Wait = FlagOn(RxContext->Flags,RX_CONTEXT_FLAG_WAIT)!=0;
|
||
ULONG ReturnedInformation;
|
||
|
||
PAGED_CODE( );
|
||
|
||
RxDbgTrace (+1, Dbg, ("MRxLocalStartIoAndWait IrpC= %08lx, lengthR=%d\n", RxContext,*pLengthRemaining));
|
||
RxLog(('TSz',0));
|
||
|
||
if (Wait) {
|
||
SyncIoContext->SyncEvent = Event = &SyncIoContext->TheActualEvent;;
|
||
KeInitializeEvent( Event, SynchronizationEvent, FALSE );
|
||
} else {
|
||
ASSERT(!"we can't handle an async call to startioandwait.......");
|
||
SyncIoContext->SyncEvent = NULL;
|
||
}
|
||
|
||
Status = IoCallDriver( DeviceObject, CalldownIrp );
|
||
|
||
if ( Status == RxStatus(PENDING) ) {
|
||
|
||
if (Event) {
|
||
|
||
KeWaitForSingleObject(Event, UserRequest, KernelMode, FALSE, NULL);
|
||
Status = CalldownIrp->IoStatus.Status;
|
||
|
||
} else {
|
||
//store nothing.....get out
|
||
ASSERT(!"we can't handle an async call to startioandwait.......");
|
||
RxDbgTrace (-1, Dbg, ("MRxLocalStartIoAndWait pending= %08lx\n", Status));
|
||
return Status;
|
||
}
|
||
}
|
||
|
||
//
|
||
// from the point of view of the guy above we never pended! so, just store the info....
|
||
ReturnedInformation = CalldownIrp->IoStatus.Information;
|
||
if (pLengthRemaining) {
|
||
RxDbgTrace (0, Dbg, ("MRxLocalStartIoAndWait before remaining= %08lx, info=%08lx\n",
|
||
*pLengthRemaining, ReturnedInformation));
|
||
*pLengthRemaining -= ReturnedInformation;
|
||
RxDbgTrace (0, Dbg, ("MRxLocalStartIoAndWait after remaining= %08lx, info=%08lx\n",
|
||
*pLengthRemaining, ReturnedInformation));
|
||
} else {
|
||
capReqPacket->IoStatus.Information = ReturnedInformation;
|
||
}
|
||
// don't RxContext->StoredStatus = Status;
|
||
IoFreeIrp(CalldownIrp);
|
||
|
||
RxDbgTrace (-1, Dbg, ("MRxLocalStartIoAndWait status= %08lx, info=%08lx\n",
|
||
Status, ReturnedInformation));
|
||
return Status;
|
||
|
||
} // StartIoAndWait
|
||
|
||
|
||
RXSTATUS
|
||
MRxLocalCalldownSyncIoCompletion (
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP CalldownIrp,
|
||
IN PVOID Context
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the I/O completion routine for calldown ios like querydirectory. the rub is that we
|
||
turned synchronous opens into async opens. what we do here is set an event (in the case of a pended
|
||
packet for a sync that we turned async) OR copyup the status;complete;free in the case of a call
|
||
that was always async.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to target device object for the request.
|
||
|
||
CalldownIrp - Pointer to I/O request packet used to call down to the underlying filesystem
|
||
|
||
Context - Irpcontext of the original request to the rdbss
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - If RxStatus(MORE_PROCESSING_REQUIRED) is returned.
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
PRX_CONTEXT RxContext = Context;
|
||
RxCaptureRequestPacket;
|
||
PMRX_SYNCIO_CONTEXT SyncIoContext = (PMRX_SYNCIO_CONTEXT)&RxContext->LowIoContext;
|
||
|
||
RxDbgTrace ( 0, Dbg, (" MRxLocalCalldownSyncIoCompletion = %08lx\n", 0));
|
||
|
||
if (CalldownIrp->PendingReturned){
|
||
if (SyncIoContext->SyncEvent){
|
||
KeSetEvent( SyncIoContext->SyncEvent, 0, FALSE );
|
||
} else {
|
||
|
||
// there's no one waiting.....obviously this was a async from the start so
|
||
// we just complete the packet from here......
|
||
|
||
capReqPacket->IoStatus = CalldownIrp->IoStatus;
|
||
RxContext->StoredStatus = CalldownIrp->IoStatus.Status;
|
||
RxCompleteRequest(RxContext,
|
||
RxContext->StoredStatus); //joejoe this is anomolous
|
||
IoFreeIrp(CalldownIrp);
|
||
}
|
||
}
|
||
|
||
return(RxStatus(MORE_PROCESSING_REQUIRED));
|
||
}
|
||
|
||
|
||
RXSTATUS
|
||
MRxLocalQueryDirectory (
|
||
IN OUT PRX_CONTEXT RxContext,
|
||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||
IN OUT PVOID Buffer,
|
||
IN OUT PULONG pLengthRemaining
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine just reroutes the query to the local guy. It is responsible
|
||
for either completing of enqueuing the input Irp. i can't handle assync yet.
|
||
|
||
Arguments:
|
||
|
||
Irp - Supplies the Irp to process
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS Status;
|
||
RxCaptureRequestPacket;
|
||
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
||
PMRX_SYNCIO_CONTEXT SyncIoContext = (PMRX_SYNCIO_CONTEXT)&RxContext->LowIoContext;
|
||
|
||
PSRV_OPEN SrvOpen = capFobx->SrvOpen;
|
||
PMRX_LOCAL_SRV_OPEN localSrvOpen = (PMRX_LOCAL_SRV_OPEN)SrvOpen;
|
||
BOOLEAN Wait = BooleanFlagOn(RxContext->Flags,RX_CONTEXT_FLAG_WAIT);
|
||
|
||
PIRP CalldownIrp;
|
||
PIO_STACK_LOCATION CalldownIrpSp;
|
||
PDEVICE_OBJECT UnderlyingDeviceObject = localSrvOpen->UnderlyingDeviceObject;
|
||
PFILE_OBJECT UnderlyingFileObject = localSrvOpen->UnderlyingFileObject;
|
||
|
||
PAGED_CODE( );
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxQueryDirectory...\n", 0));
|
||
RxLog(('DQz',0));
|
||
ASSERT(sizeof(MRX_SYNCIO_CONTEXT) <= sizeof(LOWIO_CONTEXT));
|
||
ASSERT (localSrvOpen->UnderlyingFileObject);
|
||
|
||
//
|
||
// Allocate an IRP and fill in the service-independent parameters
|
||
// for the request.
|
||
//
|
||
|
||
CalldownIrp = MRxLocalBuildCoreOfSyncIoRequest (
|
||
UnderlyingFileObject ,//IN PFILE_OBJECT FileObject,
|
||
Wait ,//IN BOOLEAN ForceSyncApi,
|
||
UnderlyingDeviceObject ,//IN PDEVICE_OBJECT DeviceObject,
|
||
MRxLocalCalldownSyncIoCompletion ,//IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
|
||
RxContext //IN PVOID Context
|
||
);
|
||
|
||
if ( CalldownIrp == NULL ) {
|
||
|
||
return RxStatus(INSUFFICIENT_RESOURCES);
|
||
|
||
}
|
||
|
||
//
|
||
// Fill in the service-dependent parameters for the request.
|
||
//
|
||
|
||
CalldownIrpSp = IoGetNextIrpStackLocation( CalldownIrp );
|
||
CalldownIrpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
|
||
CalldownIrpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
|
||
CalldownIrpSp->Parameters.QueryDirectory = capPARAMS->Parameters.QueryDirectory;
|
||
ASSERT (
|
||
(CalldownIrpSp->Parameters.QueryDirectory.FileInformationClass == FileInformationClass)
|
||
&& (CalldownIrpSp->Parameters.QueryDirectory.Length == *pLengthRemaining)
|
||
);
|
||
CalldownIrpSp->Flags = capPARAMS->Flags;
|
||
|
||
//
|
||
// Determine whether the driver wants buffered, direct, or "neither" I/O.
|
||
// we only support neither.
|
||
|
||
ASSERT ( (UnderlyingDeviceObject->Flags & ( DO_BUFFERED_IO | DO_DIRECT_IO)) == 0 );
|
||
|
||
CalldownIrp->UserBuffer = Buffer;
|
||
|
||
// RxDbgTrace( 0, Dbg, (" ->UserBufLength = %08lx\n", CalldownIrpSp->Parameters.QueryDirectory.Length));
|
||
// RxDbgTrace( 0, Dbg, (" ->FileName = %08lx\n", CalldownIrpSp->Parameters.QueryDirectory.FileName));
|
||
// IF_DEBUG {
|
||
// if (CalldownIrpSp->Parameters.QueryDirectory.FileName) {
|
||
// RxDbgTrace( 0, Dbg, (" -> %wZ\n", CalldownIrpSp->Parameters.QueryDirectory.FileName ));
|
||
// }}
|
||
// RxDbgTrace( 0, Dbg, (" ->FileInformationClass = %08lx\n", CalldownIrpSp->Parameters.QueryDirectory.FileInformationClass));
|
||
// RxDbgTrace( 0, Dbg, (" ->FileIndex = %08lx\n", CalldownIrpSp->Parameters.QueryDirectory.FileIndex));
|
||
// RxDbgTrace( 0, Dbg, (" ->UserBuffer = %08lx\n", CalldownIrp->UserBuffer));
|
||
// RxDbgTrace( 0, Dbg, (" ->RestartScan = %08lx\n", FlagOn( CalldownIrpSp->Flags, SL_RESTART_SCAN )));
|
||
// RxDbgTrace( 0, Dbg, (" ->ReturnSingleEntry = %08lx\n", FlagOn( CalldownIrpSp->Flags, SL_RETURN_SINGLE_ENTRY )));
|
||
// RxDbgTrace( 0, Dbg, (" ->IndexSpecified = %08lx\n", FlagOn( CalldownIrpSp->Flags, SL_INDEX_SPECIFIED )));
|
||
|
||
//
|
||
// Start the I/O, wait for it to complete, and return the final status.
|
||
//
|
||
|
||
Status = MRxLocalStartIoAndWait( RxContext, CalldownIrp, UnderlyingDeviceObject, pLengthRemaining );
|
||
RxDbgTrace(-1, Dbg, ("MRxQueryDirectory status=%08lx\n", Status));
|
||
//DbgBreakPoint();
|
||
return Status;
|
||
|
||
} // MRxLocalQueryDirectory
|
||
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
//
|
||
// The local debug trace level
|
||
//
|
||
|
||
#undef Dbg
|
||
#define Dbg (DEBUG_TRACE_FILEINFO)
|
||
|
||
|
||
//
|
||
// Internal support routine
|
||
//
|
||
|
||
RXSTATUS
|
||
MRxLocalQueryFileInformation (
|
||
IN PRX_CONTEXT RxContext,
|
||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||
IN OUT PVOID Buffer,
|
||
IN OUT PULONG pLengthRemaining
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine implements the query file info call
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - Returns the status for the query
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS Status;
|
||
RxCaptureRequestPacket;
|
||
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
||
PSRV_OPEN SrvOpen = capFobx->SrvOpen;
|
||
PFILE_OBJECT UnderlyingFileObject = ((PMRX_LOCAL_SRV_OPEN)(SrvOpen))->UnderlyingFileObject;
|
||
|
||
ULONG ReturnedLength = 0;
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxLocalQueryFileInfo...\n", 0));
|
||
RxLog(('FQz',0));
|
||
|
||
if ( !FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT ) ){
|
||
RxContext->PostRequest = TRUE;
|
||
RxDbgTrace(-1, Dbg, ("MRxLocalQueryFileInfo...PENDING\n", 0));
|
||
return(RxStatus(PENDING));
|
||
}
|
||
|
||
RxDbgTrace( 0, Dbg, (" ---->UserBuffer/remLength/Class = %08lx/%08lx/%08lx\n",
|
||
Buffer, *pLengthRemaining, FileInformationClass));
|
||
ASSERT (UnderlyingFileObject);
|
||
|
||
Status = IoQueryFileInformation(
|
||
UnderlyingFileObject, //IN PFILE_OBJECT FileObject,
|
||
FileInformationClass, //IN FILE_INFORMATION_CLASS FileInformationClass,
|
||
*pLengthRemaining, //IN ULONG Length,
|
||
Buffer, //OUT PVOID FileInformation,
|
||
&ReturnedLength //OUT PULONG ReturnedLength
|
||
);
|
||
|
||
|
||
*pLengthRemaining -= ReturnedLength;
|
||
RxDbgTrace(-1, Dbg, (" ---->Status/remLen/retLen = %08lx\n",
|
||
Status, *pLengthRemaining, ReturnedLength));
|
||
return(Status);
|
||
}
|
||
|
||
RXSTATUS
|
||
MRxLocalSetFileInfoAtCleanup (
|
||
IN PRX_CONTEXT RxContext,
|
||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||
IN OUT PVOID Buffer,
|
||
IN ULONG Length
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine implements the set file info call called on cleanup or flush. We dont actually set the times but we do set
|
||
the endoffile info.
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - Returns the status for the set
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS Status;
|
||
RxCaptureRequestPacket;
|
||
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
||
PSRV_OPEN SrvOpen = capFobx->SrvOpen;
|
||
PFILE_OBJECT UnderlyingFileObject = ((PMRX_LOCAL_SRV_OPEN)(SrvOpen))->UnderlyingFileObject;
|
||
|
||
if (FileInformationClass == FileBasicInformation) {
|
||
return(RxStatus(SUCCESS));
|
||
}
|
||
RxDbgTrace(+1, Dbg, ("MRxLocalSetFileInfoAtCleanup...\n", 0));
|
||
RxLog(('GSz',0));
|
||
return MRxLocalSetFileInformation(RxContext,FileInformationClass,Buffer,Length);
|
||
}
|
||
|
||
|
||
|
||
RXSTATUS
|
||
MRxLocalSetFileInformation (
|
||
IN PRX_CONTEXT RxContext,
|
||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||
IN OUT PVOID Buffer,
|
||
IN ULONG Length
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine implements the set file info call. we do not take the opportunity to set
|
||
allocationsize correctly on a setfilesize calldown.
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - Returns the status for the set
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS Status;
|
||
RxCaptureRequestPacket;
|
||
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
||
PSRV_OPEN SrvOpen = capFobx->SrvOpen;
|
||
PFILE_OBJECT UnderlyingFileObject = ((PMRX_LOCAL_SRV_OPEN)(SrvOpen))->UnderlyingFileObject;
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxLocalSetFileInfo...\n", 0));
|
||
RxLog(('FSz',0));
|
||
|
||
if(Length==0){
|
||
//zero length means that this is the special calldown from the cachemanager...for now just boost
|
||
//joejoe this should be fixed soon
|
||
Length = sizeof(FILE_END_OF_FILE_INFORMATION);
|
||
}
|
||
|
||
RxDbgTrace( 0, Dbg, (" ---->UserBuffer = %08lx\n", Buffer));
|
||
ASSERT (UnderlyingFileObject);
|
||
|
||
//this could be a setfileinfo that comes in from the lazywriter
|
||
//after the underlying file has already been cleaned up
|
||
if (UnderlyingFileObject == NULL) {
|
||
Status = RxStatus(FILE_CLOSED);
|
||
RxDbgTrace(-1, Dbg, (" ---->AlreadyClosed!!! Status = %08lx\n", Status));
|
||
return(Status);
|
||
}
|
||
|
||
Status = IoSetInformation(
|
||
UnderlyingFileObject, //IN PFILE_OBJECT FileObject,
|
||
FileInformationClass, //IN FILE_INFORMATION_CLASS FileInformationClass,
|
||
Length, //IN ULONG Length,
|
||
Buffer //IN PVOID FileInformation
|
||
);
|
||
|
||
RxDbgTrace(-1, Dbg, (" ---->Status = %08lx\n", Status));
|
||
|
||
return(Status);
|
||
}
|
||
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
//
|
||
// The local debug trace level
|
||
//
|
||
|
||
#undef Dbg
|
||
#define Dbg (DEBUG_TRACE_VOLINFO)
|
||
|
||
|
||
RXSTATUS
|
||
MRxLocalQueryVolumeInformation (
|
||
IN OUT PRX_CONTEXT RxContext,
|
||
IN FS_INFORMATION_CLASS FsInformationClass,
|
||
IN OUT PVOID Buffer,
|
||
IN OUT PULONG pLengthRemaining
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine just reroutes the query to the local guy. It is responsible
|
||
for either completing of enqueuing the input Irp. i can't handle assync yet.
|
||
|
||
Arguments:
|
||
|
||
Irp - Supplies the Irp to process
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS Status;
|
||
RxCaptureRequestPacket;
|
||
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
||
PMRX_SYNCIO_CONTEXT SyncIoContext = (PMRX_SYNCIO_CONTEXT)&RxContext->LowIoContext;
|
||
|
||
PSRV_OPEN SrvOpen = capFobx->SrvOpen;
|
||
PMRX_LOCAL_SRV_OPEN localSrvOpen = (PMRX_LOCAL_SRV_OPEN)SrvOpen;
|
||
BOOLEAN Wait = BooleanFlagOn(RxContext->Flags,RX_CONTEXT_FLAG_WAIT);
|
||
|
||
PIRP CalldownIrp;
|
||
PIO_STACK_LOCATION CalldownIrpSp;
|
||
PDEVICE_OBJECT UnderlyingDeviceObject = localSrvOpen->UnderlyingDeviceObject;
|
||
PFILE_OBJECT UnderlyingFileObject = localSrvOpen->UnderlyingFileObject;
|
||
|
||
PAGED_CODE( );
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxQueryVolumeInfo...\n", 0));
|
||
RxLog(('VQz',0));
|
||
ASSERT(sizeof(MRX_SYNCIO_CONTEXT) <= sizeof(LOWIO_CONTEXT));
|
||
ASSERT (localSrvOpen->UnderlyingFileObject);
|
||
|
||
//
|
||
// Allocate an IRP and fill in the service-independent parameters
|
||
// for the request.
|
||
//
|
||
|
||
CalldownIrp = MRxLocalBuildCoreOfSyncIoRequest (
|
||
UnderlyingFileObject ,//IN PFILE_OBJECT FileObject,
|
||
Wait ,//IN BOOLEAN ForceSyncApi,
|
||
UnderlyingDeviceObject ,//IN PDEVICE_OBJECT DeviceObject,
|
||
MRxLocalCalldownSyncIoCompletion ,//IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
|
||
RxContext //IN PVOID Context
|
||
);
|
||
|
||
if ( CalldownIrp == NULL ) {
|
||
|
||
return RxStatus(INSUFFICIENT_RESOURCES);
|
||
|
||
}
|
||
|
||
//
|
||
// Fill in the service-dependent parameters for the request.
|
||
//
|
||
|
||
CalldownIrpSp = IoGetNextIrpStackLocation( CalldownIrp );
|
||
CalldownIrpSp->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
|
||
//CalldownIrpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
|
||
CalldownIrpSp->Parameters.QueryVolume = capPARAMS->Parameters.QueryVolume;
|
||
ASSERT (
|
||
(CalldownIrpSp->Parameters.QueryVolume.FsInformationClass == FsInformationClass)
|
||
&& (CalldownIrpSp->Parameters.QueryVolume.Length == *pLengthRemaining)
|
||
);
|
||
CalldownIrpSp->Flags = capPARAMS->Flags;
|
||
|
||
//
|
||
// Determine whether the driver wants buffered, direct, or "neither" I/O.
|
||
// we only support neither.
|
||
|
||
ASSERT ( (UnderlyingDeviceObject->Flags & ( DO_BUFFERED_IO | DO_DIRECT_IO)) == 0 );
|
||
|
||
//CalldownIrp->UserBuffer = NULL;
|
||
CalldownIrp->AssociatedIrp.SystemBuffer = Buffer;
|
||
|
||
//
|
||
// Start the I/O, wait for it to complete, and return the final status.
|
||
//
|
||
|
||
Status = MRxLocalStartIoAndWait( RxContext, CalldownIrp, UnderlyingDeviceObject, pLengthRemaining );
|
||
RxDbgTrace(-1, Dbg, ("MRxQueryVolumeInfo status=%08lx\n", Status));
|
||
//DbgBreakPoint();
|
||
return Status;
|
||
|
||
} // MRxLocalQueryVolumeInformation
|
||
|
||
|
||
|
||
//
|
||
// The local debug trace level
|
||
//
|
||
|
||
#undef Dbg
|
||
#define Dbg (DEBUG_TRACE_FLUSH)
|
||
|
||
|
||
RXSTATUS
|
||
MRxLocalFlush (
|
||
IN PRX_CONTEXT RxContext
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine just reroutes the query to the local guy. It is responsible
|
||
for either completing of enqueuing the input Irp. we're already sync by the time we get here.
|
||
|
||
Arguments:
|
||
|
||
Irp - Supplies the Irp to process
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
--*/
|
||
|
||
{
|
||
RXSTATUS Status;
|
||
RxCaptureRequestPacket;
|
||
RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
|
||
PMRX_SYNCIO_CONTEXT SyncIoContext = (PMRX_SYNCIO_CONTEXT)&RxContext->LowIoContext;
|
||
|
||
PSRV_OPEN SrvOpen = capFobx->SrvOpen;
|
||
PMRX_LOCAL_SRV_OPEN localSrvOpen = (PMRX_LOCAL_SRV_OPEN)SrvOpen;
|
||
BOOLEAN Wait = BooleanFlagOn(RxContext->Flags,RX_CONTEXT_FLAG_WAIT);
|
||
|
||
PIRP CalldownIrp;
|
||
PIO_STACK_LOCATION CalldownIrpSp;
|
||
PDEVICE_OBJECT UnderlyingDeviceObject = localSrvOpen->UnderlyingDeviceObject;
|
||
PFILE_OBJECT UnderlyingFileObject = localSrvOpen->UnderlyingFileObject;
|
||
|
||
PAGED_CODE( );
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxFlush...\n", 0));
|
||
RxLog(('FFz',0));
|
||
ASSERT(sizeof(MRX_SYNCIO_CONTEXT) <= sizeof(LOWIO_CONTEXT));
|
||
ASSERT (localSrvOpen->UnderlyingFileObject);
|
||
|
||
//
|
||
// Allocate an IRP and fill in the service-independent parameters
|
||
// for the request.
|
||
//
|
||
|
||
CalldownIrp = MRxLocalBuildCoreOfSyncIoRequest (
|
||
UnderlyingFileObject ,//IN PFILE_OBJECT FileObject,
|
||
Wait ,//IN BOOLEAN ForceSyncApi,
|
||
UnderlyingDeviceObject ,//IN PDEVICE_OBJECT DeviceObject,
|
||
MRxLocalCalldownSyncIoCompletion ,//IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
|
||
RxContext //IN PVOID Context
|
||
);
|
||
|
||
if ( CalldownIrp == NULL ) {
|
||
|
||
return RxStatus(INSUFFICIENT_RESOURCES);
|
||
|
||
}
|
||
|
||
//
|
||
// Fill in the service-dependent parameters for the request.
|
||
//
|
||
|
||
CalldownIrpSp = IoGetNextIrpStackLocation( CalldownIrp );
|
||
CalldownIrpSp->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
|
||
|
||
|
||
//
|
||
// Start the I/O, wait for it to complete, and return the final status.
|
||
//
|
||
|
||
Status = MRxLocalStartIoAndWait( RxContext, CalldownIrp, UnderlyingDeviceObject,NULL );
|
||
RxDbgTrace(-1, Dbg, ("MRxFlush status=%08lx\n", Status));
|
||
//DbgBreakPoint();
|
||
return Status;
|
||
|
||
} // MRxLocalFlush
|
||
|
||
|
||
|