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

📄 rfsd.c

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

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