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

📄 swapfs.c

📁 title=Windows NT/2000/XP 一个RAM-DISK文件系统驱动 memo=SwapFs is a driver for Windows NT/2000/XP that let yo
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -