📄 strucsup.c
字号:
//
ExInitializeFastMutex( &Vcb->AdvancedFcbHeaderMutex );
FsRtlSetupAdvancedHeader( &Vcb->VolumeFileHeader,
&Vcb->AdvancedFcbHeaderMutex );
//
// With the Vcb now set up, set the IrpContext Vcb field.
//
IrpContext->Vcb = Vcb;
} finally {
DebugUnwind( FatInitializeVcb );
//
// If this is an abnormal termination then undo our work
//
if (AbnormalTermination()) {
if (UnwindCacheMap != NULL) { FatSyncUninitializeCacheMap( IrpContext, UnwindCacheMap ); }
if (UnwindFileObject != NULL) { ObDereferenceObject( UnwindFileObject ); }
if (UnwindResource != NULL) { FatDeleteResource( UnwindResource ); }
if (UnwindResource2 != NULL) { FatDeleteResource( UnwindResource2 ); }
if (UnwindWeAllocatedMcb) { FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb ); }
if (UnwindEntryList != NULL) {
(VOID)FatAcquireExclusiveGlobal( IrpContext );
RemoveEntryList( UnwindEntryList );
FatReleaseGlobal( IrpContext );
}
if (UnwindStatistics != NULL) { ExFreePool( UnwindStatistics ); }
if (Vcb->CloseContext != NULL) {
ExFreePool( Vcb->CloseContext );
Vcb->CloseContext = NULL;
}
}
DebugTrace(-1, Dbg, "FatInitializeVcb -> VOID\n", 0);
}
//
// and return to our caller
//
UNREFERENCED_PARAMETER( IrpContext );
return;
}
VOID
FatTearDownVcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb
)
/*++
Routine Description:
This routine tries to remove all internal opens from the volume.
Arguments:
IrpContext - Supplies the context for the overall request.
Vcb - Supplies the Vcb to be torn down.
Return Value:
None
--*/
{
PFILE_OBJECT DirectoryFileObject;
PAGED_CODE();
//
// Get rid of the virtual volume file, if we need to.
//
if (Vcb->VirtualVolumeFile != NULL) {
//
// Uninitialize the cache
//
FatSyncUninitializeCacheMap( IrpContext, Vcb->VirtualVolumeFile );
//
// Dereference the virtual volume file. This will cause a close
// Irp to be processed, so we need to do this before we destory
// the Vcb
//
FsRtlTeardownPerStreamContexts( &Vcb->VolumeFileHeader );
ObDereferenceObject( Vcb->VirtualVolumeFile );
Vcb->VirtualVolumeFile = NULL;
}
//
// Close down the EA file.
//
FatCloseEaFile( IrpContext, Vcb, FALSE );
//
// Close down the root directory stream..
//
if (Vcb->RootDcb != NULL) {
DirectoryFileObject = Vcb->RootDcb->Specific.Dcb.DirectoryFile;
if (DirectoryFileObject != NULL) {
//
// Tear down this directory file.
//
FatSyncUninitializeCacheMap( IrpContext,
DirectoryFileObject );
Vcb->RootDcb->Specific.Dcb.DirectoryFile = NULL;
ObDereferenceObject( DirectoryFileObject );
}
}
//
// The VCB can no longer be used.
//
FatSetVcbCondition( Vcb, VcbBad );
}
VOID
FatDeleteVcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb
)
/*++
Routine Description:
This routine removes the Vcb record from Fat's in-memory data
structures. It also will remove all associated underlings
(i.e., FCB records).
Arguments:
Vcb - Supplies the Vcb to be removed
Return Value:
None
--*/
{
PFCB Fcb;
DebugTrace(+1, Dbg, "FatDeleteVcb, Vcb = %08lx\n", Vcb);
//
// If the IrpContext points to the VCB being deleted NULL out the stail
// pointer.
//
if (IrpContext->Vcb == Vcb) {
IrpContext->Vcb = NULL;
}
//
// Chuck the backpocket Vpb we kept just in case.
//
if (Vcb->SwapVpb) {
ExFreePool( Vcb->SwapVpb );
}
//
// Free the VPB, if we need to.
//
if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VPB_MUST_BE_FREED )) {
//
// We swapped the VPB, so we need to free the main one.
//
ExFreePool( Vcb->Vpb );
}
//
// Free the close context for the virtual volume file, if it is still
// present. If this is the case, it means the last close that came
// through was for the virtual volume file, and we are processing that
// close right now.
//
if (Vcb->CloseContext != NULL) {
ExFreePool( Vcb->CloseContext );
}
//
// Remove this record from the global list of all Vcb records.
// Note that the global lock must already be held when calling
// this function.
//
RemoveEntryList( &(Vcb->VcbLinks) );
//
// Make sure the direct access open count is zero, and the open file count
// is also zero.
//
if ((Vcb->DirectAccessOpenCount != 0) || (Vcb->OpenFileCount != 0)) {
FatBugCheck( 0, 0, 0 );
}
//
// Remove the EaFcb and dereference the Fcb for the Ea file if it
// exists.
//
if (Vcb->EaFcb != NULL) {
Vcb->EaFcb->OpenCount = 0;
FatDeleteFcb( IrpContext, &Vcb->EaFcb );
}
//
// Remove the Root Dcb
//
if (Vcb->RootDcb != NULL) {
//
// Rundown stale child Fcbs that may be hanging around. Yes, this
// can happen. No, the create path isn't perfectly defensive about
// tearing down branches built up on creates that don't wind up
// succeeding. Normal system operation usually winds up having
// cleaned them out through re-visiting, but ...
//
// Just pick off Fcbs from the bottom of the tree until we run out.
// Then we delete the root Dcb.
//
while( (Fcb = FatGetNextFcbBottomUp( IrpContext, NULL, Vcb->RootDcb )) != Vcb->RootDcb ) {
FatDeleteFcb( IrpContext, &Fcb );
}
FatDeleteFcb( IrpContext, &Vcb->RootDcb );
}
//
// Uninitialize the notify sychronization object.
//
FsRtlNotifyUninitializeSync( &Vcb->NotifySync );
//
// Uninitialize the resource variable for the Vcb
//
FatDeleteResource( &Vcb->Resource );
FatDeleteResource( &Vcb->ChangeBitMapResource );
//
// If allocation support has been setup, free it.
//
if (Vcb->FreeClusterBitMap.Buffer != NULL) {
FatTearDownAllocationSupport( IrpContext, Vcb );
}
//
// UnInitialize the Mcb structure that kept track of dirty fat sectors.
//
FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb );
//
// Free the pool for the stached copy of the boot sector
//
if ( Vcb->First0x24BytesOfBootSector ) {
ExFreePool( Vcb->First0x24BytesOfBootSector );
Vcb->First0x24BytesOfBootSector = NULL;
}
//
// Cancel the CleanVolume Timer and Dpc
//
(VOID)KeCancelTimer( &Vcb->CleanVolumeTimer );
(VOID)KeRemoveQueueDpc( &Vcb->CleanVolumeDpc );
//
// Free the performance counters memory
//
ExFreePool( Vcb->Statistics );
//
// Clean out the tunneling cache
//
FsRtlDeleteTunnelCache(&Vcb->Tunnel);
//
// Dereference the target device object.
//
ObDereferenceObject( Vcb->TargetDeviceObject );
//
// We better have used all the close contexts we allocated. There could be
// one remaining if we're doing teardown due to a final close coming in on
// a directory file stream object. It will be freed on the way back up.
//
ASSERT( Vcb->CloseContextCount <= 1);
//
// And zero out the Vcb, this will help ensure that any stale data is
// wiped clean
//
RtlZeroMemory( Vcb, sizeof(VCB) );
//
// return and tell the caller
//
DebugTrace(-1, Dbg, "FatDeleteVcb -> VOID\n", 0);
return;
}
VOID
FatCreateRootDcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb
)
/*++
Routine Description:
This routine allocates, initializes, and inserts a new root DCB record
into the in memory data structure.
Arguments:
Vcb - Supplies the Vcb to associate the new DCB under
Return Value:
None. The Vcb is modified in-place.
--*/
{
PDCB Dcb;
//
// The following variables are used for abnormal unwind
//
PVOID UnwindStorage[2] = { NULL, NULL };
PERESOURCE UnwindResource = NULL;
PERESOURCE UnwindResource2 = NULL;
PLARGE_MCB UnwindMcb = NULL;
PFILE_OBJECT UnwindFileObject = NULL;
DebugTrace(+1, Dbg, "FatCreateRootDcb, Vcb = %08lx\n", Vcb);
try {
//
// Make sure we don't already have a root dcb for this vcb
//
if (Vcb->RootDcb != NULL) {
DebugDump("Error trying to create multiple root dcbs\n", 0, Vcb);
FatBugCheck( 0, 0, 0 );
}
//
// Allocate a new DCB and zero it out, we use Dcb locally so we don't
// have to continually reference through the Vcb
//
UnwindStorage[0] = Dcb = Vcb->RootDcb = FsRtlAllocatePoolWithTag( NonPagedPool,
sizeof(DCB),
TAG_FCB );
RtlZeroMemory( Dcb, sizeof(DCB));
UnwindStorage[1] =
Dcb->NonPaged = FatAllocateNonPagedFcb();
RtlZeroMemory( Dcb->NonPaged, sizeof( NON_PAGED_FCB ) );
//
// Set the proper node type code, node byte size, and call backs
//
Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB;
Dcb->Header.NodeByteSize = sizeof(DCB);
Dcb->FcbCondition = FcbGood;
//
// The parent Dcb, initial state, open count, dirent location
// information, and directory change count fields are already zero so
// we can skip setting them
//
//
// Initialize the resource variable
//
UnwindResource =
Dcb->Header.Resource = FatAllocateResource();
//
// Initialize the PagingIo Resource. We no longer use the FsRtl common
// shared pool because this led to a) deadlocks due to cases where files
// and their parent directories shared a resource and b) there is no way
// to anticipate inter-driver induced deadlock via recursive operation.
//
UnwindResource2 =
Dcb->Header.PagingIoResource = FatAllocateResource();
//
// The root Dcb has an empty parent dcb links field
//
InitializeListHead( &Dcb->ParentDcbLinks );
//
// Set the Vcb
//
Dcb->Vcb = Vcb;
//
// initialize the parent dcb queue.
//
InitializeListHead( &Dcb->Specific.Dcb.ParentDcbQueue );
//
// Set the full file name up.
//
Dcb->FullFileName.Buffer = L"\\";
Dcb->FullFileName.Length = (USHORT)2;
Dcb->FullFileName.MaximumLength = (USHORT)4;
Dcb->ShortName.Name.Oem.Buffer = "\\";
Dcb->ShortName.Name.Oem.Length = (USHORT)1;
Dcb->ShortName.Name.Oem.MaximumLength = (USHORT)2;
//
// Construct a lie about file properties since we don't
// have a proper "." entry to look at.
//
Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY;
//
// Initialize Advanced FCB Header fields
//
ExInitializeFastMutex( &Dcb->NonPaged->AdvancedFcbHeaderMutex );
FsRtlSetupAdvancedHeader( &Dcb->Header,
&Dcb->NonPaged->AdvancedFcbHeaderMutex );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -