1594 lines
39 KiB
C
1594 lines
39 KiB
C
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Copyright (C) 1992, Microsoft Corporation
|
|||
|
//
|
|||
|
// File: fastio.c
|
|||
|
//
|
|||
|
// Contents: Routines to implement Fast IO
|
|||
|
//
|
|||
|
// Classes:
|
|||
|
//
|
|||
|
// Functions:
|
|||
|
//
|
|||
|
// History: 8/11/93 Milans created
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
#include "dfsprocs.h"
|
|||
|
#include "fsctrl.h"
|
|||
|
#include "fastio.h"
|
|||
|
#include "attach.h"
|
|||
|
#include "srv.h"
|
|||
|
|
|||
|
#define Dbg (DEBUG_TRACE_FASTIO)
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoCheckIfPossible (
|
|||
|
FILE_OBJECT *pFileObject,
|
|||
|
LARGE_INTEGER *pOffset,
|
|||
|
ULONG Length,
|
|||
|
BOOLEAN fWait,
|
|||
|
ULONG LockKey,
|
|||
|
BOOLEAN fCheckForRead,
|
|||
|
IO_STATUS_BLOCK *pIoStatusBlock,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoRead(
|
|||
|
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,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoWrite(
|
|||
|
IN struct _FILE_OBJECT *FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
IN ULONG LockKey,
|
|||
|
IN PVOID Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoQueryBasicInfo(
|
|||
|
IN struct _FILE_OBJECT *FileObject,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
OUT PFILE_BASIC_INFORMATION Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoQueryStandardInfo(
|
|||
|
IN struct _FILE_OBJECT *FileObject,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
OUT PFILE_STANDARD_INFORMATION Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoLock(
|
|||
|
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,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoUnlockSingle(
|
|||
|
IN struct _FILE_OBJECT *FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN PLARGE_INTEGER Length,
|
|||
|
PEPROCESS ProcessId,
|
|||
|
ULONG Key,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoUnlockAll(
|
|||
|
IN struct _FILE_OBJECT *FileObject,
|
|||
|
PEPROCESS ProcessId,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoUnlockAllByKey(
|
|||
|
IN struct _FILE_OBJECT *FileObject,
|
|||
|
PVOID ProcessId,
|
|||
|
ULONG Key,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
DEVICE_OBJECT *DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoDeviceControl(
|
|||
|
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,
|
|||
|
DEVICE_OBJECT *DeviceObject);
|
|||
|
|
|||
|
VOID
|
|||
|
DfsFastIoAcquireFile(
|
|||
|
IN PFILE_OBJECT FileObject);
|
|||
|
|
|||
|
VOID
|
|||
|
DfsFastIoReleaseFile(
|
|||
|
IN PFILE_OBJECT FileObject);
|
|||
|
|
|||
|
VOID
|
|||
|
DfsFastIoDetachDevice(
|
|||
|
IN PDEVICE_OBJECT SourceDevice,
|
|||
|
IN PDEVICE_OBJECT TargetDevice);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoQueryNetworkOpenInfo(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PDEVICE_OBJECT DeviceObject);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlRead(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PDEVICE_OBJECT DeviceObject);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlReadComplete(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoPrepareMdlWrite(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlWriteComplete(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// If this routine is present, it will be called by FsRtl
|
|||
|
// to acquire the file for the mapped page writer.
|
|||
|
//
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
DfsFastIoAcquireForModWrite(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER EndingOffset,
|
|||
|
OUT PERESOURCE *ResourceToRelease,
|
|||
|
IN PDEVICE_OBJECT DeviceObject);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoReadCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
OUT PVOID Buffer,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
|||
|
IN ULONG CompressedDataInfoLength,
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoWriteCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
IN PVOID Buffer,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
|||
|
IN ULONG CompressedDataInfoLength,
|
|||
|
IN PDEVICE_OBJECT DeviceObject);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlReadCompleteCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlWriteCompleteCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject);
|
|||
|
|
|||
|
PFAST_IO_DISPATCH
|
|||
|
DfsFastIoLookup(
|
|||
|
IN FILE_OBJECT *pFileObject,
|
|||
|
IN DEVICE_OBJECT *DeviceObject,
|
|||
|
IN PDEVICE_OBJECT *targetVdo);
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoCheckIfPossible )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoRead )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoWrite )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoQueryBasicInfo )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoQueryStandardInfo )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoLock )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoUnlockSingle )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoUnlockAll )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoUnlockAllByKey )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoDeviceControl )
|
|||
|
#pragma alloc_text( PAGE, DfsFastIoDetachDevice )
|
|||
|
#endif // ALLOC_PRAGMA
|
|||
|
|
|||
|
FAST_IO_DISPATCH FastIoDispatch =
|
|||
|
{
|
|||
|
sizeof(FAST_IO_DISPATCH),
|
|||
|
DfsFastIoCheckIfPossible, // CheckForFastIo
|
|||
|
DfsFastIoRead, // FastIoRead
|
|||
|
DfsFastIoWrite, // FastIoWrite
|
|||
|
DfsFastIoQueryBasicInfo, // FastIoQueryBasicInfo
|
|||
|
DfsFastIoQueryStandardInfo, // FastIoQueryStandardInfo
|
|||
|
DfsFastIoLock, // FastIoLock
|
|||
|
DfsFastIoUnlockSingle, // FastIoUnlockSingle
|
|||
|
DfsFastIoUnlockAll, // FastIoUnlockAll
|
|||
|
DfsFastIoUnlockAllByKey, // FastIoUnlockAllByKey
|
|||
|
DfsFastIoDeviceControl, // FastIoDeviceControl
|
|||
|
DfsFastIoAcquireFile, // AcquireFileForNtCreateSection
|
|||
|
DfsFastIoReleaseFile, // ReleaseFileForNtCreateSection
|
|||
|
DfsFastIoDetachDevice, // FastIoDetachDevice
|
|||
|
DfsFastIoQueryNetworkOpenInfo, // FastIoQueryNetworkOpenInfo
|
|||
|
DfsFastIoAcquireForModWrite, // AcquireForModWrite
|
|||
|
DfsFastIoMdlRead, // MdlRead
|
|||
|
DfsFastIoMdlReadComplete, // MdlReadComplete
|
|||
|
DfsFastIoPrepareMdlWrite, // PrepareMdlWrite
|
|||
|
DfsFastIoMdlWriteComplete, // MdlWriteComplete
|
|||
|
DfsFastIoReadCompressed, // FastIoReadCompressed
|
|||
|
DfsFastIoWriteCompressed, // FastIoWriteCompressed
|
|||
|
DfsFastIoMdlReadCompleteCompressed, // MdlReadCompleteCompressed
|
|||
|
DfsFastIoMdlWriteCompleteCompressed // MdlWriteCompleteCompressed
|
|||
|
};
|
|||
|
|
|||
|
//
|
|||
|
// Macro to see if a PFAST_IO_DISPATCH has a particular field
|
|||
|
//
|
|||
|
|
|||
|
#define IS_VALID_INDEX(pfio, e) \
|
|||
|
((pfio != NULL) && \
|
|||
|
(pfio->SizeOfFastIoDispatch >= \
|
|||
|
(offsetof(FAST_IO_DISPATCH, e) + sizeof(PVOID))) && \
|
|||
|
(pfio->e != NULL) \
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoLookup
|
|||
|
//
|
|||
|
// Synopsis: Given a file object, this routine will locate the fast IO
|
|||
|
// dispatch table for the underlying provider
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
PFAST_IO_DISPATCH
|
|||
|
DfsFastIoLookup(
|
|||
|
IN FILE_OBJECT *pFileObject,
|
|||
|
IN DEVICE_OBJECT *DeviceObject,
|
|||
|
OUT PDEVICE_OBJECT *targetVdo)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
|
|||
|
*targetVdo = NULL;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoLookup: Entered\n", 0);
|
|||
|
|
|||
|
if (DeviceObject->DeviceType == FILE_DEVICE_DFS_VOLUME) {
|
|||
|
|
|||
|
//
|
|||
|
// In this case we have a direct pointer to the next device to which
|
|||
|
// we need to pass on (This is attached device case).
|
|||
|
//
|
|||
|
|
|||
|
*targetVdo = ((PDFS_VOLUME_OBJECT) DeviceObject)->Provider.DeviceObject;
|
|||
|
|
|||
|
pFastIoTable = (*targetVdo)->DriverObject->FastIoDispatch;
|
|||
|
|
|||
|
DebugTrace(0,Dbg, "DfsFastIoLookup: DevObj: %08lx\n", DeviceObject);
|
|||
|
DebugTrace(0, Dbg, "DfsFastIoLookup: TargetVdo %08lx\n", *targetVdo);
|
|||
|
DebugTrace(-1,Dbg, "DfsFastIoLookup: Exit -> %08lx\n", pFastIoTable );
|
|||
|
|
|||
|
return(pFastIoTable);
|
|||
|
|
|||
|
} else if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM ) {
|
|||
|
|
|||
|
//
|
|||
|
// An operation intended for a disk file system we are attached to.
|
|||
|
//
|
|||
|
|
|||
|
*targetVdo = ((PDFS_ATTACH_FILE_SYSTEM_OBJECT) DeviceObject)->TargetDevice;
|
|||
|
|
|||
|
pFastIoTable = (*targetVdo)->DriverObject->FastIoDispatch;
|
|||
|
|
|||
|
DebugTrace(0,Dbg, "DfsFastIoLookup: DevObj: %08lx ", DeviceObject);
|
|||
|
DebugTrace(0, Dbg, "TargetVdo %08lx\n", *targetVdo);
|
|||
|
DebugTrace(-1,Dbg, "DfsFastIoLookup: Exit -> %08lx\n", pFastIoTable );
|
|||
|
|
|||
|
return( pFastIoTable );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// This is an unknown device object type and we dont know what to do
|
|||
|
//
|
|||
|
|
|||
|
DebugTrace(0, 0,
|
|||
|
"DfsFastIoLookup: Unexpected DeviceObject Type %08x\n",
|
|||
|
DeviceObject);
|
|||
|
|
|||
|
ASSERT(FALSE && "Unknown DeviceObject");
|
|||
|
|
|||
|
DebugTrace(-1,Dbg, "DfsFastIoLookup: Exit -> %08lx\n", NULL );
|
|||
|
|
|||
|
return(NULL);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoCheckIfPossible
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoCheckIfPossible (
|
|||
|
FILE_OBJECT *pFileObject,
|
|||
|
LARGE_INTEGER *pOffset,
|
|||
|
ULONG Length,
|
|||
|
BOOLEAN fWait,
|
|||
|
ULONG LockKey,
|
|||
|
BOOLEAN fCheckForRead,
|
|||
|
IO_STATUS_BLOCK *pIoStatusBlock,
|
|||
|
PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoCheckIfPossible Enter \n", 0);
|
|||
|
pFastIoTable = DfsFastIoLookup(pFileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoCheckIfPossible) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoCheckIfPossible(
|
|||
|
pFileObject,
|
|||
|
pOffset,
|
|||
|
Length,
|
|||
|
fWait,
|
|||
|
LockKey,
|
|||
|
fCheckForRead,
|
|||
|
pIoStatusBlock,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoCheckIfPossible Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoRead
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoRead(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
IN ULONG LockKey,
|
|||
|
OUT PVOID Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoRead Enter \n", 0);
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoRead) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoRead(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
Wait,
|
|||
|
LockKey,
|
|||
|
Buffer,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoRead Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoWrite
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoWrite(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
IN ULONG LockKey,
|
|||
|
IN PVOID Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoWrite Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoWrite) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoWrite(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
Wait,
|
|||
|
LockKey,
|
|||
|
Buffer,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoWrite Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoQueryBasicInfo
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoQueryBasicInfo(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
OUT PFILE_BASIC_INFORMATION Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoQueryBasicInfo Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoQueryBasicInfo) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoQueryBasicInfo(
|
|||
|
FileObject,
|
|||
|
Wait,
|
|||
|
Buffer,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoQueryBasicInfo Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoQueryStandardInfo
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoQueryStandardInfo(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
OUT PFILE_STANDARD_INFORMATION Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoQueryStandardInfo Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoQueryStandardInfo) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoQueryStandardInfo(
|
|||
|
FileObject,
|
|||
|
Wait,
|
|||
|
Buffer,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoQueryStandardInfo Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoLock
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoLock(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN PLARGE_INTEGER Length,
|
|||
|
PEPROCESS ProcessId,
|
|||
|
ULONG Key,
|
|||
|
BOOLEAN FailImmediately,
|
|||
|
BOOLEAN ExclusiveLock,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoLock Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoLock) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoLock(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
ProcessId,
|
|||
|
Key,
|
|||
|
FailImmediately,
|
|||
|
ExclusiveLock,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoLock Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoUnlockSingle
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoUnlockSingle(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN PLARGE_INTEGER Length,
|
|||
|
PEPROCESS ProcessId,
|
|||
|
ULONG Key,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoUnlockSingle Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoUnlockSingle) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoUnlockSingle(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
ProcessId,
|
|||
|
Key,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoUnlockSingle Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoUnlockAll
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoUnlockAll(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
PEPROCESS ProcessId,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoUnlockAll Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoUnlockAll) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoUnlockAll(
|
|||
|
FileObject,
|
|||
|
ProcessId,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoUnlockAll Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: FastIoUnlockAllByKey
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoUnlockAllByKey(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
PVOID ProcessId,
|
|||
|
ULONG Key,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoUnlockAllByKey Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoUnlockAllByKey) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoUnlockAllByKey(
|
|||
|
FileObject,
|
|||
|
ProcessId,
|
|||
|
Key,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoUnlockAllByKey Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoDeviceControl
|
|||
|
//
|
|||
|
// Synopsis:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoDeviceControl(
|
|||
|
IN PFILE_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,
|
|||
|
PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoDeviceControl Enter \n", 0);
|
|||
|
|
|||
|
//
|
|||
|
// See if this is the server making fsctl calls to us...
|
|||
|
//
|
|||
|
|
|||
|
if (DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM) {
|
|||
|
|
|||
|
if (FileObject->FsContext == UIntToPtr( DFS_OPEN_CONTEXT )) {
|
|||
|
|
|||
|
DfsSrvFsctrl(
|
|||
|
IoControlCode,
|
|||
|
InputBuffer,
|
|||
|
InputBufferLength,
|
|||
|
OutputBuffer,
|
|||
|
OutputBufferLength,
|
|||
|
IoStatus);
|
|||
|
|
|||
|
fPossible = TRUE;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// This should never happen, since its unlikely that there is
|
|||
|
// someone else registering a FILE_DEVICE_DFS_FILE_SYSTEM, and
|
|||
|
// even if they did, we wouldn't be attaching to it.
|
|||
|
//
|
|||
|
|
|||
|
DebugTrace(0, 0,
|
|||
|
"DfsFastIoDeviceControl: Unknown device %08lx\n",
|
|||
|
DeviceObject);
|
|||
|
|
|||
|
ASSERT( FALSE && "FastIO fsctrl on illegal device!\n" );
|
|||
|
|
|||
|
DebugTrace(-1,Dbg, "DfsFastIoDeviceControl: Exit\n", 0);
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} else if (IS_DFS_CTL_CODE(IoControlCode)) {
|
|||
|
|
|||
|
//
|
|||
|
// One of our control codes, can't handle it via fast IO
|
|||
|
//
|
|||
|
|
|||
|
DebugTrace(0, Dbg, "Dfs fsctrl code %08lx - returning FALSE\n",
|
|||
|
ULongToPtr( IoControlCode ));
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoDeviceControl) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoDeviceControl(
|
|||
|
FileObject,
|
|||
|
Wait,
|
|||
|
InputBuffer,
|
|||
|
InputBufferLength,
|
|||
|
OutputBuffer,
|
|||
|
OutputBufferLength,
|
|||
|
IoControlCode,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoDeviceControl Exit \n", 0);
|
|||
|
|
|||
|
return(fPossible);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoAcquireFile
|
|||
|
//
|
|||
|
// Synopsis: Acquire file for NtCreateSection. Due to a long chain of
|
|||
|
// events, this routine must either call the underlying FS's
|
|||
|
// AcquireFileForNtCreateSection routine or, if there isn't one,
|
|||
|
// we must acquire the FileObject resource ourselves, since
|
|||
|
// there is no possibility of returning a BOOLEAN.
|
|||
|
//
|
|||
|
// Arguments: [FileObject] -- The file to be acquired.
|
|||
|
//
|
|||
|
// Returns: Nothing
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
VOID
|
|||
|
DfsFastIoAcquireFile(
|
|||
|
IN PFILE_OBJECT FileObject)
|
|||
|
{
|
|||
|
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT deviceObject, targetVdo;
|
|||
|
PFSRTL_COMMON_FCB_HEADER header;
|
|||
|
|
|||
|
//
|
|||
|
// Due to an error, this routine was defined without a device object
|
|||
|
// argument. We will have to locate our device object
|
|||
|
//
|
|||
|
|
|||
|
if (FileObject->Vpb == NULL) {
|
|||
|
|
|||
|
deviceObject = FileObject->DeviceObject;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Pick up the bottommost device object
|
|||
|
//
|
|||
|
|
|||
|
ASSERT( FileObject->Vpb->DeviceObject != NULL );
|
|||
|
|
|||
|
deviceObject = FileObject->Vpb->DeviceObject;
|
|||
|
|
|||
|
ASSERT( deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME );
|
|||
|
|
|||
|
//
|
|||
|
// Now, walk up the attached chain and find our own device object
|
|||
|
//
|
|||
|
|
|||
|
while (deviceObject &&
|
|||
|
(deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME)) {
|
|||
|
|
|||
|
deviceObject = deviceObject->AttachedDevice;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ASSERT( deviceObject != NULL );
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup( FileObject, deviceObject, &targetVdo );
|
|||
|
|
|||
|
|
|||
|
if (IS_VALID_INDEX( pFastIoTable, AcquireFileForNtCreateSection) ) {
|
|||
|
|
|||
|
IoSetTopLevelIrp( (PIRP) FSRTL_FSP_TOP_LEVEL_IRP );
|
|||
|
|
|||
|
pFastIoTable->AcquireFileForNtCreateSection( FileObject );
|
|||
|
|
|||
|
} else if ((header = FileObject->FsContext) && header->Resource) {
|
|||
|
|
|||
|
IoSetTopLevelIrp( (PIRP) FSRTL_FSP_TOP_LEVEL_IRP );
|
|||
|
|
|||
|
ExAcquireResourceExclusiveLite( header->Resource, TRUE );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
NOTHING;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoReleaseFile
|
|||
|
//
|
|||
|
// Synopsis: Release file for NtCreateSection. Due to a long chain of
|
|||
|
// events, this routine must either call the underlying FS's
|
|||
|
// ReleaseFileForNtCreateSection routine or, if there isn't one,
|
|||
|
// we must Release the FileObject resource ourselves, since
|
|||
|
// there is no possibility of returning a BOOLEAN.
|
|||
|
//
|
|||
|
// Arguments: [FileObject] -- The file to be Released.
|
|||
|
//
|
|||
|
// Returns: Nothing
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
VOID
|
|||
|
DfsFastIoReleaseFile(
|
|||
|
IN PFILE_OBJECT FileObject)
|
|||
|
{
|
|||
|
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT deviceObject, targetVdo;
|
|||
|
PFSRTL_COMMON_FCB_HEADER header;
|
|||
|
|
|||
|
//
|
|||
|
// Due to an error, this routine was defined without a device object
|
|||
|
// argument. We will have to locate our device object
|
|||
|
//
|
|||
|
|
|||
|
if (FileObject->Vpb == NULL) {
|
|||
|
|
|||
|
deviceObject = FileObject->DeviceObject;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Pick up the bottommost device object
|
|||
|
//
|
|||
|
|
|||
|
ASSERT( FileObject->Vpb->DeviceObject != NULL );
|
|||
|
|
|||
|
deviceObject = FileObject->Vpb->DeviceObject;
|
|||
|
|
|||
|
ASSERT( deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME );
|
|||
|
|
|||
|
//
|
|||
|
// Now, walk up the attached chain and find our own device object
|
|||
|
//
|
|||
|
|
|||
|
while (deviceObject &&
|
|||
|
(deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME)) {
|
|||
|
|
|||
|
deviceObject = deviceObject->AttachedDevice;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ASSERT( deviceObject != NULL );
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup( FileObject, deviceObject, &targetVdo );
|
|||
|
|
|||
|
|
|||
|
if (IS_VALID_INDEX( pFastIoTable, ReleaseFileForNtCreateSection) ) {
|
|||
|
|
|||
|
IoSetTopLevelIrp( (PIRP) NULL );
|
|||
|
|
|||
|
pFastIoTable->ReleaseFileForNtCreateSection( FileObject );
|
|||
|
|
|||
|
} else if ((header = FileObject->FsContext) && header->Resource) {
|
|||
|
|
|||
|
IoSetTopLevelIrp( (PIRP) NULL );
|
|||
|
|
|||
|
ExReleaseResourceLite( header->Resource );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
NOTHING;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//+----------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DfsFastIoDetachDevice, public
|
|||
|
//
|
|||
|
// Synopsis: This routine is a different from the rest of the fast io
|
|||
|
// routines. It is called when a device object is being deleted,
|
|||
|
// and that device object has an attached device. The semantics
|
|||
|
// of this routine are "You attached to a device object that now
|
|||
|
// needs to be deleted; please detach from the said device
|
|||
|
// object."
|
|||
|
//
|
|||
|
// Arguments: [SourceDevice] -- Our device, the one that we created to
|
|||
|
// attach ourselves to the target device.
|
|||
|
// [TargetDevice] -- Their device, the one that we are attached
|
|||
|
// to.
|
|||
|
//
|
|||
|
// Returns: Nothing - we must succeed.
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
VOID
|
|||
|
DfsFastIoDetachDevice(
|
|||
|
IN PDEVICE_OBJECT SourceDevice,
|
|||
|
IN PDEVICE_OBJECT TargetDevice)
|
|||
|
{
|
|||
|
DfsDetachVolumeForDelete( SourceDevice );
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoQueryNetworkOpenInfo(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN BOOLEAN Wait,
|
|||
|
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoQueryNetworkOpenInfo Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoQueryNetworkOpenInfo) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoQueryNetworkOpenInfo(
|
|||
|
FileObject,
|
|||
|
Wait,
|
|||
|
Buffer,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
IoStatus->Status = STATUS_NOT_SUPPORTED;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoQueryNetworkOpenInfo Exit \n", 0);
|
|||
|
|
|||
|
return( fPossible );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlRead(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoMdlRead Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, MdlRead) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->MdlRead(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
LockKey,
|
|||
|
MdlChain,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FsRtlMdlReadDev(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
LockKey,
|
|||
|
MdlChain,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoMdlRead Exit \n", 0);
|
|||
|
|
|||
|
return( fPossible );
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlReadComplete(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fSuccess;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoMdlReadComplete Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, MdlReadComplete) ) {
|
|||
|
|
|||
|
fSuccess = pFastIoTable->MdlReadComplete(
|
|||
|
FileObject,
|
|||
|
MdlChain,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fSuccess = FsRtlMdlReadCompleteDev(
|
|||
|
FileObject,
|
|||
|
MdlChain,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoMdlReadComplete Exit \n", 0);
|
|||
|
|
|||
|
return( fSuccess );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoPrepareMdlWrite(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoPrepareMdlWrite Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, PrepareMdlWrite) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->PrepareMdlWrite(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
LockKey,
|
|||
|
MdlChain,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FsRtlPrepareMdlWriteDev(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
LockKey,
|
|||
|
MdlChain,
|
|||
|
IoStatus,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoPrepareMdlWrite Exit \n", 0);
|
|||
|
|
|||
|
return( fPossible );
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlWriteComplete(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fSuccess;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoMdlWriteComplete Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, MdlWriteComplete) ) {
|
|||
|
|
|||
|
fSuccess = pFastIoTable->MdlWriteComplete(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
MdlChain,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fSuccess = FsRtlMdlWriteCompleteDev(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
MdlChain,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoMdlWriteComplete Exit \n", 0);
|
|||
|
|
|||
|
return( fSuccess );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If this routine is present, it will be called by FsRtl
|
|||
|
// to acquire the file for the mapped page writer.
|
|||
|
//
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
DfsFastIoAcquireForModWrite(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER EndingOffset,
|
|||
|
OUT PERESOURCE *ResourceToRelease,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoAcquireForModWrite Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, AcquireForModWrite) ) {
|
|||
|
|
|||
|
Status = pFastIoTable->AcquireForModWrite(
|
|||
|
FileObject,
|
|||
|
EndingOffset,
|
|||
|
ResourceToRelease,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoAcquireForModWrite Exit \n", 0);
|
|||
|
|
|||
|
return( Status );
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoReadCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
OUT PVOID Buffer,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
|||
|
IN ULONG CompressedDataInfoLength,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoReadCompressed Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoReadCompressed) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoReadCompressed(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
LockKey,
|
|||
|
Buffer,
|
|||
|
MdlChain,
|
|||
|
IoStatus,
|
|||
|
CompressedDataInfo,
|
|||
|
CompressedDataInfoLength,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
IoStatus->Status = STATUS_NOT_SUPPORTED;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoReadCompressed Exit \n", 0);
|
|||
|
|
|||
|
return( fPossible );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoWriteCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN ULONG Length,
|
|||
|
IN ULONG LockKey,
|
|||
|
IN PVOID Buffer,
|
|||
|
OUT PMDL *MdlChain,
|
|||
|
OUT PIO_STATUS_BLOCK IoStatus,
|
|||
|
IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
|||
|
IN ULONG CompressedDataInfoLength,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fPossible;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoWriteCompressed Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, FastIoWriteCompressed) ) {
|
|||
|
|
|||
|
fPossible = pFastIoTable->FastIoWriteCompressed(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
Length,
|
|||
|
LockKey,
|
|||
|
Buffer,
|
|||
|
MdlChain,
|
|||
|
IoStatus,
|
|||
|
CompressedDataInfo,
|
|||
|
CompressedDataInfoLength,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fPossible = FALSE;
|
|||
|
|
|||
|
IoStatus->Status = STATUS_NOT_SUPPORTED;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoWriteCompressed Exit \n", 0);
|
|||
|
|
|||
|
return( fPossible );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlReadCompleteCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fSuccess;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoMdlReadCompleteCompressed Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, MdlReadCompleteCompressed) ) {
|
|||
|
|
|||
|
fSuccess = pFastIoTable->MdlReadCompleteCompressed(
|
|||
|
FileObject,
|
|||
|
MdlChain,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fSuccess = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoMdlReadCompleteCompressed Exit \n", 0);
|
|||
|
|
|||
|
return( fSuccess );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DfsFastIoMdlWriteCompleteCompressed(
|
|||
|
IN PFILE_OBJECT FileObject,
|
|||
|
IN PLARGE_INTEGER FileOffset,
|
|||
|
IN PMDL MdlChain,
|
|||
|
IN PDEVICE_OBJECT DeviceObject)
|
|||
|
{
|
|||
|
PFAST_IO_DISPATCH pFastIoTable;
|
|||
|
PDEVICE_OBJECT targetVdo;
|
|||
|
BOOLEAN fSuccess;
|
|||
|
|
|||
|
DebugTrace(+1, Dbg, "DfsFastIoMdlWriteCompleteCompressed Enter \n", 0);
|
|||
|
|
|||
|
pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
|
|||
|
|
|||
|
|
|||
|
if ( IS_VALID_INDEX(pFastIoTable, MdlWriteCompleteCompressed) ) {
|
|||
|
|
|||
|
fSuccess = pFastIoTable->MdlWriteCompleteCompressed(
|
|||
|
FileObject,
|
|||
|
FileOffset,
|
|||
|
MdlChain,
|
|||
|
targetVdo);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
fSuccess = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DebugTrace(-1, Dbg, "DfsFastIoMdlWriteCompleteCompressed Exit \n", 0);
|
|||
|
|
|||
|
return( fSuccess );
|
|||
|
}
|
|||
|
|