📄 httpdisk.c
字号:
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()
NTSTATUS
HttpDiskReadWrite (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PIO_STACK_LOCATION io_stack;
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
if (!device_extension->media_in_device)
{
Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEDIA_IN_DEVICE;
}
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (io_stack->Parameters.Read.Length == 0)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
IoMarkIrpPending(Irp);
ExInterlockedInsertTailList(
&device_extension->list_head,
&Irp->Tail.Overlay.ListEntry,
&device_extension->list_lock
);
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
return STATUS_PENDING;
}
NTSTATUS
HttpDiskDeviceControl (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PIO_STACK_LOCATION io_stack;
NTSTATUS status;
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (!device_extension->media_in_device &&
io_stack->Parameters.DeviceIoControl.IoControlCode !=
IOCTL_HTTP_DISK_CONNECT)
{
Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEDIA_IN_DEVICE;
}
switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_HTTP_DISK_CONNECT:
{
if (device_extension->media_in_device)
{
DbgPrint("HttpDisk: IOCTL_HTTP_DISK_CONNECT: Media already opened.\n");
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
break;
}
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(HTTP_DISK_INFORMATION))
{
status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(HTTP_DISK_INFORMATION) +
((PHTTP_DISK_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->FileNameLength -
sizeof(UCHAR))
{
status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
IoMarkIrpPending(Irp);
ExInterlockedInsertTailList(
&device_extension->list_head,
&Irp->Tail.Overlay.ListEntry,
&device_extension->list_lock
);
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
status = STATUS_PENDING;
break;
}
case IOCTL_HTTP_DISK_DISCONNECT:
{
IoMarkIrpPending(Irp);
ExInterlockedInsertTailList(
&device_extension->list_head,
&Irp->Tail.Overlay.ListEntry,
&device_extension->list_lock
);
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
status = STATUS_PENDING;
break;
}
case IOCTL_DISK_CHECK_VERIFY:
case IOCTL_CDROM_CHECK_VERIFY:
case IOCTL_STORAGE_CHECK_VERIFY:
case IOCTL_STORAGE_CHECK_VERIFY2:
{
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
}
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
{
PDISK_GEOMETRY disk_geometry;
ULONGLONG length;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DISK_GEOMETRY))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
disk_geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
length = device_extension->file_size.QuadPart;
disk_geometry->Cylinders.QuadPart = length / SECTOR_SIZE / 32 / 2;
disk_geometry->MediaType = FixedMedia;
disk_geometry->TracksPerCylinder = 2;
disk_geometry->SectorsPerTrack = 32;
disk_geometry->BytesPerSector = SECTOR_SIZE;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
break;
}
case IOCTL_DISK_GET_LENGTH_INFO:
{
PGET_LENGTH_INFORMATION get_length_information;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(GET_LENGTH_INFORMATION))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
get_length_information = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
get_length_information->Length.QuadPart = device_extension->file_size.QuadPart;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
break;
}
case IOCTL_DISK_GET_PARTITION_INFO:
{
PPARTITION_INFORMATION partition_information;
ULONGLONG length;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARTITION_INFORMATION))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
partition_information = (PPARTITION_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
length = device_extension->file_size.QuadPart;
partition_information->StartingOffset.QuadPart = 0;
partition_information->PartitionLength.QuadPart = length;
partition_information->HiddenSectors = 1;
partition_information->PartitionNumber = 0;
partition_information->PartitionType = 0;
partition_information->BootIndicator = FALSE;
partition_information->RecognizedPartition = FALSE;
partition_information->RewritePartition = FALSE;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
break;
}
case IOCTL_DISK_GET_PARTITION_INFO_EX:
{
PPARTITION_INFORMATION_EX partition_information_ex;
ULONGLONG length;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARTITION_INFORMATION_EX))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
partition_information_ex = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer;
length = device_extension->file_size.QuadPart;
partition_information_ex->PartitionStyle = PARTITION_STYLE_MBR;
partition_information_ex->StartingOffset.QuadPart = 0;
partition_information_ex->PartitionLength.QuadPart = length;
partition_information_ex->PartitionNumber = 0;
partition_information_ex->RewritePartition = FALSE;
partition_information_ex->Mbr.PartitionType = 0;
partition_information_ex->Mbr.BootIndicator = FALSE;
partition_information_ex->Mbr.RecognizedPartition = FALSE;
partition_information_ex->Mbr.HiddenSectors = 1;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
break;
}
case IOCTL_DISK_IS_WRITABLE:
{
status = STATUS_MEDIA_WRITE_PROTECTED;
Irp->IoStatus.Information = 0;
break;
}
case IOCTL_DISK_MEDIA_REMOVAL:
case IOCTL_STORAGE_MEDIA_REMOVAL:
{
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
}
case IOCTL_CDROM_READ_TOC:
{
PCDROM_TOC cdrom_toc;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(CDROM_TOC))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
cdrom_toc = (PCDROM_TOC) Irp->AssociatedIrp.SystemBuffer;
RtlZeroMemory(cdrom_toc, sizeof(CDROM_TOC));
cdrom_toc->FirstTrack = 1;
cdrom_toc->LastTrack = 1;
cdrom_toc->TrackData[0].Control = TOC_DATA_TRACK;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(CDROM_TOC);
break;
}
case IOCTL_DISK_SET_PARTITION_INFO:
{
status = STATUS_MEDIA_WRITE_PROTECTED;
Irp->IoStatus.Information = 0;
break;
}
case IOCTL_DISK_VERIFY:
{
PVERIFY_INFORMATION verify_information;
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(VERIFY_INFORMATION))
{
status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
verify_information = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = verify_information->Length;
break;
}
default:
{
KdPrint((
"HttpDisk: Unknown IoControlCode: %#x\n",
io_stack->Parameters.DeviceIoControl.IoControlCode
));
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
}
}
if (status != STATUS_PENDING)
{
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return status;
}
#pragma code_seg("PAGE")
VOID
HttpDiskThread (
IN PVOID Context
)
{
PDEVICE_OBJECT device_object;
PDEVICE_EXTENSION device_extension;
PLIST_ENTRY request;
PIRP irp;
PIO_STACK_LOCATION io_stack;
ASSERT(Context != NULL);
device_object = (PDEVICE_OBJECT) Context;
device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
for (;;)
{
KeWaitForSingleObject(
&device_extension->request_event,
Executive,
KernelMode,
FALSE,
NULL
);
if (device_extension->terminate_thread)
{
PsTerminateSystemThread(STATUS_SUCCESS);
}
while (request = ExInterlockedRemoveHeadList(
&device_extension->list_head,
&device_extension->list_lock
))
{
irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry);
io_stack = IoGetCurrentIrpStackLocation(irp);
switch (io_stack->MajorFunction)
{
case IRP_MJ_READ:
HttpDiskGetBlock(
&device_extension->socket,
device_extension->address,
device_extension->port,
device_extension->host_name,
device_extension->file_name,
&io_stack->Parameters.Read.ByteOffset,
io_stack->Parameters.Read.Length,
&irp->IoStatus,
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority)
);
if (!NT_SUCCESS(irp->IoStatus.Status))
{
HttpDiskGetBlock(
&device_extension->socket,
device_extension->address,
device_extension->port,
device_extension->host_name,
device_extension->file_name,
&io_stack->Parameters.Read.ByteOffset,
io_stack->Parameters.Read.Length,
&irp->IoStatus,
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority)
);
}
break;
case IRP_MJ_WRITE:
irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
irp->IoStatus.Information = 0;
break;
case IRP_MJ_DEVICE_CONTROL:
switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_HTTP_DISK_CONNECT:
irp->IoStatus.Status = HttpDiskConnect(device_object, irp);
break;
case IOCTL_HTTP_DISK_DISCONNECT:
irp->IoStatus.Status = HttpDiskDisconnect(device_object, irp);
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
}
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
}
IoCompleteRequest(
irp,
(CCHAR) (NT_SUCCESS(irp->IoStatus.Status) ?
IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
}
}
}
NTSTATUS
HttpDiskConnect (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PHTTP_DISK_INFORMATION http_disk_information;
HTTP_HEADER http_header;
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
http_disk_information = (PHTTP_DISK_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
device_extension->address = http_disk_information->Address;
device_extension->port = http_disk_information->Port;
device_extension->host_name = ExAllocatePool(NonPagedPool, http_disk_information->HostNameLength + 1);
if (device_extension->host_name == NULL)
{
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
return Irp->IoStatus.Status;
}
RtlCopyMemory(
device_extension->host_name,
http_disk_information->HostName,
http_disk_information->HostNameLength
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -