|
|
/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
fastio.c
Abstract:
This module performs the hooks for the fast i/o path.
Author:
Paul McDaniel (paulmcd) 01-Mar-2000
Revision History:
--*/
#include "precomp.h"
//
// Private constants.
//
//
// Private types.
//
//
// Private prototypes.
//
//
// linker commands
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, SrFastIoCheckIfPossible )
#pragma alloc_text( PAGE, SrFastIoRead )
#pragma alloc_text( PAGE, SrFastIoWrite )
#pragma alloc_text( PAGE, SrFastIoQueryBasicInfo )
#pragma alloc_text( PAGE, SrFastIoQueryStandardInfo )
#pragma alloc_text( PAGE, SrFastIoLock )
#pragma alloc_text( PAGE, SrFastIoUnlockSingle )
#pragma alloc_text( PAGE, SrFastIoUnlockAll )
#pragma alloc_text( PAGE, SrFastIoUnlockAllByKey )
#pragma alloc_text( PAGE, SrFastIoDeviceControl )
#pragma alloc_text( PAGE, SrPreAcquireForSectionSynchronization )
#pragma alloc_text( PAGE, SrFastIoDetachDevice )
#pragma alloc_text( PAGE, SrFastIoQueryNetworkOpenInfo )
#pragma alloc_text( PAGE, SrFastIoMdlRead )
#pragma alloc_text( PAGE, SrFastIoMdlReadComplete )
#pragma alloc_text( PAGE, SrFastIoPrepareMdlWrite )
#pragma alloc_text( PAGE, SrFastIoMdlWriteComplete )
#pragma alloc_text( PAGE, SrFastIoReadCompressed )
#pragma alloc_text( PAGE, SrFastIoWriteCompressed )
#pragma alloc_text( PAGE, SrFastIoMdlReadCompleteCompressed )
#pragma alloc_text( PAGE, SrFastIoMdlWriteCompleteCompressed )
#pragma alloc_text( PAGE, SrFastIoQueryOpen )
#endif // ALLOC_PRAGMA
//
// Private globals.
//
//
// Public globals.
//
//
// Public functions.
//
//
// Define fast I/O procedure prototypes.
//
// Fast I/O read and write procedures.
//
BOOLEAN SrFastIoCheckIfPossible ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); //
// Handle calls to Control Device Object
//
if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension; //
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoCheckIfPossible)) { return pFastIoDispatch->FastIoCheckIfPossible( FileObject, FileOffset, Length, Wait, LockKey, CheckForReadOperation, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoRead ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoRead)) { return pFastIoDispatch->FastIoRead( FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoWrite ( IN struct _FILE_OBJECT *pFileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { NTSTATUS eventStatus; PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE();
if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// See if logging is enabled
//
if (!SR_LOGGING_ENABLED(pExtension) || SR_IS_FS_CONTROL_DEVICE(pExtension)) { goto CallNextDevice; }
//
// does this file have a name? skip unnamed files
//
if (FILE_OBJECT_IS_NOT_POTENTIALLY_INTERESTING( pFileObject )) { goto CallNextDevice; }
ASSERT(pFileObject->Vpb != NULL);
//
// is this file already closed? it can be the cache manager calling
// us to do work. we ignore the cache managers work as we monitored
// everything that happned prior to him seeing it.
//
if (FlagOn(pFileObject->Flags, FO_CLEANUP_COMPLETE)) { goto CallNextDevice; }
//
// Fire a notification , SrNotify will check for eligibility
//
eventStatus = SrHandleEvent( pExtension, SrEventStreamChange, pFileObject, NULL, NULL, NULL );
CHECK_STATUS(eventStatus);
//
// call the next device
//
CallNextDevice:
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoWrite)) { return pFastIoDispatch->FastIoWrite( pFileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
//
// Fast I/O query basic and standard information procedures.
//
BOOLEAN SrFastIoQueryBasicInfo ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT PFILE_BASIC_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoQueryBasicInfo)) { return pFastIoDispatch->FastIoQueryBasicInfo( FileObject, Wait, Buffer, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoQueryStandardInfo ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT PFILE_STANDARD_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoQueryStandardInfo)) { return pFastIoDispatch->FastIoQueryStandardInfo( FileObject, Wait, Buffer, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
//
// Fast I/O lock and unlock procedures.
//
BOOLEAN SrFastIoLock ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoLock)) { return pFastIoDispatch->FastIoLock( FileObject, FileOffset, Length, ProcessId, Key, FailImmediately, ExclusiveLock, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoUnlockSingle ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoUnlockSingle)) { return pFastIoDispatch->FastIoUnlockSingle( FileObject, FileOffset, Length, ProcessId, Key, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoUnlockAll ( IN struct _FILE_OBJECT *FileObject, PEPROCESS ProcessId, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoUnlockAll)) { return pFastIoDispatch->FastIoUnlockAll( FileObject, ProcessId, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoUnlockAllByKey ( IN struct _FILE_OBJECT *FileObject, PVOID ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoUnlockAllByKey)) { return pFastIoDispatch->FastIoUnlockAllByKey( FileObject, ProcessId, Key, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
//
// Fast I/O device control procedure.
//
BOOLEAN SrFastIoDeviceControl ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE();
if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoDeviceControl)) { return pFastIoDispatch->FastIoDeviceControl( FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
//
// Define callbacks for NtCreateSection to copy the file if a write section
// is being created on this file.
//
NTSTATUS SrPreAcquireForSectionSynchronization( IN PFS_FILTER_CALLBACK_DATA Data, OUT PVOID *CompletionContext ) { NTSTATUS eventStatus; PFILE_OBJECT pFileObject; PSR_DEVICE_EXTENSION pExtension; UNREFERENCED_PARAMETER( CompletionContext ); ASSERT(Data->Operation == FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION); ASSERT(CompletionContext == NULL); ASSERT(IS_SR_DEVICE_OBJECT(Data->DeviceObject));
PAGED_CODE();
//
// get the file object and device object
//
pExtension = Data->DeviceObject->DeviceExtension; ASSERT(IS_VALID_SR_DEVICE_EXTENSION(pExtension));
//
// See if logging is enabled
//
if (!SR_LOGGING_ENABLED(pExtension) || SR_IS_FS_CONTROL_DEVICE(pExtension)) { return STATUS_SUCCESS; }
pFileObject = Data->FileObject; ASSERT(IS_VALID_FILE_OBJECT(pFileObject));
//
// If they don't have write access to the section or the file don't worry
// about it.
//
// Is this file already closed? it can be the cache manager calling
// us to do work. we ignore the cache managers work as we monitored
// everything that happned prior to him seeing it.
//
if (!FlagOn(Data->Parameters.AcquireForSectionSynchronization.PageProtection, (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) || !pFileObject->WriteAccess || FlagOn(pFileObject->Flags, FO_CLEANUP_COMPLETE)) { return STATUS_SUCCESS; }
//
// does this file have a name? skip unnamed files
//
if (FILE_OBJECT_IS_NOT_POTENTIALLY_INTERESTING( pFileObject )) { return STATUS_SUCCESS; } ASSERT(pFileObject->Vpb != NULL);
//
// yep, fire a notification as if a write just happened.
// otherwise he can write to the section and we don't see the write
//
eventStatus = SrHandleEvent( pExtension, SrEventStreamChange, pFileObject, NULL, NULL, NULL );
CHECK_STATUS(eventStatus);
//
// we never want to fail the acquire, we are just a silent monitor.
//
return STATUS_SUCCESS; } // SrPreAcquireForCreateSection
//
// Define callback for drivers that have device objects attached to lower-
// level drivers' device objects. This callback is made when the lower-level
// driver is deleting its device object.
//
VOID SrFastIoDetachDevice ( IN struct _DEVICE_OBJECT *AttachedDevice, IN struct _DEVICE_OBJECT *DeviceDeleted ) { PSR_DEVICE_EXTENSION pExtension;
UNREFERENCED_PARAMETER( DeviceDeleted );
//
// < dispatch!
//
PAGED_CODE(); ASSERT(IS_SR_DEVICE_OBJECT(AttachedDevice)); pExtension = AttachedDevice->DeviceExtension;
SrTrace(NOTIFY, ("SR!SrFastIoDetachDevice: detaching from %p(%wZ)\n", DeviceDeleted, pExtension->pNtVolumeName ));
//
// Detach ourselves from the device.
//
ASSERT(pExtension->pTargetDevice == DeviceDeleted);
SrDetachDevice(AttachedDevice, TRUE); SrDeleteAttachmentDevice(AttachedDevice); NULLPTR(AttachedDevice); } // SrFastIoDetachDevice
//
// This structure is used by the server to quickly get the information needed
// to service a server open call. It is takes what would be two fast io calls
// one for basic information and the other for standard information and makes
// it into one call.
//
BOOLEAN SrFastIoQueryNetworkOpenInfo ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, OUT struct _IO_STATUS_BLOCK *IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoQueryNetworkOpenInfo)) { return pFastIoDispatch->FastIoQueryNetworkOpenInfo( FileObject, Wait, Buffer, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
//
// Define Mdl-based routines for the server to call
//
BOOLEAN SrFastIoMdlRead ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, MdlRead)) { return pFastIoDispatch->MdlRead( FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoMdlReadComplete ( IN struct _FILE_OBJECT *FileObject, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, MdlReadComplete)) { return pFastIoDispatch->MdlReadComplete( FileObject, MdlChain, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoPrepareMdlWrite ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, PrepareMdlWrite)) { return pFastIoDispatch->PrepareMdlWrite( FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, pExtension->pTargetDevice); } } return FALSE; }
BOOLEAN SrFastIoMdlWriteComplete ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, MdlWriteComplete)) { return pFastIoDispatch->MdlWriteComplete( FileObject, FileOffset, MdlChain, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoReadCompressed ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PVOID Buffer, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo, IN ULONG CompressedDataInfoLength, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoReadCompressed)) { return pFastIoDispatch->FastIoReadCompressed( FileObject, FileOffset, Length, LockKey, Buffer, MdlChain, IoStatus, CompressedDataInfo, CompressedDataInfoLength, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoWriteCompressed ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, IN PVOID Buffer, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo, IN ULONG CompressedDataInfoLength, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoWriteCompressed)) { return pFastIoDispatch->FastIoWriteCompressed( FileObject, FileOffset, Length, LockKey, Buffer, MdlChain, IoStatus, CompressedDataInfo, CompressedDataInfoLength, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoMdlReadCompleteCompressed ( IN struct _FILE_OBJECT *FileObject, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, MdlReadCompleteCompressed)) { return pFastIoDispatch->MdlReadCompleteCompressed( FileObject, MdlChain, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoMdlWriteCompleteCompressed ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, MdlWriteCompleteCompressed)) { return pFastIoDispatch->MdlWriteCompleteCompressed ( FileObject, FileOffset, MdlChain, pExtension->pTargetDevice ); } } return FALSE; }
BOOLEAN SrFastIoQueryOpen ( IN struct _IRP *pIrp, OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, IN struct _DEVICE_OBJECT *DeviceObject ) { PSR_DEVICE_EXTENSION pExtension; PFAST_IO_DISPATCH pFastIoDispatch; PIO_STACK_LOCATION pIrpSp; BOOLEAN Result;
//
// < dispatch!
//
PAGED_CODE(); if (DeviceObject->DeviceExtension) { ASSERT(IS_SR_DEVICE_OBJECT(DeviceObject)); pExtension = DeviceObject->DeviceExtension;
//
// call the next device
//
pFastIoDispatch = pExtension->pTargetDevice-> DriverObject->FastIoDispatch;
if (VALID_FAST_IO_DISPATCH_HANDLER(pFastIoDispatch, FastIoQueryOpen)) { //
// normally IoCallDriver would update this field, we should manually
//
pIrpSp = IoGetCurrentIrpStackLocation( pIrp ); pIrpSp->DeviceObject = pExtension->pTargetDevice;
Result = pFastIoDispatch->FastIoQueryOpen ( pIrp, NetworkInformation, pExtension->pTargetDevice ); if (!Result) { //
// This is ok, fastioquery does not complete the irp ever, and
// false means we are about to come down with an MJ_CREATE so
// we need the proper device object put back in the stack.
//
pIrpSp->DeviceObject = DeviceObject; } return Result; } } return FALSE; }
|