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

📄 memory.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:

    RTL_BITMAP      BlockBitmap;
    PVOID           BitmapCache;
    PBCB            BitmapBcb;

    LARGE_INTEGER   Offset;

    BOOLEAN         bModified = FALSE;


    Group = (Block - EXT2_FIRST_DATA_BLOCK) / (Vcb->ext2_super_block->s_blocks_per_group);

    dwBlk = (Block - EXT2_FIRST_DATA_BLOCK) % Vcb->ext2_super_block->s_blocks_per_group;


    Offset.QuadPart = (LONGLONG) Vcb->ext2_block;
    Offset.QuadPart = Offset.QuadPart * Vcb->ext2_group_desc[Group].bg_block_bitmap;

    if (Group == Vcb->ext2_groups - 1)
        Length = Vcb->ext2_super_block->s_blocks_count % Vcb->ext2_super_block->s_blocks_per_group;
    else
        Length = Vcb->ext2_super_block->s_blocks_per_group;

    if (dwBlk >= Length)
        return FALSE;
        
    if (!CcPinRead( Vcb->StreamObj,
                        &Offset,
                        Vcb->ext2_block,
                        TRUE,
                        &BitmapBcb,
                        &BitmapCache ) )
    {
        Ext2DbgPrint(D_MEMORY, "Ext2DeleteBlock: PinReading error ...\n");
        return FALSE;
    }

    RtlInitializeBitMap( &BlockBitmap,
                         BitmapCache,
                         Length );

    if (RtlCheckBit(&BlockBitmap, dwBlk) == 0)
    {
        Ext2DbgBreakPoint();
        RtlSetBits(&BlockBitmap, dwBlk, 1);
        bModified = TRUE;
    }

    if (bModified)
    {
	    CcSetDirtyPinnedData(BitmapBcb, NULL );

        Ext2RepinBcb(IrpContext, BitmapBcb);

        Ext2AddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->ext2_block);
    }

    {
        CcUnpinData(BitmapBcb);
        BitmapBcb = NULL;
        BitmapCache = NULL;

        RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
    }
      
    return (!bModified);
}

BOOLEAN
Ext2CheckBitmapConsistency(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)
{
    ULONG i, j, InodeBlocks;

    for (i = 0; i < Vcb->ext2_groups; i++)
    {
        Ext2CheckSetBlock(IrpContext, Vcb, Vcb->ext2_group_desc[i].bg_block_bitmap);
        Ext2CheckSetBlock(IrpContext, Vcb, Vcb->ext2_group_desc[i].bg_inode_bitmap);
        
        
        if (i == Vcb->ext2_groups - 1)
        {
            InodeBlocks = ((Vcb->ext2_super_block->s_inodes_count % Vcb->ext2_super_block->s_inodes_per_group) * sizeof(EXT2_INODE) + Vcb->ext2_block - 1) / (Vcb->ext2_block);
        }
        else
        {
            InodeBlocks = (Vcb->ext2_super_block->s_inodes_per_group * sizeof(EXT2_INODE) + Vcb->ext2_block - 1) / (Vcb->ext2_block);
        }

        for (j = 0; j < InodeBlocks; j++ )
            Ext2CheckSetBlock(IrpContext, Vcb, Vcb->ext2_group_desc[i].bg_inode_table + j);
    }

    return TRUE;
}

NTSTATUS
Ext2InitializeVcb(IN PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, 
            PEXT2_SUPER_BLOCK Ext2Sb, PDEVICE_OBJECT TargetDevice,
            PDEVICE_OBJECT VolumeDevice, 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];

    __try
    {
        if (!Vpb)
        {
            Status = STATUS_DEVICE_NOT_READY;
            __leave;
        }

        RtlZeroMemory(Vcb, sizeof(EXT2_VCB));
        
        Vcb->Identifier.Type = EXT2VCB;
        Vcb->Identifier.Size = sizeof(EXT2_VCB);

        Buffer[0] = L'\\';
        Buffer[1] = 0;

        RootNode.Buffer = Buffer;
        RootNode.MaximumLength = RootNode.Length = 2;
        Vcb->Ext2McbTree = Ext2AllocateMcb(Vcb, &RootNode, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL);
        if (!Vcb->Ext2McbTree)
            __leave;

#if EXT2_READ_ONLY
        SetFlag(Vcb->Flags, VCB_READ_ONLY);
#endif //READ_ONLY

        if (FlagOn(gExt2Global->Flags, EXT2_SUPPORT_WRITING))
            ClearFlag(Vcb->Flags, VCB_READ_ONLY);

        if (FlagOn(Ext2Sb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) ||
            FlagOn(Ext2Sb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_RECOVER) ||
            FlagOn(Ext2Sb->s_feature_compat, EXT3_FEATURE_COMPAT_HAS_JOURNAL) )
        {
            SetFlag(Vcb->Flags, VCB_READ_ONLY);
        }

        ExInitializeResourceLite(&Vcb->MainResource);
        ExInitializeResourceLite(&Vcb->PagingIoResource);

        ExInitializeResourceLite(&Vcb->CountResource);
        
        VcbResourceInitialized = TRUE;

        Vcb->Ext2McbTree->Inode = EXT2_ROOT_INO;

        Vcb->Vpb = Vpb;

        Vpb->DeviceObject = VolumeDevice;

        {
            VolumeLabelLength = 16;
            while( (VolumeLabelLength > 0) &&
                   ((Ext2Sb->s_volume_name[VolumeLabelLength-1] == 0x00) ||
                    (Ext2Sb->s_volume_name[VolumeLabelLength-1] == 0x20)) )
                VolumeLabelLength--;

            Ext2CharToWchar(
                    Vcb->Vpb->VolumeLabel,
                    Ext2Sb->s_volume_name,
                    VolumeLabelLength );
            Vpb->VolumeLabelLength = VolumeLabelLength * 2;
        }

		Vpb->SerialNumber = ((ULONG*)Ext2Sb->s_uuid)[0] + ((ULONG*)Ext2Sb->s_uuid)[1] +
                            ((ULONG*)Ext2Sb->s_uuid)[2] + ((ULONG*)Ext2Sb->s_uuid)[3];


        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->ext2_super_block = Ext2Sb;
        
        Vcb->CommonFCBHeader.NodeTypeCode = (USHORT) EXT2VCB;
        Vcb->CommonFCBHeader.NodeByteSize = sizeof(EXT2_VCB);
        Vcb->CommonFCBHeader.IsFastIoPossible = FastIoIsNotPossible;
        Vcb->CommonFCBHeader.Resource = &(Vcb->MainResource);
        Vcb->CommonFCBHeader.PagingIoResource = &(Vcb->PagingIoResource);

        Vcb->Vpb->SerialNumber = 'MATT';

        IoctlSize = sizeof(DISK_GEOMETRY);
        
        Status = Ext2DiskIoControl(
            TargetDevice,
            IOCTL_DISK_GET_DRIVE_GEOMETRY,
            NULL,
            0,
            &Vcb->DiskGeometry,
            &IoctlSize );
        
        if (!NT_SUCCESS(Status))
        {
            __leave;
        }
        
        DiskSize =
            Vcb->DiskGeometry.Cylinders.QuadPart *
            Vcb->DiskGeometry.TracksPerCylinder *
            Vcb->DiskGeometry.SectorsPerTrack *
            Vcb->DiskGeometry.BytesPerSector;

        IoctlSize = sizeof(PARTITION_INFORMATION);
        
        Status = Ext2DiskIoControl(
            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;
        }

        Vcb->CommonFCBHeader.AllocationSize.QuadPart =
        Vcb->CommonFCBHeader.FileSize.QuadPart = PartSize;

        Vcb->CommonFCBHeader.ValidDataLength.QuadPart = 
            (LONGLONG)(0x7fffffffffffffff);
/*
        Vcb->CommonFCBHeader.AllocationSize.QuadPart = (LONGLONG)(ext2_super_block->s_blocks_count - ext2_super_block->s_free_blocks_count)
            * (EXT2_MIN_BLOCK << ext2_super_block->s_log_block_size);
        Vcb->CommonFCBHeader.FileSize.QuadPart = Vcb->CommonFCBHeader.AllocationSize.QuadPart;
        Vcb->CommonFCBHeader.ValidDataLength.QuadPart = Vcb->CommonFCBHeader.AllocationSize.QuadPart;
*/
        {
                CC_FILE_SIZES FileSizes;

                FileSizes.AllocationSize.QuadPart =
                FileSizes.FileSize.QuadPart =
                    Vcb->CommonFCBHeader.AllocationSize.QuadPart;

                FileSizes.ValidDataLength.QuadPart= (LONGLONG)(0x7fffffffffffffff);

                CcInitializeCacheMap( Vcb->StreamObj,
                                      &FileSizes,
                                      TRUE,
                                      &(gExt2Global->CacheManagerNoOpCallbacks),
                                      Vcb );
        }

        Vcb->ext2_group_desc = Ext2LoadGroup(Vcb); 

        if (!Vcb->ext2_group_desc)
        {
            Status = STATUS_UNSUCCESSFUL;
            __leave;
        }

        FsRtlInitializeLargeMcb(&(Vcb->DirtyMcbs), PagedPool);

#if 0
        // Understanding Mcb Routines
        {
            LONGLONG	        ByteOffset;
            LONGLONG            DirtyVba;
            LONGLONG            DirtyLba;
            LONGLONG            DirtyLength;
            int		            i;

            Ext2AddMcbEntry(Vcb, 0x00000000, (LONGLONG)0x400);
            Ext2AddMcbEntry(Vcb, 0x00001000, (LONGLONG)0x400);
            FsRtlAddLargeMcbEntry (&(Vcb->DirtyMcbs), (LONGLONG)0x3000, (LONGLONG)0x30003000FFFF0000, (LONGLONG)0x1000);
            Ext2AddMcbEntry(Vcb, 0x00010000, (LONGLONG)0x400);
            Ext2AddMcbEntry(Vcb, 0x00100000, (LONGLONG)0x400);

            Ext2DbgPrint(D_MEMORY, "Ext2InitializeVcb: initial mcb lists:\n");
            for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
            {
	            Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
            }

            ByteOffset = 0x100;
            Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
                                                (PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);

            {
	            Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
            }


            ByteOffset = 0x1000;
            Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
                                                (PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);
            {
	            Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
            }

            ByteOffset = 0x2000;
            Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
                                                (PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);
            {
	            Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
            }

            ByteOffset = 0x110000;
            Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
                                                (PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);
            {
	            Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
            }

            Ext2RemoveMcbEntry(Vcb, 0x00003000, (LONGLONG)0x400);

            Ext2DbgPrint(D_MEMORY, "Ext2InitializeVcb: After Removing 0x300(0x400):\n");

            for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
            {
	            Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
            }

            Ext2RemoveMcbEntry(Vcb, 0x00003000, (LONGLONG)0x1000);

            Ext2DbgPrint(D_MEMORY, "Ext2InitializeVcb: After Removing 0x300(0x1000):\n");
            for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
            {
	            Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
            }

            Ext2RemoveMcbEntry(Vcb, 0x00000000, (LONGLONG)0x400);
            Ext2RemoveMcbEntry(Vcb, 0x00001000, (LONGLONG)0x400);
            Ext2RemoveMcbEntry(Vcb, 0x00010000, (LONGLONG)0x400);
            Ext2RemoveMcbEntry(Vcb, 0x00100000, (LONGLONG)0x400);

        }
#endif

        InsertTailList(&(gExt2Global->VcbList), &Vcb->Next);

        if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
            Ext2CheckBitmapConsistency(IrpContext, Vcb);

        SetFlag(Vcb->Flags, VCB_INITIALIZED);
    }

    __finally
    {
        if (!NT_SUCCESS(Status))
        {
            if (NotifySyncInitialized)
            {
                FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
            }
            
            if (Vcb->ext2_group_desc)
            {
                ExFreePool(Vcb->ext2_group_desc);
            }
            
            if (VcbResourceInitialized)
            {
                ExDeleteResourceLite(&Vcb->CountResource);
                ExDeleteResourceLite(&Vcb->MainResource);
                ExDeleteResourceLite(&Vcb->PagingIoResource);
            }
        }
    }

    return Status;
}


VOID
Ext2FreeVcb (IN PEXT2_VCB Vcb )
{
    ASSERT(Vcb != NULL);
    
    ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
        (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
    
    Ext2ClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);

    FsRtlNotifyUninitializeSync(&Vcb->NotifySync);

    ExAcquireResourceExclusiveLite(
        &gExt2Global->Resource,
        TRUE );

    if (Vcb->StreamObj)
    {
        if (Vcb->StreamObj->PrivateCacheMap)
            Ext2SyncUninitializeCacheMap(Vcb->StreamObj);

        ObDereferenceObject(Vcb->StreamObj);
        Vcb->StreamObj = NULL;
    }
    
    RemoveEntryList(&Vcb->Next);
    
    ExReleaseResourceForThreadLite(
        &gExt2Global->Resource,
        ExGetCurrentResourceThread() );
    
    ExDeleteResourceLite(&Vcb->CountResource);

    ExDeleteResourceLite(&Vcb->MainResource);
    
    ExDeleteResourceLite(&Vcb->PagingIoResource);
    
    if (Vcb->ext2_super_block)
    {
        ExFreePool(Vcb->ext2_super_block);
    }

    if (Vcb->ext2_group_desc)
    {
        ExFreePool(Vcb->ext2_group_desc);
    }

#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++)
        {
	            Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
	            Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n\n", DirtyLength);
        }

        Ext2DbgBreakPoint();
   }
#endif

    FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs));

    Ext2FreeMcbTree(Vcb->Ext2McbTree);
    
    IoDeleteDevice(Vcb->DeviceObject);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -