Rob Shearman : ole32:
Close the named pipe after revoking local server objects.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Mar 9 15:47:46 CST 2007
Module: wine
Branch: master
Commit: 880542a9f87ec7a2b023753f7e192582b478737f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=880542a9f87ec7a2b023753f7e192582b478737f
Author: Rob Shearman <rob at codeweavers.com>
Date: Fri Mar 9 17:42:34 2007 +0000
ole32: Close the named pipe after revoking local server objects.
---
dlls/ole32/compobj.c | 9 ++++++++-
dlls/ole32/compobj_private.h | 3 ++-
dlls/ole32/rpc.c | 37 +++++++++++++++++++++++++++++++------
3 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index bac067a..98ec995 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -123,6 +123,7 @@ typedef struct tagRegisteredClass
DWORD connectFlags;
DWORD dwCookie;
LPSTREAM pMarshaledData; /* FIXME: only really need to store OXID and IPID */
+ void *RpcRegistration;
struct tagRegisteredClass* nextClass;
} RegisteredClass;
@@ -1574,6 +1575,7 @@ HRESULT WINAPI CoRegisterClassObject(
newClass->runContext = dwClsContext;
newClass->connectFlags = flags;
newClass->pMarshaledData = NULL;
+ newClass->RpcRegistration = NULL;
/*
* Use the address of the chain node as the cookie since we are sure it's
@@ -1618,7 +1620,9 @@ HRESULT WINAPI CoRegisterClassObject(
IUnknown_Release(classfac);
- RPC_StartLocalServer(&newClass->classIdentifier, newClass->pMarshaledData);
+ hr = RPC_StartLocalServer(&newClass->classIdentifier,
+ newClass->pMarshaledData,
+ &newClass->RpcRegistration);
}
return S_OK;
}
@@ -1667,6 +1671,9 @@ HRESULT WINAPI CoRevokeClassObject(
*/
*prevClassLink = curClass->nextClass;
+ if (curClass->runContext & CLSCTX_LOCAL_SERVER)
+ RPC_StopLocalServer(curClass->RpcRegistration);
+
/*
* Release the reference to the class object.
*/
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index b77e05f..4c96a3c 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -221,7 +221,8 @@ HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan);
void RPC_ExecuteCall(struct dispatch_params *params);
HRESULT RPC_RegisterInterface(REFIID riid);
void RPC_UnregisterInterface(REFIID riid);
-void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
+HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, void **registration);
+void RPC_StopLocalServer(void *registration);
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook);
void RPC_UnregisterAllChannelHooks(void);
diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c
index fdb81ed..3320552 100644
--- a/dlls/ole32/rpc.c
+++ b/dlls/ole32/rpc.c
@@ -1732,6 +1732,7 @@ struct local_server_params
CLSID clsid;
IStream *stream;
HANDLE ready_event;
+ HANDLE pipe;
};
/* FIXME: should call to rpcss instead */
@@ -1757,6 +1758,7 @@ static DWORD WINAPI local_server_thread(LPVOID param)
PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
4096, 4096, 500 /* 0.5 second timeout */, NULL );
+ lsp->pipe = hPipe;
SetEvent(lsp->ready_event);
HeapFree(GetProcessHeap(), 0, lsp);
@@ -1768,9 +1770,21 @@ static DWORD WINAPI local_server_thread(LPVOID param)
}
while (1) {
- if (!ConnectNamedPipe(hPipe,NULL) && GetLastError() != ERROR_PIPE_CONNECTED) {
- ERR("Failure during ConnectNamedPipe %u, ABORT!\n",GetLastError());
- break;
+ if (!ConnectNamedPipe(hPipe,NULL))
+ {
+ DWORD error = GetLastError();
+ /* client already connected isn't an error */
+ if (error != ERROR_PIPE_CONNECTED)
+ {
+ /* if error wasn't caused by RPC_StopLocalServer closing the
+ * pipe for us */
+ if (error != ERROR_INVALID_HANDLE)
+ {
+ ERR("Failure during ConnectNamedPipe %u\n", error);
+ CloseHandle(hPipe);
+ }
+ break;
+ }
}
TRACE("marshalling IClassFactory to client\n");
@@ -1804,12 +1818,12 @@ static DWORD WINAPI local_server_thread(LPVOID param)
TRACE("done marshalling IClassFactory\n");
}
- CloseHandle(hPipe);
IStream_Release(pStm);
return 0;
}
-void RPC_StartLocalServer(REFCLSID clsid, IStream *stream)
+/* starts listening for a local server */
+HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, void **registration)
{
DWORD tid;
HANDLE thread, ready_event;
@@ -1821,9 +1835,20 @@ void RPC_StartLocalServer(REFCLSID clsid, IStream *stream)
lsp->ready_event = ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
thread = CreateThread(NULL, 0, local_server_thread, lsp, 0, &tid);
+ if (!thread)
+ return HRESULT_FROM_WIN32(GetLastError());
CloseHandle(thread);
- /* FIXME: failure handling */
WaitForSingleObject(ready_event, INFINITE);
CloseHandle(ready_event);
+
+ *registration = lsp->pipe;
+ return S_OK;
+}
+
+/* stops listening for a local server */
+void RPC_StopLocalServer(void *registration)
+{
+ HANDLE pipe = registration;
+ CloseHandle(pipe);
}
More information about the wine-cvs
mailing list