📄 rfsd.c
字号:
*/
for (j = 1; j < Vcb->NumOfGroups; j <<= 1) {
i += j;
if (i > Vcb->NumOfGroups)
i -= Vcb->NumOfGroups;
if (Vcb->GroupDesc[i].bg_free_inodes_count) {
Group = i + 1;
break;
}
}
}
if (!Group) {
/*
* That failed: try linear search for a free inode
*/
i = GroupHint + 1;
for (j = 2; j < Vcb->NumOfGroups; j++) {
if (++i >= Vcb->NumOfGroups) i = 0;
if (Vcb->GroupDesc[i].bg_free_inodes_count) {
Group = i + 1;
break;
}
}
}
}
// Could not find a proper group.
if (!Group) {
return STATUS_DISK_FULL;
} else {
Group--;
Offset.QuadPart = (LONGLONG) Vcb->BlockSize;
Offset.QuadPart = Offset.QuadPart * Vcb->GroupDesc[Group].bg_inode_bitmap;
if (Vcb->NumOfGroups == 1) {
Length = INODES_COUNT;
} else {
if (Group == Vcb->NumOfGroups - 1) {
Length = INODES_COUNT % INODES_PER_GROUP;
if (!Length) {
/* INODES_COUNT is integer multiple of INODES_PER_GROUP */
Length = INODES_PER_GROUP;
}
} else {
Length = INODES_PER_GROUP;
}
}
if (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->BlockSize,
PIN_WAIT,
&BitmapBcb,
&BitmapCache ) ) {
RfsdPrint((DBG_ERROR, "RfsdNewInode: PinReading error ...\n"));
return STATUS_UNSUCCESSFUL;
}
RtlInitializeBitMap( &InodeBitmap,
BitmapCache,
Length );
dwInode = RtlFindClearBits(&InodeBitmap, 1, 0);
if (dwInode == 0xFFFFFFFF) {
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&InodeBitmap, sizeof(RTL_BITMAP));
}
}
if (dwInode == 0xFFFFFFFF || dwInode >= Length) {
if (Vcb->GroupDesc[Group].bg_free_inodes_count != 0) {
Vcb->GroupDesc[Group].bg_free_inodes_count = 0;
RfsdSaveGroup(IrpContext, Vcb, Group);
}
goto repeat;
} else {
RtlSetBits(&InodeBitmap, dwInode, 1);
CcSetDirtyPinnedData(BitmapBcb, NULL );
RfsdRepinBcb(IrpContext, BitmapBcb);
CcUnpinData(BitmapBcb);
RfsdAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
*Inode = dwInode + 1 + Group * INODES_PER_GROUP;
//Updating Group Desc / Superblock
Vcb->GroupDesc[Group].bg_free_inodes_count--;
if (Type == RFSD_FT_DIR) {
Vcb->GroupDesc[Group].bg_used_dirs_count++;
}
RfsdSaveGroup(IrpContext, Vcb, Group);
Vcb->SuperBlock->s_free_inodes_count--;
RfsdSaveSuper(IrpContext, Vcb);
return STATUS_SUCCESS;
}
return STATUS_DISK_FULL;
#endif
}
BOOLEAN
RfsdFreeInode(
PRFSD_IRP_CONTEXT IrpContext,
PRFSD_VCB Vcb,
ULONG Inode,
ULONG Type )
{
DbgBreak();
#if DISABLED
RTL_BITMAP InodeBitmap;
PVOID BitmapCache;
PBCB BitmapBcb;
ULONG Group;
ULONG Length;
LARGE_INTEGER Offset;
ULONG dwIno;
BOOLEAN bModified = FALSE;
Group = (Inode - 1) / INODES_PER_GROUP;
dwIno = (Inode - 1) % INODES_PER_GROUP;
RfsdPrint((DBG_INFO, "RfsdFreeInode: Inode: %xh (Group/Off = %xh/%xh)\n",
Inode, Group, dwIno));
{
Offset.QuadPart = (LONGLONG) Vcb->BlockSize;
Offset.QuadPart = Offset.QuadPart * Vcb->GroupDesc[Group].bg_inode_bitmap;
if (Group == Vcb->NumOfGroups - 1) {
Length = INODES_COUNT % INODES_PER_GROUP;
if (!Length) {
/* s_inodes_count is integer multiple of s_inodes_per_group */
Length = INODES_PER_GROUP;
}
} else {
Length = INODES_PER_GROUP;
}
if (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->BlockSize,
PIN_WAIT,
&BitmapBcb,
&BitmapCache ) ) {
RfsdPrint((DBG_ERROR, "RfsdFreeInode: PinReading error ...\n"));
return FALSE;
}
RtlInitializeBitMap( &InodeBitmap,
BitmapCache,
Length );
if (RtlCheckBit(&InodeBitmap, dwIno) == 0) {
DbgBreak();
} else {
RtlClearBits(&InodeBitmap, dwIno, 1);
bModified = TRUE;
}
if (!bModified) {
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&InodeBitmap, sizeof(RTL_BITMAP));
}
}
if (bModified) {
CcSetDirtyPinnedData(BitmapBcb, NULL );
RfsdRepinBcb(IrpContext, BitmapBcb);
CcUnpinData(BitmapBcb);
RfsdAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
//Updating Group Desc / Superblock
if (Type == RFSD_FT_DIR) {
Vcb->GroupDesc[Group].bg_used_dirs_count--;
}
Vcb->GroupDesc[Group].bg_free_inodes_count++;
RfsdSaveGroup(IrpContext, Vcb, Group);
Vcb->SuperBlock->s_free_inodes_count++;
RfsdSaveSuper(IrpContext, Vcb);
return TRUE;
}
return FALSE;
#endif
}
NTSTATUS
RfsdAddEntry (
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN PRFSD_FCB Dcb,
IN ULONG FileType,
IN ULONG Inode,
IN PUNICODE_STRING FileName )
{
DbgBreak();
#if DISABLED
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PRFSD_DIR_ENTRY2 pDir = NULL;
PRFSD_DIR_ENTRY2 pNewDir = NULL;
PRFSD_DIR_ENTRY2 pTarget = NULL;
ULONG Length = 0;
ULONG dwBytes = 0;
BOOLEAN bFound = FALSE;
BOOLEAN bAdding = FALSE;
BOOLEAN MainResourceAcquired = FALSE;
ULONG dwRet;
if (!IsDirectory(Dcb)) {
DbgBreak();
return STATUS_NOT_A_DIRECTORY;
}
MainResourceAcquired = ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
__try {
Dcb->ReferenceCount++;
pDir = (PRFSD_DIR_ENTRY2) ExAllocatePool(PagedPool,
RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
if (!pDir) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
pTarget = (PRFSD_DIR_ENTRY2) ExAllocatePool(PagedPool,
2 * RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
if (!pTarget) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
#if DISABLED // disabled in FFS too
if (IsFlagOn( SUPER_BLOCK->s_feature_incompat,
RFSD_FEATURE_INCOMPAT_FILETYPE)) {
pDir->file_type = (UCHAR) FileType;
} else
#endif
{
pDir->file_type = 0;
}
{
OEM_STRING OemName;
OemName.Buffer = pDir->name;
OemName.MaximumLength = RFSD_NAME_LEN;
OemName.Length = 0;
Status = RfsdUnicodeToOEM(&OemName, FileName);
if (!NT_SUCCESS(Status)) {
__leave;
}
pDir->name_len = (CCHAR) OemName.Length;
}
pDir->inode = Inode;
pDir->rec_len = (USHORT) (RFSD_DIR_REC_LEN(pDir->name_len));
dwBytes = 0;
Repeat:
while ((LONGLONG)dwBytes < Dcb->Header.AllocationSize.QuadPart) {
RtlZeroMemory(pTarget, RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
// Reading the DCB contents
Status = RfsdReadInode(
NULL,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
dwBytes,
(PVOID)pTarget,
RFSD_DIR_REC_LEN(RFSD_NAME_LEN),
&dwRet);
if (!NT_SUCCESS(Status)) {
RfsdPrint((DBG_ERROR, "RfsdAddDirectory: Reading Directory Content error.\n"));
__leave;
}
if (((pTarget->inode == 0) && pTarget->rec_len >= pDir->rec_len) ||
(pTarget->rec_len >= RFSD_DIR_REC_LEN(pTarget->name_len) + pDir->rec_len)) {
if (pTarget->inode) {
RtlZeroMemory(pTarget, 2 * RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
// Reading the DCB contents
Status = RfsdReadInode(
NULL,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
dwBytes,
(PVOID)pTarget,
2 * RFSD_DIR_REC_LEN(RFSD_NAME_LEN),
&dwRet);
if (!NT_SUCCESS(Status)) {
RfsdPrint((DBG_ERROR, "RfsdAddDirectory: Reading Directory Content error.\n"));
__leave;
}
Length = RFSD_DIR_REC_LEN(pTarget->name_len);
pNewDir = (PRFSD_DIR_ENTRY2) ((PUCHAR)pTarget + RFSD_DIR_REC_LEN(pTarget->name_len));
pNewDir->rec_len = pTarget->rec_len - RFSD_DIR_REC_LEN(pTarget->name_len);
pTarget->rec_len = RFSD_DIR_REC_LEN(pTarget->name_len);
} else {
Length = 0;
pNewDir = pTarget;
}
pNewDir->file_type = pDir->file_type;
pNewDir->inode = pDir->inode;
pNewDir->name_len = pDir->name_len;
memcpy(pNewDir->name, pDir->name, pDir->name_len);
Length += RFSD_DIR_REC_LEN(pDir->name_len);
bFound = TRUE;
break;
}
dwBytes += pTarget->rec_len;
}
if (bFound) {
ULONG dwRet;
if ( FileType==RFSD_FT_DIR ) {
if(((pDir->name_len == 1) && (pDir->name[0] == '.')) ||
((pDir->name_len == 2) && (pDir->name[0] == '.') && (pDir->name[1] == '.')) ) {
} else {
Dcb->Inode->i_links_count++;
}
}
Status = RfsdWriteInode(
IrpContext,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
(ULONGLONG)dwBytes,
pTarget,
Length,
FALSE,
&dwRet );
} else {
// We should expand the size of the dir inode
if (!bAdding) {
ULONG dwRet;
Status = RfsdExpandInode(IrpContext, Vcb, Dcb, &dwRet);
if (NT_SUCCESS(Status)) {
Dcb->Inode->i_size = Dcb->Header.AllocationSize.LowPart;
RfsdSaveInode(IrpContext, Vcb, Dcb->RfsdMcb->Inode, Dcb->Inode);
Dcb->Header.FileSize = Dcb->Header.AllocationSize;
bAdding = TRUE;
goto Repeat;
}
__leave;
} else { // Something must be error!
__leave;
}
}
} __finally {
Dcb->ReferenceCount--;
if(MainResourceAcquired) {
ExReleaseResourceForThreadLite(
&Dcb->MainResource,
ExGetCurrentResourceThread());
}
if (pTarget != NULL) {
ExFreePool(pTarget);
}
if (pDir) {
ExFreePool(pDir);
}
}
return Status;
#endif
}
NTSTATUS
RfsdRemoveEntry (
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN PRFSD_FCB Dcb,
IN ULONG FileType,
IN ULONG Inode )
{
DbgBreak();
#if DISABLED
NTSTATUS Status = STATUS_UNSUCCESSFUL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -