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

📄 mkdosfs.c

📁 title=Windows NT/2000/XP 一个RAM-DISK文件系统驱动 memo=SwapFs is a driver for Windows NT/2000/XP that let yo
💻 C
字号:
/*
    Function to format a device to FAT.
    Copyright (C) 1999-2002 Bo Brant閚.
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <ntddk.h>
#include <ntdddisk.h>
#include "swapfs.h"
#include "swap.h"
#include "mkdosfs.h"

#define ROOT_DIR_ENTRYS 512

#pragma alloc_text(INIT, SwapFsFormatDeviceToFat)

NTSTATUS
SwapFsFormatDeviceToFat (
    IN PDEVICE_OBJECT DeviceObject
    )
{
    ULONG                       size;
    NTSTATUS                    status;
    DISK_GEOMETRY               disk_geometry;
    PARTITION_INFORMATION       partition_information;
    USHORT                      sector_size;
    PUCHAR                      buffer;
    struct msdos_boot_sector*   boot_sector;
    ULONG                       nsector;
    ULONG                       ncluster;
    ULONG                       fat_type;
    ULONG                       fat_length;
    LARGE_INTEGER               offset;
    ULONG                       n;
    struct msdos_dir_entry*     root_dir;

    ASSERT(DeviceObject != NULL);

    size = sizeof(disk_geometry);

    status = BlockDeviceIoControl(
        DeviceObject,
        IOCTL_DISK_GET_DRIVE_GEOMETRY,
        NULL,
        0,
        &disk_geometry,
        &size
        );

    if (!NT_SUCCESS(status))
    {
        return status;
    }

    size = sizeof(partition_information);

    status = BlockDeviceIoControl(
        DeviceObject,
        IOCTL_DISK_GET_PARTITION_INFO,
        NULL,
        0,
        &partition_information,
        &size
        );

    if (!NT_SUCCESS(status))
    {
        return status;
    }

    sector_size = (USHORT) disk_geometry.BytesPerSector;

    if (!sector_size)
    {
        return STATUS_DEVICE_CONFIGURATION_ERROR;
    }

    buffer = (PUCHAR) ExAllocatePool(NonPagedPoolCacheAligned, sector_size);

    if (!buffer)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(buffer, sector_size);

    boot_sector = (struct msdos_boot_sector*) buffer;

    boot_sector->boot_jump[0] = 0xeb;
    boot_sector->boot_jump[1] = 0x3c;
    boot_sector->boot_jump[2] = 0x90;

    RtlCopyMemory(boot_sector->system_id, "SwapFs  ", 8);

    *(PUSHORT)boot_sector->sector_size = sector_size;

    boot_sector->reserved = 1;

    boot_sector->fats = 1;

    *(PUSHORT)boot_sector->dir_entries = ROOT_DIR_ENTRYS;

    nsector = (ULONG) ((partition_information.PartitionLength.QuadPart -
        sizeof(union swap_header)) / sector_size);

    if (nsector <= 0xffff)
    {
        *(PUSHORT)boot_sector->sectors = (USHORT) nsector;
    }
    else
    {
        boot_sector->total_sect = nsector;
    }

    boot_sector->cluster_size = 1;
    ncluster = nsector;

    while (ncluster > 0xffff && boot_sector->cluster_size <= 128)
    {
        boot_sector->cluster_size <<= 1;
        ncluster = nsector / boot_sector->cluster_size;
    }

    boot_sector->media = 0xf8;

    if (ncluster > 4087)
    {
        fat_type = 16;

        fat_length = (ncluster * 2 + sector_size - 1) / sector_size;

        RtlCopyMemory(boot_sector->fs_type, MSDOS_FAT16_SIGN, 8);
    }
    else
    {
        fat_type = 12;

        fat_length = (((ncluster * 3 + 1) / 2) + sector_size - 1) / sector_size;

        RtlCopyMemory(boot_sector->fs_type, MSDOS_FAT12_SIGN, 8);
    }

    boot_sector->fat_length = (USHORT) fat_length;

    boot_sector->secs_track = (USHORT) disk_geometry.SectorsPerTrack;

    boot_sector->heads = (USHORT) disk_geometry.TracksPerCylinder;

    boot_sector->ext_boot_sign = MSDOS_EXT_SIGN;

    *(PULONG)boot_sector->volume_id = 0x12345678;

    RtlCopyMemory(boot_sector->volume_label, "SwapFs     ", 11);

    boot_sector->boot_sign = BOOT_SIGN;

    offset.QuadPart = sizeof(union swap_header);

    status = WriteBlockDevice(
        DeviceObject,
        &offset,
        sector_size,
        buffer
        );

    if (!NT_SUCCESS(status))
    {
        ExFreePool(buffer);
        return status;
    }

    RtlZeroMemory(buffer, sector_size);

    buffer[0] = 0xf8;
    buffer[1] = 0xff;
    buffer[2] = 0xff;

    if (fat_type == 16)
    {
        buffer[3] = 0xff;
    }

    offset.QuadPart += sector_size;

    status = WriteBlockDevice(
        DeviceObject,
        &offset,
        sector_size,
        buffer
        );

    if (!NT_SUCCESS(status))
    {
        ExFreePool(buffer);
        return status;
    }

    RtlZeroMemory(buffer, sector_size);

    offset.QuadPart += sector_size;

    for (n = 0;
         n < fat_length - 1;
         n++, offset.QuadPart += sector_size
        )
    {
        status = WriteBlockDevice(
            DeviceObject,
            &offset,
            sector_size,
            buffer
            );

        if (!NT_SUCCESS(status))
        {
            ExFreePool(buffer);
            return status;
        }
    }

    root_dir = (struct msdos_dir_entry*) buffer;

    RtlCopyMemory(root_dir->name, "SwapFs  ", 8);
    RtlCopyMemory(root_dir->ext, "   ", 3);
    root_dir->attr = ATTR_VOLUME;

    status = WriteBlockDevice(
        DeviceObject,
        &offset,
        sector_size,
        buffer
        );

    if (!NT_SUCCESS(status))
    {
        ExFreePool(buffer);
        return status;
    }

    RtlZeroMemory(buffer, sector_size);

    offset.QuadPart += sector_size;

    for (n = 0;
         n < (sizeof(struct msdos_dir_entry) * ROOT_DIR_ENTRYS / sector_size);
         n++, offset.QuadPart += sector_size
        )
    {
        status = WriteBlockDevice(
            DeviceObject,
            &offset,
            sector_size,
            buffer
            );

        if (!NT_SUCCESS(status))
        {
            ExFreePool(buffer);
            return status;
        }
    }

    ExFreePool(buffer);

    KdPrint(("SwapFs: FormatDeviceToFat: Device is %uMB\n",
        (ULONG) ((partition_information.PartitionLength.QuadPart -
        sizeof(union swap_header)) / 0x100000)));

    return STATUS_SUCCESS;
}

⌨️ 快捷键说明

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