[RPCRT4_WINETEST] Sync with Wine Staging 2.16. CORE-13762
[reactos.git] / rostests / winetests / rpcrt4 / cstub.c
1 /*
2 * Unit test suite for cstubs
3 *
4 * Copyright 2006 Huw Davies
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <stdarg.h>
22
23 #define PROXY_DELEGATION
24 #define COBJMACROS
25
26 #include "wine/test.h"
27 #include <windef.h>
28 #include <winbase.h>
29 #include <winnt.h>
30 #include <winerror.h>
31
32
33 #include "initguid.h"
34 #include "rpc.h"
35 #include "rpcdce.h"
36 #include "rpcproxy.h"
37
38 static CStdPSFactoryBuffer PSFactoryBuffer;
39
40 CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer)
41 CSTDSTUBBUFFER2RELEASE(&PSFactoryBuffer)
42
43 static GUID IID_if1 = {0x12345678, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
44 static GUID IID_if2 = {0x12345679, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
45 static GUID IID_if3 = {0x1234567a, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
46 static GUID IID_if4 = {0x1234567b, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
47 static CLSID CLSID_psfact = {0x1234567c, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}};
48
49 static int my_alloc_called;
50 static int my_free_called;
51
52 static void * CALLBACK my_alloc(SIZE_T size)
53 {
54 my_alloc_called++;
55 return NdrOleAllocate(size);
56 }
57
58 static void CALLBACK my_free(void *ptr)
59 {
60 my_free_called++;
61 NdrOleFree(ptr);
62 }
63
64 typedef struct _MIDL_PROC_FORMAT_STRING
65 {
66 short Pad;
67 unsigned char Format[ 2 ];
68 } MIDL_PROC_FORMAT_STRING;
69
70 typedef struct _MIDL_TYPE_FORMAT_STRING
71 {
72 short Pad;
73 unsigned char Format[ 2 ];
74 } MIDL_TYPE_FORMAT_STRING;
75
76
77 static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =
78 {
79 0,
80 {
81 0, 0
82 }
83 };
84
85 static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =
86 {
87 0,
88 {
89 0, 0
90 }
91 };
92
93 static const MIDL_STUB_DESC Object_StubDesc =
94 {
95 NULL,
96 my_alloc,
97 my_free,
98 { 0 },
99 0,
100 0,
101 0,
102 0,
103 __MIDL_TypeFormatString.Format,
104 1, /* -error bounds_check flag */
105 0x20000, /* Ndr library version */
106 0,
107 0x50100a4, /* MIDL Version 5.1.164 */
108 0,
109 NULL,
110 0, /* notify & notify_flag routine table */
111 1, /* Flags */
112 0, /* Reserved3 */
113 0, /* Reserved4 */
114 0 /* Reserved5 */
115 };
116
117 static HRESULT WINAPI if1_fn1_Proxy(void *This)
118 {
119 return S_OK;
120 }
121
122 static void __RPC_STUB if1_fn1_Stub(
123 IRpcStubBuffer *This,
124 IRpcChannelBuffer *_pRpcChannelBuffer,
125 PRPC_MESSAGE _pRpcMessage,
126 DWORD *_pdwStubPhase)
127 {
128 trace("fn1 stub\n");
129 }
130
131 static HRESULT WINAPI if1_fn2_Proxy(void *This)
132 {
133 return S_OK;
134 }
135
136 static void __RPC_STUB if1_fn2_Stub(
137 IRpcStubBuffer *This,
138 IRpcChannelBuffer *_pRpcChannelBuffer,
139 PRPC_MESSAGE _pRpcMessage,
140 DWORD *_pdwStubPhase)
141 {
142 trace("fn2 stub\n");
143 }
144
145 static CINTERFACE_PROXY_VTABLE(5) if1_proxy_vtbl =
146 {
147 { &IID_if1 },
148 { IUnknown_QueryInterface_Proxy,
149 IUnknown_AddRef_Proxy,
150 IUnknown_Release_Proxy ,
151 if1_fn1_Proxy,
152 if1_fn2_Proxy
153 }
154 };
155
156
157 static const unsigned short if1_FormatStringOffsetTable[] =
158 {
159 0,
160 0
161 };
162
163 static const MIDL_SERVER_INFO if1_server_info =
164 {
165 &Object_StubDesc,
166 0,
167 __MIDL_ProcFormatString.Format,
168 &if1_FormatStringOffsetTable[-3],
169 0,
170 0,
171 0,
172 0};
173
174
175 static const PRPC_STUB_FUNCTION if1_table[] =
176 {
177 if1_fn1_Stub,
178 if1_fn2_Stub
179 };
180
181 static CInterfaceStubVtbl if1_stub_vtbl =
182 {
183 {
184 &IID_if1,
185 &if1_server_info,
186 5,
187 &if1_table[-3]
188 },
189 { CStdStubBuffer_METHODS }
190 };
191
192 static CINTERFACE_PROXY_VTABLE(13) if2_proxy_vtbl =
193 {
194 { &IID_if2 },
195 { IUnknown_QueryInterface_Proxy,
196 IUnknown_AddRef_Proxy,
197 IUnknown_Release_Proxy ,
198 0,
199 0,
200 0,
201 0,
202 0,
203 0,
204 0,
205 0,
206 0,
207 0
208 }
209 };
210
211 static const unsigned short if2_FormatStringOffsetTable[] =
212 {
213 (unsigned short) -1,
214 (unsigned short) -1,
215 (unsigned short) -1,
216 (unsigned short) -1,
217 (unsigned short) -1,
218 (unsigned short) -1,
219 (unsigned short) -1,
220 (unsigned short) -1,
221 (unsigned short) -1,
222 (unsigned short) -1,
223 0
224 };
225
226 static const MIDL_SERVER_INFO if2_server_info =
227 {
228 &Object_StubDesc,
229 0,
230 __MIDL_ProcFormatString.Format,
231 &if2_FormatStringOffsetTable[-3],
232 0,
233 0,
234 0,
235 0};
236
237
238 static const PRPC_STUB_FUNCTION if2_table[] =
239 {
240 STUB_FORWARDING_FUNCTION,
241 STUB_FORWARDING_FUNCTION,
242 STUB_FORWARDING_FUNCTION,
243 STUB_FORWARDING_FUNCTION,
244 STUB_FORWARDING_FUNCTION,
245 STUB_FORWARDING_FUNCTION,
246 STUB_FORWARDING_FUNCTION,
247 STUB_FORWARDING_FUNCTION,
248 STUB_FORWARDING_FUNCTION,
249 STUB_FORWARDING_FUNCTION
250 };
251
252 static CInterfaceStubVtbl if2_stub_vtbl =
253 {
254 {
255 &IID_if2,
256 &if2_server_info,
257 13,
258 &if2_table[-3]
259 },
260 { CStdStubBuffer_DELEGATING_METHODS }
261 };
262
263 static CINTERFACE_PROXY_VTABLE(5) if3_proxy_vtbl =
264 {
265 { &IID_if3 },
266 { IUnknown_QueryInterface_Proxy,
267 IUnknown_AddRef_Proxy,
268 IUnknown_Release_Proxy ,
269 if1_fn1_Proxy,
270 0
271 }
272 };
273
274
275 static const unsigned short if3_FormatStringOffsetTable[] =
276 {
277 0,
278 0
279 };
280
281 static const MIDL_SERVER_INFO if3_server_info =
282 {
283 &Object_StubDesc,
284 0,
285 __MIDL_ProcFormatString.Format,
286 &if3_FormatStringOffsetTable[-3],
287 0,
288 0,
289 0,
290 0};
291
292 static CInterfaceStubVtbl if3_stub_vtbl =
293 {
294 {
295 &IID_if3,
296 &if3_server_info,
297 5,
298 &if1_table[-3]
299 },
300 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
301 };
302
303 static CINTERFACE_PROXY_VTABLE(7) if4_proxy_vtbl =
304 {
305 { &IID_if4 },
306 { IUnknown_QueryInterface_Proxy,
307 IUnknown_AddRef_Proxy,
308 IUnknown_Release_Proxy ,
309 0,
310 0,
311 0,
312 0
313 }
314 };
315
316 static const unsigned short if4_FormatStringOffsetTable[] =
317 {
318 (unsigned short) -1,
319 (unsigned short) -1,
320 (unsigned short) -1,
321 (unsigned short) -1,
322 0
323 };
324
325 static const MIDL_SERVER_INFO if4_server_info =
326 {
327 &Object_StubDesc,
328 0,
329 __MIDL_ProcFormatString.Format,
330 &if4_FormatStringOffsetTable[-3],
331 0,
332 0,
333 0,
334 0};
335
336 static CInterfaceStubVtbl if4_stub_vtbl =
337 {
338 {
339 &IID_if4,
340 &if4_server_info,
341 7,
342 &if2_table[-3]
343 },
344 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
345 };
346
347 static const CInterfaceProxyVtbl *cstub_ProxyVtblList[] =
348 {
349 (const CInterfaceProxyVtbl *) &if1_proxy_vtbl,
350 (const CInterfaceProxyVtbl *) &if2_proxy_vtbl,
351 (const CInterfaceProxyVtbl *) &if3_proxy_vtbl,
352 (const CInterfaceProxyVtbl *) &if4_proxy_vtbl,
353 NULL
354 };
355
356 static const CInterfaceStubVtbl *cstub_StubVtblList[] =
357 {
358 &if1_stub_vtbl,
359 &if2_stub_vtbl,
360 &if3_stub_vtbl,
361 &if4_stub_vtbl,
362 NULL
363 };
364
365 static PCInterfaceName const if_name_list[] =
366 {
367 "if1",
368 "if2",
369 "if3",
370 "if4",
371 NULL
372 };
373
374 static const IID *base_iid_list[] =
375 {
376 NULL,
377 &IID_ITypeLib,
378 NULL,
379 &IID_IDispatch,
380 NULL
381 };
382
383 #define cstub_CHECK_IID(n) IID_GENERIC_CHECK_IID( cstub, pIID, n)
384
385 static int __stdcall iid_lookup( const IID * pIID, int * pIndex )
386 {
387 IID_BS_LOOKUP_SETUP
388
389 IID_BS_LOOKUP_INITIAL_TEST( cstub, 4, 4 )
390 IID_BS_LOOKUP_NEXT_TEST( cstub, 2 )
391 IID_BS_LOOKUP_NEXT_TEST( cstub, 1 )
392 IID_BS_LOOKUP_RETURN_RESULT( cstub, 4, *pIndex )
393
394 }
395
396
397 static BOOL check_address(void *actual, void *expected)
398 {
399 static void *ole32_start = NULL;
400 static void *ole32_end = NULL;
401 static void *combase_start = NULL;
402 static void *combase_end = NULL;
403
404 if (actual == expected)
405 return TRUE;
406
407 /* On Win7, actual can be located inside ole32.dll */
408 if (ole32_start == NULL || ole32_end == NULL)
409 {
410 PIMAGE_NT_HEADERS nt_headers;
411 ole32_start = (void *) GetModuleHandleA("ole32.dll");
412 if (ole32_start == NULL)
413 return FALSE;
414 nt_headers = (PIMAGE_NT_HEADERS)((char *) ole32_start + ((PIMAGE_DOS_HEADER) ole32_start)->e_lfanew);
415 ole32_end = (void *)((char *) ole32_start + nt_headers->OptionalHeader.SizeOfImage);
416 }
417
418 if (ole32_start <= actual && actual < ole32_end)
419 return TRUE;
420
421 /* On Win8, actual can be located inside combase.dll */
422 if (combase_start == NULL || combase_end == NULL)
423 {
424 PIMAGE_NT_HEADERS nt_headers;
425 combase_start = (void *) GetModuleHandleA("combase.dll");
426 if (combase_start == NULL)
427 return FALSE;
428 nt_headers = (PIMAGE_NT_HEADERS)((char *) combase_start + ((PIMAGE_DOS_HEADER) combase_start)->e_lfanew);
429 combase_end = (void *)((char *) combase_start + nt_headers->OptionalHeader.SizeOfImage);
430 }
431
432 return (combase_start <= actual && actual < combase_end);
433 }
434
435 static const ExtendedProxyFileInfo my_proxy_file_info =
436 {
437 (const PCInterfaceProxyVtblList *) &cstub_ProxyVtblList,
438 (const PCInterfaceStubVtblList *) &cstub_StubVtblList,
439 (const PCInterfaceName *) &if_name_list,
440 (const IID **) &base_iid_list,
441 &iid_lookup,
442 4,
443 1,
444 NULL,
445 0,
446 0,
447 0
448 };
449
450 static const ProxyFileInfo *proxy_file_list[] = {
451 &my_proxy_file_info,
452 NULL
453 };
454
455
456 static IPSFactoryBuffer *test_NdrDllGetClassObject(void)
457 {
458 HMODULE rpcrt4 = GetModuleHandleA("rpcrt4.dll");
459 IPSFactoryBuffer *ppsf = NULL;
460 const PCInterfaceProxyVtblList* proxy_vtbl;
461 const PCInterfaceStubVtblList* stub_vtbl;
462 const CLSID CLSID_Unknown = {0x45678, 0x1234, 0x6666, {0xff, 0x67, 0x45, 0x98, 0x76, 0x12, 0x34, 0x56}};
463 static const GUID * const interfaces[] = { &IID_if1, &IID_if2, &IID_if3, &IID_if4 };
464 UINT i;
465 HRESULT r;
466 HMODULE hmod = GetModuleHandleA("rpcrt4.dll");
467 void *CStd_QueryInterface = GetProcAddress(hmod, "CStdStubBuffer_QueryInterface");
468 void *CStd_AddRef = GetProcAddress(hmod, "CStdStubBuffer_AddRef");
469 void *CStd_Release = GetProcAddress(hmod, "NdrCStdStubBuffer_Release");
470 void *CStd_Connect = GetProcAddress(hmod, "CStdStubBuffer_Connect");
471 void *CStd_Disconnect = GetProcAddress(hmod, "CStdStubBuffer_Disconnect");
472 void *CStd_Invoke = GetProcAddress(hmod, "CStdStubBuffer_Invoke");
473 void *CStd_IsIIDSupported = GetProcAddress(hmod, "CStdStubBuffer_IsIIDSupported");
474 void *CStd_CountRefs = GetProcAddress(hmod, "CStdStubBuffer_CountRefs");
475 void *CStd_DebugServerQueryInterface = GetProcAddress(hmod, "CStdStubBuffer_DebugServerQueryInterface");
476 void *CStd_DebugServerRelease = GetProcAddress(hmod, "CStdStubBuffer_DebugServerRelease");
477
478 r = NdrDllGetClassObject(&CLSID_Unknown, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
479 &CLSID_psfact, &PSFactoryBuffer);
480 ok(r == CLASS_E_CLASSNOTAVAILABLE, "NdrDllGetClassObject with unknown clsid should have returned CLASS_E_CLASSNOTAVAILABLE instead of 0x%x\n", r);
481 ok(ppsf == NULL, "NdrDllGetClassObject should have set ppsf to NULL on failure\n");
482
483 r = NdrDllGetClassObject(&CLSID_psfact, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
484 &CLSID_psfact, &PSFactoryBuffer);
485
486 ok(r == S_OK, "ret %08x\n", r);
487 ok(ppsf != NULL, "ppsf == NULL\n");
488
489 proxy_vtbl = PSFactoryBuffer.pProxyFileList[0]->pProxyVtblList;
490 stub_vtbl = PSFactoryBuffer.pProxyFileList[0]->pStubVtblList;
491 ok(PSFactoryBuffer.pProxyFileList == proxy_file_list, "pfl not the same\n");
492 ok(proxy_vtbl == (PCInterfaceProxyVtblList *) &cstub_ProxyVtblList, "proxy vtbllist not the same\n");
493 ok(stub_vtbl == (PCInterfaceStubVtblList *) &cstub_StubVtblList, "stub vtbllist not the same\n");
494
495 /* if1 is non-delegating, if2 is delegating, if3 is non-delegating
496 but I've zero'ed the vtbl entries, similarly if4 is delegating
497 with zero'ed vtbl entries */
498
499 #define VTBL_TEST_NOT_CHANGE_TO(name, i) \
500 ok(stub_vtbl[i]->Vtbl.name != CStd_##name, #name "vtbl %d updated %p %p\n", \
501 i, stub_vtbl[i]->Vtbl.name, CStd_##name )
502 #define VTBL_TEST_CHANGE_TO(name, i) \
503 ok(check_address(stub_vtbl[i]->Vtbl.name, CStd_##name), #name "vtbl %d not updated %p %p\n", \
504 i, stub_vtbl[i]->Vtbl.name, CStd_##name )
505 #define VTBL_TEST_ZERO(name, i) \
506 ok(stub_vtbl[i]->Vtbl.name == NULL, #name "vtbl %d not null %p\n", \
507 i, stub_vtbl[i]->Vtbl.name )
508
509 VTBL_TEST_NOT_CHANGE_TO(QueryInterface, 0);
510 VTBL_TEST_NOT_CHANGE_TO(AddRef, 0);
511 VTBL_TEST_NOT_CHANGE_TO(Release, 0);
512 VTBL_TEST_NOT_CHANGE_TO(Connect, 0);
513 VTBL_TEST_NOT_CHANGE_TO(Disconnect, 0);
514 VTBL_TEST_NOT_CHANGE_TO(Invoke, 0);
515 VTBL_TEST_NOT_CHANGE_TO(IsIIDSupported, 0);
516 VTBL_TEST_NOT_CHANGE_TO(CountRefs, 0);
517 VTBL_TEST_NOT_CHANGE_TO(DebugServerQueryInterface, 0);
518 VTBL_TEST_NOT_CHANGE_TO(DebugServerRelease, 0);
519
520 VTBL_TEST_CHANGE_TO(QueryInterface, 1);
521 VTBL_TEST_CHANGE_TO(AddRef, 1);
522 VTBL_TEST_NOT_CHANGE_TO(Release, 1);
523 VTBL_TEST_NOT_CHANGE_TO(Connect, 1);
524 VTBL_TEST_NOT_CHANGE_TO(Disconnect, 1);
525 VTBL_TEST_CHANGE_TO(Invoke, 1);
526 VTBL_TEST_CHANGE_TO(IsIIDSupported, 1);
527 VTBL_TEST_NOT_CHANGE_TO(CountRefs, 1);
528 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface, 1);
529 VTBL_TEST_CHANGE_TO(DebugServerRelease, 1);
530
531 VTBL_TEST_CHANGE_TO(QueryInterface, 2);
532 VTBL_TEST_CHANGE_TO(AddRef, 2);
533 VTBL_TEST_ZERO(Release, 2);
534 VTBL_TEST_CHANGE_TO(Connect, 2);
535 VTBL_TEST_CHANGE_TO(Disconnect, 2);
536 VTBL_TEST_CHANGE_TO(Invoke, 2);
537 VTBL_TEST_CHANGE_TO(IsIIDSupported, 2);
538 VTBL_TEST_CHANGE_TO(CountRefs, 2);
539 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface, 2);
540 VTBL_TEST_CHANGE_TO(DebugServerRelease, 2);
541
542 VTBL_TEST_CHANGE_TO(QueryInterface, 3);
543 VTBL_TEST_CHANGE_TO(AddRef, 3);
544 VTBL_TEST_ZERO(Release, 3);
545 VTBL_TEST_NOT_CHANGE_TO(Connect, 3);
546 VTBL_TEST_NOT_CHANGE_TO(Disconnect, 3);
547 VTBL_TEST_CHANGE_TO(Invoke, 3);
548 VTBL_TEST_CHANGE_TO(IsIIDSupported, 3);
549 VTBL_TEST_NOT_CHANGE_TO(CountRefs, 3);
550 VTBL_TEST_CHANGE_TO(DebugServerQueryInterface, 3);
551 VTBL_TEST_CHANGE_TO(DebugServerRelease, 3);
552
553 #define VTBL_PROXY_TEST(i,num,ptr) \
554 ok( check_address(proxy_vtbl[i]->Vtbl[num], (ptr)), "wrong proxy %u func %u %p/%p\n", \
555 (i), (num), proxy_vtbl[i]->Vtbl[num], (ptr) )
556 #define VTBL_PROXY_TEST_NOT_ZERO(i,num) \
557 ok( proxy_vtbl[i]->Vtbl[num] != NULL, "wrong proxy %u func %u is NULL\n", (i), (num))
558
559 VTBL_PROXY_TEST(0, 0, IUnknown_QueryInterface_Proxy);
560 VTBL_PROXY_TEST(0, 1, IUnknown_AddRef_Proxy);
561 VTBL_PROXY_TEST(0, 2, IUnknown_Release_Proxy);
562 VTBL_PROXY_TEST(0, 3, if1_fn1_Proxy);
563 VTBL_PROXY_TEST(0, 4, if1_fn2_Proxy);
564
565 VTBL_PROXY_TEST(1, 0, GetProcAddress(rpcrt4,"IUnknown_QueryInterface_Proxy"));
566 VTBL_PROXY_TEST(1, 1, GetProcAddress(rpcrt4,"IUnknown_AddRef_Proxy"));
567 VTBL_PROXY_TEST(1, 2, GetProcAddress(rpcrt4,"IUnknown_Release_Proxy"));
568 VTBL_PROXY_TEST_NOT_ZERO(1, 3);
569 VTBL_PROXY_TEST_NOT_ZERO(1, 4);
570 VTBL_PROXY_TEST_NOT_ZERO(1, 5);
571 VTBL_PROXY_TEST_NOT_ZERO(1, 6);
572 VTBL_PROXY_TEST_NOT_ZERO(1, 7);
573 VTBL_PROXY_TEST_NOT_ZERO(1, 8);
574 VTBL_PROXY_TEST_NOT_ZERO(1, 9);
575 VTBL_PROXY_TEST_NOT_ZERO(1, 10);
576 VTBL_PROXY_TEST_NOT_ZERO(1, 11);
577 VTBL_PROXY_TEST_NOT_ZERO(1, 12);
578
579 VTBL_PROXY_TEST(2, 0, IUnknown_QueryInterface_Proxy);
580 VTBL_PROXY_TEST(2, 1, IUnknown_AddRef_Proxy);
581 VTBL_PROXY_TEST(2, 2, IUnknown_Release_Proxy);
582 VTBL_PROXY_TEST(2, 3, if1_fn1_Proxy);
583 todo_wine VTBL_PROXY_TEST_NOT_ZERO(2, 4);
584
585 VTBL_PROXY_TEST(3, 0, GetProcAddress(rpcrt4,"IUnknown_QueryInterface_Proxy"));
586 VTBL_PROXY_TEST(3, 1, GetProcAddress(rpcrt4,"IUnknown_AddRef_Proxy"));
587 VTBL_PROXY_TEST(3, 2, GetProcAddress(rpcrt4,"IUnknown_Release_Proxy"));
588 VTBL_PROXY_TEST_NOT_ZERO(3, 3);
589 VTBL_PROXY_TEST_NOT_ZERO(3, 4);
590 VTBL_PROXY_TEST_NOT_ZERO(3, 5);
591 VTBL_PROXY_TEST_NOT_ZERO(3, 6);
592
593 #undef VTBL_TEST_NOT_CHANGE_TO
594 #undef VTBL_TEST_CHANGE_TO
595 #undef VTBL_TEST_ZERO
596 #undef VTBL_PROXY_TEST
597 #undef VTBL_PROXY_TEST_NOT_ZERO
598
599 for (i = 0; i < sizeof(interfaces)/sizeof(interfaces[0]); i++)
600 ok( proxy_vtbl[i]->header.piid == interfaces[i],
601 "wrong proxy %u iid %p/%p\n", i, proxy_vtbl[i]->header.piid, interfaces[i] );
602
603 ok(PSFactoryBuffer.RefCount == 1, "ref count %d\n", PSFactoryBuffer.RefCount);
604 IPSFactoryBuffer_Release(ppsf);
605
606 /* One can also search by IID */
607 r = NdrDllGetClassObject(&IID_if3, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
608 &CLSID_psfact, &PSFactoryBuffer);
609 ok(r == S_OK, "ret %08x\n", r);
610 ok(ppsf != NULL, "ppsf == NULL\n");
611 IPSFactoryBuffer_Release(ppsf);
612
613 r = NdrDllGetClassObject(&IID_if3, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
614 NULL, &PSFactoryBuffer);
615 ok(r == S_OK, "ret %08x\n", r);
616 ok(ppsf != NULL, "ppsf == NULL\n");
617 IPSFactoryBuffer_Release(ppsf);
618
619 /* but only if the PS factory implements it */
620 r = NdrDllGetClassObject(&IID_IDispatch, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
621 &CLSID_psfact, &PSFactoryBuffer);
622 ok(r == CLASS_E_CLASSNOTAVAILABLE, "ret %08x\n", r);
623
624 /* Create it again to return */
625 r = NdrDllGetClassObject(&CLSID_psfact, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
626 &CLSID_psfact, &PSFactoryBuffer);
627 ok(r == S_OK, "ret %08x\n", r);
628 ok(ppsf != NULL, "ppsf == NULL\n");
629
630 /* Because this PS factory is not loaded as a dll in the normal way, Windows 8 / 10
631 get confused and will crash when one of the proxies for the delegated ifaces is created.
632 Registering the ifaces fixes this (in fact calling CoRegisterPSClsid() with any IID / CLSID is enough). */
633
634 r = CoRegisterPSClsid(&IID_if1, &CLSID_psfact);
635 ok(r == S_OK, "ret %08x\n", r);
636 r = CoRegisterPSClsid(&IID_if2, &CLSID_psfact);
637 ok(r == S_OK, "ret %08x\n", r);
638 r = CoRegisterPSClsid(&IID_if3, &CLSID_psfact);
639 ok(r == S_OK, "ret %08x\n", r);
640 r = CoRegisterPSClsid(&IID_if4, &CLSID_psfact);
641 ok(r == S_OK, "ret %08x\n", r);
642
643 return ppsf;
644 }
645
646 static int base_buffer_invoke_called;
647 static HRESULT WINAPI base_buffer_Invoke(IRpcStubBuffer *This, RPCOLEMESSAGE *msg, IRpcChannelBuffer *channel)
648 {
649 base_buffer_invoke_called++;
650 ok(msg == (RPCOLEMESSAGE*)0xcafebabe, "msg ptr changed\n");
651 ok(channel == (IRpcChannelBuffer*)0xdeadbeef, "channel ptr changed\n");
652 return S_OK; /* returning any failure here results in an exception */
653 }
654
655 static IRpcStubBufferVtbl base_buffer_vtbl = {
656 (void*)0xcafebab0,
657 (void*)0xcafebab1,
658 (void*)0xcafebab2,
659 (void*)0xcafebab3,
660 (void*)0xcafebab4,
661 base_buffer_Invoke,
662 (void*)0xcafebab6,
663 (void*)0xcafebab7,
664 (void*)0xcafebab8,
665 (void*)0xcafebab9
666 };
667
668 static void test_NdrStubForwardingFunction(void)
669 {
670 void *This[5];
671 void *real_this;
672 IRpcChannelBuffer *channel = (IRpcChannelBuffer*)0xdeadbeef;
673 RPC_MESSAGE *msg = (RPC_MESSAGE*)0xcafebabe;
674 DWORD *phase = (DWORD*)0x12345678;
675 IRpcStubBufferVtbl *base_buffer_vtbl_ptr = &base_buffer_vtbl;
676 IRpcStubBuffer *base_stub_buffer = (IRpcStubBuffer*)&base_buffer_vtbl_ptr;
677
678 memset(This, 0xcc, sizeof(This));
679 This[0] = base_stub_buffer;
680 real_this = &This[1];
681
682 NdrStubForwardingFunction( real_this, channel, msg, phase );
683 ok(base_buffer_invoke_called == 1, "base_buffer_invoke called %d times\n", base_buffer_invoke_called);
684
685 }
686
687 static IRpcStubBuffer *create_stub(IPSFactoryBuffer *ppsf, REFIID iid, IUnknown *obj, HRESULT expected_result)
688 {
689 IRpcStubBuffer *pstub = NULL;
690 HRESULT r;
691
692 r = IPSFactoryBuffer_CreateStub(ppsf, iid, obj, &pstub);
693 ok(r == expected_result, "CreateStub returned %08x expected %08x\n", r, expected_result);
694 return pstub;
695 }
696
697 static HRESULT WINAPI create_stub_test_QI(IUnknown *This, REFIID iid, void **ppv)
698 {
699 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n");
700 *ppv = (void*)0xdeadbeef;
701 return S_OK;
702 }
703
704 static IUnknownVtbl create_stub_test_vtbl =
705 {
706 create_stub_test_QI,
707 NULL,
708 NULL
709 };
710
711 static HRESULT WINAPI create_stub_test_fail_QI(IUnknown *This, REFIID iid, void **ppv)
712 {
713 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n");
714 *ppv = NULL;
715 return E_NOINTERFACE;
716 }
717
718 static IUnknownVtbl create_stub_test_fail_vtbl =
719 {
720 create_stub_test_fail_QI,
721 NULL,
722 NULL
723 };
724
725 struct dummy_unknown
726 {
727 IUnknown IUnknown_iface;
728 LONG ref;
729 };
730
731 static inline struct dummy_unknown *impl_from_IUnknown(IUnknown *iface)
732 {
733 return CONTAINING_RECORD(iface, struct dummy_unknown, IUnknown_iface);
734 }
735
736 static HRESULT WINAPI dummy_QueryInterface(IUnknown *This, REFIID iid, void **ppv)
737 {
738 *ppv = NULL;
739 return E_NOINTERFACE;
740 }
741
742 static ULONG WINAPI dummy_AddRef(LPUNKNOWN iface)
743 {
744 struct dummy_unknown *this = impl_from_IUnknown(iface);
745 return InterlockedIncrement( &this->ref );
746 }
747
748 static ULONG WINAPI dummy_Release(LPUNKNOWN iface)
749 {
750 struct dummy_unknown *this = impl_from_IUnknown(iface);
751 return InterlockedDecrement( &this->ref );
752 }
753
754 static IUnknownVtbl dummy_unknown_vtbl =
755 {
756 dummy_QueryInterface,
757 dummy_AddRef,
758 dummy_Release
759 };
760 static struct dummy_unknown dummy_unknown = { { &dummy_unknown_vtbl }, 0 };
761
762 static void create_proxy_test( IPSFactoryBuffer *ppsf, REFIID iid, const void *expected_vtbl )
763 {
764 IRpcProxyBuffer *proxy = NULL;
765 IUnknown *iface = NULL;
766 HRESULT r;
767 ULONG count;
768
769 r = IPSFactoryBuffer_CreateProxy(ppsf, NULL, iid, &proxy, (void **)&iface);
770 ok( r == S_OK, "IPSFactoryBuffer_CreateProxy failed %x\n", r );
771 ok( *(void **)iface == expected_vtbl, "wrong iface pointer %p/%p\n", *(void **)iface, expected_vtbl );
772 count = IUnknown_Release( iface );
773 ok( count == 1, "wrong refcount %u\n", count );
774 count = IRpcProxyBuffer_Release( proxy );
775 ok( count == 0, "wrong refcount %u\n", count );
776
777 dummy_unknown.ref = 4;
778 r = IPSFactoryBuffer_CreateProxy(ppsf, &dummy_unknown.IUnknown_iface, iid, &proxy,
779 (void **)&iface);
780 ok( r == S_OK, "IPSFactoryBuffer_CreateProxy failed %x\n", r );
781 ok( dummy_unknown.ref == 5, "wrong refcount %u\n", dummy_unknown.ref );
782 ok( *(void **)iface == expected_vtbl, "wrong iface pointer %p/%p\n", *(void **)iface, expected_vtbl );
783 count = IUnknown_Release( iface );
784 ok( count == 4, "wrong refcount %u\n", count );
785 ok( dummy_unknown.ref == 4, "wrong refcount %u\n", dummy_unknown.ref );
786 count = IRpcProxyBuffer_Release( proxy );
787 ok( count == 0, "wrong refcount %u\n", count );
788 ok( dummy_unknown.ref == 4, "wrong refcount %u\n", dummy_unknown.ref );
789 }
790
791 static void test_CreateProxy( IPSFactoryBuffer *ppsf )
792 {
793 create_proxy_test( ppsf, &IID_if1, if1_proxy_vtbl.Vtbl );
794 create_proxy_test( ppsf, &IID_if2, if2_proxy_vtbl.Vtbl );
795 create_proxy_test( ppsf, &IID_if3, if3_proxy_vtbl.Vtbl );
796 create_proxy_test( ppsf, &IID_if4, if4_proxy_vtbl.Vtbl );
797 }
798
799 static void test_CreateStub(IPSFactoryBuffer *ppsf)
800 {
801 IUnknownVtbl *vtbl = &create_stub_test_vtbl;
802 IUnknown *obj = (IUnknown*)&vtbl;
803 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
804 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
805 const CInterfaceStubHeader *header = &CONTAINING_RECORD(cstd_stub->lpVtbl, const CInterfaceStubVtbl, Vtbl)->header;
806
807 ok(IsEqualIID(header->piid, &IID_if1), "header iid differs\n");
808 ok(cstd_stub->RefCount == 1, "ref count %d\n", cstd_stub->RefCount);
809 /* 0xdeadbeef returned from create_stub_test_QI */
810 ok(cstd_stub->pvServerObject == (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub->pvServerObject);
811 ok(cstd_stub->pPSFactory != NULL, "pPSFactory was NULL\n");
812 cstd_stub->pvServerObject = NULL;
813 IRpcStubBuffer_Release(pstub);
814
815 vtbl = &create_stub_test_fail_vtbl;
816 pstub = create_stub(ppsf, &IID_if1, obj, E_NOINTERFACE);
817 ok(pstub == S_OK, "create_stub failed: %u\n", GetLastError());
818
819 }
820
821 static HRESULT WINAPI connect_test_orig_QI(IUnknown *This, REFIID iid, void **ppv)
822 {
823 ok(IsEqualIID(iid, &IID_if1) ||
824 IsEqualIID(iid, &IID_if2), "incorrect iid\n");
825 *ppv = (void*)This;
826 return S_OK;
827 }
828
829 static int connect_test_orig_release_called;
830 static ULONG WINAPI connect_test_orig_release(IUnknown *This)
831 {
832 connect_test_orig_release_called++;
833 return 0;
834 }
835
836 static IUnknownVtbl connect_test_orig_vtbl =
837 {
838 connect_test_orig_QI,
839 NULL,
840 connect_test_orig_release
841 };
842
843 static HRESULT WINAPI connect_test_new_QI(IUnknown *This, REFIID iid, void **ppv)
844 {
845 ok(IsEqualIID(iid, &IID_if1) ||
846 IsEqualIID(iid, &IID_if2), "incorrect iid\n");
847 *ppv = (void*)0xcafebabe;
848 return S_OK;
849 }
850
851 static IUnknownVtbl connect_test_new_vtbl =
852 {
853 connect_test_new_QI,
854 NULL,
855 NULL
856 };
857
858 static HRESULT WINAPI connect_test_new_fail_QI(IUnknown *This, REFIID iid, void **ppv)
859 {
860 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n");
861 *ppv = (void*)0xdeadbeef;
862 return E_NOINTERFACE;
863 }
864
865 static IUnknownVtbl connect_test_new_fail_vtbl =
866 {
867 connect_test_new_fail_QI,
868 NULL,
869 NULL
870 };
871
872 static int connect_test_base_Connect_called;
873 static HRESULT WINAPI connect_test_base_Connect(IRpcStubBuffer *pstub, IUnknown *obj)
874 {
875 connect_test_base_Connect_called++;
876 ok(*(void**)obj == (void*)0xbeefcafe, "unexpected obj %p\n", obj);
877 return S_OK;
878 }
879
880 static IRpcStubBufferVtbl connect_test_base_stub_buffer_vtbl =
881 {
882 (void*)0xcafebab0,
883 (void*)0xcafebab1,
884 (void*)0xcafebab2,
885 connect_test_base_Connect,
886 (void*)0xcafebab4,
887 (void*)0xcafebab5,
888 (void*)0xcafebab6,
889 (void*)0xcafebab7,
890 (void*)0xcafebab8,
891 (void*)0xcafebab9
892 };
893
894 static void test_Connect(IPSFactoryBuffer *ppsf)
895 {
896 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl;
897 IUnknownVtbl *new_vtbl = &connect_test_new_vtbl;
898 IUnknownVtbl *new_fail_vtbl = &connect_test_new_fail_vtbl;
899 IUnknown *obj = (IUnknown*)&orig_vtbl;
900 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
901 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
902 IRpcStubBufferVtbl *base_stub_buf_vtbl = &connect_test_base_stub_buffer_vtbl;
903 HRESULT r;
904
905 obj = (IUnknown*)&new_vtbl;
906 r = IRpcStubBuffer_Connect(pstub, obj);
907 ok(r == S_OK, "r %08x\n", r);
908 ok(connect_test_orig_release_called == 1, "release called %d\n", connect_test_orig_release_called);
909 ok(cstd_stub->pvServerObject == (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub->pvServerObject);
910
911 cstd_stub->pvServerObject = (IUnknown*)&orig_vtbl;
912 obj = (IUnknown*)&new_fail_vtbl;
913 r = IRpcStubBuffer_Connect(pstub, obj);
914 ok(r == E_NOINTERFACE, "r %08x\n", r);
915 ok(cstd_stub->pvServerObject == (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub->pvServerObject);
916 ok(connect_test_orig_release_called == 2, "release called %d\n", connect_test_orig_release_called);
917
918 /* Now use a delegated stub.
919
920 We know from the NdrStubForwardFunction test that
921 (void**)pstub-1 is the base interface stub buffer. This shows
922 that (void**)pstub-2 contains the address of a vtable that gets
923 passed to the base interface's Connect method. Note that
924 (void**)pstub-2 itself gets passed to Connect and not
925 *((void**)pstub-2), so it should contain the vtable ptr and not
926 an interface ptr. */
927
928 obj = (IUnknown*)&orig_vtbl;
929 pstub = create_stub(ppsf, &IID_if2, obj, S_OK);
930 *((void**)pstub-1) = &base_stub_buf_vtbl;
931 *((void**)pstub-2) = (void*)0xbeefcafe;
932
933 obj = (IUnknown*)&new_vtbl;
934 r = IRpcStubBuffer_Connect(pstub, obj);
935 ok(r == S_OK, "r %08x\n", r);
936 ok(connect_test_base_Connect_called == 1, "connect_test_bsae_Connect called %d times\n",
937 connect_test_base_Connect_called);
938 ok(connect_test_orig_release_called == 3, "release called %d\n", connect_test_orig_release_called);
939 cstd_stub = (CStdStubBuffer*)pstub;
940 ok(cstd_stub->pvServerObject == (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub->pvServerObject);
941 }
942
943 static void test_Disconnect(IPSFactoryBuffer *ppsf)
944 {
945 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl;
946 IUnknown *obj = (IUnknown*)&orig_vtbl;
947 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
948 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
949
950 connect_test_orig_release_called = 0;
951 IRpcStubBuffer_Disconnect(pstub);
952 ok(connect_test_orig_release_called == 1, "release called %d\n", connect_test_orig_release_called);
953 ok(cstd_stub->pvServerObject == NULL, "pvServerObject %p\n", cstd_stub->pvServerObject);
954 IRpcStubBuffer_Release(pstub);
955 }
956
957
958 static int release_test_psfacbuf_release_called;
959 static ULONG WINAPI release_test_pretend_psfacbuf_release(IUnknown *pUnk)
960 {
961 release_test_psfacbuf_release_called++;
962 return 1;
963 }
964
965 static IUnknownVtbl release_test_pretend_psfacbuf_vtbl =
966 {
967 NULL,
968 NULL,
969 release_test_pretend_psfacbuf_release
970 };
971
972 static void test_Release(IPSFactoryBuffer *ppsf)
973 {
974 LONG facbuf_refs;
975 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl;
976 IUnknown *obj = (IUnknown*)&orig_vtbl;
977 IUnknownVtbl *pretend_psfacbuf_vtbl = &release_test_pretend_psfacbuf_vtbl;
978 IUnknown *pretend_psfacbuf = (IUnknown *)&pretend_psfacbuf_vtbl;
979 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
980 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
981
982 facbuf_refs = PSFactoryBuffer.RefCount;
983
984 /* This shows that NdrCStdStubBuffer_Release doesn't call Disconnect */
985 ok(cstd_stub->RefCount == 1, "ref count %d\n", cstd_stub->RefCount);
986 connect_test_orig_release_called = 0;
987 IRpcStubBuffer_Release(pstub);
988 todo_wine {
989 ok(connect_test_orig_release_called == 0, "release called %d\n", connect_test_orig_release_called);
990 }
991 ok(PSFactoryBuffer.RefCount == facbuf_refs - 1, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs);
992
993 /* This shows that NdrCStdStubBuffer_Release calls Release on its 2nd arg, rather than on This->pPSFactory
994 (which are usually the same and indeed it's odd that _Release requires this 2nd arg). */
995 pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
996 ok(PSFactoryBuffer.RefCount == facbuf_refs, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs);
997 NdrCStdStubBuffer_Release(pstub, (IPSFactoryBuffer*)pretend_psfacbuf);
998 ok(release_test_psfacbuf_release_called == 1, "pretend_psfacbuf_release called %d\n", release_test_psfacbuf_release_called);
999 ok(PSFactoryBuffer.RefCount == facbuf_refs, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs);
1000 }
1001
1002 static HRESULT WINAPI delegating_invoke_test_QI(ITypeLib *pUnk, REFIID iid, void** ppv)
1003 {
1004
1005 *ppv = pUnk;
1006 return S_OK;
1007 }
1008
1009 static ULONG WINAPI delegating_invoke_test_addref(ITypeLib *pUnk)
1010 {
1011 return 1;
1012 }
1013
1014 static ULONG WINAPI delegating_invoke_test_release(ITypeLib *pUnk)
1015 {
1016 return 1;
1017 }
1018
1019 static UINT WINAPI delegating_invoke_test_get_type_info_count(ITypeLib *pUnk)
1020 {
1021 return 0xabcdef;
1022 }
1023
1024 static ITypeLibVtbl delegating_invoke_test_obj_vtbl =
1025 {
1026 delegating_invoke_test_QI,
1027 delegating_invoke_test_addref,
1028 delegating_invoke_test_release,
1029 delegating_invoke_test_get_type_info_count,
1030 NULL,
1031 NULL,
1032 NULL,
1033 NULL,
1034 NULL,
1035 NULL,
1036 NULL,
1037 NULL,
1038 NULL
1039 };
1040
1041 static HRESULT WINAPI delegating_invoke_chan_query_interface(IRpcChannelBuffer *pchan,
1042 REFIID iid,
1043 void **ppv)
1044 {
1045 ok(0, "call to QueryInterface not expected\n");
1046 return E_NOINTERFACE;
1047 }
1048
1049 static ULONG WINAPI delegating_invoke_chan_add_ref(IRpcChannelBuffer *pchan)
1050 {
1051 return 2;
1052 }
1053
1054 static ULONG WINAPI delegating_invoke_chan_release(IRpcChannelBuffer *pchan)
1055 {
1056 return 1;
1057 }
1058
1059 static HRESULT WINAPI delegating_invoke_chan_get_buffer(IRpcChannelBuffer *pchan,
1060 RPCOLEMESSAGE *msg,
1061 REFIID iid)
1062 {
1063 msg->Buffer = HeapAlloc(GetProcessHeap(), 0, msg->cbBuffer);
1064 return S_OK;
1065 }
1066
1067 static HRESULT WINAPI delegating_invoke_chan_send_receive(IRpcChannelBuffer *pchan,
1068 RPCOLEMESSAGE *pMessage,
1069 ULONG *pStatus)
1070 {
1071 ok(0, "call to SendReceive not expected\n");
1072 return E_NOTIMPL;
1073 }
1074
1075 static HRESULT WINAPI delegating_invoke_chan_free_buffer(IRpcChannelBuffer *pchan,
1076 RPCOLEMESSAGE *pMessage)
1077 {
1078 ok(0, "call to FreeBuffer not expected\n");
1079 return E_NOTIMPL;
1080 }
1081
1082 static HRESULT WINAPI delegating_invoke_chan_get_dest_ctx(IRpcChannelBuffer *pchan,
1083 DWORD *pdwDestContext,
1084 void **ppvDestContext)
1085 {
1086 *pdwDestContext = MSHCTX_LOCAL;
1087 *ppvDestContext = NULL;
1088 return S_OK;
1089 }
1090
1091 static HRESULT WINAPI delegating_invoke_chan_is_connected(IRpcChannelBuffer *pchan)
1092 {
1093 ok(0, "call to IsConnected not expected\n");
1094 return E_NOTIMPL;
1095 }
1096
1097 static IRpcChannelBufferVtbl delegating_invoke_test_rpc_chan_vtbl =
1098 {
1099 delegating_invoke_chan_query_interface,
1100 delegating_invoke_chan_add_ref,
1101 delegating_invoke_chan_release,
1102 delegating_invoke_chan_get_buffer,
1103 delegating_invoke_chan_send_receive,
1104 delegating_invoke_chan_free_buffer,
1105 delegating_invoke_chan_get_dest_ctx,
1106 delegating_invoke_chan_is_connected
1107 };
1108
1109 static void test_delegating_Invoke(IPSFactoryBuffer *ppsf)
1110 {
1111 ITypeLibVtbl *obj_vtbl = &delegating_invoke_test_obj_vtbl;
1112 IUnknown *obj = (IUnknown*)&obj_vtbl;
1113 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if2, obj, S_OK);
1114 IRpcChannelBufferVtbl *pchan_vtbl = &delegating_invoke_test_rpc_chan_vtbl;
1115 IRpcChannelBuffer *pchan = (IRpcChannelBuffer *)&pchan_vtbl;
1116 HRESULT r = E_FAIL;
1117 RPCOLEMESSAGE msg;
1118
1119 memset(&msg, 0, sizeof(msg));
1120 msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
1121 msg.iMethod = 3;
1122 r = IRpcStubBuffer_Invoke(pstub, &msg, pchan);
1123 ok(r == S_OK, "ret %08x\n", r);
1124 if(r == S_OK)
1125 {
1126 ok(*(DWORD*)msg.Buffer == 0xabcdef, "buf[0] %08x\n", *(DWORD*)msg.Buffer);
1127 ok(*((DWORD*)msg.Buffer + 1) == S_OK, "buf[1] %08x\n", *((DWORD*)msg.Buffer + 1));
1128 }
1129 /* free the buffer allocated by delegating_invoke_chan_get_buffer */
1130 HeapFree(GetProcessHeap(), 0, msg.Buffer);
1131 IRpcStubBuffer_Release(pstub);
1132 }
1133 static const CInterfaceProxyVtbl *cstub_ProxyVtblList2[] =
1134 {
1135 NULL
1136 };
1137
1138 static const CInterfaceStubVtbl *cstub_StubVtblList2[] =
1139 {
1140 NULL
1141 };
1142
1143 static PCInterfaceName const if_name_list2[] =
1144 {
1145 NULL
1146 };
1147
1148 static const IID *base_iid_list2[] =
1149 {
1150 NULL,
1151 };
1152
1153 static const ExtendedProxyFileInfo my_proxy_file_info2 =
1154 {
1155 (const PCInterfaceProxyVtblList *) &cstub_ProxyVtblList2,
1156 (const PCInterfaceStubVtblList *) &cstub_StubVtblList2,
1157 (const PCInterfaceName *) &if_name_list2,
1158 (const IID **) &base_iid_list2,
1159 &iid_lookup,
1160 0,
1161 1,
1162 NULL,
1163 0,
1164 0,
1165 0
1166 };
1167
1168 static const ProxyFileInfo *proxy_file_list2[] = {
1169 &my_proxy_file_info2,
1170 NULL
1171 };
1172
1173 static void test_NdrDllRegisterProxy( void )
1174 {
1175 HRESULT res;
1176 const ExtendedProxyFileInfo *pf;
1177 HMODULE hmod = GetModuleHandleA(NULL);
1178
1179
1180 res = NdrDllRegisterProxy(NULL, NULL, NULL);
1181 ok(res == E_HANDLE, "Incorrect return code %x\n",res);
1182 pf = NULL;
1183 res = NdrDllRegisterProxy(hmod, &pf, NULL);
1184 ok(res == E_NOINTERFACE, "Incorrect return code %x\n",res);
1185 res = NdrDllRegisterProxy(hmod, proxy_file_list2, NULL);
1186 ok(res == E_NOINTERFACE, "Incorrect return code %x\n",res);
1187 /* This fails on Vista and Windows 7 due to permissions */
1188 res = NdrDllRegisterProxy(hmod, proxy_file_list, NULL);
1189 ok(res == S_OK || res == E_ACCESSDENIED, "NdrDllRegisterProxy failed %x\n",res);
1190 if (res == S_OK)
1191 {
1192 res = NdrDllUnregisterProxy(hmod,proxy_file_list, NULL);
1193 ok(res == S_OK, "NdrDllUnregisterProxy failed %x\n",res);
1194 }
1195 }
1196
1197 START_TEST( cstub )
1198 {
1199 IPSFactoryBuffer *ppsf;
1200
1201 OleInitialize(NULL);
1202
1203 ppsf = test_NdrDllGetClassObject();
1204 test_NdrStubForwardingFunction();
1205 test_CreateProxy(ppsf);
1206 test_CreateStub(ppsf);
1207 test_Connect(ppsf);
1208 test_Disconnect(ppsf);
1209 test_Release(ppsf);
1210 test_delegating_Invoke(ppsf);
1211 test_NdrDllRegisterProxy();
1212
1213 OleUninitialize();
1214 }