📄 swapfs.c
字号:
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 = DeviceIoControl(
DeviceObject,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&disk_geometry,
&size
);
if (!NT_SUCCESS(status))
{
return status;
}
size = sizeof(partition_information);
status = DeviceIoControl(
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;
}
NTSTATUS
DeviceIoControl (
IN PDEVICE_OBJECT DeviceObject,
IN ULONG IoctlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
OUT PVOID OutputBuffer,
OUT PULONG OutputBufferSize
)
{
ULONG output_buffer_size;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK io_status;
NTSTATUS status;
ASSERT(DeviceObject != NULL);
if (OutputBuffer)
{
ASSERT(OutputBufferSize != NULL);
output_buffer_size = *OutputBufferSize;
}
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(
IoctlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
output_buffer_size,
FALSE,
&event,
&io_status
);
if (!irp)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL
);
status = io_status.Status;
}
if (OutputBuffer)
{
*OutputBufferSize = io_status.Information;
}
return status;
}
NTSTATUS
ReadBlockDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PLARGE_INTEGER Offset,
IN ULONG Length,
OUT PVOID Buffer
)
{
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK io_status;
NTSTATUS status;
ASSERT(DeviceObject != NULL);
ASSERT(Offset != NULL);
ASSERT(Buffer != NULL);
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildSynchronousFsdRequest(
IRP_MJ_READ,
DeviceObject,
Buffer,
Length,
Offset,
&event,
&io_status
);
if (!irp)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL
);
status = io_status.Status;
}
return status;
}
NTSTATUS
WriteBlockDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PLARGE_INTEGER Offset,
IN ULONG Length,
IN PVOID Buffer
)
{
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK io_status;
NTSTATUS status;
ASSERT(DeviceObject != NULL);
ASSERT(Offset != NULL);
ASSERT(Buffer != NULL);
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildSynchronousFsdRequest(
IRP_MJ_WRITE,
DeviceObject,
Buffer,
Length,
Offset,
&event,
&io_status
);
if (!irp)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL
);
status = io_status.Status;
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -