📄 easup.c
字号:
UnwindInitializeDataMcb = TRUE;
FatSplitAllocation( IrpContext,
Vcb,
&EaFcb->Mcb,
EaSetVbo,
&DataMcb );
UnwindSplitData = TRUE;
if (EaSetLength + EaSetVbo != EaFcb->Header.FileSize.LowPart) {
FsRtlInitializeLargeMcb( &TailMcb, PagedPool );
UnwindInitializeTailMcb = TRUE;
FatSplitAllocation( IrpContext,
Vcb,
&DataMcb,
EaSetLength,
&TailMcb );
UnwindSplitTail = TRUE;
FatMergeAllocation( IrpContext,
Vcb,
&EaFcb->Mcb,
&TailMcb );
UnwindMergeTail = TRUE;
}
}
//
// Update the Fcb for the Ea file
//
UnwindPrevFileSize = EaFcb->Header.FileSize.LowPart;
(VOID)ExAcquireResourceExclusiveLite( EaFcb->Header.PagingIoResource,
TRUE );
EaFcb->Header.FileSize.LowPart = EaFcb->Header.FileSize.LowPart - EaSetLength;
EaFcb->Header.AllocationSize = EaFcb->Header.FileSize;
CcSetFileSizes( VirtualEaFile,
(PCC_FILE_SIZES)&EaFcb->Header.AllocationSize );
ExReleaseResourceLite( EaFcb->Header.PagingIoResource );
UnwindCacheValues = TRUE;
EaDirent->FileSize = EaFcb->Header.FileSize.LowPart;
FatSetDirtyBcb( IrpContext, EaBcb, Vcb, TRUE );
//
// Update the Ea base and offset tables. For the Ea base table,
// all subsequent index values must be decremented by the number
// of clusters removed.
//
// For the entries in the relevant Ea offset table, all entries
// after this index must also be decreased by the number of
// clusters removed.
//
//
// Pin down the EA file header.
//
RtlZeroMemory( &EaHeaderRange,
sizeof( EA_RANGE ));
FatPinEaRange( IrpContext,
VirtualEaFile,
EaFcb,
&EaHeaderRange,
0,
sizeof( EA_FILE_HEADER ),
STATUS_NONEXISTENT_EA_ENTRY );
EaHeader = (PEA_FILE_HEADER) EaHeaderRange.Data;
//
// Pin down the Ea offset table for the particular index.
//
RtlZeroMemory( &EaOffsetRange,
sizeof( EA_RANGE ));
FatPinEaRange( IrpContext,
VirtualEaFile,
EaFcb,
&EaOffsetRange,
EaOffsetVbo,
sizeof( EA_OFF_TABLE ),
STATUS_NONEXISTENT_EA_ENTRY );
{
ULONG Count;
PUSHORT NextEaIndex;
Count = MAX_EA_BASE_INDEX - EaHeaderBaseIndex - 1;
NextEaIndex = &EaHeader->EaBaseTable[EaHeaderBaseIndex + 1];
while (Count--) {
*(NextEaIndex++) -= EaSetClusterCount;
}
FatMarkEaRangeDirty( IrpContext, VirtualEaFile, &EaHeaderRange );
Count = MAX_EA_OFFSET_INDEX - EaOffsetIndex - 1;
NextEaIndex = (PUSHORT) EaOffsetRange.Data + EaOffsetIndex;
*(NextEaIndex++) = UNUSED_EA_HANDLE;
while (Count--) {
if (*NextEaIndex != UNUSED_EA_HANDLE) {
*NextEaIndex -= EaSetClusterCount;
}
NextEaIndex++;
}
FatMarkEaRangeDirty( IrpContext, VirtualEaFile, &EaOffsetRange );
}
UnwindModifiedEaHeader = TRUE;
//
// Deallocate the ea set removed
//
FatDeallocateDiskSpace( IrpContext,
Vcb,
&DataMcb );
} finally {
DebugUnwind( FatDeleteEaSet );
//
// Restore file if abnormal termination.
//
// If we have modified the ea file header we ignore this
// error. Otherwise we walk through the state variables.
//
if (AbnormalTermination()
&& !UnwindModifiedEaHeader) {
//
// If we modified the Ea dirent or Fcb, recover the previous
// values.
//
if (UnwindPrevFileSize) {
EaFcb->Header.FileSize.LowPart = UnwindPrevFileSize;
EaFcb->Header.AllocationSize.LowPart = UnwindPrevFileSize;
EaDirent->FileSize = UnwindPrevFileSize;
if (UnwindCacheValues) {
CcSetFileSizes( VirtualEaFile,
(PCC_FILE_SIZES)&EaFcb->Header.AllocationSize );
}
}
//
// If we merged the tail with the
// ea file header. We split it out
// again.
//
if (UnwindMergeTail) {
FatSplitAllocation( IrpContext,
Vcb,
&EaFcb->Mcb,
EaSetVbo,
&TailMcb );
}
//
// If we split the tail off we merge the tail back
// with the ea data to remove.
//
if (UnwindSplitTail) {
FatMergeAllocation( IrpContext,
Vcb,
&DataMcb,
&TailMcb );
}
//
// If the ea set has been split out, we merge that
// cluster string back in the file. Otherwise we
// simply uninitialize the local Mcb.
//
if (UnwindSplitData) {
FatMergeAllocation( IrpContext,
Vcb,
&EaFcb->Mcb,
&DataMcb );
}
}
//
// Unpin any Bcb's still active.
//
FatUnpinEaRange( IrpContext, &EaHeaderRange );
FatUnpinEaRange( IrpContext, &EaOffsetRange );
FatUnpinEaRange( IrpContext, &EaSetRange );
//
// Uninitialize any initialized Mcbs
//
if (UnwindInitializeDataMcb) {
FsRtlUninitializeLargeMcb( &DataMcb );
}
if (UnwindInitializeTailMcb) {
FsRtlUninitializeLargeMcb( &TailMcb );
}
DebugTrace(-1, Dbg, "FatDeleteEaSet -> Exit\n", 0);
}
return;
}
VOID
FatAddEaSet (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN ULONG EaSetLength,
IN PBCB EaBcb,
OUT PDIRENT EaDirent,
OUT PUSHORT EaHandle,
OUT PEA_RANGE EaSetRange
)
/*++
Routine Description:
This routine will add the necessary clusters to support a new
Ea set of the given size. This is done by splicing a chain of
clusters into the existing Ea file. An Ea index is assigned to
this new chain and the Ea base and offset tables are updated to
include this new handle. This routine also pins the added
clusters and returns their address and a Bcb.
The caller of this function will have verified that the Ea file
exists and that the Vcb field points to an initialized cache file.
The caller will already have gained exclusive access to the
EaFcb.
Arguments:
Vcb - Supplies the Vcb to fill in.
EaSetLength - The number of bytes needed to contain the Ea set. This
routine will round this up the next cluster size.
EaBcb - Supplies a pointer to the Bcb for the Ea dirent.
EaDirent - Supplies a pointer to the dirent for the Ea file.
EaHandle - Supplies the address to store the ea index generated here.
EaSetRange - This is the structure that describes new range in the Ea file.
Return Value:
None.
--*/
{
ULONG BytesPerCluster = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster;
EA_RANGE EaHeaderRange;
USHORT EaHeaderIndex;
PEA_FILE_HEADER EaHeader;
EA_RANGE EaOffsetRange;
ULONG EaNewOffsetVbo;
USHORT EaOffsetIndex;
ULONG EaOffsetTableSize;
PUSHORT EaOffsetTable;
ULONG EaSetClusterOffset;
ULONG EaSetVbo;
USHORT EaSetClusterCount;
PEA_SET_HEADER EaSet;
PFILE_OBJECT VirtualEaFile = Vcb->VirtualEaFile;
PFCB EaFcb = Vcb->EaFcb;
LARGE_MCB EaSetMcb;
BOOLEAN UnwindInitializedEaSetMcb = FALSE;
BOOLEAN UnwindAllocatedNewAllocation = FALSE;
BOOLEAN UnwindMergedNewEaSet = FALSE;
LARGE_MCB EaOffsetMcb;
BOOLEAN UnwindInitializedOffsetMcb = FALSE;
BOOLEAN UnwindSplitNewAllocation = FALSE;
BOOLEAN UnwindMergedNewOffset = FALSE;
LARGE_MCB EaTailMcb;
BOOLEAN UnwindInitializedTailMcb = FALSE;
BOOLEAN UnwindSplitTail = FALSE;
BOOLEAN UnwindMergedTail = FALSE;
LARGE_MCB EaInitialEaMcb;
BOOLEAN UnwindInitializedInitialEaMcb = FALSE;
BOOLEAN UnwindSplitInitialEa = FALSE;
BOOLEAN UnwindMergedInitialEa = FALSE;
USHORT NewEaIndex;
PUSHORT NextEaOffset;
ULONG NewAllocation;
LARGE_INTEGER FileOffset;
ULONG Count;
ULONG UnwindPrevFileSize = 0;
BOOLEAN UnwindCacheValues = FALSE;
BOOLEAN TailExists = FALSE;
BOOLEAN AddedOffsetTableCluster = FALSE;
BOOLEAN UnwindPurgeCacheMap = FALSE;
DebugTrace(+1, Dbg, "FatAddEaSet\n", 0);
DebugTrace( 0, Dbg, " Vcb = %8lx\n", Vcb);
DebugTrace( 0, Dbg, " EaSetLength = %ul\n", EaSetLength );
//
// Zero the Ea range structures.
//
RtlZeroMemory( &EaHeaderRange, sizeof( EA_RANGE ));
RtlZeroMemory( &EaOffsetRange, sizeof( EA_RANGE ));
//
// Use a try statement to facilitate cleanup.
//
try {
//
// Pin down the file header.
//
FatPinEaRange( IrpContext,
VirtualEaFile,
EaFcb,
&EaHeaderRange,
0,
sizeof( EA_FILE_HEADER ),
STATUS_DATA_ERROR );
EaHeader = (PEA_FILE_HEADER) EaHeaderRange.Data;
//
// Compute the size of the offset table.
//
EaNewOffsetVbo = EaHeader->EaBaseTable[0] << Vcb->AllocationSupport.LogOfBytesPerCluster;
EaOffsetTableSize = EaNewOffsetVbo - sizeof( EA_FILE_HEADER );
//
// Pin down the entire offset table.
//
FatPinEaRange( IrpContext,
VirtualEaFile,
EaFcb,
&EaOffsetRange,
sizeof( EA_FILE_HEADER ),
EaOffsetTableSize,
STATUS_DATA_ERROR );
//
// We now look for a valid handle out of the existing offset table.
// We start at the last entry and walk backwards. We stop at the
// first unused handle which is preceded by a used handle (or handle
// 1).
//
// As we walk backwards, we need to remember the file offset of the
// cluster which will follow the clusters we add. We initially
// remember the end of the file. If the end of the offset table
// consists of a string of used handles, we remember the offset of
// the handle prior to the transition from used to unused handles.
//
EaSetClusterOffset = EaFcb->Header.FileSize.LowPart
>> Vcb->AllocationSupport.LogOfBytesPerCluster;
NewEaIndex = (USHORT) ((EaOffsetTableSize >> 1) - 1);
NextEaOffset = (PUSHORT) EaOffsetRange.Data + NewEaIndex;
//
// Walk through the used handles at the end of the offset table.
//
if (*NextEaOffset != UNUSED_EA_HANDLE) {
while (NewEaIndex != 0) {
if (*(NextEaOffset - 1) == UNUSED_EA_HANDLE) {
//
// If the handle is 1, we take no action. Otherwise
// we save the cluster offset of the current handle
// knowing we will use a previous handle and insert
// a chain of clusters.
//
if (NewEaIndex != 1) {
EaSetClusterOffset = *NextEaOffset
+ EaHeader->EaBaseTable[NewEaIndex >> 7];
TailExists = TRUE;
}
NewEaIndex--;
NextEaOffset--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -