www.pudn.com > filesys.rar > fastio.c
/*************************************************************************
*
* File: fastio.c
*
* Module: Sample File System Driver (Kernel mode execution only)
*
* Description:
* Contains code to handle the various "fast-io" calls.
*
* Author: R. Nagar
*
* (c) 1996-97 Rajeev Nagar, All Rights Reserved
*
*************************************************************************/
#include "sfsd.h"
// define the file specific bug-check id
#define SFSD_BUG_CHECK_ID SFSD_FILE_FAST_IO
/*************************************************************************
*
* Function: SFsdFastIoCheckIfPossible()
*
* Description:
* To fast-io or not to fast-io, that is the question ...
* This routine helps the I/O Manager determine whether the FSD wishes
* to permit fast-io on a specific file stream.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoCheckIfPossible(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN BOOLEAN CheckForReadOperation,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE;
PtrSFsdFCB PtrFCB = NULL;
PtrSFsdCCB PtrCCB = NULL;
LARGE_INTEGER IoLength;
// Obtain a pointer to the FCB and CCB for the file stream.
PtrCCB = (PtrSFsdCCB)(FileObject->FsContext2);
ASSERT(PtrCCB);
PtrFCB = PtrCCB->PtrFCB;
ASSERT(PtrFCB);
// Validate that this is a fast-IO request to a regular file.
// The sample FSD for example, will not allow fast-IO requests
// to volume objects, or to directories.
if ((PtrFCB->NodeIdentifier.NodeType == SFSD_NODE_TYPE_VCB) ||
(PtrFCB->FCBFlags & SFSD_FCB_DIRECTORY)) {
// This is not allowed.
return(ReturnedStatus);
}
IoLength = RtlConvertUlongToLargeInteger(Length);
// Your FSD can determine the checks that it needs to perform.
// Typically, a FSD will check whether there exist any byte-range
// locks that would prevent a fast-IO operation from proceeding.
// ... (FSD specific checks go here).
if (CheckForReadOperation) {
// Chapter 11 describes how to use the FSRTL package for byte-range
// lock requests. The following routine is exported by the FSRTL
// package and it returns TRUE if the read operation should be
// allowed to proceed based on the status of the current byte-range
// locks on the file stream. If you do not use the FSRTL package
// for byte-range locking support, then you must substitute your
// own checks over here.
// ReturnedStatus = FsRtlFastCheckLockForRead(&(PtrFCB->FCBByteRangeLock),
// FileOffset, &IoLength, LockKey, FileObject,
// PsGetCurrentProcess());
} else {
// This is a write request. Invoke the FSRTL byte-range lock package
// to see whether the write should be allowed to proceed.
// ReturnedStatus = FsRtlFastCheckLockForWrite(&(PtrFCB->FCBByteRangeLock),
// FileOffset, &IoLength, LockKey, FileObject,
// PsGetCurrentProcess());
}
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoRead()
*
* Description:
* Bypass the traditional IRP method to perform a read operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoRead(
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,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// Chapter 11 describes how to roll your own fast-IO entry points.
// Typically, you will acquire appropriate resources here and
// then (maybe) forward the request to FsRtlCopyRead().
// If you are a suitably complex file system, you may even choose
// to do some pre-processing (e.g. prefetching data from someplace)
// before passing on the request to the FSRTL package.
// Of course, you also have the option of bypassing the FSRTL
// package completely and simply forwarding the request directly
// to the NT Cache Manager.
// Bottom line is that you have complete flexibility on determining
// what you decide to do here. Read Chapter 11 well (and obviously
// other related issues) before filling in this and other fast-IO
// dispatch entry points.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoWrite()
*
* Description:
* Bypass the traditional IRP method to perform a write operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoWrite(
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,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoQueryBasicInfo()
*
* Description:
* Bypass the traditional IRP method to perform a query basic
* information operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoQueryBasicInfo(
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoQueryStdInfo()
*
* Description:
* Bypass the traditional IRP method to perform a query standard
* information operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoQueryStdInfo(
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_STANDARD_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoLock()
*
* Description:
* Bypass the traditional IRP method to perform a byte range lock
* operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoLock(
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,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoUnlockSingle()
*
* Description:
* Bypass the traditional IRP method to perform a byte range unlock
* operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoUnlockSingle(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
PEPROCESS ProcessId,
ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoUnlockAll()
*
* Description:
* Bypass the traditional IRP method to perform multiple byte range unlock
* operations.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoUnlockAll(
IN PFILE_OBJECT FileObject,
PEPROCESS ProcessId,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoUnlockAllByKey()
*
* Description:
* Bypass the traditional IRP method to perform multiple byte range unlock
* operations.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoUnlockAllByKey(
IN PFILE_OBJECT FileObject,
PEPROCESS ProcessId,
ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoAcqCreateSec()
*
* Description:
* Not really a fast-io operation. Used by the VMM to acquire FSD resources
* before processing a file map (create section object) request.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: None (we must be prepared to handle VMM initiated calls)
*
*************************************************************************/
void SFsdFastIoAcqCreateSec(
IN PFILE_OBJECT FileObject)
{
PtrSFsdFCB PtrFCB = NULL;
PtrSFsdCCB PtrCCB = NULL;
PtrSFsdNTRequiredFCB PtrReqdFCB = NULL;
// Obtain a pointer to the FCB and CCB for the file stream.
PtrCCB = (PtrSFsdCCB)(FileObject->FsContext2);
ASSERT(PtrCCB);
PtrFCB = PtrCCB->PtrFCB;
ASSERT(PtrFCB);
PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
// Acquire the MainResource exclusively for the file stream
ExAcquireResourceExclusiveLite(&(PtrReqdFCB->MainResource), TRUE);
// Although this is typically not required, the sample FSD will
// also acquire the PagingIoResource exclusively at this time
// to conform with the resource acquisition described in the set
// file information routine. Once again though, you will probably
// not need to do this.
ExAcquireResourceExclusiveLite(&(PtrReqdFCB->PagingIoResource), TRUE);
return;
}
/*************************************************************************
*
* Function: SFsdFastIoRelCreateSec()
*
* Description:
* Not really a fast-io operation. Used by the VMM to release FSD resources
* after processing a file map (create section object) request.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: None
*
*************************************************************************/
void SFsdFastIoRelCreateSec(
IN PFILE_OBJECT FileObject)
{
PtrSFsdFCB PtrFCB = NULL;
PtrSFsdCCB PtrCCB = NULL;
PtrSFsdNTRequiredFCB PtrReqdFCB = NULL;
// Obtain a pointer to the FCB and CCB for the file stream.
PtrCCB = (PtrSFsdCCB)(FileObject->FsContext2);
ASSERT(PtrCCB);
PtrFCB = PtrCCB->PtrFCB;
ASSERT(PtrFCB);
PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
// Release the PagingIoResource for the file stream
SFsdReleaseResource(&(PtrReqdFCB->PagingIoResource));
// Release the MainResource for the file stream
SFsdReleaseResource(&(PtrReqdFCB->MainResource));
return;
}
/*************************************************************************
*
* Function: SFsdAcqLazyWrite()
*
* Description:
* Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
* resources before performing a delayed write (write behind/lazy write)
* operation.
* NOTE: this function really must succeed since the Cache Manager will
* typically ignore failure and continue on ...
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE (Cache Manager does not tolerate FALSE well)
*
*************************************************************************/
BOOLEAN SFsdAcqLazyWrite(
IN PVOID Context,
IN BOOLEAN Wait)
{
BOOLEAN ReturnedStatus = TRUE;
PtrSFsdFCB PtrFCB = NULL;
PtrSFsdCCB PtrCCB = NULL;
PtrSFsdNTRequiredFCB PtrReqdFCB = NULL;
// The context is whatever we passed to the Cache Manager when invoking
// the CcInitializeCacheMaps() function. In the case of the sample FSD
// implementation, this context is a pointer to the CCB structure.
ASSERT(Context);
PtrCCB = (PtrSFsdCCB)(Context);
ASSERT(PtrCCB->NodeIdentifier.NodeType == SFSD_NODE_TYPE_CCB);
PtrFCB = PtrCCB->PtrFCB;
ASSERT(PtrFCB);
PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
// Acquire the MainResource in the FCB exclusively. Then, set the
// lazy-writer thread id in the FCB structure for identification when
// an actual write request is received by the FSD.
// Note: The lazy-writer typically always supplies WAIT set to TRUE.
if (!ExAcquireResourceExclusiveLite(&(PtrReqdFCB->MainResource),
Wait)) {
ReturnedStatus = FALSE;
} else {
// Now, set the lazy-writer thread id.
ASSERT(!(PtrFCB->LazyWriterThreadID));
PtrFCB->LazyWriterThreadID = (unsigned int)(PsGetCurrentThread());
}
// If your FSD needs to perform some special preparations in anticipation
// of receving a lazy-writer request, do so now.
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdRelLazyWrite()
*
* Description:
* Not really a fast-io operation. Used by the NT Cache Mgr to release FSD
* resources after performing a delayed write (write behind/lazy write)
* operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: None
*
*************************************************************************/
void SFsdRelLazyWrite(
IN PVOID Context)
{
BOOLEAN ReturnedStatus = TRUE;
PtrSFsdFCB PtrFCB = NULL;
PtrSFsdCCB PtrCCB = NULL;
PtrSFsdNTRequiredFCB PtrReqdFCB = NULL;
// The context is whatever we passed to the Cache Manager when invoking
// the CcInitializeCacheMaps() function. In the case of the sample FSD
// implementation, this context is a pointer to the CCB structure.
ASSERT(Context);
PtrCCB = (PtrSFsdCCB)(Context);
ASSERT(PtrCCB->NodeIdentifier.NodeType == SFSD_NODE_TYPE_CCB);
PtrFCB = PtrCCB->PtrFCB;
ASSERT(PtrFCB);
PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
// Remove the current thread-id from the FCB and release the MainResource.
ASSERT((PtrFCB->LazyWriterThreadID) == (unsigned int)PsGetCurrentThread());
PtrFCB->LazyWriterThreadID = 0;
// Release the acquired resource.
SFsdReleaseResource(&(PtrReqdFCB->MainResource));
// Of course, your FSD should undo whatever else seems appropriate at this
// time.
return;
}
/*************************************************************************
*
* Function: SFsdAcqReadAhead()
*
* Description:
* Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
* resources before performing a read-ahead operation.
* NOTE: this function really must succeed since the Cache Manager will
* typically ignore failure and continue on ...
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE (Cache Manager does not tolerate FALSE well)
*
*************************************************************************/
BOOLEAN SFsdAcqReadAhead(
IN PVOID Context,
IN BOOLEAN Wait)
{
BOOLEAN ReturnedStatus = TRUE;
PtrSFsdFCB PtrFCB = NULL;
PtrSFsdCCB PtrCCB = NULL;
PtrSFsdNTRequiredFCB PtrReqdFCB = NULL;
// The context is whatever we passed to the Cache Manager when invoking
// the CcInitializeCacheMaps() function. In the case of the sample FSD
// implementation, this context is a pointer to the CCB structure.
ASSERT(Context);
PtrCCB = (PtrSFsdCCB)(Context);
ASSERT(PtrCCB->NodeIdentifier.NodeType == SFSD_NODE_TYPE_CCB);
PtrFCB = PtrCCB->PtrFCB;
ASSERT(PtrFCB);
PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
// Acquire the MainResource in the FCB shared.
// Note: The read-ahead thread typically always supplies WAIT set to TRUE.
if (!ExAcquireResourceSharedLite(&(PtrReqdFCB->MainResource),
Wait)) {
ReturnedStatus = FALSE;
}
// If your FSD needs to perform some special preparations in anticipation
// of receving a read-ahead request, do so now.
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdRelReadAhead()
*
* Description:
* Not really a fast-io operation. Used by the NT Cache Mgr to release FSD
* resources after performing a read-ahead operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: None
*
*************************************************************************/
void SFsdRelReadAhead(
IN PVOID Context)
{
BOOLEAN ReturnedStatus = TRUE;
PtrSFsdFCB PtrFCB = NULL;
PtrSFsdCCB PtrCCB = NULL;
PtrSFsdNTRequiredFCB PtrReqdFCB = NULL;
// The context is whatever we passed to the Cache Manager when invoking
// the CcInitializeCacheMaps() function. In the case of the sample FSD
// implementation, this context is a pointer to the CCB structure.
ASSERT(Context);
PtrCCB = (PtrSFsdCCB)(Context);
ASSERT(PtrCCB->NodeIdentifier.NodeType == SFSD_NODE_TYPE_CCB);
PtrFCB = PtrCCB->PtrFCB;
ASSERT(PtrFCB);
PtrReqdFCB = &(PtrFCB->NTRequiredFCB);
// Release the acquired resource.
SFsdReleaseResource(&(PtrReqdFCB->MainResource));
// Of course, your FSD should undo whatever else seems appropriate at this
// time.
return;
}
/* the remaining are only valid under NT Version 4.0 and later */
#if(_WIN32_WINNT >= 0x0400)
/*************************************************************************
*
* Function: SFsdFastIoQueryNetInfo()
*
* Description:
* Get information requested by a redirector across the network. This call
* will originate from the LAN Manager server.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoQueryNetInfo(
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoMdlRead()
*
* Description:
* Bypass the traditional IRP method to perform a MDL read operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoMdlRead(
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 ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoMdlReadComplete()
*
* Description:
* Bypass the traditional IRP method to inform the NT Cache Manager and the
* FSD that the caller no longer requires the data locked in the system cache
* or the MDL to stay around anymore ..
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoMdlReadComplete(
IN PFILE_OBJECT FileObject,
OUT PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoPrepareMdlWrite()
*
* Description:
* Bypass the traditional IRP method to prepare for a MDL write operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoPrepareMdlWrite(
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 ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoMdlWriteComplete()
*
* Description:
* Bypass the traditional IRP method to inform the NT Cache Manager and the
* FSD that the caller has updated the contents of the MDL. This data can
* now be asynchronously written out to secondary storage by the Cache Mgr.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: TRUE/FALSE
*
*************************************************************************/
BOOLEAN SFsdFastIoMdlWriteComplete(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
OUT PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// See description in SFsdFastIoRead() before filling-in the
// stub here.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(ReturnedStatus);
}
/*************************************************************************
*
* Function: SFsdFastIoAcqModWrite()
*
* Description:
* Not really a fast-io operation. Used by the VMM to acquire FSD resources
* before initiating a write operation via the Modified Page/Block Writer.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: STATUS_SUCCESS/Error (try not to return an error, will 'ya ? :-)
*
*************************************************************************/
NTSTATUS SFsdFastIoAcqModWrite(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER EndingOffset,
OUT PERESOURCE *ResourceToRelease,
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// You must determine which resource(s) you would like to
// acquire at this time. You know that a write is imminent;
// you will probably therefore acquire appropriate resources
// exclusively.
// You must first get the FCB and CCB pointers from the file object
// that is passed in to this function (as an argument). Note that
// the ending offset (when examined in conjunction with current valid data
// length) may help you in determining the appropriate resource(s) to acquire.
// For example, if the ending offset is beyond current valid data length,
// you may decide to acquire *both* the MainResource and the PagingIoResource
// exclusively; otherwise, you may decide simply to acquire the PagingIoResource.
// Consult the text for more information on synchronization in FSDs.
// One final note; the VMM expects that you will return a pointer to
// the resource that you acquired (single return value). This pointer
// will be returned back to you in the release call (below).
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(RC);
}
/*************************************************************************
*
* Function: SFsdFastIoRelModWrite()
*
* Description:
* Not really a fast-io operation. Used by the VMM to release FSD resources
* after processing a modified page/block write operation.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: STATUS_SUCCESS/Error (an error returned here is really not expected!)
*
*************************************************************************/
NTSTATUS SFsdFastIoRelModWrite(
IN PFILE_OBJECT FileObject,
IN PERESOURCE ResourceToRelease,
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// The MPW has complete the write for modified pages and therefore
// wants you to release pre-acquired resource(s).
// You must undo here whatever it is that you did in the
// SFsdFastIoAcqModWrite() call above.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(RC);
}
/*************************************************************************
*
* Function: SFsdFastIoAcqCcFlush()
*
* Description:
* Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
* resources before performing a CcFlush() operation on a specific file
* stream.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: STATUS_SUCCESS/Error
*
*************************************************************************/
NTSTATUS SFsdFastIoAcqCcFlush(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// Acquire appropriate resources that will allow correct synchronization
// with a flush call (and avoid deadlock).
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(RC);
}
/*************************************************************************
*
* Function: SFsdFastIoRelCcFlush()
*
* Description:
* Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
* resources before performing a CcFlush() operation on a specific file
* stream.
*
* Expected Interrupt Level (for execution) :
*
* IRQL_PASSIVE_LEVEL
*
* Return Value: STATUS_SUCCESS/Error
*
*************************************************************************/
NTSTATUS SFsdFastIoRelCcFlush(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS RC = STATUS_SUCCESS;
PtrSFsdIrpContext PtrIrpContext = NULL;
FsRtlEnterFileSystem();
try {
try {
// Release resources acquired in SFsdFastIoAcqCcFlush() above.
NOTHING;
} except (SFsdExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
RC = SFsdExceptionHandler(PtrIrpContext, NULL);
SFsdLogEvent(SFSD_ERROR_INTERNAL_ERROR, RC);
}
try_exit: NOTHING;
} finally {
}
FsRtlExitFileSystem();
return(RC);
}
#endif //_WIN32_WINNT >= 0x0400