2025-04-27 07:49:33 -04:00

808 lines
27 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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