Zebediah Figura : http.sys: Implement HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY.
Alexandre Julliard
julliard at winehq.org
Tue Aug 27 15:28:15 CDT 2019
Module: wine
Branch: master
Commit: fc8996cc6038c319aaebc5592f67ae24154acb92
URL: https://source.winehq.org/git/wine.git/?a=commit;h=fc8996cc6038c319aaebc5592f67ae24154acb92
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Mon Aug 26 23:31:21 2019 -0500
http.sys: Implement HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/http.sys/http.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c
index 2607af5..fe53638 100644
--- a/dlls/http.sys/http.c
+++ b/dlls/http.sys/http.c
@@ -45,6 +45,26 @@ struct http_unknown_header_32
ULONG pRawValue; /* char string */
};
+struct http_data_chunk_32
+{
+ HTTP_DATA_CHUNK_TYPE DataChunkType;
+ union
+ {
+ struct
+ {
+ ULONG pBuffer; /* char string */
+ ULONG BufferLength;
+ } FromMemory;
+ /* for the struct size */
+ struct
+ {
+ ULARGE_INTEGER StartingOffset;
+ ULARGE_INTEGER Length;
+ HANDLE FileHandle;
+ } FromFileHandle;
+ };
+};
+
struct http_request_32
{
ULONG Flags;
@@ -102,6 +122,26 @@ struct http_unknown_header_64
ULONGLONG pRawValue; /* char string */
};
+struct http_data_chunk_64
+{
+ HTTP_DATA_CHUNK_TYPE DataChunkType;
+ union
+ {
+ struct
+ {
+ ULONGLONG pBuffer; /* char string */
+ ULONG BufferLength;
+ } FromMemory;
+ /* for the struct size */
+ struct
+ {
+ ULARGE_INTEGER StartingOffset;
+ ULARGE_INTEGER Length;
+ HANDLE FileHandle;
+ } FromFileHandle;
+ };
+};
+
struct http_request_64
{
ULONG Flags;
@@ -358,7 +398,7 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
DWORD irp_size = (params.bits == 32) ? sizeof(struct http_request_32) : sizeof(struct http_request_64);
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
const DWORD output_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
- ULONG cooked_len, host_len, abs_path_len, query_len, offset;
+ ULONG cooked_len, host_len, abs_path_len, query_len, chunk_len = 0, offset;
const char *p, *name, *value, *host, *abs_path, *query;
USHORT unk_headers_count = 0, unk_header_idx;
int name_len, value_len, len;
@@ -447,6 +487,7 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
struct http_request_32 *req = irp->AssociatedIrp.SystemBuffer;
struct http_unknown_header_32 *unk_headers = NULL;
char *buffer = irp->AssociatedIrp.SystemBuffer;
+ struct http_data_chunk_32 *chunk = NULL;
offset = sizeof(*req);
@@ -544,6 +585,26 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
}
p += 2;
+ if (irp_size + sizeof(*chunk) < output_len && (params.flags & HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY))
+ chunk_len = min(conn->content_len, output_len - (irp_size + sizeof(*chunk)));
+ if (chunk_len)
+ {
+ req->EntityChunkCount = 1;
+ req->pEntityChunks = params.addr + offset;
+ chunk = (struct http_data_chunk_32 *)(buffer + offset);
+ offset += sizeof(*chunk);
+ chunk->DataChunkType = HttpDataChunkFromMemory;
+ chunk->FromMemory.BufferLength = chunk_len;
+ chunk->FromMemory.pBuffer = params.addr + offset;
+ memcpy(buffer + offset, p, chunk_len);
+ offset += chunk_len;
+
+ irp->IoStatus.Information = irp_size + sizeof(*chunk) + chunk_len;
+ }
+
+ if (chunk_len < conn->content_len)
+ req->Flags |= HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS;
+
req->BytesReceived = conn->req_len;
}
else
@@ -551,6 +612,7 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
struct http_request_64 *req = irp->AssociatedIrp.SystemBuffer;
struct http_unknown_header_64 *unk_headers = NULL;
char *buffer = irp->AssociatedIrp.SystemBuffer;
+ struct http_data_chunk_64 *chunk = NULL;
offset = sizeof(*req);
@@ -648,6 +710,26 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
}
p += 2;
+ if (irp_size + sizeof(*chunk) < output_len && (params.flags & HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY))
+ chunk_len = min(conn->content_len, output_len - (irp_size + sizeof(*chunk)));
+ if (chunk_len)
+ {
+ req->EntityChunkCount = 1;
+ req->pEntityChunks = params.addr + offset;
+ chunk = (struct http_data_chunk_64 *)(buffer + offset);
+ offset += sizeof(*chunk);
+ chunk->DataChunkType = HttpDataChunkFromMemory;
+ chunk->FromMemory.BufferLength = chunk_len;
+ chunk->FromMemory.pBuffer = params.addr + offset;
+ memcpy(buffer + offset, p, chunk_len);
+ offset += chunk_len;
+
+ irp->IoStatus.Information = irp_size + sizeof(*chunk) + chunk_len;
+ }
+
+ if (chunk_len < conn->content_len)
+ req->Flags |= HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS;
+
req->BytesReceived = conn->req_len;
}
More information about the wine-cvs
mailing list