Various formatting/style changes.
This commit is contained in:
parent
97b85cc88c
commit
70c1c26869
511
dlls/ole32/rpc.c
511
dlls/ole32/rpc.c
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* (Local) RPC Stuff
|
||||
*
|
||||
* Copyright 2002 Marcus Meissner
|
||||
* Copyright 2002 Marcus Meissner
|
||||
* Copyright 2005 Mike Hearn, Rob Shearman for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -52,26 +53,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|||
#define OLESTUBMGR PIPEPREF"WINE_OLE_StubMgr"
|
||||
|
||||
#define REQTYPE_REQUEST 0
|
||||
typedef struct _wine_rpc_request_header {
|
||||
#define REQTYPE_RESPONSE 1
|
||||
#define REQTYPE_DISCONNECT 2
|
||||
|
||||
struct request_header
|
||||
{
|
||||
DWORD reqid;
|
||||
wine_marshal_id mid;
|
||||
DWORD iMethod;
|
||||
DWORD cbBuffer;
|
||||
} wine_rpc_request_header;
|
||||
};
|
||||
|
||||
#define REQTYPE_RESPONSE 1
|
||||
typedef struct _wine_rpc_response_header {
|
||||
struct response_header
|
||||
{
|
||||
DWORD reqid;
|
||||
DWORD cbBuffer;
|
||||
DWORD retval;
|
||||
} wine_rpc_response_header;
|
||||
};
|
||||
|
||||
/* used when shutting down a pipe, e.g. at the end of a process */
|
||||
#define REQTYPE_DISCONNECT 2
|
||||
typedef struct _wine_rpc_disconnect_header {
|
||||
struct disconnect_header
|
||||
{
|
||||
DWORD reqid;
|
||||
wine_marshal_id mid; /* mid of stub to delete */
|
||||
} wine_rpc_disconnect_header;
|
||||
};
|
||||
|
||||
|
||||
#define REQSTATE_START 0
|
||||
|
@ -83,22 +88,24 @@ typedef struct _wine_rpc_disconnect_header {
|
|||
#define REQSTATE_RESP_GOT 6
|
||||
#define REQSTATE_DONE 6
|
||||
|
||||
typedef struct _wine_rpc_request {
|
||||
struct rpc
|
||||
{
|
||||
int state;
|
||||
HANDLE hPipe; /* temp copy of handle */
|
||||
wine_rpc_request_header reqh;
|
||||
wine_rpc_response_header resph;
|
||||
struct request_header reqh;
|
||||
struct response_header resph;
|
||||
LPBYTE Buffer;
|
||||
} wine_rpc_request;
|
||||
};
|
||||
|
||||
static wine_rpc_request **reqs = NULL;
|
||||
static struct rpc **reqs = NULL;
|
||||
static int nrofreqs = 0;
|
||||
|
||||
/* This pipe is _thread_ based, each thread which talks to a remote
|
||||
* apartment (mid) has its own pipe. The same structure is used both
|
||||
* for outgoing and incoming RPCs.
|
||||
*/
|
||||
typedef struct _wine_pipe {
|
||||
struct pipe
|
||||
{
|
||||
wine_marshal_id mid; /* target mid */
|
||||
DWORD tid; /* thread which owns this pipe */
|
||||
HANDLE hPipe;
|
||||
|
@ -108,18 +115,18 @@ typedef struct _wine_pipe {
|
|||
CRITICAL_SECTION crit;
|
||||
|
||||
APARTMENT *apt; /* apartment of the marshalling thread for the stub dispatch case */
|
||||
} wine_pipe;
|
||||
};
|
||||
|
||||
#define MAX_WINE_PIPES 256
|
||||
|
||||
static wine_pipe pipes[MAX_WINE_PIPES];
|
||||
static struct pipe pipes[MAX_WINE_PIPES];
|
||||
static int nrofpipes = 0;
|
||||
|
||||
typedef struct _PipeBuf {
|
||||
IRpcChannelBufferVtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
IRpcChannelBufferVtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
|
||||
wine_marshal_id mid;
|
||||
wine_marshal_id mid;
|
||||
} PipeBuf;
|
||||
|
||||
static HRESULT WINAPI
|
||||
|
@ -136,32 +143,6 @@ read_pipe(HANDLE hf, LPVOID ptr, DWORD size) {
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
drs(LPCSTR where) {
|
||||
#if 0
|
||||
static int nrofreaders = 0;
|
||||
|
||||
int i, states[10];
|
||||
|
||||
memset(states,0,sizeof(states));
|
||||
for (i=nrofreqs;i--;)
|
||||
states[reqs[i]->state]++;
|
||||
FIXME("%lx/%s/%d: rq %d, w %d, rg %d, rsq %d, rsg %d, d %d\n",
|
||||
GetCurrentProcessId(),
|
||||
where,
|
||||
nrofreaders,
|
||||
states[REQSTATE_REQ_QUEUED],
|
||||
states[REQSTATE_REQ_WAITING_FOR_REPLY],
|
||||
states[REQSTATE_REQ_GOT],
|
||||
states[REQSTATE_RESP_QUEUED],
|
||||
states[REQSTATE_RESP_GOT],
|
||||
states[REQSTATE_DONE]
|
||||
);
|
||||
#endif
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
write_pipe(HANDLE hf, LPVOID ptr, DWORD size) {
|
||||
DWORD res;
|
||||
|
@ -179,36 +160,37 @@ write_pipe(HANDLE hf, LPVOID ptr, DWORD size) {
|
|||
static DWORD WINAPI stub_dispatch_thread(LPVOID);
|
||||
|
||||
static HRESULT
|
||||
PIPE_RegisterPipe(wine_marshal_id *mid, HANDLE hPipe, BOOL startreader) {
|
||||
PIPE_RegisterPipe(wine_marshal_id *mid, HANDLE hPipe, BOOL startreader)
|
||||
{
|
||||
|
||||
/* FIXME: this pipe caching code is commented out because it is breaks the
|
||||
* tests, causing them hang due to writing to or reading from the wrong pipe.
|
||||
*/
|
||||
/* FIXME: this pipe caching code is commented out because it is breaks the
|
||||
* tests, causing them hang due to writing to or reading from the wrong pipe.
|
||||
*/
|
||||
#if 0
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0;i<nrofpipes;i++)
|
||||
if (pipes[i].mid.oxid==mid->oxid)
|
||||
return S_OK;
|
||||
for (i=0;i<nrofpipes;i++)
|
||||
if (pipes[i].mid.oxid==mid->oxid)
|
||||
return S_OK;
|
||||
#endif
|
||||
|
||||
if (nrofpipes + 1 >= MAX_WINE_PIPES)
|
||||
{
|
||||
FIXME("Out of pipes, please increase MAX_WINE_PIPES\n");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(&(pipes[nrofpipes].mid),mid,sizeof(*mid));
|
||||
pipes[nrofpipes].hPipe = hPipe;
|
||||
pipes[nrofpipes].apt = COM_CurrentApt();
|
||||
assert( pipes[nrofpipes].apt );
|
||||
InitializeCriticalSection(&(pipes[nrofpipes].crit));
|
||||
nrofpipes++;
|
||||
if (startreader) {
|
||||
pipes[nrofpipes-1].hThread = CreateThread(NULL,0,stub_dispatch_thread,(LPVOID)(pipes+(nrofpipes-1)),0,&(pipes[nrofpipes-1].tid));
|
||||
} else {
|
||||
pipes[nrofpipes-1].tid = GetCurrentThreadId();
|
||||
}
|
||||
return S_OK;
|
||||
if (nrofpipes + 1 >= MAX_WINE_PIPES)
|
||||
{
|
||||
FIXME("Out of pipes, please increase MAX_WINE_PIPES\n");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(&(pipes[nrofpipes].mid),mid,sizeof(*mid));
|
||||
pipes[nrofpipes].hPipe = hPipe;
|
||||
pipes[nrofpipes].apt = COM_CurrentApt();
|
||||
assert( pipes[nrofpipes].apt );
|
||||
InitializeCriticalSection(&(pipes[nrofpipes].crit));
|
||||
nrofpipes++;
|
||||
if (startreader) {
|
||||
pipes[nrofpipes-1].hThread = CreateThread(NULL,0,stub_dispatch_thread,(LPVOID)(pipes+(nrofpipes-1)),0,&(pipes[nrofpipes-1].tid));
|
||||
} else {
|
||||
pipes[nrofpipes-1].tid = GetCurrentThreadId();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HANDLE
|
||||
|
@ -222,7 +204,7 @@ PIPE_FindByMID(wine_marshal_id *mid) {
|
|||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static wine_pipe*
|
||||
static struct pipe*
|
||||
PIPE_GetFromMID(wine_marshal_id *mid) {
|
||||
int i;
|
||||
for (i=0;i<nrofpipes;i++) {
|
||||
|
@ -235,7 +217,7 @@ PIPE_GetFromMID(wine_marshal_id *mid) {
|
|||
}
|
||||
|
||||
static HRESULT
|
||||
RPC_GetRequest(wine_rpc_request **req) {
|
||||
RPC_GetRequest(struct rpc **req) {
|
||||
static int reqid = 0xdeadbeef;
|
||||
int i;
|
||||
|
||||
|
@ -251,21 +233,21 @@ RPC_GetRequest(wine_rpc_request **req) {
|
|||
}
|
||||
/* create new */
|
||||
if (reqs)
|
||||
reqs = (wine_rpc_request**)HeapReAlloc(
|
||||
reqs = (struct rpc**)HeapReAlloc(
|
||||
GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
reqs,
|
||||
sizeof(wine_rpc_request*)*(nrofreqs+1)
|
||||
sizeof(struct rpc*)*(nrofreqs+1)
|
||||
);
|
||||
else
|
||||
reqs = (wine_rpc_request**)HeapAlloc(
|
||||
reqs = (struct rpc**)HeapAlloc(
|
||||
GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(wine_rpc_request*)
|
||||
sizeof(struct rpc*)
|
||||
);
|
||||
if (!reqs)
|
||||
return E_OUTOFMEMORY;
|
||||
reqs[nrofreqs] = (wine_rpc_request*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(wine_rpc_request));
|
||||
reqs[nrofreqs] = (struct rpc*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(struct rpc));
|
||||
reqs[nrofreqs]->reqh.reqid = reqid++;
|
||||
reqs[nrofreqs]->resph.reqid = reqs[nrofreqs]->reqh.reqid;
|
||||
reqs[nrofreqs]->hPipe = INVALID_HANDLE_VALUE;
|
||||
|
@ -276,7 +258,7 @@ RPC_GetRequest(wine_rpc_request **req) {
|
|||
}
|
||||
|
||||
static void
|
||||
RPC_FreeRequest(wine_rpc_request *req) {
|
||||
RPC_FreeRequest(struct rpc *req) {
|
||||
req->state = REQSTATE_DONE; /* Just reuse slot. */
|
||||
return;
|
||||
}
|
||||
|
@ -304,7 +286,7 @@ static ULONG WINAPI
|
|||
PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
|
||||
PipeBuf *This = (PipeBuf *)iface;
|
||||
ULONG ref;
|
||||
wine_rpc_disconnect_header header;
|
||||
struct disconnect_header header;
|
||||
HANDLE pipe;
|
||||
DWORD reqtype = REQTYPE_DISCONNECT;
|
||||
DWORD magic;
|
||||
|
@ -318,7 +300,7 @@ PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
|
|||
pipe = PIPE_FindByMID(&This->mid);
|
||||
|
||||
write_pipe(pipe, &reqtype, sizeof(reqtype));
|
||||
write_pipe(pipe, &header, sizeof(wine_rpc_disconnect_header));
|
||||
write_pipe(pipe, &header, sizeof(struct disconnect_header));
|
||||
|
||||
TRACE("written disconnect packet\n");
|
||||
|
||||
|
@ -333,11 +315,8 @@ PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
|
|||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_GetBuffer(
|
||||
LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,REFIID riid
|
||||
) {
|
||||
/*PipeBuf *This = (PipeBuf *)iface;*/
|
||||
|
||||
PipeBuf_GetBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,REFIID riid)
|
||||
{
|
||||
TRACE("(%p,%s)\n",msg,debugstr_guid(riid));
|
||||
/* probably reuses IID in real. */
|
||||
if (msg->cbBuffer && (msg->Buffer == NULL))
|
||||
|
@ -346,7 +325,7 @@ PipeBuf_GetBuffer(
|
|||
}
|
||||
|
||||
static HRESULT
|
||||
COM_InvokeAndRpcSend(wine_rpc_request *req) {
|
||||
COM_InvokeAndRpcSend(struct rpc *req) {
|
||||
IRpcStubBuffer *stub;
|
||||
RPCOLEMESSAGE msg;
|
||||
HRESULT hres;
|
||||
|
@ -376,19 +355,18 @@ COM_InvokeAndRpcSend(wine_rpc_request *req) {
|
|||
hres = write_pipe(req->hPipe,req->Buffer,req->resph.cbBuffer);
|
||||
if (hres) return hres;
|
||||
req->state = REQSTATE_DONE;
|
||||
drs("invoke");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT COM_RpcReceive(wine_pipe *xpipe);
|
||||
static HRESULT COM_RpcReceive(struct pipe *xpipe);
|
||||
|
||||
static HRESULT
|
||||
RPC_QueueRequestAndWait(wine_rpc_request *req) {
|
||||
int i;
|
||||
wine_rpc_request *xreq;
|
||||
HRESULT hres;
|
||||
DWORD reqtype;
|
||||
wine_pipe *xpipe = PIPE_GetFromMID(&(req->reqh.mid));
|
||||
RPC_QueueRequestAndWait(struct rpc *req) {
|
||||
int i;
|
||||
struct rpc *xreq;
|
||||
HRESULT hres;
|
||||
DWORD reqtype;
|
||||
struct pipe *xpipe = PIPE_GetFromMID(&(req->reqh.mid));
|
||||
|
||||
if (!xpipe) {
|
||||
FIXME("no pipe found.\n");
|
||||
|
@ -426,11 +404,10 @@ RPC_QueueRequestAndWait(wine_rpc_request *req) {
|
|||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_SendReceive(
|
||||
LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,ULONG *status
|
||||
) {
|
||||
PipeBuf_SendReceive(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,ULONG *status)
|
||||
{
|
||||
PipeBuf *This = (PipeBuf *)iface;
|
||||
wine_rpc_request *req;
|
||||
struct rpc *req;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("()\n");
|
||||
|
@ -460,21 +437,22 @@ PipeBuf_SendReceive(
|
|||
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_FreeBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg) {
|
||||
PipeBuf_FreeBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg)
|
||||
{
|
||||
FIXME("(%p), stub!\n",msg);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_GetDestCtx(
|
||||
LPRPCCHANNELBUFFER iface,DWORD* pdwDestContext,void** ppvDestContext
|
||||
) {
|
||||
PipeBuf_GetDestCtx(LPRPCCHANNELBUFFER iface,DWORD* pdwDestContext,void** ppvDestContext)
|
||||
{
|
||||
FIXME("(%p,%p), stub!\n",pdwDestContext,ppvDestContext);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_IsConnected(LPRPCCHANNELBUFFER iface) {
|
||||
PipeBuf_IsConnected(LPRPCCHANNELBUFFER iface)
|
||||
{
|
||||
FIXME("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -490,96 +468,99 @@ static IRpcChannelBufferVtbl pipebufvt = {
|
|||
PipeBuf_IsConnected
|
||||
};
|
||||
|
||||
HRESULT
|
||||
PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf) {
|
||||
wine_marshal_id ourid;
|
||||
DWORD res;
|
||||
HANDLE hPipe;
|
||||
HRESULT hres;
|
||||
PipeBuf *pbuf;
|
||||
HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf)
|
||||
{
|
||||
wine_marshal_id ourid;
|
||||
DWORD res;
|
||||
HANDLE hPipe;
|
||||
HRESULT hres;
|
||||
PipeBuf *pbuf;
|
||||
|
||||
hPipe = PIPE_FindByMID(mid);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
char pipefn[200];
|
||||
sprintf(pipefn,OLESTUBMGR"_%08lx%08lx",(DWORD)(mid->oxid >> 32),(DWORD)mid->oxid);
|
||||
hPipe = CreateFileA(
|
||||
pipefn,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
0
|
||||
);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
FIXME("Could not open named pipe %s, le is %lx\n",pipefn,GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
hres = PIPE_RegisterPipe(mid, hPipe, FALSE);
|
||||
if (hres) return hres;
|
||||
memset(&ourid,0,sizeof(ourid));
|
||||
ourid.oxid = COM_CurrentApt()->oxid;
|
||||
if (!WriteFile(hPipe,&ourid,sizeof(ourid),&res,NULL)||(res!=sizeof(ourid))) {
|
||||
ERR("Failed writing startup mid!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
pbuf = (PipeBuf*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PipeBuf));
|
||||
pbuf->lpVtbl = &pipebufvt;
|
||||
pbuf->ref = 1;
|
||||
memcpy(&(pbuf->mid),mid,sizeof(*mid));
|
||||
*pipebuf = (IRpcChannelBuffer*)pbuf;
|
||||
return S_OK;
|
||||
hPipe = PIPE_FindByMID(mid);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
char pipefn[200];
|
||||
|
||||
sprintf(pipefn,OLESTUBMGR"_%08lx%08lx",(DWORD)(mid->oxid >> 32),(DWORD)mid->oxid);
|
||||
hPipe = CreateFileA(pipefn, GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, 0, 0);
|
||||
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
FIXME("Could not open named pipe %s, le is %lx\n",pipefn,GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hres = PIPE_RegisterPipe(mid, hPipe, FALSE);
|
||||
if (hres) return hres;
|
||||
|
||||
memset(&ourid,0,sizeof(ourid));
|
||||
ourid.oxid = COM_CurrentApt()->oxid;
|
||||
|
||||
if (!WriteFile(hPipe,&ourid,sizeof(ourid),&res,NULL)||(res!=sizeof(ourid))) {
|
||||
ERR("Failed writing startup mid!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
pbuf = (PipeBuf*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PipeBuf));
|
||||
pbuf->lpVtbl = &pipebufvt;
|
||||
pbuf->ref = 1;
|
||||
memcpy(&(pbuf->mid),mid,sizeof(*mid));
|
||||
|
||||
*pipebuf = (IRpcChannelBuffer*)pbuf;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
create_server(REFCLSID rclsid) {
|
||||
static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
|
||||
HKEY key;
|
||||
char buf[200];
|
||||
HRESULT hres = E_UNEXPECTED;
|
||||
char xclsid[80];
|
||||
WCHAR exe[MAX_PATH+1];
|
||||
DWORD exelen = sizeof(exe);
|
||||
WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
|
||||
STARTUPINFOW sinfo;
|
||||
PROCESS_INFORMATION pinfo;
|
||||
create_server(REFCLSID rclsid)
|
||||
{
|
||||
static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
|
||||
HKEY key;
|
||||
char buf[200];
|
||||
HRESULT hres = E_UNEXPECTED;
|
||||
char xclsid[80];
|
||||
WCHAR exe[MAX_PATH+1];
|
||||
DWORD exelen = sizeof(exe);
|
||||
WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
|
||||
STARTUPINFOW sinfo;
|
||||
PROCESS_INFORMATION pinfo;
|
||||
|
||||
WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
|
||||
WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
|
||||
|
||||
sprintf(buf,"CLSID\\%s\\LocalServer32",xclsid);
|
||||
hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key);
|
||||
sprintf(buf,"CLSID\\%s\\LocalServer32",xclsid);
|
||||
hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key);
|
||||
|
||||
if (hres != ERROR_SUCCESS) {
|
||||
WARN("CLSID %s not registered as LocalServer32\n", xclsid);
|
||||
return REGDB_E_READREGDB; /* Probably */
|
||||
}
|
||||
if (hres != ERROR_SUCCESS) {
|
||||
WARN("CLSID %s not registered as LocalServer32\n", xclsid);
|
||||
return REGDB_E_READREGDB; /* Probably */
|
||||
}
|
||||
|
||||
memset(exe,0,sizeof(exe));
|
||||
hres= RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)exe, &exelen);
|
||||
RegCloseKey(key);
|
||||
if (hres) {
|
||||
WARN("No default value for LocalServer32 key\n");
|
||||
return REGDB_E_CLASSNOTREG; /* FIXME: check retval */
|
||||
}
|
||||
memset(exe,0,sizeof(exe));
|
||||
hres= RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)exe, &exelen);
|
||||
RegCloseKey(key);
|
||||
if (hres) {
|
||||
WARN("No default value for LocalServer32 key\n");
|
||||
return REGDB_E_CLASSNOTREG; /* FIXME: check retval */
|
||||
}
|
||||
|
||||
memset(&sinfo,0,sizeof(sinfo));
|
||||
sinfo.cb = sizeof(sinfo);
|
||||
memset(&sinfo,0,sizeof(sinfo));
|
||||
sinfo.cb = sizeof(sinfo);
|
||||
|
||||
/* EXE servers are started with the -Embedding switch. MSDN also claims /Embedding is used,
|
||||
9x does -Embedding, perhaps an 9x/NT difference? */
|
||||
/* EXE servers are started with the -Embedding switch. MSDN also claims /Embedding is used,
|
||||
* 9x does -Embedding, perhaps an 9x/NT difference?
|
||||
*/
|
||||
|
||||
strcpyW(command, exe);
|
||||
strcatW(command, embedding);
|
||||
strcpyW(command, exe);
|
||||
strcatW(command, embedding);
|
||||
|
||||
TRACE("activating local server '%s' for %s\n", debugstr_w(command), xclsid);
|
||||
TRACE("activating local server '%s' for %s\n", debugstr_w(command), xclsid);
|
||||
|
||||
if (!CreateProcessW(exe, command, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) {
|
||||
WARN("failed to run local server %s\n", debugstr_w(exe));
|
||||
return E_FAIL;
|
||||
}
|
||||
if (!CreateProcessW(exe, command, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) {
|
||||
WARN("failed to run local server %s\n", debugstr_w(exe));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -589,7 +570,7 @@ static DWORD
|
|||
start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
|
||||
{
|
||||
SC_HANDLE handle, hsvc;
|
||||
DWORD r = ERROR_FUNCTION_FAILED;
|
||||
DWORD r = ERROR_FUNCTION_FAILED;
|
||||
|
||||
TRACE("Starting service %s %ld params\n", debugstr_w(name), num);
|
||||
|
||||
|
@ -603,7 +584,7 @@ start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
|
|||
r = ERROR_SUCCESS;
|
||||
else
|
||||
r = GetLastError();
|
||||
if (r==ERROR_SERVICE_ALREADY_RUNNING)
|
||||
if (r == ERROR_SERVICE_ALREADY_RUNNING)
|
||||
r = ERROR_SUCCESS;
|
||||
CloseServiceHandle(hsvc);
|
||||
}
|
||||
|
@ -631,10 +612,8 @@ create_local_service(REFCLSID rclsid)
|
|||
static const WCHAR szClsId[] = { 'C','L','S','I','D','\\',0 };
|
||||
static const WCHAR szAppId[] = { 'A','p','p','I','d',0 };
|
||||
static const WCHAR szAppIdKey[] = { 'A','p','p','I','d','\\',0 };
|
||||
static const WCHAR szLocalService[] = {
|
||||
'L','o','c','a','l','S','e','r','v','i','c','e',0 };
|
||||
static const WCHAR szServiceParams[] = {
|
||||
'S','e','r','v','i','c','e','P','a','r','a','m','s',0};
|
||||
static const WCHAR szLocalService[] = { 'L','o','c','a','l','S','e','r','v','i','c','e',0 };
|
||||
static const WCHAR szServiceParams[] = {'S','e','r','v','i','c','e','P','a','r','a','m','s',0};
|
||||
HKEY hkey;
|
||||
LONG r;
|
||||
DWORD type, sz;
|
||||
|
@ -692,78 +671,77 @@ create_local_service(REFCLSID rclsid)
|
|||
}
|
||||
|
||||
/* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, Figure 4 */
|
||||
HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) {
|
||||
HRESULT hres;
|
||||
HANDLE hPipe;
|
||||
char pipefn[200];
|
||||
DWORD res,bufferlen;
|
||||
char marshalbuffer[200];
|
||||
IStream *pStm;
|
||||
LARGE_INTEGER seekto;
|
||||
ULARGE_INTEGER newpos;
|
||||
int tries = 0;
|
||||
#define MAXTRIES 10000
|
||||
HRESULT
|
||||
create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
||||
{
|
||||
HRESULT hres;
|
||||
HANDLE hPipe;
|
||||
char pipefn[200];
|
||||
DWORD res, bufferlen;
|
||||
char marshalbuffer[200];
|
||||
IStream *pStm;
|
||||
LARGE_INTEGER seekto;
|
||||
ULARGE_INTEGER newpos;
|
||||
int tries = 0;
|
||||
|
||||
static const int MAXTRIES = 10000;
|
||||
|
||||
TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
|
||||
TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
|
||||
|
||||
strcpy(pipefn,PIPEPREF);
|
||||
WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF));
|
||||
strcpy(pipefn,PIPEPREF);
|
||||
WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF));
|
||||
|
||||
while (tries++<MAXTRIES) {
|
||||
TRACE("waiting for %s\n", pipefn);
|
||||
while (tries++ < MAXTRIES) {
|
||||
TRACE("waiting for %s\n", pipefn);
|
||||
|
||||
WaitNamedPipeA( pipefn, NMPWAIT_WAIT_FOREVER );
|
||||
hPipe = CreateFileA(
|
||||
pipefn,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
0
|
||||
);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
if (tries == 1) {
|
||||
if ( (hres = create_server(rclsid)) &&
|
||||
(hres = create_local_service(rclsid)) )
|
||||
return hres;
|
||||
Sleep(1000);
|
||||
} else {
|
||||
WARN("Could not open named pipe to broker %s, le is %lx\n",pipefn,GetLastError());
|
||||
Sleep(1000);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
bufferlen = 0;
|
||||
if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) {
|
||||
FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid));
|
||||
Sleep(1000);
|
||||
continue;
|
||||
}
|
||||
TRACE("read marshal id from pipe\n");
|
||||
CloseHandle(hPipe);
|
||||
break;
|
||||
}
|
||||
if (tries>=MAXTRIES)
|
||||
return E_NOINTERFACE;
|
||||
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
|
||||
if (hres) return hres;
|
||||
hres = IStream_Write(pStm,marshalbuffer,bufferlen,&res);
|
||||
if (hres) goto out;
|
||||
seekto.u.LowPart = 0;seekto.u.HighPart = 0;
|
||||
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
|
||||
TRACE("unmarshalling classfactory\n");
|
||||
hres = CoUnmarshalInterface(pStm,&IID_IClassFactory,ppv);
|
||||
WaitNamedPipeA( pipefn, NMPWAIT_WAIT_FOREVER );
|
||||
hPipe = CreateFileA(pipefn, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
if (tries == 1) {
|
||||
if ( (hres = create_server(rclsid)) &&
|
||||
(hres = create_local_service(rclsid)) )
|
||||
return hres;
|
||||
Sleep(1000);
|
||||
} else {
|
||||
WARN("Could not open named pipe to broker %s, le is %lx\n",pipefn,GetLastError());
|
||||
Sleep(1000);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
bufferlen = 0;
|
||||
if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) {
|
||||
FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid));
|
||||
Sleep(1000);
|
||||
continue;
|
||||
}
|
||||
TRACE("read marshal id from pipe\n");
|
||||
CloseHandle(hPipe);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tries >= MAXTRIES)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
|
||||
if (hres) return hres;
|
||||
hres = IStream_Write(pStm,marshalbuffer,bufferlen,&res);
|
||||
if (hres) goto out;
|
||||
seekto.u.LowPart = 0;seekto.u.HighPart = 0;
|
||||
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
|
||||
|
||||
TRACE("unmarshalling classfactory\n");
|
||||
hres = CoUnmarshalInterface(pStm,&IID_IClassFactory,ppv);
|
||||
out:
|
||||
IStream_Release(pStm);
|
||||
return hres;
|
||||
IStream_Release(pStm);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
static void WINAPI
|
||||
PIPE_StartRequestThread(HANDLE xhPipe) {
|
||||
wine_marshal_id remoteid;
|
||||
HRESULT hres;
|
||||
PIPE_StartRequestThread(HANDLE xhPipe)
|
||||
{
|
||||
wine_marshal_id remoteid;
|
||||
HRESULT hres;
|
||||
|
||||
hres = read_pipe(xhPipe,&remoteid,sizeof(remoteid));
|
||||
if (hres) {
|
||||
|
@ -774,19 +752,18 @@ PIPE_StartRequestThread(HANDLE xhPipe) {
|
|||
}
|
||||
|
||||
static HRESULT
|
||||
COM_RpcReceive(wine_pipe *xpipe) {
|
||||
DWORD reqtype;
|
||||
HRESULT hres = S_OK;
|
||||
HANDLE xhPipe = xpipe->hPipe;
|
||||
COM_RpcReceive(struct pipe *xpipe) {
|
||||
DWORD reqtype;
|
||||
HRESULT hres = S_OK;
|
||||
HANDLE xhPipe = xpipe->hPipe;
|
||||
|
||||
/*FIXME("%lx %d reading reqtype\n",GetCurrentProcessId(),xhPipe);*/
|
||||
hres = read_pipe(xhPipe,&reqtype,sizeof(reqtype));
|
||||
if (hres) goto end;
|
||||
EnterCriticalSection(&(xpipe->crit));
|
||||
/*FIXME("%lx got reqtype %ld\n",GetCurrentProcessId(),reqtype);*/
|
||||
|
||||
if (reqtype == REQTYPE_DISCONNECT) { /* only received by servers */
|
||||
wine_rpc_disconnect_header header;
|
||||
/* only received by servers */
|
||||
if (reqtype == REQTYPE_DISCONNECT) {
|
||||
struct disconnect_header header;
|
||||
struct stub_manager *stubmgr;
|
||||
DWORD magic = 0xcafebabe;
|
||||
APARTMENT *apt;
|
||||
|
@ -821,25 +798,29 @@ disconnect_end:
|
|||
write_pipe(xhPipe, &magic, sizeof(magic));
|
||||
goto end;
|
||||
} else if (reqtype == REQTYPE_REQUEST) {
|
||||
wine_rpc_request *xreq;
|
||||
struct rpc *xreq;
|
||||
|
||||
RPC_GetRequest(&xreq);
|
||||
xreq->hPipe = xhPipe;
|
||||
hres = read_pipe(xhPipe,&(xreq->reqh),sizeof(xreq->reqh));
|
||||
if (hres) goto end;
|
||||
|
||||
xreq->resph.reqid = xreq->reqh.reqid;
|
||||
xreq->Buffer = HeapAlloc(GetProcessHeap(),0, xreq->reqh.cbBuffer);
|
||||
hres = read_pipe(xhPipe,xreq->Buffer,xreq->reqh.cbBuffer);
|
||||
if (hres) goto end;
|
||||
|
||||
xreq->state = REQSTATE_REQ_GOT;
|
||||
goto end;
|
||||
} else if (reqtype == REQTYPE_RESPONSE) {
|
||||
wine_rpc_response_header resph;
|
||||
struct response_header resph;
|
||||
int i;
|
||||
|
||||
hres = read_pipe(xhPipe,&resph,sizeof(resph));
|
||||
if (hres) goto end;
|
||||
|
||||
for (i=nrofreqs;i--;) {
|
||||
wine_rpc_request *xreq = reqs[i];
|
||||
struct rpc *xreq = reqs[i];
|
||||
if (xreq->state != REQSTATE_REQ_WAITING_FOR_REPLY)
|
||||
continue;
|
||||
if (xreq->reqh.reqid == resph.reqid) {
|
||||
|
@ -857,10 +838,12 @@ disconnect_end:
|
|||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ERR("Did not find request for id %lx\n",resph.reqid);
|
||||
hres = S_OK;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ERR("Unknown reqtype %ld\n",reqtype);
|
||||
hres = E_FAIL;
|
||||
end:
|
||||
|
@ -871,9 +854,9 @@ end:
|
|||
/* This thread listens on the given pipe for requests to a particular stub manager */
|
||||
static DWORD WINAPI stub_dispatch_thread(LPVOID param)
|
||||
{
|
||||
wine_pipe *xpipe = (wine_pipe*)param;
|
||||
HANDLE xhPipe = xpipe->hPipe;
|
||||
HRESULT hres = S_OK;
|
||||
struct pipe *xpipe = (struct pipe*)param;
|
||||
HANDLE xhPipe = xpipe->hPipe;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("starting for apartment OXID %08lx%08lx\n", (DWORD)(xpipe->mid.oxid >> 32), (DWORD)(xpipe->mid.oxid));
|
||||
|
||||
|
@ -887,7 +870,7 @@ static DWORD WINAPI stub_dispatch_thread(LPVOID param)
|
|||
if (hres) break;
|
||||
|
||||
for (i=nrofreqs;i--;) {
|
||||
wine_rpc_request *xreq = reqs[i];
|
||||
struct rpc *xreq = reqs[i];
|
||||
if ((xreq->state == REQSTATE_REQ_GOT) && (xreq->hPipe == xhPipe)) {
|
||||
hres = COM_InvokeAndRpcSend(xreq);
|
||||
if (!hres) break;
|
||||
|
|
Loading…
Reference in New Issue