rpc exception patch
Ove Kaaven
ovek at arcticnet.no
Wed May 21 15:07:49 CDT 2003
I've encountered an installer that needed this...
This is the last rpcrt4 update for now, I guess it's finally time to
start looking at chopping up my ole32 work for submission.
Log:
Ove Kaaven <ovek at transgaming.com>
Initial support for RPC call failures, by catching RPC server exceptions
and returning simple failure packets, and throwing exceptions on the
client side when unmarshalling the failure packet.
? dlls/rpcrt4/rpc_misc.h
Index: dlls/rpcrt4/ndr_midl.c
===================================================================
RCS file: /home/wine/wine/dlls/rpcrt4/ndr_midl.c,v
retrieving revision 1.13
diff -u -r1.13 ndr_midl.c
--- dlls/rpcrt4/ndr_midl.c 21 May 2003 18:22:49 -0000 1.13
+++ dlls/rpcrt4/ndr_midl.c 21 May 2003 19:56:57 -0000
@@ -106,6 +106,10 @@
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
pStubMsg->Buffer = pStubMsg->BufferStart;
+
+ /* raise exception if call failed */
+ if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
+ else if (FAILED(hr)) RpcRaiseException(hr);
}
/***********************************************************************
Index: dlls/rpcrt4/rpc_message.c
===================================================================
RCS file: /home/wine/wine/dlls/rpcrt4/rpc_message.c,v
retrieving revision 1.6
diff -u -r1.6 rpc_message.c
--- dlls/rpcrt4/rpc_message.c 21 May 2003 18:23:06 -0000 1.6
+++ dlls/rpcrt4/rpc_message.c 21 May 2003 19:56:57 -0000
@@ -37,6 +37,7 @@
#include "wine/debug.h"
#include "rpc_binding.h"
+#include "rpc_misc.h"
#include "rpc_defs.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -111,7 +112,9 @@
/* initialize packet header */
memset(&hdr, 0, sizeof(hdr));
hdr.rpc_ver = 4;
- hdr.ptype = bind->server ? PKT_RESPONSE : PKT_REQUEST;
+ hdr.ptype = bind->server
+ ? ((pMsg->RpcFlags & WINE_RPCFLAG_EXCEPTION) ? PKT_FAULT : PKT_RESPONSE)
+ : PKT_REQUEST;
hdr.object = *obj; /* FIXME: IIRC iff no object, the header structure excludes this elt */
hdr.if_id = (bind->server) ? sif->InterfaceId.SyntaxGUID : cif->InterfaceId.SyntaxGUID;
hdr.if_vers =
@@ -227,10 +230,27 @@
goto fail;
}
+ status = RPC_S_PROTOCOL_ERROR;
+
+ switch (hdr.ptype) {
+ case PKT_RESPONSE:
+ if (bind->server) goto fail;
+ break;
+ case PKT_REQUEST:
+ if (!bind->server) goto fail;
+ break;
+ case PKT_FAULT:
+ pMsg->RpcFlags |= WINE_RPCFLAG_EXCEPTION;
+ status = RPC_S_CALL_FAILED; /* ? */
+ goto fail;
+ default:
+ goto fail;
+ }
+
/* success */
status = RPC_S_OK;
- /* FIXME: check packet type, destination, etc? */
+ /* FIXME: check destination, etc? */
break;
}
fail:
Index: dlls/rpcrt4/rpc_server.c
===================================================================
RCS file: /home/wine/wine/dlls/rpcrt4/rpc_server.c,v
retrieving revision 1.16
diff -u -r1.16 rpc_server.c
--- dlls/rpcrt4/rpc_server.c 21 May 2003 18:23:06 -0000 1.16
+++ dlls/rpcrt4/rpc_server.c 21 May 2003 19:56:58 -0000
@@ -33,8 +33,11 @@
#include "rpc.h"
#include "wine/debug.h"
+#include "wine/exception.h"
+#include "msvcrt/excpt.h"
#include "rpc_server.h"
+#include "rpc_misc.h"
#include "rpc_defs.h"
#define MAX_THREADS 128
@@ -63,7 +66,7 @@
static RpcPacket* spacket_tail;
static HANDLE server_sem;
-static DWORD worker_count, worker_free;
+static DWORD worker_count, worker_free, worker_tls;
static RpcServerInterface* RPCRT4_find_interface(UUID* object, UUID* if_id)
{
@@ -110,6 +113,18 @@
return packet;
}
+static WINE_EXCEPTION_FILTER(rpc_filter)
+{
+ PRPC_MESSAGE msg;
+ msg = TlsGetValue(worker_tls);
+ I_RpcFreeBuffer(msg);
+ msg->RpcFlags |= WINE_RPCFLAG_EXCEPTION;
+ msg->BufferLength = sizeof(DWORD);
+ I_RpcGetBuffer(msg);
+ *(DWORD*)msg->Buffer = GetExceptionCode();
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, void* buf)
{
RpcBinding* pbind;
@@ -117,6 +132,7 @@
RpcServerInterface* sif;
RPC_DISPATCH_FUNCTION func;
+ TlsSetValue(worker_tls, &msg);
memset(&msg, 0, sizeof(msg));
msg.BufferLength = hdr->len;
msg.Buffer = buf;
@@ -152,7 +168,12 @@
MAKEWORD(hdr->drep[2], 0));
/* dispatch */
- if (func) func(&msg);
+ __TRY {
+ if (func) func(&msg);
+ } __EXCEPT(rpc_filter) {
+ /* failure packet was created in rpc_filter */
+ TRACE("exception caught, returning failure packet\n");
+ } __ENDTRY
/* send response packet */
I_RpcSend(&msg);
@@ -176,6 +197,7 @@
HeapFree(GetProcessHeap(), 0, buf);
I_RpcFreeBuffer(&msg);
msg.Buffer = NULL;
+ TlsSetValue(worker_tls, NULL);
}
static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg)
@@ -411,6 +433,7 @@
if (! ++listen_count) {
if (!mgr_event) mgr_event = CreateEventA(NULL, TRUE, FALSE, NULL);
if (!server_sem) server_sem = CreateSemaphoreA(NULL, 0, MAX_THREADS, NULL);
+ if (!worker_tls) worker_tls = TlsAlloc();
std_listen = TRUE;
server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL);
LeaveCriticalSection(&listen_cs);
--- /dev/null 2003-01-10 01:23:22.000000000 +0100
+++ dlls/rpcrt4/rpc_misc.h 2003-05-21 21:55:52.000000000 +0200
@@ -0,0 +1,13 @@
+/*
+ * RPC definitions
+ *
+ * Copyright 2003 Ove Kåven, TransGaming Technologies
+ */
+
+#ifndef __WINE_RPC_MISC_H
+#define __WINE_RPC_MISC_H
+
+/* flags for RPC_MESSAGE.RpcFlags */
+#define WINE_RPCFLAG_EXCEPTION 0x0001
+
+#endif /* __WINE_RPC_MISC_H */
More information about the wine-patches
mailing list