Signed-off-by: Zebediah Figura z.figura12@gmail.com --- configure | 2 ++ configure.ac | 1 + dlls/http.sys/Makefile.in | 6 ++++++ dlls/http.sys/http.c | 36 ++++++++++++++++++++++++++++++++++++ dlls/http.sys/http.sys.spec | 1 + loader/wine.inf.in | 11 +++++++++++ 6 files changed, 57 insertions(+) create mode 100644 dlls/http.sys/Makefile.in create mode 100644 dlls/http.sys/http.c create mode 100644 dlls/http.sys/http.sys.spec
diff --git a/configure b/configure index 0cf86af877..a64045f705 100755 --- a/configure +++ b/configure @@ -1339,6 +1339,7 @@ enable_hid enable_hidclass_sys enable_hlink enable_hnetcfg +enable_http_sys enable_httpapi enable_iccvid enable_icmp @@ -20297,6 +20298,7 @@ wine_fn_config_makefile dlls/hlink enable_hlink wine_fn_config_makefile dlls/hlink/tests enable_tests wine_fn_config_makefile dlls/hnetcfg enable_hnetcfg wine_fn_config_makefile dlls/hnetcfg/tests enable_tests +wine_fn_config_makefile dlls/http.sys enable_http_sys wine_fn_config_makefile dlls/httpapi enable_httpapi wine_fn_config_makefile dlls/httpapi/tests enable_tests wine_fn_config_makefile dlls/iccvid enable_iccvid diff --git a/configure.ac b/configure.ac index a136031658..32942125bc 100644 --- a/configure.ac +++ b/configure.ac @@ -3290,6 +3290,7 @@ WINE_CONFIG_MAKEFILE(dlls/hlink) WINE_CONFIG_MAKEFILE(dlls/hlink/tests) WINE_CONFIG_MAKEFILE(dlls/hnetcfg) WINE_CONFIG_MAKEFILE(dlls/hnetcfg/tests) +WINE_CONFIG_MAKEFILE(dlls/http.sys) WINE_CONFIG_MAKEFILE(dlls/httpapi) WINE_CONFIG_MAKEFILE(dlls/httpapi/tests) WINE_CONFIG_MAKEFILE(dlls/iccvid) diff --git a/dlls/http.sys/Makefile.in b/dlls/http.sys/Makefile.in new file mode 100644 index 0000000000..449ebaef0a --- /dev/null +++ b/dlls/http.sys/Makefile.in @@ -0,0 +1,6 @@ +MODULE = http.sys +IMPORTS = ntoskrnl +EXTRADLLFLAGS = -Wl,--subsystem,native -mno-cygwin + +C_SRCS = \ + http.c diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c new file mode 100644 index 0000000000..ed19c00676 --- /dev/null +++ b/dlls/http.sys/http.c @@ -0,0 +1,36 @@ +/* + * HTTP server driver + * + * Copyright 2019 Zebediah Figura + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" +#include "ddk/wdm.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(http); + +NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) +{ + TRACE("driver %p, path %s.\n", driver, debugstr_w(path->Buffer)); + + return STATUS_SUCCESS; +} diff --git a/dlls/http.sys/http.sys.spec b/dlls/http.sys/http.sys.spec new file mode 100644 index 0000000000..76421d7e35 --- /dev/null +++ b/dlls/http.sys/http.sys.spec @@ -0,0 +1 @@ +# nothing to export diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 4f19fb2dc4..58fa3804e3 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -123,6 +123,7 @@ AddReg=\
[DefaultInstall.Services] AddService=BITS,0,BITSService +AddService=HTTP,0,HTTPService AddService=MSIServer,0,MSIService AddService=MountMgr,0x800,MountMgrService AddService=RpcSs,0,RpcSsService @@ -138,6 +139,7 @@ AddService=Winmgmt,0,WinmgmtService
[DefaultInstall.NT.Services] AddService=BITS,0,BITSService +AddService=HTTP,0,HTTPService AddService=MSIServer,0,MSIService AddService=MountMgr,0x800,MountMgrService AddService=RpcSs,0,RpcSsService @@ -153,6 +155,7 @@ AddService=Winmgmt,0,WinmgmtService
[DefaultInstall.ntamd64.Services] AddService=BITS,0,BITSService +AddService=HTTP,0,HTTPService AddService=MSIServer,0,MSIService AddService=MountMgr,0x800,MountMgrService AddService=RpcSs,0,RpcSsService @@ -3422,6 +3425,14 @@ ServiceType=16 StartType=3 ErrorControl=1
+[HTTPService] +Description="HTTP server" +DisplayName="HTTP" +ServiceBinary="%12%\http.sys" +ServiceType=1 +StartType=3 +ErrorControl=1 + [MSIService] Description="MSI Installer Server" DisplayName="MSIServer"
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/http.sys/http.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c index ed19c00676..aca29407d8 100644 --- a/dlls/http.sys/http.c +++ b/dlls/http.sys/http.c @@ -23,14 +23,61 @@ #include "ntstatus.h" #define WIN32_NO_STATUS #include "winternl.h" +#include "winioctl.h" #include "ddk/wdm.h" #include "wine/debug.h"
+static HANDLE directory_obj; +static DEVICE_OBJECT *device_obj; + WINE_DEFAULT_DEBUG_CHANNEL(http);
+static NTSTATUS WINAPI dispatch_create(DEVICE_OBJECT *device, IRP *irp) +{ + irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +static NTSTATUS WINAPI dispatch_close(DEVICE_OBJECT *device, IRP *irp) +{ + irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +static void WINAPI unload(DRIVER_OBJECT *driver) +{ + IoDeleteDevice(device_obj); + NtClose(directory_obj); +} + NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) { + static const WCHAR device_nameW[] = {'\','D','e','v','i','c','e','\','H','t','t','p','\','R','e','q','Q','u','e','u','e',0}; + static const WCHAR directory_nameW[] = {'\','D','e','v','i','c','e','\','H','t','t','p',0}; + OBJECT_ATTRIBUTES attr = {sizeof(attr)}; + UNICODE_STRING string; + NTSTATUS ret; + TRACE("driver %p, path %s.\n", driver, debugstr_w(path->Buffer));
+ RtlInitUnicodeString(&string, directory_nameW); + attr.ObjectName = &string; + if ((ret = NtCreateDirectoryObject(&directory_obj, 0, &attr)) && ret != STATUS_OBJECT_NAME_COLLISION) + ERR("Failed to create \Device\Http directory, status %#x.\n", ret); + + RtlInitUnicodeString(&string, device_nameW); + if ((ret = IoCreateDevice(driver, 0, &string, FILE_DEVICE_UNKNOWN, 0, FALSE, &device_obj))) + { + ERR("Failed to create request queue device, status %#x.\n", ret); + NtClose(directory_obj); + return ret; + } + + driver->MajorFunction[IRP_MJ_CREATE] = dispatch_create; + driver->MajorFunction[IRP_MJ_CLOSE] = dispatch_close; + driver->DriverUnload = unload; + return STATUS_SUCCESS; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/http.sys/http.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c index aca29407d8..3a8aa3953d 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); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/httpapi/httpapi_main.c | 19 ++++++++++++++++--- dlls/httpapi/tests/httpapi.c | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/httpapi/httpapi_main.c b/dlls/httpapi/httpapi_main.c index 429ae1a1af..4536aa8446 100644 --- a/dlls/httpapi/httpapi_main.c +++ b/dlls/httpapi/httpapi_main.c @@ -22,6 +22,7 @@
#include "windef.h" #include "winbase.h" +#include "winternl.h" #include "http.h" #include "wine/debug.h"
@@ -167,10 +168,22 @@ ULONG WINAPI HttpSetServiceConfiguration( HANDLE handle, HTTP_SERVICE_CONFIG_ID * NO_ERROR if function succeeds, or error code if function fails * */ -ULONG WINAPI HttpCreateHttpHandle( PHANDLE handle, ULONG reserved ) +ULONG WINAPI HttpCreateHttpHandle(HANDLE *handle, ULONG reserved) { - FIXME( "(%p, %d): stub!\n", handle, reserved); - return ERROR_CALL_NOT_IMPLEMENTED; + static const WCHAR device_nameW[] = {'\','D','e','v','i','c','e','\','H','t','t','p','\','R','e','q','Q','u','e','u','e',0}; + OBJECT_ATTRIBUTES attr = {sizeof(attr)}; + UNICODE_STRING string; + IO_STATUS_BLOCK iosb; + + TRACE("handle %p, reserved %#x.\n", handle, reserved); + + if (!handle) + return ERROR_INVALID_PARAMETER; + + RtlInitUnicodeString(&string, device_nameW); + attr.ObjectName = &string; + return RtlNtStatusToDosError(NtCreateFile(handle, 0, &attr, &iosb, NULL, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0)); }
/*********************************************************************** diff --git a/dlls/httpapi/tests/httpapi.c b/dlls/httpapi/tests/httpapi.c index 6646e8e219..c30c380899 100644 --- a/dlls/httpapi/tests/httpapi.c +++ b/dlls/httpapi/tests/httpapi.c @@ -117,7 +117,7 @@ static void test_v1_server(void) memset(req_buffer, 0xcc, sizeof(req_buffer));
ret = HttpCreateHttpHandle(NULL, 0); - todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Unexpected error %u.\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Unexpected error %u.\n", ret);
/* Non-zero reserved parameter is accepted on XP/2k3. */ queue = NULL;