[PATCH 3/8] winhttp: Implement WinHttpWebSocketShutdown.
Hans Leidekker
hans at codeweavers.com
Wed Jun 24 03:33:05 CDT 2020
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/winhttp/request.c | 69 +++++++++++++++++++++++++++++++++-
dlls/winhttp/winhttp_private.h | 8 ++++
2 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index 372e0e5e77..7f1c727cba 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -3469,10 +3469,75 @@ DWORD WINAPI WinHttpWebSocketReceive( HINTERNET hsocket, void *buf, DWORD len, D
return ret;
}
+static DWORD socket_shutdown( struct socket *socket, USHORT status, const void *reason, DWORD len, BOOL async )
+{
+ DWORD ret;
+
+ ret = send_frame( socket->request->netconn, WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE, status, reason, len, TRUE );
+ if (async)
+ {
+ if (!ret) send_callback( &socket->hdr, WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE, NULL, 0 );
+ else
+ {
+ WINHTTP_WEB_SOCKET_ASYNC_RESULT result;
+ result.AsyncResult.dwResult = API_WRITE_DATA;
+ result.AsyncResult.dwError = ret;
+ result.Operation = WINHTTP_WEB_SOCKET_SHUTDOWN_OPERATION;
+ send_callback( &socket->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, &result, sizeof(result) );
+ }
+ }
+
+ if (!ret) socket->state = SOCKET_STATE_SHUTDOWN;
+ return ret;
+}
+
+static void task_socket_shutdown( struct task_header *task )
+{
+ struct socket *socket = (struct socket *)task->object;
+ struct socket_shutdown *s = (struct socket_shutdown *)task;
+
+ socket_shutdown( socket, s->status, s->reason, s->len, TRUE );
+}
+
DWORD WINAPI WinHttpWebSocketShutdown( HINTERNET hsocket, USHORT status, void *reason, DWORD len )
{
- FIXME("%p, %u, %p, %u\n", hsocket, status, reason, len);
- return ERROR_INVALID_PARAMETER;
+ struct socket *socket;
+ DWORD ret;
+
+ TRACE("%p, %u, %p, %u\n", hsocket, status, reason, len);
+
+ if (len && !reason) return ERROR_INVALID_PARAMETER;
+
+ if (!(socket = (struct socket *)grab_object( hsocket ))) return ERROR_INVALID_HANDLE;
+ if (socket->hdr.type != WINHTTP_HANDLE_TYPE_SOCKET)
+ {
+ release_object( &socket->hdr );
+ return ERROR_WINHTTP_INCORRECT_HANDLE_TYPE;
+ }
+ if (socket->state >= SOCKET_STATE_SHUTDOWN)
+ {
+ release_object( &socket->hdr );
+ return ERROR_WINHTTP_INCORRECT_HANDLE_STATE;
+ }
+
+ if (socket->request->connect->hdr.flags & WINHTTP_FLAG_ASYNC)
+ {
+ struct socket_shutdown *s;
+
+ if (!(s = heap_alloc( sizeof(*s) ))) return FALSE;
+ s->hdr.object = &socket->hdr;
+ s->hdr.proc = task_socket_shutdown;
+ s->status = status;
+ s->reason = reason;
+ s->len = len;
+
+ addref_object( &socket->hdr );
+ ret = queue_task( &socket->hdr, &socket->send_q, (struct task_header *)s );
+ }
+ else ret = socket_shutdown( socket, status, reason, len, FALSE );
+
+ release_object( &socket->hdr );
+ return ret;
}
DWORD WINAPI WinHttpWebSocketClose( HINTERNET hsocket, USHORT status, void *reason, DWORD len )
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index 9cf9c396cb..7d81e35934 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -292,6 +292,14 @@ struct socket_receive
DWORD len;
};
+struct socket_shutdown
+{
+ struct task_header hdr;
+ USHORT status;
+ const void *reason;
+ DWORD len;
+};
+
struct object_header *addref_object( struct object_header * ) DECLSPEC_HIDDEN;
struct object_header *grab_object( HINTERNET ) DECLSPEC_HIDDEN;
void release_object( struct object_header * ) DECLSPEC_HIDDEN;
--
2.20.1
More information about the wine-devel
mailing list