📄 httpdisk.c
字号:
device_extension->file_name,
&Irp->IoStatus,
&http_header
);
if (!NT_SUCCESS(Irp->IoStatus.Status))
{
HttpDiskGetHeader(
device_extension->address,
device_extension->port,
device_extension->host_name,
device_extension->file_name,
&Irp->IoStatus,
&http_header
);
}
if (!NT_SUCCESS(Irp->IoStatus.Status))
{
if (device_extension->host_name != NULL)
{
ExFreePool(device_extension->host_name);
device_extension->host_name = NULL;
}
if (device_extension->file_name != NULL)
{
ExFreePool(device_extension->file_name);
device_extension->file_name = NULL;
}
return Irp->IoStatus.Status;
}
device_extension->file_size.QuadPart = http_header.ContentLength.QuadPart;
device_extension->media_in_device = TRUE;
return Irp->IoStatus.Status;
}
NTSTATUS
HttpDiskDisconnect (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
device_extension->media_in_device = FALSE;
if (device_extension->host_name != NULL)
{
ExFreePool(device_extension->host_name);
device_extension->host_name = NULL;
}
if (device_extension->file_name != NULL)
{
ExFreePool(device_extension->file_name);
device_extension->file_name = NULL;
}
if (device_extension->socket > 0)
{
close(device_extension->socket);
device_extension->socket = -1;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
NTSTATUS
HttpDiskGetHeader (
IN ULONG Address,
IN USHORT Port,
IN PUCHAR HostName,
IN PUCHAR FileName,
OUT PIO_STATUS_BLOCK IoStatus,
OUT PHTTP_HEADER HttpHeader
)
{
int kSocket;
struct sockaddr_in toAddr;
int status, nSent, nRecv;
char *request, *buffer, *pStr;
ASSERT(HostName != NULL);
ASSERT(FileName != NULL);
ASSERT(IoStatus != NULL);
ASSERT(HttpHeader != NULL);
request = ExAllocatePool(PagedPool, PAGE_SIZE);
if (request == NULL)
{
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return IoStatus->Status;
}
buffer = ExAllocatePool(PagedPool, BUFFER_SIZE);
if (buffer == NULL)
{
ExFreePool(request);
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return IoStatus->Status;
}
kSocket = socket(AF_INET, SOCK_STREAM, 0);
if (kSocket < 0)
{
DbgPrint("HttpDisk: socket() error: %#x\n", kSocket);
ExFreePool(request);
ExFreePool(buffer);
IoStatus->Status = kSocket;
return IoStatus->Status;
}
toAddr.sin_family = AF_INET;
toAddr.sin_port = Port;
toAddr.sin_addr.s_addr = Address;
status = connect(kSocket, (struct sockaddr*) &toAddr, sizeof(toAddr));
if (status < 0)
{
DbgPrint("HttpDisk: connect() error: %#x\n", status);
ExFreePool(request);
ExFreePool(buffer);
close(kSocket);
IoStatus->Status = status;
return IoStatus->Status;
}
// Example request:
// HEAD 'FileName' HTTP/1.1
// Host: 'HostName'
// Accept: */*
// User-Agent: HttpDisk/1.4
// Connection: close
//
// Interesting lines in response:
// HTTP/1.1 200 OK
// Accept-Ranges: bytes
// Content-Length: 'total file size'
_snprintf(
request,
PAGE_SIZE,
"HEAD %s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\nUser-Agent: HttpDisk/1.4\r\nConnection: close\r\n\r\n",
FileName,
HostName
);
nSent = send(kSocket, request, strlen(request), 0);
if (nSent < 0)
{
DbgPrint("HttpDisk: send() error: %#x\n", nSent);
ExFreePool(request);
ExFreePool(buffer);
close(kSocket);
IoStatus->Status = nSent;
return IoStatus->Status;
}
nRecv = recv(kSocket, buffer, BUFFER_SIZE, 0);
if (nRecv < 0)
{
DbgPrint("HttpDisk: recv() error: %#x\n", nRecv);
ExFreePool(request);
ExFreePool(buffer);
close(kSocket);
IoStatus->Status = nRecv;
return IoStatus->Status;
}
close(kSocket);
buffer[BUFFER_SIZE - 1] = '\0';
if (_strnicmp(buffer, "HTTP/1.1 200 OK", 15))
{
DbgPrint("HttpDisk: Invalid HTTP response:\n%s", buffer);
DbgPrint("HttpDisk: Request was:\n%s", request);
ExFreePool(request);
ExFreePool(buffer);
IoStatus->Status = STATUS_NO_SUCH_FILE;
return IoStatus->Status;
}
pStr = strstr(buffer, "Content-Length:");
if (pStr == NULL || pStr + 16 >= buffer + BUFFER_SIZE)
{
DbgPrint("HttpDisk: Invalid HTTP response:\n%s", buffer);
DbgPrint("HttpDisk: Request was:\n%s", request);
ExFreePool(request);
ExFreePool(buffer);
IoStatus->Status = STATUS_NO_SUCH_FILE;
return IoStatus->Status;
}
HttpHeader->ContentLength.QuadPart = _atoi64(pStr + 16);
if (HttpHeader->ContentLength.QuadPart == 0)
{
DbgPrint("HttpDisk: Invalid HTTP response:\n%s", buffer);
DbgPrint("HttpDisk: Request was:\n%s", request);
ExFreePool(request);
ExFreePool(buffer);
IoStatus->Status = STATUS_NO_SUCH_FILE;
return IoStatus->Status;
}
ExFreePool(request);
ExFreePool(buffer);
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = 0;
return STATUS_SUCCESS;
}
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
)
{
struct sockaddr_in toAddr;
int status, nSent, nRecv;
unsigned int dataLen;
char *request, *buffer, *pDataPart;
ASSERT(Socket != NULL);
ASSERT(HostName != NULL);
ASSERT(FileName != NULL);
ASSERT(Offset != NULL);
ASSERT(IoStatus != NULL);
ASSERT(SystemBuffer != NULL);
IoStatus->Information = 0;
request = ExAllocatePool(PagedPool, PAGE_SIZE);
if (request == NULL)
{
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return IoStatus->Status;
}
buffer = ExAllocatePool(PagedPool, BUFFER_SIZE + 1);
if (buffer == NULL)
{
ExFreePool(request);
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return IoStatus->Status;
}
// Example request:
// GET 'FileName' HTTP/1.1
// Host: 'HostName'
// Range: bytes='Offset'-'Offset + Length - 1'
// Accept: */*
// User-Agent: HttpDisk/1.4
//
// Interesting lines in response:
// HTTP/1.1 206 Partial content
// Content-Length: 'requested size'
// Content-Range: bytes 'start'-'end'/'total file size'
// Data follows after '\r\n\r\n'
_snprintf(
request,
PAGE_SIZE,
"GET %s HTTP/1.1\r\nHost: %s\r\nRange: bytes=%I64u-%I64u\r\nAccept: */*\r\nUser-Agent: HttpDisk/1.4\r\n\r\n",
FileName,
HostName,
Offset->QuadPart,
Offset->QuadPart + Length - 1
);
if (*Socket < 0)
{
*Socket = socket(AF_INET, SOCK_STREAM, 0);
if (*Socket < 0)
{
ExFreePool(request);
ExFreePool(buffer);
*Socket = -1;
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return IoStatus->Status;
}
toAddr.sin_family = AF_INET;
toAddr.sin_port = Port;
toAddr.sin_addr.s_addr = Address;
status = connect(*Socket, (struct sockaddr*) &toAddr, sizeof(toAddr));
if (status < 0)
{
DbgPrint("HttpDisk: connect() error: %#x\n", status);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = status;
return IoStatus->Status;
}
}
nSent = send(*Socket, request, strlen(request), 0);
if (nSent < 0)
{
KdPrint(("HttpDisk: send() error: %#x\n", nSent));
close(*Socket);
*Socket = socket(AF_INET, SOCK_STREAM, 0);
if (*Socket < 0)
{
ExFreePool(request);
ExFreePool(buffer);
*Socket = -1;
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return IoStatus->Status;
}
toAddr.sin_family = AF_INET;
toAddr.sin_port = Port;
toAddr.sin_addr.s_addr = Address;
status = connect(*Socket, (struct sockaddr*) &toAddr, sizeof(toAddr));
if (status < 0)
{
DbgPrint("HttpDisk: connect() error: %#x\n", status);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = status;
return IoStatus->Status;
}
nSent = send(*Socket, request, strlen(request), 0);
if (nSent < 0)
{
DbgPrint("HttpDisk: send() error: %#x\n", nSent);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = nSent;
return IoStatus->Status;
}
}
nRecv = recv(*Socket, buffer, BUFFER_SIZE, 0);
if (nRecv < 0)
{
KdPrint(("HttpDisk: recv() error: %#x\n", nRecv));
close(*Socket);
*Socket = socket(AF_INET, SOCK_STREAM, 0);
if (*Socket < 0)
{
ExFreePool(request);
ExFreePool(buffer);
*Socket = -1;
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return IoStatus->Status;
}
toAddr.sin_family = AF_INET;
toAddr.sin_port = Port;
toAddr.sin_addr.s_addr = Address;
status = connect(*Socket, (struct sockaddr*) &toAddr, sizeof(toAddr));
if (status < 0)
{
DbgPrint("HttpDisk: connect() error: %#x\n", status);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = status;
return IoStatus->Status;
}
nSent = send(*Socket, request, strlen(request), 0);
if (nSent < 0)
{
DbgPrint("HttpDisk: send() error: %#x\n", nSent);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = nSent;
return IoStatus->Status;
}
nRecv = recv(*Socket, buffer, BUFFER_SIZE, 0);
if (nRecv < 0)
{
DbgPrint("HttpDisk: recv() error: %#x\n", nRecv);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = nRecv;
return IoStatus->Status;
}
}
buffer[BUFFER_SIZE] = '\0';
if (_strnicmp(buffer, "HTTP/1.1 206 Partial Content", 28))
{
DbgPrint("HttpDisk: Invalid HTTP response:\n%s", buffer);
DbgPrint("HttpDisk: Request was:\n%s", request);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = STATUS_UNSUCCESSFUL;
return IoStatus->Status;
}
pDataPart = strstr(buffer, "\r\n\r\n") + 4;
if (pDataPart == NULL || pDataPart < buffer || pDataPart >= buffer + BUFFER_SIZE)
{
DbgPrint("HttpDisk: Invalid HTTP response:\n%s", buffer);
DbgPrint("HttpDisk: Request was:\n%s", request);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = STATUS_UNSUCCESSFUL;
return IoStatus->Status;
}
dataLen = nRecv - (pDataPart - buffer);
if (dataLen > Length || pDataPart + dataLen > buffer + BUFFER_SIZE)
{
DbgPrint("HttpDisk: Invalid data length %u in HTTP response:\n%s", dataLen, buffer);
DbgPrint("HttpDisk: Request was:\n%s", request);
ExFreePool(request);
ExFreePool(buffer);
close(*Socket);
*Socket = -1;
IoStatus->Status = STATUS_UNSUCCESSFUL;
return IoStatus->Status;
}
if (dataLen > 0)
{
RtlCopyMemory(
SystemBuffer,
pDataPart,
dataLen
);
}
while (dataLen < Length)
{
nRecv = recv(*Socket, buffer, BUFFER_SIZE, 0);
if (nRecv < 0)
{
DbgPrint("HttpDisk: recv() error: %#x\n", nRecv);
close(*Socket);
*Socket = -1;
break;
}
if (nRecv < 1 || dataLen + nRecv > Length || nRecv > BUFFER_SIZE)
{
DbgPrint("HttpDisk: Invalid data length %u+%u\n", dataLen, nRecv);
DbgPrint("HttpDisk: Request was:\n%s", request);
close(*Socket);
*Socket = -1;
break;
}
RtlCopyMemory(
(PVOID)((PUCHAR) SystemBuffer + dataLen),
buffer,
nRecv
);
dataLen += nRecv;
}
if (dataLen != Length)
{
DbgPrint("HttpDisk: received data length: %u, expected data length: %u\n", dataLen, Length);
DbgPrint("HttpDisk: Request was:\n%s", request);
}
ExFreePool(request);
ExFreePool(buffer);
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = dataLen;
return IoStatus->Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -