⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfsd.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 5 页
字号:

    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 + -