📄 rfsd.c
字号:
PRFSD_DIR_ENTRY2 pTarget = NULL;
PRFSD_DIR_ENTRY2 pPrevDir = NULL;
USHORT PrevRecLen = 0;
ULONG Length = 0;
ULONG dwBytes = 0;
BOOLEAN MainResourceAcquired = FALSE;
ULONG dwRet;
if (!IsDirectory(Dcb)) {
return STATUS_NOT_A_DIRECTORY;
}
MainResourceAcquired =
ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
__try {
Dcb->ReferenceCount++;
pTarget = (PRFSD_DIR_ENTRY2) ExAllocatePool(PagedPool,
RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
if (!pTarget) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
pPrevDir = (PRFSD_DIR_ENTRY2) ExAllocatePool(PagedPool,
RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
if (!pPrevDir) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
dwBytes = 0;
while ((LONGLONG)dwBytes < Dcb->Header.AllocationSize.QuadPart) {
RtlZeroMemory(pTarget, RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
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, "RfsdRemoveEntry: Reading Directory Content error.\n"));
__leave;
}
//
// Find it ! Then remove the entry from Dcb ...
//
if (pTarget->inode == Inode) {
ULONG RecLen;
BOOLEAN bAcross = FALSE;
if (((ULONG)PrevRecLen + pTarget->rec_len) > BLOCK_SIZE) {
bAcross = TRUE;
} else {
dwRet = (dwBytes - PrevRecLen) & (~(BLOCK_SIZE - 1));
if (dwRet != (dwBytes & (~(BLOCK_SIZE - 1))))
{
bAcross = TRUE;
}
}
if (!bAcross) {
pPrevDir->rec_len += pTarget->rec_len;
RecLen = RFSD_DIR_REC_LEN(pTarget->name_len);
RtlZeroMemory(pTarget, RecLen);
Status = RfsdWriteInode(
IrpContext,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
dwBytes - PrevRecLen,
pPrevDir,
8,
FALSE,
&dwRet
);
ASSERT(NT_SUCCESS(Status));
Status = RfsdWriteInode(
IrpContext,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
dwBytes,
pTarget,
RecLen,
FALSE,
&dwRet
);
ASSERT(NT_SUCCESS(Status));
} else {
RecLen = (ULONG)pTarget->rec_len;
if (RecLen > RFSD_DIR_REC_LEN(RFSD_NAME_LEN)) {
RtlZeroMemory(pTarget, RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
pTarget->rec_len = (USHORT)RecLen;
Status = RfsdWriteInode(
IrpContext,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
dwBytes,
pTarget,
RFSD_DIR_REC_LEN(RFSD_NAME_LEN),
FALSE,
&dwRet
);
ASSERT(NT_SUCCESS(Status));
} else {
RtlZeroMemory(pTarget, RecLen);
pTarget->rec_len = (USHORT)RecLen;
Status = RfsdWriteInode(
IrpContext,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
dwBytes,
pTarget,
RecLen,
FALSE,
&dwRet
);
ASSERT(NT_SUCCESS(Status));
}
}
//
// Error if it's the entry of dot or dot-dot or drop the parent's refer link
//
if (FileType == RFSD_FT_DIR) {
if(((pTarget->name_len == 1) && (pTarget->name[0] == '.')) ||
((pTarget->name_len == 2) && (pTarget->name[0] == '.') && (pTarget->name[1] == '.')) ) {
DbgBreak();
} else {
Dcb->Inode->i_links_count--;
}
}
//
// Update at least mtime/atime if !RFSD_FT_DIR.
//
if ( !RfsdSaveInode(
IrpContext,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode
) ) {
Status = STATUS_UNSUCCESSFUL;
}
break;
} else {
RtlCopyMemory(pPrevDir, pTarget, RFSD_DIR_REC_LEN(RFSD_NAME_LEN));
PrevRecLen = pTarget->rec_len;
}
dwBytes += pTarget->rec_len;
}
} __finally {
Dcb->ReferenceCount--;
if(MainResourceAcquired)
ExReleaseResourceForThreadLite(
&Dcb->MainResource,
ExGetCurrentResourceThread());
if (pTarget != NULL) {
ExFreePool(pTarget);
}
if (pPrevDir != NULL) {
ExFreePool(pPrevDir);
}
}
return Status;
#endif
}
NTSTATUS
RfsdSetParentEntry (
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN PRFSD_FCB Dcb,
IN ULONG OldParent,
IN ULONG NewParent )
{
DbgBreak();
#if DISABLED
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PRFSD_DIR_ENTRY2 pSelf = NULL;
PRFSD_DIR_ENTRY2 pParent = NULL;
ULONG dwBytes = 0;
BOOLEAN MainResourceAcquired = FALSE;
ULONG Offset = 0;
if (!IsDirectory(Dcb)) {
return STATUS_NOT_A_DIRECTORY;
}
MainResourceAcquired =
ExAcquireResourceExclusiveLite(&Dcb->MainResource, TRUE);
__try {
Dcb->ReferenceCount++;
pSelf = (PRFSD_DIR_ENTRY2) ExAllocatePool(PagedPool,
RFSD_DIR_REC_LEN(1) + RFSD_DIR_REC_LEN(2));
if (!pSelf) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
dwBytes = 0;
//
// Reading the DCB contents
//
Status = RfsdReadInode(
NULL,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
Offset,
(PVOID)pSelf,
RFSD_DIR_REC_LEN(1) + RFSD_DIR_REC_LEN(2),
&dwBytes );
if (!NT_SUCCESS(Status)) {
RfsdPrint((DBG_ERROR, "RfsdSetParentEntry: Reading Directory Content error.\n"));
__leave;
}
ASSERT(dwBytes == RFSD_DIR_REC_LEN(1) + RFSD_DIR_REC_LEN(2));
pParent = (PRFSD_DIR_ENTRY2)((PUCHAR)pSelf + pSelf->rec_len);
if (pParent->inode != OldParent) {
DbgBreak();
}
pParent->inode = NewParent;
Status = RfsdWriteInode(
IrpContext,
Vcb,
Dcb->RfsdMcb->Inode,
Dcb->Inode,
Offset,
pSelf,
dwBytes,
FALSE,
&dwBytes );
} __finally {
Dcb->ReferenceCount--;
if(MainResourceAcquired) {
ExReleaseResourceForThreadLite(
&Dcb->MainResource,
ExGetCurrentResourceThread());
}
if (pSelf) {
ExFreePool(pSelf);
}
}
return Status;
#endif
{ return 1; }
}
NTSTATUS
RfsdTruncateBlock(
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN PRFSD_FCB Fcb,
IN ULONG dwContent,
IN ULONG Index,
IN ULONG layer,
OUT BOOLEAN *bFreed )
{
DbgBreak();
#if DISABLED
ULONG *pData = NULL;
ULONG i = 0, j = 0, temp = 1;
BOOLEAN bDirty = FALSE;
ULONG dwBlk;
LONGLONG Offset;
PBCB Bcb;
NTSTATUS Status = STATUS_SUCCESS;
PRFSD_INODE Inode = Fcb->Inode;
*bFreed = FALSE;
if (layer == 0) {
if ( dwContent > 0 && (dwContent / BLOCKS_PER_GROUP) < Vcb->NumOfGroups) {
Status = RfsdFreeBlock(IrpContext, Vcb, dwContent);
if (NT_SUCCESS(Status)) {
ASSERT(Inode->i_blocks >= (Vcb->BlockSize / SECTOR_SIZE));
Inode->i_blocks -= (Vcb->BlockSize / SECTOR_SIZE);
*bFreed = TRUE;
}
} else if (dwContent == 0) {
Status = STATUS_SUCCESS;
} else {
DbgBreak();
Status = STATUS_INVALID_PARAMETER;
}
} else if (layer <= 3) {
Offset = (LONGLONG) dwContent;
Offset = Offset * Vcb->BlockSize;
if (!CcPinRead( Vcb->StreamObj,
(PLARGE_INTEGER) (&Offset),
Vcb->BlockSize,
PIN_WAIT,
&Bcb,
&pData )) {
RfsdPrint((DBG_ERROR, "RfsdSaveBuffer: PinReading error ...\n"));
Status = STATUS_INSUFFICIENT_RESOURCES;
goto errorout;
}
temp = 1 << ((BLOCK_BITS - 2) * (layer - 1));
i = Index / temp;
j = Index % temp;
dwBlk = pData[i];
if (dwBlk) {
Status = RfsdTruncateBlock(
IrpContext,
Vcb,
Fcb,
dwBlk,
j,
layer - 1,
&bDirty
);
if(!NT_SUCCESS(Status)) {
goto errorout;
}
if (bDirty) {
pData[i] = 0;
}
}
if (i == 0 && j == 0) {
CcUnpinData(Bcb);
pData = NULL;
Status = RfsdFreeBlock(IrpContext, Vcb, dwContent);
if (NT_SUCCESS(Status)) {
ASSERT(Inode->i_blocks >= (Vcb->BlockSize / SECTOR_SIZE));
Inode->i_blocks -= (Vcb->BlockSize / SECTOR_SIZE);
*bFreed = TRUE;
}
} else {
if (bDirty) {
CcSetDirtyPinnedData(Bcb, NULL );
RfsdRepinBcb(IrpContext, Bcb);
RfsdAddMcbEntry(Vcb, Offset, (LONGLONG)Vcb->BlockSize);
}
}
}
errorout:
if (pData) {
CcUnpinData(Bcb);
}
return Status;
#endif
}
NTSTATUS
RfsdTruncateInode(
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN PRFSD_FCB Fcb )
{
DbgBreak();
#if DISABLED
ULONG dwSizes[RFSD_BLOCK_TYPES];
ULONG Index = 0;
ULONG dwTotal = 0;
ULONG dwBlk = 0;
ULONG i;
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN bFreed = FALSE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -