source: trunk/src/ole32/rpc.c@ 8553

Last change on this file since 8553 was 8441, checked in by sandervl, 23 years ago

Wine resync

File size: 18.0 KB
Line 
1/*
2 * (Local) RPC Stuff
3 *
4 * Copyright 2002 Marcus Meissner
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "config.h"
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include <assert.h>
27
28#include "windef.h"
29#include "objbase.h"
30#include "ole2.h"
31#include "ole2ver.h"
32#include "rpc.h"
33#include "winerror.h"
34#include "winreg.h"
35#include "wownt32.h"
36#include "wtypes.h"
37#include "wine/unicode.h"
38#include "wine/obj_base.h"
39#include "wine/obj_clientserver.h"
40#include "wine/obj_misc.h"
41#include "wine/obj_marshal.h"
42#include "wine/obj_storage.h"
43#include "wine/obj_channel.h"
44#include "wine/winbase16.h"
45#include "compobj_private.h"
46#include "ifs.h"
47
48#include "compobj_private.h"
49
50#include "wine/debug.h"
51
52WINE_DEFAULT_DEBUG_CHANNEL(ole);
53
54typedef struct _wine_rpc_request {
55 int state;
56 HANDLE hPipe; /* temp copy of handle */
57 wine_rpc_request_header reqh;
58 wine_rpc_response_header resph;
59 LPBYTE Buffer;
60} wine_rpc_request;
61
62static wine_rpc_request **reqs = NULL;
63static int nrofreqs = 0;
64
65/* This pipe is _thread_ based */
66typedef struct _wine_pipe {
67 wine_marshal_id mid; /* target mid */
68 DWORD tid; /* thread in which we execute */
69 HANDLE hPipe;
70
71 int pending;
72 HANDLE hThread;
73 CRITICAL_SECTION crit;
74} wine_pipe;
75
76static wine_pipe *pipes = NULL;
77static int nrofpipes = 0;
78
79typedef struct _PipeBuf {
80 ICOM_VTABLE(IRpcChannelBuffer) *lpVtbl;
81 DWORD ref;
82
83 wine_marshal_id mid;
84 wine_pipe *pipe;
85} PipeBuf;
86
87static int nrofreaders = 0;
88
89static HRESULT WINAPI
90_xread(HANDLE hf, LPVOID ptr, DWORD size) {
91 DWORD res;
92 if (!ReadFile(hf,ptr,size,&res,NULL)) {
93 FIXME("Failed to read from %x, le is %lx\n",hf,GetLastError());
94 return E_FAIL;
95 }
96 if (res!=size) {
97 FIXME("Read only %ld of %ld bytes.\n",res,size);
98 return E_FAIL;
99 }
100 return S_OK;
101}
102
103static void
104drs(LPCSTR where) {
105 int i, states[10];
106
107 return ;
108
109 memset(states,0,sizeof(states));
110 for (i=nrofreqs;i--;)
111 states[reqs[i]->state]++;
112 FIXME("%lx/%s/%d: rq %d, w %d, rg %d, rsq %d, rsg %d, d %d\n",
113 GetCurrentProcessId(),
114 where,
115 nrofreaders,
116 states[REQSTATE_REQ_QUEUED],
117 states[REQSTATE_REQ_WAITING_FOR_REPLY],
118 states[REQSTATE_REQ_GOT],
119 states[REQSTATE_RESP_QUEUED],
120 states[REQSTATE_RESP_GOT],
121 states[REQSTATE_DONE]
122 );
123}
124
125static HRESULT WINAPI
126_xwrite(HANDLE hf, LPVOID ptr, DWORD size) {
127 DWORD res;
128 if (!WriteFile(hf,ptr,size,&res,NULL)) {
129 FIXME("Failed to write to %x, le is %lx\n",hf,GetLastError());
130 return E_FAIL;
131 }
132 if (res!=size) {
133 FIXME("Wrote only %ld of %ld bytes.\n",res,size);
134 return E_FAIL;
135 }
136 return S_OK;
137}
138
139static DWORD WINAPI _StubReaderThread(LPVOID);
140
141static HRESULT
142PIPE_RegisterPipe(wine_marshal_id *mid, HANDLE hPipe, BOOL startreader) {
143 int i;
144 char pipefn[100];
145
146 for (i=0;i<nrofpipes;i++)
147 if (pipes[i].mid.processid==mid->processid)
148 return S_OK;
149 if (pipes)
150 pipes=(wine_pipe*)HeapReAlloc(GetProcessHeap(),0,pipes,sizeof(pipes[0])*(nrofpipes+1));
151 else
152 pipes=(wine_pipe*)HeapAlloc(GetProcessHeap(),0,sizeof(pipes[0]));
153 if (!pipes) return E_OUTOFMEMORY;
154 sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
155 memcpy(&(pipes[nrofpipes].mid),mid,sizeof(*mid));
156 pipes[nrofpipes].hPipe = hPipe;
157 InitializeCriticalSection(&(pipes[nrofpipes].crit));
158 nrofpipes++;
159 if (startreader) {
160#ifdef __WIN32OS2__
161 pipes[nrofpipes-1].hThread = CreateThread(NULL,0,_StubReaderThread,(LPVOID)(pipes+(nrofpipes-1)),0,&(pipes[nrofpipes-1].tid));
162#else
163 pipes[nrofpipes-1].hThread = CreateThread(NULL,0,_StubReaderThread,(LPVOID)pipes+(nrofpipes-1),0,&(pipes[nrofpipes-1].tid));
164#endif
165 } else {
166 pipes[nrofpipes-1].tid = GetCurrentThreadId();
167 }
168 return S_OK;
169}
170
171static HANDLE
172PIPE_FindByMID(wine_marshal_id *mid) {
173 int i;
174 for (i=0;i<nrofpipes;i++)
175 if ((pipes[i].mid.processid==mid->processid) &&
176 (GetCurrentThreadId()==pipes[i].tid)
177 )
178 return pipes[i].hPipe;
179 return INVALID_HANDLE_VALUE;
180}
181
182static wine_pipe*
183PIPE_GetFromMID(wine_marshal_id *mid) {
184 int i;
185 for (i=0;i<nrofpipes;i++) {
186 if ((pipes[i].mid.processid==mid->processid) &&
187 (GetCurrentThreadId()==pipes[i].tid)
188 )
189 return pipes+i;
190 }
191 return NULL;
192}
193
194static HRESULT
195RPC_GetRequest(wine_rpc_request **req) {
196 static int reqid = 0xdeadbeef;
197 int i;
198
199 for (i=0;i<nrofreqs;i++) { /* try to reuse */
200 if (reqs[i]->state == REQSTATE_DONE) {
201 reqs[i]->reqh.reqid = reqid++;
202 reqs[i]->resph.reqid = reqs[i]->reqh.reqid;
203 reqs[i]->hPipe = INVALID_HANDLE_VALUE;
204 *req = reqs[i];
205 reqs[i]->state = REQSTATE_START;
206 return S_OK;
207 }
208 }
209 /* create new */
210 if (reqs)
211 reqs = (wine_rpc_request**)HeapReAlloc(
212 GetProcessHeap(),
213 HEAP_ZERO_MEMORY,
214 reqs,
215 sizeof(wine_rpc_request*)*(nrofreqs+1)
216 );
217 else
218 reqs = (wine_rpc_request**)HeapAlloc(
219 GetProcessHeap(),
220 HEAP_ZERO_MEMORY,
221 sizeof(wine_rpc_request*)
222 );
223 if (!reqs)
224 return E_OUTOFMEMORY;
225 reqs[nrofreqs] = (wine_rpc_request*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(wine_rpc_request));
226 reqs[nrofreqs]->reqh.reqid = reqid++;
227 reqs[nrofreqs]->resph.reqid = reqs[nrofreqs]->reqh.reqid;
228 reqs[nrofreqs]->hPipe = INVALID_HANDLE_VALUE;
229 *req = reqs[nrofreqs];
230 reqs[nrofreqs]->state = REQSTATE_START;
231 nrofreqs++;
232 return S_OK;
233}
234
235static void
236RPC_FreeRequest(wine_rpc_request *req) {
237 req->state = REQSTATE_DONE; /* Just reuse slot. */
238 return;
239}
240
241static HRESULT WINAPI
242PipeBuf_QueryInterface(
243 LPRPCCHANNELBUFFER iface,REFIID riid,LPVOID *ppv
244) {
245 *ppv = NULL;
246 if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown)) {
247 *ppv = (LPVOID)iface;
248 IUnknown_AddRef(iface);
249 return S_OK;
250 }
251 return E_NOINTERFACE;
252}
253
254static ULONG WINAPI
255PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) {
256 ICOM_THIS(PipeBuf,iface);
257 This->ref++;
258 return This->ref;
259}
260
261static ULONG WINAPI
262PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
263 ICOM_THIS(PipeBuf,iface);
264 This->ref--;
265 if (This->ref)
266 return This->ref;
267 ERR("Free all stuff.\n");
268 HeapFree(GetProcessHeap(),0,This);
269 return 0;
270}
271
272static HRESULT WINAPI
273PipeBuf_GetBuffer(
274 LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,REFIID riid
275) {
276 /*ICOM_THIS(PipeBuf,iface);*/
277
278 TRACE("(%p,%s), slightly wrong.\n",msg,debugstr_guid(riid));
279 /* probably reuses IID in real. */
280 if (msg->cbBuffer && (msg->Buffer == NULL))
281 msg->Buffer = HeapAlloc(GetProcessHeap(),0,msg->cbBuffer);
282 return S_OK;
283}
284
285static HRESULT
286_invoke_onereq(wine_rpc_request *req) {
287 IRpcStubBuffer *stub;
288 RPCOLEMESSAGE msg;
289 HRESULT hres;
290 DWORD reqtype;
291
292 hres = MARSHAL_Find_Stub_Buffer(&(req->reqh.mid),&stub);
293 if (hres) {
294 ERR("Stub not found?\n");
295 return hres;
296 }
297 msg.Buffer = req->Buffer;
298 msg.iMethod = req->reqh.iMethod;
299 msg.cbBuffer = req->reqh.cbBuffer;
300 req->state = REQSTATE_INVOKING;
301 req->resph.retval = IRpcStubBuffer_Invoke(stub,&msg,NULL);
302 req->Buffer = msg.Buffer;
303 req->resph.cbBuffer = msg.cbBuffer;
304 reqtype = REQTYPE_RESPONSE;
305 hres = _xwrite(req->hPipe,&reqtype,sizeof(reqtype));
306 if (hres) return hres;
307 hres = _xwrite(req->hPipe,&(req->resph),sizeof(req->resph));
308 if (hres) return hres;
309 hres = _xwrite(req->hPipe,req->Buffer,req->resph.cbBuffer);
310 if (hres) return hres;
311 req->state = REQSTATE_DONE;
312 drs("invoke");
313 return S_OK;
314}
315
316static HRESULT _read_one(wine_pipe *xpipe);
317
318static HRESULT
319RPC_QueueRequestAndWait(wine_rpc_request *req) {
320 int i;
321 wine_rpc_request *xreq;
322 HRESULT hres;
323 DWORD reqtype;
324 wine_pipe *xpipe = PIPE_GetFromMID(&(req->reqh.mid));
325
326 if (!xpipe) {
327 FIXME("no pipe found.\n");
328 return E_POINTER;
329 }
330 if (GetCurrentProcessId() == req->reqh.mid.processid) {
331 ERR("In current process?\n");
332 return E_FAIL;
333 }
334 req->hPipe = xpipe->hPipe;
335 req->state = REQSTATE_REQ_WAITING_FOR_REPLY;
336 reqtype = REQTYPE_REQUEST;
337 hres = _xwrite(req->hPipe,&reqtype,sizeof(reqtype));
338 if (hres) return hres;
339 hres = _xwrite(req->hPipe,&(req->reqh),sizeof(req->reqh));
340 if (hres) return hres;
341 hres = _xwrite(req->hPipe,req->Buffer,req->reqh.cbBuffer);
342 if (hres) return hres;
343
344 while (1) {
345 /*WaitForSingleObject(hRpcChanged,INFINITE);*/
346 hres = _read_one(xpipe);
347 if (hres) break;
348
349 for (i=0;i<nrofreqs;i++) {
350 xreq = reqs[i];
351 if ((xreq->state==REQSTATE_REQ_GOT) && (xreq->hPipe==req->hPipe)) {
352 _invoke_onereq(xreq);
353 }
354 }
355 if (req->state == REQSTATE_RESP_GOT)
356 return S_OK;
357 }
358 return hres;
359}
360
361static HRESULT WINAPI
362PipeBuf_SendReceive(
363 LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,ULONG *status
364) {
365 ICOM_THIS(PipeBuf,iface);
366 wine_rpc_request *req;
367 HRESULT hres;
368
369 TRACE("()\n");
370
371 if (This->mid.processid == GetCurrentProcessId()) {
372 ERR("Need to call directly!\n");
373 return E_FAIL;
374 }
375
376 hres = RPC_GetRequest(&req);
377 if (hres) return hres;
378 req->reqh.iMethod = msg->iMethod;
379 req->reqh.cbBuffer = msg->cbBuffer;
380 memcpy(&(req->reqh.mid),&(This->mid),sizeof(This->mid));
381 req->Buffer = msg->Buffer;
382 hres = RPC_QueueRequestAndWait(req);
383 if (hres) {
384 RPC_FreeRequest(req);
385 return hres;
386 }
387 msg->cbBuffer = req->resph.cbBuffer;
388 msg->Buffer = req->Buffer;
389 *status = req->resph.retval;
390 RPC_FreeRequest(req);
391 return S_OK;
392}
393
394
395static HRESULT WINAPI
396PipeBuf_FreeBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg) {
397 FIXME("(%p), stub!\n",msg);
398 return E_FAIL;
399}
400
401static HRESULT WINAPI
402PipeBuf_GetDestCtx(
403 LPRPCCHANNELBUFFER iface,DWORD* pdwDestContext,void** ppvDestContext
404) {
405 FIXME("(%p,%p), stub!\n",pdwDestContext,ppvDestContext);
406 return E_FAIL;
407}
408
409static HRESULT WINAPI
410PipeBuf_IsConnected(LPRPCCHANNELBUFFER iface) {
411 FIXME("(), stub!\n");
412 return S_OK;
413}
414
415static ICOM_VTABLE(IRpcChannelBuffer) pipebufvt = {
416 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
417 PipeBuf_QueryInterface,
418 PipeBuf_AddRef,
419 PipeBuf_Release,
420 PipeBuf_GetBuffer,
421 PipeBuf_SendReceive,
422 PipeBuf_FreeBuffer,
423 PipeBuf_GetDestCtx,
424 PipeBuf_IsConnected
425};
426
427HRESULT
428PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf) {
429 wine_marshal_id ourid;
430 DWORD res;
431 HANDLE hPipe;
432 HRESULT hres;
433 PipeBuf *pbuf;
434
435 hPipe = PIPE_FindByMID(mid);
436 if (hPipe == INVALID_HANDLE_VALUE) {
437 char pipefn[200];
438 sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
439 hPipe = CreateFileA(
440 pipefn,
441 GENERIC_READ|GENERIC_WRITE,
442 0,
443 NULL,
444 OPEN_EXISTING,
445 0,
446 -1
447 );
448 if (hPipe == INVALID_HANDLE_VALUE) {
449 FIXME("Could not open named pipe %s, le is %lx\n",pipefn,GetLastError());
450 return E_FAIL;
451 }
452 hres = PIPE_RegisterPipe(mid, hPipe, FALSE);
453 if (hres) return hres;
454 memset(&ourid,0,sizeof(ourid));
455 ourid.processid = GetCurrentProcessId();
456 if (!WriteFile(hPipe,&ourid,sizeof(ourid),&res,NULL)||(res!=sizeof(ourid))) {
457 ERR("Failed writing startup mid!\n");
458 return E_FAIL;
459 }
460 }
461 pbuf = (PipeBuf*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PipeBuf));
462 pbuf->lpVtbl = &pipebufvt;
463 pbuf->ref = 1;
464 memcpy(&(pbuf->mid),mid,sizeof(*mid));
465 *pipebuf = (IRpcChannelBuffer*)pbuf;
466 return S_OK;
467}
468
469static HRESULT
470create_server(REFCLSID rclsid) {
471 HKEY key;
472 char buf[200];
473 HRESULT hres = E_UNEXPECTED;
474 char xclsid[80];
475 WCHAR dllName[MAX_PATH+1];
476 DWORD dllNameLen = sizeof(dllName);
477 STARTUPINFOW sinfo;
478 PROCESS_INFORMATION pinfo;
479
480 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
481
482 sprintf(buf,"CLSID\\%s\\LocalServer32",xclsid);
483 hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key);
484
485 if (hres != ERROR_SUCCESS)
486 return REGDB_E_CLASSNOTREG;
487
488 memset(dllName,0,sizeof(dllName));
489 hres= RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)dllName,&dllNameLen);
490 if (hres)
491 return REGDB_E_CLASSNOTREG; /* FIXME: check retval */
492 RegCloseKey(key);
493 memset(&sinfo,0,sizeof(sinfo));
494 sinfo.cb = sizeof(sinfo);
495 if (!CreateProcessW(NULL,dllName,NULL,NULL,FALSE,0,NULL,NULL,&sinfo,&pinfo))
496 return E_FAIL;
497 return S_OK;
498}
499/* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, Figure 4 */
500HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) {
501 HRESULT hres;
502 HANDLE hPipe;
503 char pipefn[200];
504 DWORD res,bufferlen;
505 char marshalbuffer[200];
506 IStream *pStm;
507 LARGE_INTEGER seekto;
508 ULARGE_INTEGER newpos;
509 int tries = 0;
510#define MAXTRIES 10000
511
512 strcpy(pipefn,PIPEPREF);
513 WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF));
514
515 while (tries++<MAXTRIES) {
516 hPipe = CreateFileA(
517 pipefn,
518 GENERIC_READ|GENERIC_WRITE,
519 0,
520 NULL,
521 OPEN_EXISTING,
522 0,
523 -1
524 );
525 if (hPipe == INVALID_HANDLE_VALUE) {
526 if (tries == 1) {
527 if ((hres = create_server(rclsid)))
528 return hres;
529 Sleep(1000);
530 } else {
531 WARN("Could not open named pipe to broker %s, le is %lx\n",pipefn,GetLastError());
532 Sleep(1000);
533 }
534 continue;
535 }
536 bufferlen = 0;
537 if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) {
538 FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid));
539 Sleep(1000);
540 continue;
541 }
542 CloseHandle(hPipe);
543 break;
544 }
545 if (tries>=MAXTRIES)
546 return E_NOINTERFACE;
547 hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
548 if (hres) return hres;
549 hres = IStream_Write(pStm,marshalbuffer,bufferlen,&res);
550 if (hres) goto out;
551 seekto.s.LowPart = 0;seekto.s.HighPart = 0;
552 hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
553 hres = CoUnmarshalInterface(pStm,&IID_IClassFactory,ppv);
554out:
555 IStream_Release(pStm);
556 return hres;
557}
558
559
560static void WINAPI
561PIPE_StartRequestThread(HANDLE xhPipe) {
562 wine_marshal_id remoteid;
563 HRESULT hres;
564
565 hres = _xread(xhPipe,&remoteid,sizeof(remoteid));
566 if (hres) {
567 ERR("Failed to read remote mid!\n");
568 return;
569 }
570 PIPE_RegisterPipe(&remoteid,xhPipe, TRUE);
571}
572
573static HRESULT
574_read_one(wine_pipe *xpipe) {
575 DWORD reqtype;
576 HRESULT hres = S_OK;
577 HANDLE xhPipe = xpipe->hPipe;
578
579 /*FIXME("%lx %d reading reqtype\n",GetCurrentProcessId(),xhPipe);*/
580 hres = _xread(xhPipe,&reqtype,sizeof(reqtype));
581 if (hres) goto end;
582 EnterCriticalSection(&(xpipe->crit));
583 /*FIXME("%lx got reqtype %ld\n",GetCurrentProcessId(),reqtype);*/
584
585 if (reqtype == REQTYPE_REQUEST) {
586 wine_rpc_request *xreq;
587 RPC_GetRequest(&xreq);
588 xreq->hPipe = xhPipe;
589 hres = _xread(xhPipe,&(xreq->reqh),sizeof(xreq->reqh));
590 if (hres) goto end;
591 xreq->resph.reqid = xreq->reqh.reqid;
592 xreq->Buffer = HeapAlloc(GetProcessHeap(),0, xreq->reqh.cbBuffer);
593 hres = _xread(xhPipe,xreq->Buffer,xreq->reqh.cbBuffer);
594 if (hres) goto end;
595 xreq->state = REQSTATE_REQ_GOT;
596 goto end;
597 }
598 if (reqtype == REQTYPE_RESPONSE) {
599 wine_rpc_response_header resph;
600 int i;
601
602 hres = _xread(xhPipe,&resph,sizeof(resph));
603 if (hres) goto end;
604 for (i=nrofreqs;i--;) {
605 wine_rpc_request *xreq = reqs[i];
606 if (xreq->state != REQSTATE_REQ_WAITING_FOR_REPLY)
607 continue;
608 if (xreq->reqh.reqid == resph.reqid) {
609 memcpy(&(xreq->resph),&resph,sizeof(resph));
610 xreq->Buffer = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,xreq->Buffer,xreq->resph.cbBuffer);
611 hres = _xread(xhPipe,xreq->Buffer,xreq->resph.cbBuffer);
612 if (hres) goto end;
613 xreq->state = REQSTATE_RESP_GOT;
614 /*PulseEvent(hRpcChanged);*/
615 goto end;
616 }
617 }
618 ERR("Did not find request for id %lx\n",resph.reqid);
619 hres = S_OK;
620 goto end;
621 }
622 ERR("Unknown reqtype %ld\n",reqtype);
623 hres = E_FAIL;
624end:
625 LeaveCriticalSection(&(xpipe->crit));
626 return hres;
627}
628
629static DWORD WINAPI
630_StubReaderThread(LPVOID param) {
631 wine_pipe *xpipe = (wine_pipe*)param;
632 HANDLE xhPipe = xpipe->hPipe;
633 HRESULT hres;
634
635 TRACE("STUB reader thread %lx\n",GetCurrentProcessId());
636 while (1) {
637 int i;
638 hres = _read_one(xpipe);
639 if (hres) break;
640
641 for (i=nrofreqs;i--;) {
642 wine_rpc_request *xreq = reqs[i];
643 if ((xreq->state == REQSTATE_REQ_GOT) && (xreq->hPipe == xhPipe)) {
644 _invoke_onereq(xreq);
645 }
646 }
647 }
648 FIXME("Failed with hres %lx\n",hres);
649 CloseHandle(xhPipe);
650 return 0;
651}
652
653static DWORD WINAPI
654_StubMgrThread(LPVOID param) {
655 char pipefn[200];
656 HANDLE listenPipe;
657
658 sprintf(pipefn,OLESTUBMGR"_%08lx",GetCurrentProcessId());
659 TRACE("Stub Manager Thread starting on (%s)\n",pipefn);
660
661 listenPipe = CreateNamedPipeA(
662 pipefn,
663 PIPE_ACCESS_DUPLEX,
664 PIPE_TYPE_BYTE|PIPE_WAIT,
665 PIPE_UNLIMITED_INSTANCES,
666 4096,
667 4096,
668 NMPWAIT_USE_DEFAULT_WAIT,
669 NULL
670 );
671 if (listenPipe == INVALID_HANDLE_VALUE) {
672 FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError());
673 return 1; /* permanent failure, so quit stubmgr thread */
674 }
675
676 while (1) {
677 if (!ConnectNamedPipe(listenPipe,NULL)) {
678 ERR("Failure during ConnectNamedPipe %lx!\n",GetLastError());
679 CloseHandle(listenPipe);
680 continue;
681 }
682 PIPE_StartRequestThread(listenPipe);
683 listenPipe = CreateNamedPipeA(
684 pipefn,
685 PIPE_ACCESS_DUPLEX,
686 PIPE_TYPE_BYTE|PIPE_WAIT,
687 PIPE_UNLIMITED_INSTANCES,
688 4096,
689 4096,
690 NMPWAIT_USE_DEFAULT_WAIT,
691 NULL
692 );
693 if (listenPipe == INVALID_HANDLE_VALUE) {
694 FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError());
695 return 1; /* permanent failure, so quit stubmgr thread */
696 }
697 }
698 return 0;
699}
700
701void
702STUBMGR_Start() {
703 static BOOL stubMgrRunning = FALSE;
704 DWORD tid;
705
706 if (!stubMgrRunning) {
707 stubMgrRunning = TRUE;
708 CreateThread(NULL,0,_StubMgrThread,NULL,0,&tid);
709 Sleep(2000); /* actually we just try opening the pipe until it succeeds */
710 }
711}
Note: See TracBrowser for help on using the repository browser.