📄 memory.c
字号:
if(!IsFlagOn(FFSMcb->Flags, MCB_IN_TREE))
{
return TRUE;
}
if (FFSMcb->Parent)
{
if (FFSMcb->Parent->Child == FFSMcb)
{
FFSMcb->Parent->Child = FFSMcb->Next;
}
else
{
TmpMcb = FFSMcb->Parent->Child;
while (TmpMcb && TmpMcb->Next != FFSMcb)
TmpMcb = TmpMcb->Next;
if (TmpMcb)
{
TmpMcb->Next = FFSMcb->Next;
}
else
{
// error
return FALSE;
}
}
}
else if (FFSMcb->Child)
{
return FALSE;
}
RemoveEntryList(&(FFSMcb->Link));
ClearFlag(FFSMcb->Flags, MCB_IN_TREE);
return TRUE;
}
VOID
FFSFreeMcbTree(
PFFS_MCB McbTree)
{
if (!McbTree)
return;
if (McbTree->Child)
{
FFSFreeMcbTree(McbTree->Child);
}
if (McbTree->Next)
{
PFFS_MCB Current;
PFFS_MCB Next;
Current = McbTree->Next;
while (Current)
{
Next = Current->Next;
if (Current->Child)
{
FFSFreeMcbTree(Current->Child);
}
FFSFreeMcb(Current);
Current = Next;
}
}
FFSFreeMcb(McbTree);
}
BOOLEAN
FFSCheckSetBlock(
PFFS_IRP_CONTEXT IrpContext,
PFFS_VCB Vcb,
ULONG Block)
{
#if 0
ULONG Group, dwBlk, Length;
RTL_BITMAP BlockBitmap;
PVOID BitmapCache;
PBCB BitmapBcb;
LARGE_INTEGER Offset;
BOOLEAN bModified = FALSE;
//Group = (Block - FFS_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;
dwBlk = (Block - FFS_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP;
Offset.QuadPart = (LONGLONG) Vcb->BlockSize;
Offset.QuadPart = Offset.QuadPart * Vcb->ffs_group_desc[Group].bg_block_bitmap;
if (Group == Vcb->ffs_groups - 1)
{
Length = TOTAL_BLOCKS % BLOCKS_PER_GROUP;
/* s_blocks_count is integer multiple of s_blocks_per_group */
if (Length == 0)
Length = BLOCKS_PER_GROUP;
}
else
{
Length = BLOCKS_PER_GROUP;
}
if (dwBlk >= Length)
return FALSE;
if (!CcPinRead(Vcb->StreamObj,
&Offset,
Vcb->BlockSize,
PIN_WAIT,
&BitmapBcb,
&BitmapCache))
{
FFSPrint((DBG_ERROR, "FFSDeleteBlock: PinReading error ...\n"));
return FALSE;
}
RtlInitializeBitMap(&BlockBitmap,
BitmapCache,
Length);
if (RtlCheckBit(&BlockBitmap, dwBlk) == 0)
{
FFSBreakPoint();
RtlSetBits(&BlockBitmap, dwBlk, 1);
bModified = TRUE;
}
if (bModified)
{
CcSetDirtyPinnedData(BitmapBcb, NULL);
FFSRepinBcb(IrpContext, BitmapBcb);
FFSAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
}
{
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
return (!bModified);
#endif
return FALSE;
}
BOOLEAN
FFSCheckBitmapConsistency(
PFFS_IRP_CONTEXT IrpContext,
PFFS_VCB Vcb)
{
#if 0
ULONG i, j, InodeBlocks;
for (i = 0; i < Vcb->ffs_groups; i++)
{
FFSCheckSetBlock(IrpContext, Vcb, Vcb->ffs_group_desc[i].bg_block_bitmap);
FFSCheckSetBlock(IrpContext, Vcb, Vcb->ffs_group_desc[i].bg_inode_bitmap);
if (i == Vcb->ffs_groups - 1)
{
InodeBlocks = ((INODES_COUNT % INODES_PER_GROUP) * sizeof(FFS_INODE) + Vcb->BlockSize - 1) / (Vcb->BlockSize);
}
else
{
InodeBlocks = (INODES_PER_GROUP * sizeof(FFS_INODE) + Vcb->BlockSize - 1) / (Vcb->BlockSize);
}
for (j = 0; j < InodeBlocks; j++)
FFSCheckSetBlock(IrpContext, Vcb, Vcb->ffs_group_desc[i].bg_inode_table + j);
}
return TRUE;
#endif
return FALSE;
}
VOID
FFSInsertVcb(
PFFS_VCB Vcb)
{
InsertTailList(&(FFSGlobal->VcbList), &Vcb->Next);
}
VOID
FFSRemoveVcb(
PFFS_VCB Vcb)
{
RemoveEntryList(&Vcb->Next);
}
NTSTATUS
FFSInitializeVcb(
IN PFFS_IRP_CONTEXT IrpContext,
IN PFFS_VCB Vcb,
IN PFFS_SUPER_BLOCK FFSSb,
IN PDEVICE_OBJECT TargetDevice,
IN PDEVICE_OBJECT VolumeDevice,
IN PVPB Vpb)
{
BOOLEAN VcbResourceInitialized = FALSE;
USHORT VolumeLabelLength;
ULONG IoctlSize;
BOOLEAN NotifySyncInitialized = FALSE;
LONGLONG DiskSize;
LONGLONG PartSize;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING RootNode;
USHORT Buffer[2];
ULONG ChangeCount;
__try
{
if (!Vpb)
{
Status = STATUS_DEVICE_NOT_READY;
__leave;
}
Buffer[0] = L'\\';
Buffer[1] = 0;
RootNode.Buffer = Buffer;
RootNode.MaximumLength = RootNode.Length = 2;
Vcb->McbTree = FFSAllocateMcb(Vcb, &RootNode,
FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL);
if (!Vcb->McbTree)
{
__leave;
}
#if FFS_READ_ONLY
SetFlag(Vcb->Flags, VCB_READ_ONLY);
#endif //READ_ONLY
if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA))
{
SetFlag(Vcb->Flags, VCB_REMOVABLE_MEDIA);
}
if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE))
{
SetFlag(Vcb->Flags, VCB_FLOPPY_DISK);
}
#if 0
if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING))
{
if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING))
{
ClearFlag(Vcb->Flags, VCB_READ_ONLY);
}
else
{
SetFlag(Vcb->Flags, VCB_READ_ONLY);
}
}
else
#endif
{
SetFlag(Vcb->Flags, VCB_READ_ONLY);
}
ExInitializeResourceLite(&Vcb->MainResource);
ExInitializeResourceLite(&Vcb->PagingIoResource);
ExInitializeResourceLite(&Vcb->McbResource);
VcbResourceInitialized = TRUE;
Vcb->McbTree->Inode = FFS_ROOT_INO;
Vcb->Vpb = Vpb;
Vcb->RealDevice = Vpb->RealDevice;
Vpb->DeviceObject = VolumeDevice;
{
UNICODE_STRING LabelName;
OEM_STRING OemName;
LabelName.MaximumLength = 16 * 2;
LabelName.Length = 0;
LabelName.Buffer = Vcb->Vpb->VolumeLabel;
RtlZeroMemory(LabelName.Buffer, LabelName.MaximumLength);
VolumeLabelLength = 16;
while((VolumeLabelLength > 0) &&
((FFSSb->fs_volname[VolumeLabelLength-1] == 0x00) ||
(FFSSb->fs_volname[VolumeLabelLength-1] == 0x20)))
{
VolumeLabelLength--;
}
OemName.Buffer = FFSSb->fs_volname;
OemName.MaximumLength = 16;
OemName.Length = VolumeLabelLength;
Status = FFSOEMToUnicode(&LabelName,
&OemName);
if (!NT_SUCCESS(Status))
{
__leave;
}
Vpb->VolumeLabelLength = LabelName.Length;
}
Vpb->SerialNumber = ((ULONG*)FFSSb->fs_id)[0] + ((ULONG*)FFSSb->fs_id)[1] +
((ULONG*)FFSSb->fs_id)[2];
Vcb->StreamObj = IoCreateStreamFileObject(NULL, Vcb->Vpb->RealDevice);
if (Vcb->StreamObj)
{
Vcb->StreamObj->SectionObjectPointer = &(Vcb->SectionObject);
Vcb->StreamObj->Vpb = Vcb->Vpb;
Vcb->StreamObj->ReadAccess = TRUE;
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
{
Vcb->StreamObj->WriteAccess = TRUE;
Vcb->StreamObj->DeleteAccess = TRUE;
}
else
{
Vcb->StreamObj->WriteAccess = TRUE;
Vcb->StreamObj->DeleteAccess = TRUE;
}
Vcb->StreamObj->FsContext = (PVOID) Vcb;
Vcb->StreamObj->FsContext2 = NULL;
Vcb->StreamObj->Vpb = Vcb->Vpb;
SetFlag(Vcb->StreamObj->Flags, FO_NO_INTERMEDIATE_BUFFERING);
}
else
{
__leave;
}
InitializeListHead(&Vcb->FcbList);
InitializeListHead(&Vcb->NotifyList);
FsRtlNotifyInitializeSync(&Vcb->NotifySync);
NotifySyncInitialized = TRUE;
Vcb->DeviceObject = VolumeDevice;
Vcb->TargetDeviceObject = TargetDevice;
Vcb->OpenFileHandleCount = 0;
Vcb->ReferenceCount = 0;
Vcb->ffs_super_block = FFSSb;
Vcb->Header.NodeTypeCode = (USHORT) FFSVCB;
Vcb->Header.NodeByteSize = sizeof(FFS_VCB);
Vcb->Header.IsFastIoPossible = FastIoIsNotPossible;
Vcb->Header.Resource = &(Vcb->MainResource);
Vcb->Header.PagingIoResource = &(Vcb->PagingIoResource);
Vcb->Vpb->SerialNumber = 'PS';
DiskSize =
Vcb->DiskGeometry.Cylinders.QuadPart *
Vcb->DiskGeometry.TracksPerCylinder *
Vcb->DiskGeometry.SectorsPerTrack *
Vcb->DiskGeometry.BytesPerSector;
IoctlSize = sizeof(PARTITION_INFORMATION);
Status = FFSDiskIoControl(
TargetDevice,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&Vcb->PartitionInformation,
&IoctlSize);
PartSize = Vcb->PartitionInformation.PartitionLength.QuadPart;
if (!NT_SUCCESS(Status))
{
Vcb->PartitionInformation.StartingOffset.QuadPart = 0;
Vcb->PartitionInformation.PartitionLength.QuadPart =
DiskSize;
PartSize = DiskSize;
Status = STATUS_SUCCESS;
}
IoctlSize = sizeof(ULONG);
Status = FFSDiskIoControl(
TargetDevice,
IOCTL_DISK_CHECK_VERIFY,
NULL,
0,
&ChangeCount,
&IoctlSize);
if (!NT_SUCCESS(Status))
{
__leave;
}
Vcb->ChangeCount = ChangeCount;
Vcb->Header.AllocationSize.QuadPart =
Vcb->Header.FileSize.QuadPart = PartSize;
Vcb->Header.ValidDataLength.QuadPart =
(LONGLONG)(0x7fffffffffffffff);
/*
Vcb->Header.AllocationSize.QuadPart = (LONGLONG)(ffs_super_block->s_blocks_count - ffs_super_block->s_free_blocks_count)
* (FFS_MIN_BLOCK << ffs_super_block->s_log_block_size);
Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart;
Vcb->Header.ValidDataLength.QuadPart = Vcb->Header.AllocationSize.QuadPart;
*/
{
CC_FILE_SIZES FileSizes;
FileSizes.AllocationSize.QuadPart =
FileSizes.FileSize.QuadPart =
Vcb->Header.AllocationSize.QuadPart;
FileSizes.ValidDataLength.QuadPart= (LONGLONG)(0x7fffffffffffffff);
CcInitializeCacheMap(Vcb->StreamObj,
&FileSizes,
TRUE,
&(FFSGlobal->CacheManagerNoOpCallbacks),
Vcb);
}
#if 0 // LoadGroup XXX
if (!FFSLoadGroup(Vcb))
{
Status = STATUS_UNSUCCESSFUL;
__leave;
}
#endif
FsRtlInitializeLargeMcb(&(Vcb->DirtyMcbs), PagedPool);
InitializeListHead(&(Vcb->McbList));
if (IsFlagOn(FFSGlobal->Flags, FFS_CHECKING_BITMAP))
{
FFSCheckBitmapConsistency(IrpContext, Vcb);
}
{
ULONG dwData[FFS_BLOCK_TYPES] = {NDADDR, 1, 1, 1};
ULONG dwMeta[FFS_BLOCK_TYPES] = {0, 0, 0, 0};
ULONG i;
if (FS_VERSION == 1)
{
for (i = 0; i < FFS_BLOCK_TYPES; i++)
{
dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i);
if (i > 0)
{
dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2));
}
Vcb->dwData[i] = dwData[i];
Vcb->dwMeta[i] = dwMeta[i];
}
}
else
{
for (i = 0; i < FFS_BLOCK_TYPES; i++)
{
dwData[i] = dwData[i] << ((BLOCK_BITS - 3) * i);
if (i > 0)
{
dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 3));
}
Vcb->dwData[i] = dwData[i];
Vcb->dwMeta[i] = dwMeta[i];
}
}
}
SetFlag(Vcb->Flags, VCB_INITIALIZED);
}
__finally
{
if (!NT_SUCCESS(Status))
{
if (NotifySyncInitialized)
{
FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
}
if (Vcb->ffs_super_block)
{
ExFreePool(Vcb->ffs_super_block);
Vcb->ffs_super_block = NULL;
}
if (VcbResourceInitialized)
{
ExDeleteResourceLite(&Vcb->MainResource);
ExDeleteResourceLite(&Vcb->PagingIoResource);
}
}
}
return Status;
}
VOID
FFSFreeVcb(
IN PFFS_VCB Vcb)
{
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
if (Vcb->StreamObj)
{
if (IsFlagOn(Vcb->StreamObj->Flags, FO_FILE_MODIFIED))
{
IO_STATUS_BLOCK IoStatus;
CcFlushCache(&(Vcb->SectionObject), NULL, 0, &IoStatus);
ClearFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED);
}
if (Vcb->StreamObj->PrivateCacheMap)
FFSSyncUninitializeCacheMap(Vcb->StreamObj);
ObDereferenceObject(Vcb->StreamObj);
Vcb->StreamObj = NULL;
}
#if DBG
if (FsRtlNumberOfRunsInLargeMcb(&(Vcb->DirtyMcbs)) != 0)
{
LONGLONG DirtyVba;
LONGLONG DirtyLba;
LONGLONG DirtyLength;
int i;
for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
{
FFSPrint((DBG_INFO, "DirtyVba = %I64xh\n", DirtyVba));
FFSPrint((DBG_INFO, "DirtyLba = %I64xh\n", DirtyLba));
FFSPrint((DBG_INFO, "DirtyLen = %I64xh\n\n", DirtyLength));
}
FFSBreakPoint();
}
#endif
FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs));
FFSFreeMcbTree(Vcb->McbTree);
if (Vcb->ffs_super_block)
{
ExFreePool(Vcb->ffs_super_block);
Vcb->ffs_super_block = NULL;
}
ExDeleteResourceLite(&Vcb->McbResource);
ExDeleteResourceLite(&Vcb->PagingIoResource);
ExDeleteResourceLite(&Vcb->MainResource);
IoDeleteDevice(Vcb->DeviceObject);
}
VOID
FFSSyncUninitializeCacheMap(
IN PFILE_OBJECT FileObject)
{
CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent;
NTSTATUS WaitStatus;
LARGE_INTEGER FFSLargeZero = {0, 0};
KeInitializeEvent(&UninitializeCompleteEvent.Event,
SynchronizationEvent,
FALSE);
CcUninitializeCacheMap(FileObject,
&FFSLargeZero,
&UninitializeCompleteEvent);
WaitStatus = KeWaitForSingleObject(&UninitializeCompleteEvent.Event,
Executive,
KernelMode,
FALSE,
NULL);
ASSERT (NT_SUCCESS(WaitStatus));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -