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

📄 memory.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 3 页
字号:
RfsdCheckSetBlock(PRFSD_IRP_CONTEXT IrpContext, PRFSD_VCB Vcb, ULONG Block)
{
	DbgBreak();

    ULONG           Group, dwBlk, Length;

    RTL_BITMAP      BlockBitmap;
    PVOID           BitmapCache;
    PBCB            BitmapBcb;

    LARGE_INTEGER   Offset;

    BOOLEAN         bModified = FALSE;


    Group = (Block - RFSD_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;

    dwBlk = (Block - RFSD_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP;


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

    if (Group == Vcb->NumOfGroups - 1) {
        Length = TOTAL_BLOCKS % BLOCKS_PER_GROUP;

        /* s_blocks_count is integer multiple of s_blocks_per_group */
        if (Length == 0)
            Length = BLOCKS_PER_GROUP;
    } else {
        Length = BLOCKS_PER_GROUP;
    }

    if (dwBlk >= Length)
        return FALSE;
        
    if (!CcPinRead( Vcb->StreamObj,
                        &Offset,
                        Vcb->BlockSize,
                        PIN_WAIT,
                        &BitmapBcb,
                        &BitmapCache ) ) {

        RfsdPrint((DBG_ERROR, "RfsdDeleteBlock: PinReading error ...\n"));
        return FALSE;
    }

    RtlInitializeBitMap( &BlockBitmap,
                         BitmapCache,
                         Length );

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

    if (bModified) {

        CcSetDirtyPinnedData(BitmapBcb, NULL );

        RfsdRepinBcb(IrpContext, BitmapBcb);

        RfsdAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
    }

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

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


#if DISABLED
BOOLEAN
RfsdCheckBitmapConsistency(PRFSD_IRP_CONTEXT IrpContext, PRFSD_VCB Vcb)
{
	DbgBreak();

    ULONG i, j, InodeBlocks;

    for (i = 0; i < Vcb->NumOfGroups; i++) {

        RfsdCheckSetBlock(IrpContext, Vcb, Vcb->GroupDesc[i].bg_block_bitmap);
        RfsdCheckSetBlock(IrpContext, Vcb, Vcb->GroupDesc[i].bg_inode_bitmap);
        
        
        if (i == Vcb->NumOfGroups - 1) {
            InodeBlocks = ((INODES_COUNT % INODES_PER_GROUP) * 
                            sizeof(RFSD_INODE) + Vcb->BlockSize - 1) /
                            (Vcb->BlockSize);
        } else {
            InodeBlocks = (INODES_PER_GROUP * sizeof(RFSD_INODE) + Vcb->BlockSize - 1) / (Vcb->BlockSize);
        }

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

    return TRUE;
}
#endif

VOID
RfsdInsertVcb(PRFSD_VCB Vcb)
{
    InsertTailList(&(RfsdGlobal->VcbList), &Vcb->Next);
}

VOID
RfsdRemoveVcb(PRFSD_VCB Vcb)
{
    RemoveEntryList(&Vcb->Next);
}

NTSTATUS
RfsdInitializeVcb( IN PRFSD_IRP_CONTEXT IrpContext, 
                   IN PRFSD_VCB Vcb, 
                   IN PRFSD_SUPER_BLOCK RfsdSb,
                   IN PDEVICE_OBJECT TargetDevice,
                   IN PDEVICE_OBJECT VolumeDevice,
                   IN 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];
    ULONG                       ChangeCount;
	 char	s_volume_name[16] = "ReiserFS\0"; /* volume name */		// FUTURE: pull in from v2 superblock, if available
	 int templen;

    __try {

        if (!Vpb) {

            Status = STATUS_DEVICE_NOT_READY;
            __leave;
        }

        RfsdPrint((DBG_ERROR, "RfsdInitializeVcb: Flink = %xh McbList = %xh\n",
                              Vcb->McbList.Flink, &(Vcb->McbList.Flink)));

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

        if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) {
            SetFlag(Vcb->Flags, VCB_REMOVABLE_MEDIA);
        }

        if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) {
            SetFlag(Vcb->Flags, VCB_FLOPPY_DISK);
        }

        /*if (IsFlagOn(RfsdGlobal->Flags, RFSD_SUPPORT_WRITING)) {
            if ((IsFlagOn(RfsdSb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) ||
                  IsFlagOn(RfsdSb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_RECOVER) ||
                  IsFlagOn(RfsdSb->s_feature_compat, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) ) {
                if(IsFlagOn(RfsdGlobal->Flags, EXT3_FORCE_WRITING)) {
                    ClearFlag(Vcb->Flags, VCB_READ_ONLY);
                } else {
                    SetFlag(Vcb->Flags, VCB_READ_ONLY);
                }
            } else {
                ClearFlag(Vcb->Flags, VCB_READ_ONLY);
            }
        } else {
            SetFlag(Vcb->Flags, VCB_READ_ONLY);
        }*/
		  // RFSD will be read only.
		  SetFlag(Vcb->Flags, VCB_READ_ONLY);

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

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

        Vcb->Vpb = Vpb;

        Vcb->RealDevice = Vpb->RealDevice;
        Vpb->DeviceObject = VolumeDevice;

        {
            UNICODE_STRING      LabelName;
            OEM_STRING          OemName;

				

            LabelName.MaximumLength = 16 * 2;
            LabelName.Length    = 0;
            LabelName.Buffer    = Vcb->Vpb->VolumeLabel;

            RtlZeroMemory(LabelName.Buffer, LabelName.MaximumLength);

            VolumeLabelLength = 16;

            while( (VolumeLabelLength > 0) &&
                   ((s_volume_name[VolumeLabelLength-1] == '\0') ||
                    (s_volume_name[VolumeLabelLength-1] == ' ')) ) {
                VolumeLabelLength--;
            }

            OemName.Buffer =  s_volume_name;
            OemName.MaximumLength = 16;
            OemName.Length = VolumeLabelLength;

				templen = RtlOemStringToUnicodeSize(&OemName);

            Status = RfsdOEMToUnicode( &LabelName,
                                       &OemName );

            if (!NT_SUCCESS(Status)) {
                __leave;
            }

            Vpb->VolumeLabelLength = LabelName.Length;
        }

#if DISABLED
        Vpb->SerialNumber = ((ULONG*)RfsdSb->s_uuid)[0] + ((ULONG*)RfsdSb->s_uuid)[1] +
                            ((ULONG*)RfsdSb->s_uuid)[2] + ((ULONG*)RfsdSb->s_uuid)[3];
#endif

        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->SuperBlock = RfsdSb;
        
        Vcb->Header.NodeTypeCode = (USHORT) RFSDVCB;
        Vcb->Header.NodeByteSize = sizeof(RFSD_VCB);
        Vcb->Header.IsFastIoPossible = FastIoIsNotPossible;
        Vcb->Header.Resource = &(Vcb->MainResource);
        Vcb->Header.PagingIoResource = &(Vcb->PagingIoResource);

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

        DiskSize =
            Vcb->DiskGeometry.Cylinders.QuadPart *
            Vcb->DiskGeometry.TracksPerCylinder *
            Vcb->DiskGeometry.SectorsPerTrack *
            Vcb->DiskGeometry.BytesPerSector;

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

        IoctlSize = sizeof(ULONG);
        Status = RfsdDiskIoControl(
                TargetDevice,
                IOCTL_DISK_CHECK_VERIFY,
                NULL,
                0,
                &ChangeCount,
                &IoctlSize );

        if (!NT_SUCCESS(Status)) {
            __leave;
        }

        Vcb->ChangeCount = ChangeCount;

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

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

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

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

            CcInitializeCacheMap( Vcb->StreamObj,
                                  &FileSizes,
                                  TRUE,
                                  &(RfsdGlobal->CacheManagerNoOpCallbacks),
                                  Vcb );
        }
#if DISABLED	// IN FFFS TOO
        if (!RfsdLoadGroup(Vcb)) {
            Status = STATUS_UNSUCCESSFUL;
            __leave;
        }
#endif

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


        //
        // Now allocating the mcb for root ...
        //

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

        RootNode.Buffer = Buffer;
        RootNode.MaximumLength = RootNode.Length = 2;

        Vcb->McbTree = RfsdAllocateMcb( Vcb, &RootNode,
                            FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL);

        if (!Vcb->McbTree) {
            __leave;
        }

		// Set the root of the filesystem to the root directory's inode / stat data structure
		Vcb->McbTree->Key.k_dir_id = RFSD_ROOT_PARENT_ID;
		Vcb->McbTree->Key.k_objectid = RFSD_ROOT_OBJECT_ID;
		Vcb->McbTree->Key.k_offset = 0;
		Vcb->McbTree->Key.k_type   = RFSD_KEY_TYPE_v1_STAT_DATA;		

#ifdef DISABLED
        if (IsFlagOn(RfsdGlobal->Flags, RFSD_CHECKING_BITMAP)) {
            RfsdCheckBitmapConsistency(IrpContext, Vcb);
        }

        {
			ULONG   dwData[RFSD_BLOCK_TYPES] = {RFSD_NDIR_BLOCKS, 1, 1, 1};
            ULONG   dwMeta[RFSD_BLOCK_TYPES] = {0, 0, 0, 0};
            ULONG   i;

				KdPrint(("Reminder: " __FUNCTION__ ", dwData, dwMeta??\n"));

            for (i = 0; i < RFSD_BLOCK_TYPES; i++) {
                dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i);

                if (i > 0) {
                    dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2));
                }

                Vcb->dwData[i] = dwData[i];
                Vcb->dwMeta[i] = dwMeta[i];
            }
        }
#endif

        SetFlag(Vcb->Flags, VCB_INITIALIZED);

    } __finally {

        if (!NT_SUCCESS(Status)) {

            if (NotifySyncInitialized) {
                FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
            }

            if (Vcb->GroupDesc) {
                ExFreePool(Vcb->GroupDesc);
                // CcUnpinData(Vcb->GroupDescBcb);
                Vcb->GroupDesc = NULL;
            }

            if (Vcb->SuperBlock) {
                ExFreePool(Vcb->SuperBlock);
                Vcb->SuperBlock = NULL;
            }

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

    return Status;
}


VOID
RfsdFreeVcb (IN PRFSD_VCB Vcb )
{
    ASSERT(Vcb != NULL);
    
    ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
        (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
    
    FsRtlNotifyUninitializeSync(&Vcb->NotifySync);

    if (Vcb->StreamObj) {
        if (IsFlagOn(Vcb->StreamObj->Flags, FO_FILE_MODIFIED)) {
            IO_STATUS_BLOCK    IoStatus;

            CcFlushCache(&(Vcb->SectionObject), NULL, 0, &IoStatus);
            ClearFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED);
        }

        if (Vcb->StreamObj->PrivateCacheMap)
            RfsdSyncUninitializeCacheMap(Vcb->StreamObj);

        ObDereferenceObject(Vcb->StreamObj);
        Vcb->StreamObj = NULL;
    }

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

        DbgBreak();
   }
#endif

    FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs));

    RfsdFreeMcbTree(Vcb->McbTree);

    if (Vcb->GroupDesc) {
        ExFreePool(Vcb->GroupDesc);
        // CcUnpinData(Vcb->GroupDescBcb);
        Vcb->GroupDesc = NULL;
    }
    
    if (Vcb->SuperBlock) {
        ExFreePool(Vcb->SuperBlock);
        Vcb->SuperBlock = NULL;
    }

    ExDeleteResourceLite(&Vcb->McbResource);

    ExDeleteResourceLite(&Vcb->PagingIoResource);

    ExDeleteResourceLite(&Vcb->MainResource);

    IoDeleteDevice(Vcb->DeviceObject);
}


VOID
RfsdSyncUninitializeCacheMap (
    IN PFILE_OBJECT FileObject
    )
{
    CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent;
    NTSTATUS WaitStatus;
    LARGE_INTEGER RfsdLargeZero = {0,0};


    KeInitializeEvent( &UninitializeCompleteEvent.Event,
                       SynchronizationEvent,
                       FALSE);

    CcUninitializeCacheMap( FileObject,
                            &RfsdLargeZero,
                            &UninitializeCompleteEvent );

    WaitStatus = KeWaitForSingleObject( &UninitializeCompleteEvent.Event,
                                        Executive,
                                        KernelMode,
                                        FALSE,
                                        NULL);

    ASSERT (NT_SUCCESS(WaitStatus));
}

⌨️ 快捷键说明

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