📄 mkdosfs.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 + -