diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c index aca29407d88..3a8aa3953d7 100644 --- a/dlls/http.sys/http.c +++ b/dlls/http.sys/http.c @@ -26,21 +26,67 @@ #include "winioctl.h" #include "ddk/wdm.h" #include "wine/debug.h" +#include "wine/heap.h" +#include "wine/list.h" static HANDLE directory_obj; static DEVICE_OBJECT *device_obj; WINE_DEFAULT_DEBUG_CHANNEL(http); +#define DECLARE_CRITICAL_SECTION(cs) \ + static CRITICAL_SECTION cs; \ + static CRITICAL_SECTION_DEBUG cs##_debug = \ + { 0, 0, &cs, { &cs##_debug.ProcessLocksList, &cs##_debug.ProcessLocksList }, \ + 0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \ + static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 }; + +DECLARE_CRITICAL_SECTION(http_cs); + +struct request_queue +{ + struct list entry; +}; + +static struct list request_queues = LIST_INIT(request_queues); + static NTSTATUS WINAPI dispatch_create(DEVICE_OBJECT *device, IRP *irp) { + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + struct request_queue *queue; + + if (!(queue = heap_alloc_zero(sizeof(*queue)))) + return STATUS_NO_MEMORY; + stack->FileObject->FsContext = queue; + + EnterCriticalSection(&http_cs); + list_add_head(&request_queues, &queue->entry); + LeaveCriticalSection(&http_cs); + + TRACE("Created queue %p.\n", queue); + irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } +static void close_queue(struct request_queue *queue) +{ + EnterCriticalSection(&http_cs); + list_remove(&queue->entry); + LeaveCriticalSection(&http_cs); + + heap_free(queue); +} + static NTSTATUS WINAPI dispatch_close(DEVICE_OBJECT *device, IRP *irp) { + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + struct request_queue *queue = stack->FileObject->FsContext; + + TRACE("Closing queue %p.\n", queue); + close_queue(queue); + irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_SUCCESS; @@ -48,6 +94,13 @@ static NTSTATUS WINAPI dispatch_close(DEVICE_OBJECT *device, IRP *irp) static void WINAPI unload(DRIVER_OBJECT *driver) { + struct request_queue *queue, *queue_next; + + LIST_FOR_EACH_ENTRY_SAFE(queue, queue_next, &request_queues, struct request_queue, entry) + { + close_queue(queue); + } + IoDeleteDevice(device_obj); NtClose(directory_obj); }