📄 cachesup.c
字号:
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
CacheSup.c
Abstract:
This module implements the cache management routines for the Udfs
FSD and FSP, by calling the Common Cache Manager.
Author:
Dan Lovinger [DanLo] 12-Sep-1996
Revision History:
--*/
#include "UdfProcs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (UDFS_BUG_CHECK_CACHESUP)
//
// The local debug trace level
//
#define Dbg (UDFS_DEBUG_LEVEL_CACHESUP)
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, UdfCompleteMdl)
#pragma alloc_text(PAGE, UdfCreateInternalStream)
#pragma alloc_text(PAGE, UdfDeleteInternalStream)
#pragma alloc_text(PAGE, UdfMapMetadataView)
#pragma alloc_text(PAGE, UdfPurgeVolume)
#endif
VOID
UdfCreateInternalStream (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFCB Fcb
)
/*++
Routine Description:
This function creates an internal stream file for interaction
with the cache manager. The Fcb here will be for a directory
stream.
Arguments:
Vcb - Vcb for this volume.
Fcb - Points to the Fcb for this file. It is an Index Fcb.
Return Value:
None.
--*/
{
PFILE_OBJECT StreamFile = NULL;
BOOLEAN DecrementReference = FALSE;
PAGED_CODE();
//
// Check inputs.
//
ASSERT_IRP_CONTEXT( IrpContext );
ASSERT_FCB_INDEX( Fcb );
//
// We may only have the Fcb shared. Lock the Fcb and do a
// safe test to see if we need to really create the file object.
//
UdfLockFcb( IrpContext, Fcb );
if (Fcb->FileObject != NULL) {
UdfUnlockFcb( IrpContext, Fcb );
return;
}
//
// Use a try-finally to facilitate cleanup.
//
try {
//
// Create the internal stream. The Vpb should be pointing at our volume
// device object at this point.
//
StreamFile = IoCreateStreamFileObject( NULL, Vcb->Vpb->RealDevice );
if (StreamFile == NULL) {
UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
}
//
// Initialize the fields of the file object.
//
StreamFile->ReadAccess = TRUE;
StreamFile->WriteAccess = FALSE;
StreamFile->DeleteAccess = FALSE;
StreamFile->SectionObjectPointer = &Fcb->FcbNonpaged->SegmentObject;
//
// Set the file object type and increment the Vcb counts.
//
UdfSetFileObject( IrpContext,
StreamFile,
StreamFileOpen,
Fcb,
NULL );
//
// We will reference the current Fcb twice to keep it from going
// away in the error path. Otherwise if we dereference it
// below in the finally clause a close could cause the Fcb to
// be deallocated.
//
UdfLockVcb( IrpContext, Vcb );
DebugTrace(( +1, Dbg,
"UdfCreateInternalStream, Fcb %08x Vcb %d/%d Fcb %d/%d\n",
Fcb,
Vcb->VcbReference,
Vcb->VcbUserReference,
Fcb->FcbReference,
Fcb->FcbUserReference ));
UdfIncrementReferenceCounts( IrpContext, Fcb, 2, 0 );
UdfUnlockVcb( IrpContext, Vcb );
DecrementReference = TRUE;
//
// Initialize the cache map for the file.
//
CcInitializeCacheMap( StreamFile,
(PCC_FILE_SIZES)&Fcb->AllocationSize,
TRUE,
&UdfData.CacheManagerCallbacks,
Fcb );
//
// Go ahead and store the stream file into the Fcb.
//
Fcb->FileObject = StreamFile;
StreamFile = NULL;
} finally {
DebugUnwind( "UdfCreateInternalStream" );
//
// If we raised then we need to dereference the file object.
//
if (StreamFile != NULL) {
ObDereferenceObject( StreamFile );
Fcb->FileObject = NULL;
}
//
// Dereference and unlock the Fcb.
//
if (DecrementReference) {
UdfLockVcb( IrpContext, Vcb );
UdfDecrementReferenceCounts( IrpContext, Fcb, 1, 0 );
DebugTrace(( -1, Dbg,
"UdfCreateInternalStream, Vcb %d/%d Fcb %d/%d\n",
Vcb->VcbReference,
Vcb->VcbUserReference,
Fcb->FcbReference,
Fcb->FcbUserReference ));
UdfUnlockVcb( IrpContext, Vcb );
}
UdfUnlockFcb( IrpContext, Fcb );
}
return;
}
VOID
UdfDeleteInternalStream (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb
)
/*++
Routine Description:
This function creates an internal stream file for interaction
with the cache manager. The Fcb here can be for either a
directory stream or for a metadata stream.
Arguments:
Fcb - Points to the Fcb for this file. It is either an Index or
Metadata Fcb.
Return Value:
None.
--*/
{
PFILE_OBJECT FileObject;
PAGED_CODE();
ASSERT_IRP_CONTEXT( IrpContext );
ASSERT_FCB( Fcb );
//
// Lock the Fcb.
//
UdfLockFcb( IrpContext, Fcb );
//
// Capture the file object.
//
FileObject = Fcb->FileObject;
Fcb->FileObject = NULL;
//
// It is now safe to unlock the Fcb.
//
UdfUnlockFcb( IrpContext, Fcb );
//
// Dereference the file object if present.
//
if (FileObject != NULL) {
if (FileObject->PrivateCacheMap != NULL) {
CcUninitializeCacheMap( FileObject, NULL, NULL );
}
ObDereferenceObject( FileObject );
}
return;
}
NTSTATUS
UdfCompleteMdl (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
)
/*++
Routine Description:
This routine performs the function of completing Mdl reads.
It should be called only from UdfCommonRead.
Arguments:
Irp - Supplies the originating Irp.
Return Value:
NTSTATUS - Will always be STATUS_SUCCESS.
--*/
{
PFILE_OBJECT FileObject;
PAGED_CODE();
//
// Do completion processing.
//
FileObject = IoGetCurrentIrpStackLocation( Irp )->FileObject;
CcMdlReadComplete( FileObject, Irp->MdlAddress );
//
// Mdl is now deallocated.
//
Irp->MdlAddress = NULL;
//
// Complete the request and exit right away.
//
UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -