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

📄 ramdisk.c

📁 本软件是一款可以把内存模拟为硬盘的驱动程序.
💻 C
📖 第 1 页 / 共 3 页
字号:

    rtlQueryRegTbl[1].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[1].Name          = L"BreakOnEntry";
    rtlQueryRegTbl[1].EntryContext  = &BreakOnEntry;
    rtlQueryRegTbl[1].DefaultType   = REG_DWORD;
    rtlQueryRegTbl[1].DefaultData   = &defDebugRegInfo.BreakOnEntry;
    rtlQueryRegTbl[1].DefaultLength = sizeof(ULONG);

    rtlQueryRegTbl[2].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[2].Name          = L"DebugLevel";
    rtlQueryRegTbl[2].EntryContext  = &DbgLevel;
    rtlQueryRegTbl[2].DefaultType   = REG_DWORD;
    rtlQueryRegTbl[2].DefaultData   = &defDebugRegInfo.DebugLevel;
    rtlQueryRegTbl[2].DefaultLength = sizeof(ULONG);

    rtlQueryRegTbl[3].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[3].Name          = L"DebugComp";
    rtlQueryRegTbl[3].EntryContext  = &DbgComp;
    rtlQueryRegTbl[3].DefaultType   = REG_DWORD;
    rtlQueryRegTbl[3].DefaultData   = &defDebugRegInfo.DebugComp;
    rtlQueryRegTbl[3].DefaultLength = sizeof(ULONG);

    status = RtlQueryRegistryValues(
                                    RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,    
                                    RegistryPath->Buffer,
                                    rtlQueryRegTbl,
                                    NULL,
                                    NULL
                                    );

    if ( !NT_SUCCESS( status ) ) {
        DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_WARN, ("RrlQueryRegistryValues returned 0x%x\n", status ) );
        BreakOnEntry = defDebugRegInfo.BreakOnEntry;
        DbgLevel     = defDebugRegInfo.DebugLevel;
        DbgComp      = defDebugRegInfo.DebugComp;
    }
    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("BreakOnEntry = 0x%lx\n", BreakOnEntry) );
    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("DebugLevel   = 0x%lx\n", DbgLevel) );
    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("DebugComp    = 0x%lx\n", DbgComp) );
    return;
}   // End of RamDiskDebugQueryRegParameters()

#endif

VOID
RamDiskQueryDiskRegParameters(
    IN PUNICODE_STRING RegistryPath,
    IN PDISK_INFO DiskRegInfo
    )
/*++

Routine Description:

    This routine is called from the DriverEntry to get the debug
    parameters from the registry. If the registry query fails, then
    default values are used.


Arguments:

    RegistryPath    - Points the service path to get the registry parameters

Return Value:

    None

--*/
{

    RTL_QUERY_REGISTRY_TABLE    rtlQueryRegTbl[ 5 + 1 ];  // Need 1 for NULL
    NTSTATUS                    status;
    DISK_INFO                   defDiskRegInfo;

    PAGED_CODE();

    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, ("QueryDiskRegParameters \n" ) );
    ASSERT( RegistryPath->Buffer != NULL );

    // Set the default values

    defDiskRegInfo.DiskSize          = DEFAULT_DISK_SIZE;
    defDiskRegInfo.RootDirEntries    = DEFAULT_ROOT_DIR_ENTRIES;
    defDiskRegInfo.SectorsPerCluster = DEFAULT_SECTORS_PER_CLUSTER;

    RtlInitUnicodeString( &defDiskRegInfo.DriveLetter, DEFAULT_DRIVE_LETTER );

    RtlZeroMemory( rtlQueryRegTbl, sizeof(rtlQueryRegTbl) );

    //
    // Setup the query table
    //

    rtlQueryRegTbl[0].Flags         = RTL_QUERY_REGISTRY_SUBKEY;
    rtlQueryRegTbl[0].Name          = L"Parameters";
    rtlQueryRegTbl[0].EntryContext  = NULL;
    rtlQueryRegTbl[0].DefaultType   = (ULONG)NULL;
    rtlQueryRegTbl[0].DefaultData   = NULL;
    rtlQueryRegTbl[0].DefaultLength = (ULONG)NULL;

    //
    // Disk paramters
    //

    rtlQueryRegTbl[1].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[1].Name          = L"DiskSize";
    rtlQueryRegTbl[1].EntryContext  = &DiskRegInfo->DiskSize;
    rtlQueryRegTbl[1].DefaultType   = REG_DWORD;
    rtlQueryRegTbl[1].DefaultData   = &defDiskRegInfo.DiskSize;
    rtlQueryRegTbl[1].DefaultLength = sizeof(ULONG);

    rtlQueryRegTbl[2].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[2].Name          = L"RootDirEntries";
    rtlQueryRegTbl[2].EntryContext  = &DiskRegInfo->RootDirEntries;
    rtlQueryRegTbl[2].DefaultType   = REG_DWORD;
    rtlQueryRegTbl[2].DefaultData   = &defDiskRegInfo.RootDirEntries;
    rtlQueryRegTbl[2].DefaultLength = sizeof(ULONG);

    rtlQueryRegTbl[3].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[3].Name          = L"SectorsPerCluster";
    rtlQueryRegTbl[3].EntryContext  = &DiskRegInfo->SectorsPerCluster;
    rtlQueryRegTbl[3].DefaultType   = REG_DWORD;
    rtlQueryRegTbl[3].DefaultData   = &defDiskRegInfo.SectorsPerCluster;
    rtlQueryRegTbl[3].DefaultLength = sizeof(ULONG);

    rtlQueryRegTbl[4].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[4].Name          = L"DriveLetter";
    rtlQueryRegTbl[4].EntryContext  = &DiskRegInfo->DriveLetter;
    rtlQueryRegTbl[4].DefaultType   = REG_SZ;
    rtlQueryRegTbl[4].DefaultData   = defDiskRegInfo.DriveLetter.Buffer;
    rtlQueryRegTbl[4].DefaultLength = 0;


    status = RtlQueryRegistryValues(
                                    RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,    
                                    RegistryPath->Buffer,
                                    rtlQueryRegTbl,
                                    NULL,
                                    NULL
                                    );

    if ( !NT_SUCCESS( status ) ) {
        DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_WARN, ("RrlQueryRegistryValues returned 0x%x\n", status ) );
        DiskRegInfo->DiskSize          = defDiskRegInfo.DiskSize;
        DiskRegInfo->RootDirEntries    = defDiskRegInfo.RootDirEntries;
        DiskRegInfo->SectorsPerCluster = defDiskRegInfo.SectorsPerCluster;
        RtlCopyUnicodeString( &DiskRegInfo->DriveLetter, &defDiskRegInfo.DriveLetter );
    }

    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("DiskSize          = 0x%lx\n", DiskRegInfo->DiskSize) );
    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("RootDirEntries    = 0x%lx\n", DiskRegInfo->RootDirEntries) );
    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("SectorsPerCluster = 0x%lx\n", DiskRegInfo->SectorsPerCluster) );
    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("DriveLetter       = %wZ\n",   &(DiskRegInfo->DriveLetter)) );
    return;
}   // End of RamDiskQueryRegParameters()


NTSTATUS
RamDiskFormatDisk(
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This routine formats the new disk.


Arguments:

    DeviceObject - Supplies a pointer to the device object that represents
                   the device whose capacity is to be read.

Return Value:

    status is returned.

--*/
{

    PDEVICE_EXTENSION   devExt = DeviceObject->DeviceExtension;
    PBOOT_SECTOR        bootSector = (PBOOT_SECTOR) devExt->DiskImage;
    PUCHAR              firstFatSector;
    ULONG               rootDirEntries;
    ULONG               sectorsPerCluster;
    USHORT              fatType;        // Type FAT 12 or 16
    USHORT              fatEntries;     // Number of cluster entries in FAT
    USHORT              fatSectorCnt;   // Number of sectors for FAT
    PDIR_ENTRY          rootDir;        // Pointer to first entry in root dir
    NTSTATUS            status = STATUS_SUCCESS;

    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, ("FormatDisk\n" ) );

    PAGED_CODE();
    ASSERT( sizeof(BOOT_SECTOR) == 512);
    ASSERT( devExt->DiskImage != NULL );

    RtlZeroMemory( devExt->DiskImage, devExt->DiskRegInfo.DiskSize );

    devExt->DiskGeometry.BytesPerSector = 512;
    devExt->DiskGeometry.SectorsPerTrack = 32;     // Using Ramdisk value
    devExt->DiskGeometry.TracksPerCylinder = 2;    // Using Ramdisk value
    
    //
    // Calculate number of cylinders.
    //

    devExt->DiskGeometry.Cylinders.QuadPart = (__int64)devExt->DiskRegInfo.DiskSize / devExt->DiskGeometry.BytesPerSector    /
                                                                                      devExt->DiskGeometry.SectorsPerTrack   / 
                                                                                      devExt->DiskGeometry.TracksPerCylinder ;

    
    if ( devExt->DiskGeometry.Cylinders.QuadPart > 1023 )
    {
        devExt->DiskGeometry.SectorsPerTrack = 64;     // Using Ramdisk value
        devExt->DiskGeometry.Cylinders.QuadPart = (__int64)devExt->DiskRegInfo.DiskSize / devExt->DiskGeometry.BytesPerSector    /
                                                                                          devExt->DiskGeometry.SectorsPerTrack   / 
                                                                                          devExt->DiskGeometry.TracksPerCylinder ;
    }

    if ( ( (ULONGLONG)devExt->DiskRegInfo.SectorsPerCluster * (ULONGLONG)((ULONG)65536 * 512 )) <  (ULONGLONG)devExt->DiskRegInfo.DiskSize  )
    {
        devExt->DiskRegInfo.SectorsPerCluster = ( devExt->DiskRegInfo.DiskSize - 1 ) / ( (ULONG)65536 * 512 ) + 1 ; 
    }
    // round up to the next power of 2
    {
        ULONG    _SectorsPerCluster = 2 ;
        devExt->DiskRegInfo.SectorsPerCluster &= 0x7FFFFFFF ; // safety first 
        while ( devExt->DiskRegInfo.SectorsPerCluster > _SectorsPerCluster ) _SectorsPerCluster = _SectorsPerCluster << 1 ; 
        devExt->DiskRegInfo.SectorsPerCluster = _SectorsPerCluster ;
    }


    //
    // Our media type is RAMDISK_MEDIA_TYPE
    //

//  devExt->DiskGeometry.MediaType = RAMDISK_MEDIA_TYPE ; 
    devExt->DiskGeometry.MediaType = FixedMedia         ; 

    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, 
        ("Cylinders: %d\n TracksPerCylinder: %d\n SectorsPerTrack: %d\n BytesPerSector: %d\n", 
        (ULONG)devExt->DiskGeometry.Cylinders.QuadPart, devExt->DiskGeometry.TracksPerCylinder,
        devExt->DiskGeometry.SectorsPerTrack, devExt->DiskGeometry.BytesPerSector ) );

    rootDirEntries = devExt->DiskRegInfo.RootDirEntries;
    sectorsPerCluster = devExt->DiskRegInfo.SectorsPerCluster;

    //
    // Round Root Directory entries up if necessary
    //
    if (rootDirEntries & (DIR_ENTRIES_PER_SECTOR - 1)) {
        DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_WARN, ("Adjusting RootDirEntries \n" ) );

        rootDirEntries =
            (rootDirEntries + ( DIR_ENTRIES_PER_SECTOR - 1 )) &
                ~ ( DIR_ENTRIES_PER_SECTOR - 1 );
    }

    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, 
        ("Root dir entries: %ld\n Sectors/cluster: %ld\n", 
        rootDirEntries, sectorsPerCluster ) );
    //
    // We need to have the 0xeb and 0x90 since this is one of the
    // checks the file system recognizer uses
    //
    bootSector->bsJump[0] = 0xeb;
    bootSector->bsJump[1] = 0x3c;
    bootSector->bsJump[2] = 0x90;

    strncpy(bootSector->bsOemName, "QSoftRam ", 8);
    bootSector->bsBytesPerSec = (USHORT)devExt->DiskGeometry.BytesPerSector;
    bootSector->bsResSectors  = 1;
    bootSector->bsFATs        = 1;
    bootSector->bsRootDirEnts = (USHORT)rootDirEntries;

//  bootSector->bsSectors     = (USHORT)( devExt->DiskRegInfo.DiskSize / devExt->DiskGeometry.BytesPerSector );
    bootSector->bsHugeSectors = devExt->DiskRegInfo.DiskSize / devExt->DiskGeometry.BytesPerSector ;

    bootSector->bsMedia       = RAMDISK_MEDIA_TYPE ;       // (UCHAR) devExt->DiskGeometry.MediaType;
    bootSector->bsSecPerClus  = (UCHAR)sectorsPerCluster;

    //
    // Calculate number of sectors required for FAT
    //
    fatEntries = (USHORT)( ( bootSector->bsHugeSectors - bootSector->bsResSectors - bootSector->bsRootDirEnts / DIR_ENTRIES_PER_SECTOR) /
                             (ULONG)bootSector->bsSecPerClus + 2 ) ;

    //
    // Choose between 12 and 16 bit FAT based on number of clusters we
    // need to map
    //
    if (fatEntries > 4087) {
        fatType =  16;
        fatSectorCnt = (USHORT)(((ULONG)fatEntries * 2 + 511) / 512 ) ;
        fatEntries -= fatSectorCnt;
        fatSectorCnt = (USHORT)(((ULONG)fatEntries * 2 + 511) / 512 ) ;
    }
    else {
        fatType =  12;
        fatSectorCnt = (USHORT)(((((ULONG)fatEntries * 3 + 1) / 2) + 511) / 512 ) ;
        fatEntries -= fatSectorCnt;
        fatSectorCnt = (USHORT)(((((ULONG)fatEntries * 3 + 1) / 2) + 511) / 512 ) ;
    }

    if ( bootSector->bsHugeSectors < 0x10000 )
    {
        bootSector->bsSectors     = (USHORT)bootSector->bsHugeSectors ;
        bootSector->bsHugeSectors = 0 ;
    }
    

    bootSector->bsFATsecs       = fatSectorCnt;
    bootSector->bsSecPerTrack   = (USHORT)devExt->DiskGeometry.SectorsPerTrack;
    bootSector->bsHeads         = (USHORT)devExt->DiskGeometry.TracksPerCylinder;
    bootSector->bsBootSignature = 0x29;
    bootSector->bsVolumeID      = 0x12345678;
    strncpy(bootSector->bsLabel, "RamDisk    ", 11);
    strncpy(bootSector->bsFileSystemType, "FAT1?   ", 8);
    bootSector->bsFileSystemType[4] = ( fatType == 16 ) ? '6' : '2';

    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_WARN, ( "FatType = %s , bootSector->bsHugeSectors = %d , bootSector->bsSectors = %d \n" ,
                                               bootSector->bsFileSystemType  ,
                                               bootSector->bsHugeSectors     ,
                                               (ULONG)bootSector->bsSectors  ) );
    
    bootSector->bsSig2[0] = 0x55;
    bootSector->bsSig2[1] = 0xAA;
    
    //
    // The FAT is located immediately following the boot sector.
    //
    firstFatSector    = (PUCHAR)(bootSector + 1);
    firstFatSector[0] = (UCHAR)RAMDISK_MEDIA_TYPE ; // devExt->DiskGeometry.MediaType;
    firstFatSector[1] = 0xFF;
    firstFatSector[2] = 0xF0;

    if (fatType == 16) firstFatSector[2] = 0xFF;

    //
    // The Root Directory follows the FAT
    //
    rootDir = (PDIR_ENTRY)(bootSector + 1 + fatSectorCnt);
    strcpy(rootDir->deName, "RAMDisk ");
    strcpy(rootDir->deExtension, "   ");
    rootDir->deAttributes = DIR_ATTR_VOLUME;

    return status;
} // end RamDiskFormatDisk()



⌨️ 快捷键说明

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