📄 httpdisk.c
字号:
/*
HTTP Virtual Disk.
Copyright (C) 2006, 2008 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 <ntddcdrm.h>
#include <ntverp.h>
#include "ksocket.h"
//
// We include some stuff from newer DDK:s here so that one
// version of the driver for all versions of Windows can
// be compiled with the Windows NT 4.0 DDK.
//
#if (VER_PRODUCTBUILD < 2195)
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif // (VER_PRODUCTBUILD < 2195)
#if (VER_PRODUCTBUILD < 2600)
#define IOCTL_DISK_GET_PARTITION_INFO_EX CTL_CODE(IOCTL_DISK_BASE, 0x0012, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_GET_LENGTH_INFO CTL_CODE(IOCTL_DISK_BASE, 0x0017, METHOD_BUFFERED, FILE_READ_ACCESS)
typedef enum _PARTITION_STYLE {
PARTITION_STYLE_MBR,
PARTITION_STYLE_GPT
} PARTITION_STYLE;
typedef unsigned __int64 ULONG64, *PULONG64;
typedef struct _PARTITION_INFORMATION_MBR {
UCHAR PartitionType;
BOOLEAN BootIndicator;
BOOLEAN RecognizedPartition;
ULONG HiddenSectors;
} PARTITION_INFORMATION_MBR, *PPARTITION_INFORMATION_MBR;
typedef struct _PARTITION_INFORMATION_GPT {
GUID PartitionType;
GUID PartitionId;
ULONG64 Attributes;
WCHAR Name[36];
} PARTITION_INFORMATION_GPT, *PPARTITION_INFORMATION_GPT;
typedef struct _PARTITION_INFORMATION_EX {
PARTITION_STYLE PartitionStyle;
LARGE_INTEGER StartingOffset;
LARGE_INTEGER PartitionLength;
ULONG PartitionNumber;
BOOLEAN RewritePartition;
union {
PARTITION_INFORMATION_MBR Mbr;
PARTITION_INFORMATION_GPT Gpt;
};
} PARTITION_INFORMATION_EX, *PPARTITION_INFORMATION_EX;
typedef struct _GET_LENGTH_INFORMATION {
LARGE_INTEGER Length;
} GET_LENGTH_INFORMATION, *PGET_LENGTH_INFORMATION;
#endif // (VER_PRODUCTBUILD < 2600)
//
// For backward compatibility with Windows NT 4.0 by Bruce Engle.
//
#ifndef MmGetSystemAddressForMdlSafe
#define MmGetSystemAddressForMdlSafe(MDL, PRIORITY) MmGetSystemAddressForMdlPrettySafe(MDL)
PVOID
MmGetSystemAddressForMdlPrettySafe (
PMDL Mdl
)
{
CSHORT MdlMappingCanFail;
PVOID MappedSystemVa;
MdlMappingCanFail = Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL;
Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
MappedSystemVa = MmGetSystemAddressForMdl(Mdl);
if (MdlMappingCanFail == 0)
{
Mdl->MdlFlags &= ~MDL_MAPPING_CAN_FAIL;
}
return MappedSystemVa;
}
#endif
#include "httpdisk.h"
#define PARAMETER_KEY L"\\Parameters"
#define NUMBEROFDEVICES_VALUE L"NumberOfDevices"
#define DEFAULT_NUMBEROFDEVICES 4
#define SECTOR_SIZE 512
#define TOC_DATA_TRACK 0x04
#define BUFFER_SIZE (4096 * 4)
HANDLE dir_handle;
typedef struct _HTTP_HEADER {
LARGE_INTEGER ContentLength;
} HTTP_HEADER, *PHTTP_HEADER;
typedef struct _DEVICE_EXTENSION {
BOOLEAN media_in_device;
ULONG address;
USHORT port;
PUCHAR host_name;
PUCHAR file_name;
LARGE_INTEGER file_size;
int socket;
LIST_ENTRY list_head;
KSPIN_LOCK list_lock;
KEVENT request_event;
PVOID thread_pointer;
BOOLEAN terminate_thread;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
HttpDiskCreateDevice (
IN PDRIVER_OBJECT DriverObject,
IN ULONG Number,
IN DEVICE_TYPE DeviceType
);
VOID
HttpDiskUnload (
IN PDRIVER_OBJECT DriverObject
);
PDEVICE_OBJECT
HttpDiskDeleteDevice (
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
HttpDiskCreateClose (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
HttpDiskReadWrite (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
HttpDiskDeviceControl (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
HttpDiskThread (
IN PVOID Context
);
NTSTATUS
HttpDiskConnect (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
HttpDiskDisconnect (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
HttpDiskGetHeader (
IN ULONG Address,
IN USHORT Port,
IN PUCHAR HostName,
IN PUCHAR FileName,
OUT PIO_STATUS_BLOCK IoStatus,
OUT PHTTP_HEADER HttpHeader
);
NTSTATUS
HttpDiskGetBlock (
IN int *Socket,
IN ULONG Address,
IN USHORT Port,
IN PUCHAR HostName,
IN PUCHAR FileName,
IN PLARGE_INTEGER Offset,
IN ULONG Length,
OUT PIO_STATUS_BLOCK IoStatus,
OUT PVOID SystemBuffer
);
__int64 __cdecl _atoi64(const char *);
int __cdecl _snprintf(char *, size_t, const char *, ...);
int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
#pragma code_seg("INIT")
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
UNICODE_STRING parameter_path;
RTL_QUERY_REGISTRY_TABLE query_table[2];
ULONG n_devices;
NTSTATUS status;
UNICODE_STRING device_dir_name;
OBJECT_ATTRIBUTES object_attributes;
ULONG n;
USHORT n_created_devices;
parameter_path.Length = 0;
parameter_path.MaximumLength = RegistryPath->Length + sizeof(PARAMETER_KEY);
parameter_path.Buffer = (PWSTR) ExAllocatePool(PagedPool, parameter_path.MaximumLength);
if (parameter_path.Buffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(¶meter_path, RegistryPath);
RtlAppendUnicodeToString(¶meter_path, PARAMETER_KEY);
RtlZeroMemory(&query_table[0], sizeof(query_table));
query_table[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
query_table[0].Name = NUMBEROFDEVICES_VALUE;
query_table[0].EntryContext = &n_devices;
status = RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
parameter_path.Buffer,
&query_table[0],
NULL,
NULL
);
ExFreePool(parameter_path.Buffer);
if (!NT_SUCCESS(status))
{
DbgPrint("HttpDisk: Query registry failed, using default values.\n");
n_devices = DEFAULT_NUMBEROFDEVICES;
}
RtlInitUnicodeString(&device_dir_name, DEVICE_DIR_NAME);
InitializeObjectAttributes(
&object_attributes,
&device_dir_name,
OBJ_PERMANENT,
NULL,
NULL
);
status = ZwCreateDirectoryObject(
&dir_handle,
DIRECTORY_ALL_ACCESS,
&object_attributes
);
if (!NT_SUCCESS(status))
{
return status;
}
ZwMakeTemporaryObject(dir_handle);
for (n = 0, n_created_devices = 0; n < n_devices; n++)
{
status = HttpDiskCreateDevice(DriverObject, n, FILE_DEVICE_DISK);
if (NT_SUCCESS(status))
{
n_created_devices++;
}
}
for (n = 0; n < n_devices; n++)
{
status = HttpDiskCreateDevice(DriverObject, n, FILE_DEVICE_CD_ROM);
if (NT_SUCCESS(status))
{
n_created_devices++;
}
}
if (n_created_devices == 0)
{
ZwClose(dir_handle);
return status;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = HttpDiskCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = HttpDiskCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = HttpDiskReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = HttpDiskReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HttpDiskDeviceControl;
DriverObject->DriverUnload = HttpDiskUnload;
return STATUS_SUCCESS;
}
NTSTATUS
HttpDiskCreateDevice (
IN PDRIVER_OBJECT DriverObject,
IN ULONG Number,
IN DEVICE_TYPE DeviceType
)
{
WCHAR device_name_buffer[MAXIMUM_FILENAME_LENGTH];
UNICODE_STRING device_name;
NTSTATUS status;
PDEVICE_OBJECT device_object;
PDEVICE_EXTENSION device_extension;
HANDLE thread_handle;
ASSERT(DriverObject != NULL);
if (DeviceType == FILE_DEVICE_CD_ROM)
{
swprintf(
device_name_buffer,
DEVICE_NAME_PREFIX L"Cd" L"%u",
Number
);
}
else
{
swprintf(
device_name_buffer,
DEVICE_NAME_PREFIX L"Disk" L"%u",
Number
);
}
RtlInitUnicodeString(&device_name, device_name_buffer);
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&device_name,
DeviceType,
0,
FALSE,
&device_object
);
if (!NT_SUCCESS(status))
{
return status;
}
device_object->Flags |= DO_DIRECT_IO;
device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
device_extension->media_in_device = FALSE;
device_extension->host_name = NULL;
device_extension->file_name = NULL;
device_extension->socket = -1;
device_object->Characteristics |= FILE_READ_ONLY_DEVICE;
InitializeListHead(&device_extension->list_head);
KeInitializeSpinLock(&device_extension->list_lock);
KeInitializeEvent(
&device_extension->request_event,
SynchronizationEvent,
FALSE
);
device_extension->terminate_thread = FALSE;
status = PsCreateSystemThread(
&thread_handle,
(ACCESS_MASK) 0L,
NULL,
NULL,
NULL,
HttpDiskThread,
device_object
);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(device_object);
return status;
}
status = ObReferenceObjectByHandle(
thread_handle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&device_extension->thread_pointer,
NULL
);
if (!NT_SUCCESS(status))
{
ZwClose(thread_handle);
device_extension->terminate_thread = TRUE;
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
IoDeleteDevice(device_object);
return status;
}
ZwClose(thread_handle);
return STATUS_SUCCESS;
}
#pragma code_seg("PAGE")
VOID
HttpDiskUnload (
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT device_object;
device_object = DriverObject->DeviceObject;
while (device_object)
{
device_object = HttpDiskDeleteDevice(device_object);
}
ZwClose(dir_handle);
}
PDEVICE_OBJECT
HttpDiskDeleteDevice (
IN PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION device_extension;
PDEVICE_OBJECT next_device_object;
ASSERT(DeviceObject != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
device_extension->terminate_thread = TRUE;
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
KeWaitForSingleObject(
device_extension->thread_pointer,
Executive,
KernelMode,
FALSE,
NULL
);
ObDereferenceObject(device_extension->thread_pointer);
next_device_object = DeviceObject->NextDevice;
IoDeleteDevice(DeviceObject);
return next_device_object;
}
NTSTATUS
HttpDiskCreateClose (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
#pragma code_seg()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -