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

Last change on this file since 10367 was 9451, checked in by sandervl, 23 years ago

PF: Removed stupid wait in STUBMGR_Start. Blocks PM for two seconds.

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 from %x.\n",res,size,hf);
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 to %x.\n",res,size,hf);
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 wine_pipe *new_pipes;
146
147 for (i=0;i<nrofpipes;i++)
148 if (pipes[i].mid.processid==mid->processid)
149 return S_OK;
150 if (pipes)
151 new_pipes=(wine_pipe*)HeapReAlloc(GetProcessHeap(),0,pipes,sizeof(pipes[0])*(nrofpipes+1));
152 else
153 new_pipes=(wine_pipe*)HeapAlloc(GetProcessHeap(),0,sizeof(pipes[0]));
154 if (!new_pipes) return E_OUTOFMEMORY;
155 pipes = new_pipes;
156 sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
157 memcpy(&(pipes[nrofpipes].mid),mid,sizeof(*mid));
158 pipes[nrofpipes].hPipe = hPipe;
159 InitializeCriticalSection(&(pipes[nrofpipes].crit));
160 nrofpipes++;
161 if (startreader) {
162 pipes[nrofpipes-1].hThread = CreateThread(NULL,0,_StubReaderThread,(LPVOID)(pipes+(nrofpipes-1)),0,&(pipes[nrofpipes-1].tid));
163 } else {
164 pipes[nrofpipes-1].tid = GetCurrentThreadId();
165 }
166 return S_OK;
167}
168
169static HANDLE
170PIPE_FindByMID(wine_marshal_id *mid) {
171 int i;
172 for (i=0;i<nrofpipes;i++)
173 if ((pipes[i].mid.processid==mid->processid) &&
174 (GetCurrentThreadId()==pipes[i].tid)
175 )
176 return pipes[i].hPipe;
177 return INVALID_HANDLE_VALUE;
178}
179
180static wine_pipe*
181PIPE_GetFromMID(wine_marshal_id *mid) {
182 int i;
183 for (i=0;i<nrofpipes;i++) {
184 if ((pipes[i].mid.processid==mid->processid) &&
185 (GetCurrentThreadId()==pipes[i].tid)
186 )
187 return pipes+i;
188 }
189 return NULL;
190}
191
192static HRESULT
193RPC_GetRequest(wine_rpc_request **req) {
194 static int reqid = 0xdeadbeef;
195 int i;
196
197 for (i=0;i<nrofreqs;i++) { /* try to reuse */
198 if (reqs[i]->state == REQSTATE_DONE) {
199 reqs[i]->reqh.reqid = reqid++;
200 reqs[i]->resph.reqid = reqs[i]->reqh.reqid;
201 reqs[i]->hPipe = INVALID_HANDLE_VALUE;
202 *req = reqs[i];
203 reqs[i]->state = REQSTATE_START;
204 return S_OK;
205 }
206 }
207 /* create new */
208 if (reqs)
209 reqs = (wine_rpc_request**)HeapReAlloc(
210 GetProcessHeap(),
211 HEAP_ZERO_MEMORY,
212 reqs,
213 sizeof(wine_rpc_request*)*(nrofreqs+1)
214 );
215 else
216 reqs = (wine_rpc_request**)HeapAlloc(
217 GetProcessHeap(),
218 HEAP_ZERO_MEMORY,
219 sizeof(wine_rpc_request*)
220 );
221 if (!reqs)
222 return E_OUTOFMEMORY;
223 reqs[nrofreqs] = (wine_rpc_request*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(wine_rpc_request));
224 reqs[nrofreqs]->reqh.reqid = reqid++;
225 reqs[nrofreqs]->resph.reqid = reqs[nrofreqs]->reqh.reqid;
226 reqs[nrofreqs]->hPipe = INVALID_HANDLE_VALUE;
227 *req = reqs[nrofreqs];
228 reqs[nrofreqs]->state = REQSTATE_START;
229 nrofreqs++;
230 return S_OK;
231}
232
233static void
234RPC_FreeRequest(wine_rpc_request *req) {
235 req->state = REQSTATE_DONE; /* Just reuse slot. */
236 return;
237}
238
239static HRESULT WINAPI
240PipeBuf_QueryInterface(
241 LPRPCCHANNELBUFFER iface,REFIID riid,LPVOID *ppv
242) {
243 *ppv = NULL;
244 if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown)) {
245 *ppv = (LPVOID)iface;
246 IUnknown_AddRef(iface);
247 return S_OK;
248 }
249 return E_NOINTERFACE;
250}
251
252static ULONG WINAPI
253PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) {
254 ICOM_THIS(PipeBuf,iface);
255 This->ref++;
256 return This->ref;
257}
258
259static ULONG WINAPI
260PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
261 ICOM_THIS(PipeBuf,iface);
262 This->ref--;
263 if (This->ref)
264 return This->ref;
265 ERR("Free all stuff.\n");
266 HeapFree(GetProcessHeap(),0,This);
267 return 0;
268}
269
270static HRESULT WINAPI
271PipeBuf_GetBuffer(
272 LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,REFIID riid
273) {
274 /*ICOM_THIS(PipeBuf,iface);*/
275
276 TRACE("(%p,%s), slightly wrong.\n",msg,debugstr_guid(riid));
277 /* probably reuses IID in real. */
278 if (msg->cbBuffer && (msg->Buffer == NULL))
279 msg->Buffer = HeapAlloc(GetProcessHeap(),0,msg->cbBuffer);
280 return S_OK;
281}
282
283static HRESULT
284_invoke_onereq(wine_rpc_request *req) {
285 IRpcStubBuffer *stub;
286 RPCOLEMESSAGE msg;
287 HRESULT hres;
288 DWORD reqtype;
289
290 hres = MARSHAL_Find_Stub_Buffer(&(req->reqh.mid),&stub);
291 if (hres) {
292 ERR("Stub not found?\n");
293 return hres;
294 }
295 msg.Buffer = req->Buffer;
296 msg.iMethod = req->reqh.iMethod;
297 msg.cbBuffer = req->reqh.cbBuffer;
298 req->state = REQSTATE_INVOKING;
299 req->resph.retval = IRpcStubBuffer_Invoke(stub,&msg,NULL);
300 req->Buffer = msg.Buffer;
301 req->resph.cbBuffer = msg.cbBuffer;
302 reqtype = REQTYPE_RESPONSE;
303 hres = _xwrite(req->hPipe,&reqtype,sizeof(reqtype));
304 if (hres) return hres;
305 hres = _xwrite(req->hPipe,&(req->resph),sizeof(req->resph));
306 if (hres) return hres;
307 hres = _xwrite(req->hPipe,req->Buffer,req->resph.cbBuffer);
308 if (hres) return hres;
309 req->state = REQSTATE_DONE;
310 drs("invoke");
311 return S_OK;
312}
313
314static HRESULT _read_one(wine_pipe *xpipe);
315
316static HRESULT
317RPC_QueueRequestAndWait(wine_rpc_request *req) {
318 int i;
319 wine_rpc_request *xreq;
320 HRESULT hres;
321 DWORD reqtype;
322 wine_pipe *xpipe = PIPE_GetFromMID(&(req->reqh.mid));
323
324 if (!xpipe) {
325 FIXME("no pipe found.\n");
326 return E_POINTER;
327 }
328 if (GetCurrentProcessId() == req->reqh.mid.processid) {
329 ERR("In current process?\n");
330 return E_FAIL;
331 }
332 req->hPipe = xpipe->hPipe;
333 req->state = REQSTATE_REQ_WAITING_FOR_REPLY;
334 reqtype = REQTYPE_REQUEST;
335 hres = _xwrite(req->hPipe,&reqtype,sizeof(reqtype));
336 if (hres) return hres;
337 hres = _xwrite(req->hPipe,&(req->reqh),sizeof(req->reqh));
338 if (hres) return hres;
339 hres = _xwrite(req->hPipe,req->Buffer,req->reqh.cbBuffer);
340 if (hres) return hres;
341
342 while (1) {
343 /*WaitForSingleObject(hRpcChanged,INFINITE);*/
344 hres = _read_one(xpipe);
345 if (hres) break;
346
347 for (i=0;i<nrofreqs;i++) {
348 xreq = reqs[i];
349 if ((xreq->state==REQSTATE_REQ_GOT) && (xreq->hPipe==req->hPipe)) {
350 _invoke_onereq(xreq);
351 }
352 }
353 if (req->state == REQSTATE_RESP_GOT)
354 return S_OK;
355 }
356 return hres;
357}
358
359static HRESULT WINAPI
360PipeBuf_SendReceive(
361 LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,ULONG *status
362) {
363 ICOM_THIS(PipeBuf,iface);
364 wine_rpc_request *req;
365 HRESULT hres;
366
367 TRACE("()\n");
368
369 if (This->mid.processid == GetCurrentProcessId()) {
370 ERR("Need to call directly!\n");
371 return E_FAIL;
372 }
373
374 hres = RPC_GetRequest(&req);
375 if (hres) return hres;
376 req->reqh.iMethod = msg->iMethod;
377 req->reqh.cbBuffer = msg->cbBuffer;
378 memcpy(&(req->reqh.mid),&(This->mid),sizeof(This->mid));
379 req->Buffer = msg->Buffer;
380 hres = RPC_QueueRequestAndWait(req);
381 if (hres) {
382 RPC_FreeRequest(req);
383 return hres;
384 }
385 msg->cbBuffer = req->resph.cbBuffer;
386 msg->Buffer = req->Buffer;
387 *status = req->resph.retval;
388 RPC_FreeRequest(req);
389 return S_OK;
390}
391
392
393static HRESULT WINAPI
394PipeBuf_FreeBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg) {
395 FIXME("(%p), stub!\n",msg);
396 return E_FAIL;
397}
398
399static HRESULT WINAPI
400PipeBuf_GetDestCtx(
401 LPRPCCHANNELBUFFER iface,DWORD* pdwDestContext,void** ppvDestContext
402) {
403 FIXME("(%p,%p), stub!\n",pdwDestContext,ppvDestContext);
404 return E_FAIL;
405}
406
407static HRESULT WINAPI
408PipeBuf_IsConnected(LPRPCCHANNELBUFFER iface) {
409 FIXME("(), stub!\n");
410 return S_OK;
411}
412
413static ICOM_VTABLE(IRpcChannelBuffer) pipebufvt = {
414 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
415 PipeBuf_QueryInterface,
416 PipeBuf_AddRef,
417 PipeBuf_Release,
418 PipeBuf_GetBuffer,
419 PipeBuf_SendReceive,
420 PipeBuf_FreeBuffer,
421 PipeBuf_GetDestCtx,
422 PipeBuf_IsConnected
423};
424
425HRESULT
426PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf) {
427 wine_marshal_id ourid;
428 DWORD res;
429 HANDLE hPipe;
430 HRESULT hres;
431 PipeBuf *pbuf;
432
433 hPipe = PIPE_FindByMID(mid);
434 if (hPipe == INVALID_HANDLE_VALUE) {
435 char pipefn[200];
436 sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
437 hPipe = CreateFileA(
438 pipefn,
439 GENERIC_READ|GENERIC_WRITE,
440 0,
441 NULL,
442 OPEN_EXISTING,
443 0,
444 -1
445 );
446 if (hPipe == INVALID_HANDLE_VALUE) {
447 FIXME("Could not open named pipe %s, le is %lx\n",pipefn,GetLastError());
448 return E_FAIL;
449 }
450 hres = PIPE_RegisterPipe(mid, hPipe, FALSE);
451 if (hres) return hres;
452 memset(&ourid,0,sizeof(ourid));
453 ourid.processid = GetCurrentProcessId();
454 if (!WriteFile(hPipe,&ourid,sizeof(ourid),&res,NULL)||(res!=sizeof(ourid))) {
455 ERR("Failed writing startup mid!\n");
456 return E_FAIL;
457 }
458 }
459 pbuf = (PipeBuf*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PipeBuf));
460 pbuf->lpVtbl = &pipebufvt;
461 pbuf->ref = 1;
462 memcpy(&(pbuf->mid),mid,sizeof(*mid));
463 *pipebuf = (IRpcChannelBuffer*)pbuf;
464 return S_OK;
465}
466
467static HRESULT
468create_server(REFCLSID rclsid) {
469 HKEY key;
470 char buf[200];
471 HRESULT hres = E_UNEXPECTED;
472 char xclsid[80];
473 WCHAR dllName[MAX_PATH+1];
474 DWORD dllNameLen = sizeof(dllName);
475 STARTUPINFOW sinfo;
476 PROCESS_INFORMATION pinfo;
477
478 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
479
480 sprintf(buf,"CLSID\\%s\\LocalServer32",xclsid);
481 hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key);
482
483 if (hres != ERROR_SUCCESS)
484 return REGDB_E_READREGDB; /* Probably */
485
486 memset(dllName,0,sizeof(dllName));
487 hres= RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)dllName,&dllNameLen);
488 RegCloseKey(key);
489 if (hres)
490 return REGDB_E_CLASSNOTREG; /* FIXME: check retval */
491 memset(&sinfo,0,sizeof(sinfo));
492 sinfo.cb = sizeof(sinfo);
493 if (!CreateProcessW(NULL,dllName,NULL,NULL,FALSE,0,NULL,NULL,&sinfo,&pinfo))
494 return E_FAIL;
495 return S_OK;
496}
497/* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, Figure 4 */
498HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) {
499 HRESULT hres;
500 HANDLE hPipe;
501 char pipefn[200];
502 DWORD res,bufferlen;
503 char marshalbuffer[200];
504 IStream *pStm;
505 LARGE_INTEGER seekto;
506 ULARGE_INTEGER newpos;
507 int tries = 0;
508#define MAXTRIES 10000
509
510 strcpy(pipefn,PIPEPREF);
511 WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF));
512
513 while (tries++<MAXTRIES) {
514 hPipe = CreateFileA(
515 pipefn,
516 GENERIC_READ|GENERIC_WRITE,
517 0,
518 NULL,
519 OPEN_EXISTING,
520 0,
521 -1
522 );
523 if (hPipe == INVALID_HANDLE_VALUE) {
524 if (tries == 1) {
525 if ((hres = create_server(rclsid)))
526 return hres;
527 Sleep(1000);
528 } else {
529 WARN("Could not open named pipe to broker %s, le is %lx\n",pipefn,GetLastError());
530 Sleep(1000);
531 }
532 continue;
533 }
534 bufferlen = 0;
535 if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) {
536 FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid));
537 Sleep(1000);
538 continue;
539 }
540 CloseHandle(hPipe);
541 break;
542 }
543 if (tries>=MAXTRIES)
544 return E_NOINTERFACE;
545 hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
546 if (hres) return hres;
547 hres = IStream_Write(pStm,marshalbuffer,bufferlen,&res);
548 if (hres) goto out;
549 seekto.s.LowPart = 0;seekto.s.HighPart = 0;
550 hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
551 hres = CoUnmarshalInterface(pStm,&IID_IClassFactory,ppv);
552out:
553 IStream_Release(pStm);
554 return hres;
555}
556
557
558static void WINAPI
559PIPE_StartRequestThread(HANDLE xhPipe) {
560 wine_marshal_id remoteid;
561 HRESULT hres;
562
563 hres = _xread(xhPipe,&remoteid,sizeof(remoteid));
564 if (hres) {
565 ERR("Failed to read remote mid!\n");
566 return;
567 }
568 PIPE_RegisterPipe(&remoteid,xhPipe, TRUE);
569}
570
571static HRESULT
572_read_one(wine_pipe *xpipe) {
573 DWORD reqtype;
574 HRESULT hres = S_OK;
575 HANDLE xhPipe = xpipe->hPipe;
576
577 /*FIXME("%lx %d reading reqtype\n",GetCurrentProcessId(),xhPipe);*/
578 hres = _xread(xhPipe,&reqtype,sizeof(reqtype));
579 if (hres) goto end;
580 EnterCriticalSection(&(xpipe->crit));
581 /*FIXME("%lx got reqtype %ld\n",GetCurrentProcessId(),reqtype);*/
582
583 if (reqtype == REQTYPE_REQUEST) {
584 wine_rpc_request *xreq;
585 RPC_GetRequest(&xreq);
586 xreq->hPipe = xhPipe;
587 hres = _xread(xhPipe,&(xreq->reqh),sizeof(xreq->reqh));
588 if (hres) goto end;
589 xreq->resph.reqid = xreq->reqh.reqid;
590 xreq->Buffer = HeapAlloc(GetProcessHeap(),0, xreq->reqh.cbBuffer);
591 hres = _xread(xhPipe,xreq->Buffer,xreq->reqh.cbBuffer);
592 if (hres) goto end;
593 xreq->state = REQSTATE_REQ_GOT;
594 goto end;
595 }
596 if (reqtype == REQTYPE_RESPONSE) {
597 wine_rpc_response_header resph;
598 int i;
599
600 hres = _xread(xhPipe,&resph,sizeof(resph));
601 if (hres) goto end;
602 for (i=nrofreqs;i--;) {
603 wine_rpc_request *xreq = reqs[i];
604 if (xreq->state != REQSTATE_REQ_WAITING_FOR_REPLY)
605 continue;
606 if (xreq->reqh.reqid == resph.reqid) {
607 memcpy(&(xreq->resph),&resph,sizeof(resph));
608 xreq->Buffer = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,xreq->Buffer,xreq->resph.cbBuffer);
609 hres = _xread(xhPipe,xreq->Buffer,xreq->resph.cbBuffer);
610 if (hres) goto end;
611 xreq->state = REQSTATE_RESP_GOT;
612 /*PulseEvent(hRpcChanged);*/
613 goto end;
614 }
615 }
616 ERR("Did not find request for id %lx\n",resph.reqid);
617 hres = S_OK;
618 goto end;
619 }
620 ERR("Unknown reqtype %ld\n",reqtype);
621 hres = E_FAIL;
622end:
623 LeaveCriticalSection(&(xpipe->crit));
624 return hres;
625}
626
627static DWORD WINAPI
628_StubReaderThread(LPVOID param) {
629 wine_pipe *xpipe = (wine_pipe*)param;
630 HANDLE xhPipe = xpipe->hPipe;
631 HRESULT hres;
632
633 TRACE("STUB reader thread %lx\n",GetCurrentProcessId());
634 while (1) {
635 int i;
636 hres = _read_one(xpipe);
637 if (hres) break;
638
639 for (i=nrofreqs;i--;) {
640 wine_rpc_request *xreq = reqs[i];
641 if ((xreq->state == REQSTATE_REQ_GOT) && (xreq->hPipe == xhPipe)) {
642 _invoke_onereq(xreq);
643 }
644 }
645 }
646 FIXME("Failed with hres %lx\n",hres);
647 CloseHandle(xhPipe);
648 return 0;
649}
650
651static DWORD WINAPI
652_StubMgrThread(LPVOID param) {
653 char pipefn[200];
654 HANDLE listenPipe;
655
656 sprintf(pipefn,OLESTUBMGR"_%08lx",GetCurrentProcessId());
657 TRACE("Stub Manager Thread starting on (%s)\n",pipefn);
658
659 listenPipe = CreateNamedPipeA(
660 pipefn,
661 PIPE_ACCESS_DUPLEX,
662 PIPE_TYPE_BYTE|PIPE_WAIT,
663 PIPE_UNLIMITED_INSTANCES,
664 4096,
665 4096,
666 NMPWAIT_USE_DEFAULT_WAIT,
667 NULL
668 );
669
670 if (listenPipe == INVALID_HANDLE_VALUE) {
671 FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError());
672 return 1; /* permanent failure, so quit stubmgr thread */
673 }
674
675 while (1) {
676 if (!ConnectNamedPipe(listenPipe,NULL)) {
677 ERR("Failure during ConnectNamedPipe %lx!\n",GetLastError());
678 CloseHandle(listenPipe);
679 continue;
680 }
681 PIPE_StartRequestThread(listenPipe);
682 listenPipe = CreateNamedPipeA(
683 pipefn,
684 PIPE_ACCESS_DUPLEX,
685 PIPE_TYPE_BYTE|PIPE_WAIT,
686 PIPE_UNLIMITED_INSTANCES,
687 4096,
688 4096,
689 NMPWAIT_USE_DEFAULT_WAIT,
690 NULL
691 );
692 if (listenPipe == INVALID_HANDLE_VALUE) {
693 FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError());
694 return 1; /* permanent failure, so quit stubmgr thread */
695 }
696 }
697 return 0;
698}
699
700void
701STUBMGR_Start() {
702 static BOOL stubMgrRunning = FALSE;
703 DWORD tid;
704
705 if (!stubMgrRunning) {
706 stubMgrRunning = TRUE;
707 CreateThread(NULL,0,_StubMgrThread,NULL,0,&tid);
708#ifndef __WIN32OS2__
709 Sleep(2000); /* actually we just try opening the pipe until it succeeds */
710#endif
711 }
712}
Note: See TracBrowser for help on using the repository browser.