f853cf61cbff9c6973662cf22d97be9ccd1670d5
[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
48 static int my_alloc_called;
49 static int my_free_called;
50
51 static void * CALLBACK my_alloc(SIZE_T size)
52 {
53 my_alloc_called++;
54 return NdrOleAllocate(size);
55 }
56
57 static void CALLBACK my_free(void *ptr)
58 {
59 my_free_called++;
60 NdrOleFree(ptr);
61 }
62
63 typedef struct _MIDL_PROC_FORMAT_STRING
64 {
65 short Pad;
66 unsigned char Format[ 2 ];
67 } MIDL_PROC_FORMAT_STRING;
68
69 typedef struct _MIDL_TYPE_FORMAT_STRING
70 {
71 short Pad;
72 unsigned char Format[ 2 ];
73 } MIDL_TYPE_FORMAT_STRING;
74
75
76 static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =
77 {
78 0,
79 {
80 0, 0
81 }
82 };
83
84 static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =
85 {
86 0,
87 {
88 0, 0
89 }
90 };
91
92 static const MIDL_STUB_DESC Object_StubDesc =
93 {
94 NULL,
95 my_alloc,
96 my_free,
97 { 0 },
98 0,
99 0,
100 0,
101 0,
102 __MIDL_TypeFormatString.Format,
103 1, /* -error bounds_check flag */
104 0x20000, /* Ndr library version */
105 0,
106 0x50100a4, /* MIDL Version 5.1.164 */
107 0,
108 NULL,
109 0, /* notify & notify_flag routine table */
110 1, /* Flags */
111 0, /* Reserved3 */
112 0, /* Reserved4 */
113 0 /* Reserved5 */
114 };
115
116 static HRESULT WINAPI if1_fn1_Proxy(void *This)
117 {
118 return S_OK;
119 }
120
121 static void __RPC_STUB if1_fn1_Stub(
122 IRpcStubBuffer *This,
123 IRpcChannelBuffer *_pRpcChannelBuffer,
124 PRPC_MESSAGE _pRpcMessage,
125 DWORD *_pdwStubPhase)
126 {
127 trace("fn1 stub\n");
128 }
129
130 static HRESULT WINAPI if1_fn2_Proxy(void *This)
131 {
132 return S_OK;
133 }
134
135 static void __RPC_STUB if1_fn2_Stub(
136 IRpcStubBuffer *This,
137 IRpcChannelBuffer *_pRpcChannelBuffer,
138 PRPC_MESSAGE _pRpcMessage,
139 DWORD *_pdwStubPhase)
140 {
141 trace("fn2 stub\n");
142 }
143
144 static CINTERFACE_PROXY_VTABLE(5) if1_proxy_vtbl =
145 {
146 { &IID_if1 },
147 { IUnknown_QueryInterface_Proxy,
148 IUnknown_AddRef_Proxy,
149 IUnknown_Release_Proxy ,
150 if1_fn1_Proxy,
151 if1_fn2_Proxy
152 }
153 };
154
155
156 static const unsigned short if1_FormatStringOffsetTable[] =
157 {
158 0,
159 0
160 };
161
162 static const MIDL_SERVER_INFO if1_server_info =
163 {
164 &Object_StubDesc,
165 0,
166 __MIDL_ProcFormatString.Format,
167 &if1_FormatStringOffsetTable[-3],
168 0,
169 0,
170 0,
171 0};
172
173
174 static const PRPC_STUB_FUNCTION if1_table[] =
175 {
176 if1_fn1_Stub,
177 if1_fn2_Stub
178 };
179
180 static CInterfaceStubVtbl if1_stub_vtbl =
181 {
182 {
183 &IID_if1,
184 &if1_server_info,
185 5,
186 &if1_table[-3]
187 },
188 { CStdStubBuffer_METHODS }
189 };
190
191 static CINTERFACE_PROXY_VTABLE(13) if2_proxy_vtbl =
192 {
193 { &IID_if2 },
194 { IUnknown_QueryInterface_Proxy,
195 IUnknown_AddRef_Proxy,
196 IUnknown_Release_Proxy ,
197 0,
198 0,
199 0,
200 0,
201 0,
202 0,
203 0,
204 0,
205 0,
206 0
207 }
208 };
209
210 static const unsigned short if2_FormatStringOffsetTable[] =
211 {
212 (unsigned short) -1,
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 0
223 };
224
225 static const MIDL_SERVER_INFO if2_server_info =
226 {
227 &Object_StubDesc,
228 0,
229 __MIDL_ProcFormatString.Format,
230 &if2_FormatStringOffsetTable[-3],
231 0,
232 0,
233 0,
234 0};
235
236
237 static const PRPC_STUB_FUNCTION if2_table[] =
238 {
239 STUB_FORWARDING_FUNCTION,
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 };
250
251 static CInterfaceStubVtbl if2_stub_vtbl =
252 {
253 {
254 &IID_if2,
255 &if2_server_info,
256 13,
257 &if2_table[-3]
258 },
259 { CStdStubBuffer_DELEGATING_METHODS }
260 };
261
262 static CINTERFACE_PROXY_VTABLE(5) if3_proxy_vtbl =
263 {
264 { &IID_if3 },
265 { IUnknown_QueryInterface_Proxy,
266 IUnknown_AddRef_Proxy,
267 IUnknown_Release_Proxy ,
268 if1_fn1_Proxy,
269 0
270 }
271 };
272
273
274 static const unsigned short if3_FormatStringOffsetTable[] =
275 {
276 0,
277 0
278 };
279
280 static const MIDL_SERVER_INFO if3_server_info =
281 {
282 &Object_StubDesc,
283 0,
284 __MIDL_ProcFormatString.Format,
285 &if3_FormatStringOffsetTable[-3],
286 0,
287 0,
288 0,
289 0};
290
291 static CInterfaceStubVtbl if3_stub_vtbl =
292 {
293 {
294 &IID_if3,
295 &if3_server_info,
296 5,
297 &if1_table[-3]
298 },
299 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
300 };
301
302 static CINTERFACE_PROXY_VTABLE(7) if4_proxy_vtbl =
303 {
304 { &IID_if4 },
305 { IUnknown_QueryInterface_Proxy,
306 IUnknown_AddRef_Proxy,
307 IUnknown_Release_Proxy ,
308 0,
309 0,
310 0,
311 0
312 }
313 };
314
315 static const unsigned short if4_FormatStringOffsetTable[] =
316 {
317 (unsigned short) -1,
318 (unsigned short) -1,
319 (unsigned short) -1,
320 (unsigned short) -1,
321 0
322 };
323
324 static const MIDL_SERVER_INFO if4_server_info =
325 {
326 &Object_StubDesc,
327 0,
328 __MIDL_ProcFormatString.Format,
329 &if4_FormatStringOffsetTable[-3],
330 0,
331 0,
332 0,
333 0};
334
335 static CInterfaceStubVtbl if4_stub_vtbl =
336 {
337 {
338 &IID_if4,
339 &if4_server_info,
340 7,
341 &if2_table[-3]
342 },
343 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
344 };
345
346 static const CInterfaceProxyVtbl *cstub_ProxyVtblList[] =
347 {
348 (const CInterfaceProxyVtbl *) &if1_proxy_vtbl,
349 (const CInterfaceProxyVtbl *) &if2_proxy_vtbl,
350 (const CInterfaceProxyVtbl *) &if3_proxy_vtbl,
351 (const CInterfaceProxyVtbl *) &if4_proxy_vtbl,
352 NULL
353 };
354
355 static const CInterfaceStubVtbl *cstub_StubVtblList[] =
356 {
357 &if1_stub_vtbl,
358 &if2_stub_vtbl,
359 &if3_stub_vtbl,
360 &if4_stub_vtbl,
361 NULL
362 };
363
364 static PCInterfaceName const if_name_list[] =
365 {
366 "if1",
367 "if2",
368 "if3",
369 "if4",
370 NULL
371 };
372
373 static const IID *base_iid_list[] =
374 {
375 NULL,
376 &IID_ITypeLib,
377 NULL,
378 &IID_IDispatch,
379 NULL
380 };
381
382 #define cstub_CHECK_IID(n) IID_GENERIC_CHECK_IID( cstub, pIID, n)
383
384 static int __stdcall iid_lookup( const IID * pIID, int * pIndex )
385 {
386 IID_BS_LOOKUP_SETUP
387
388 IID_BS_LOOKUP_INITIAL_TEST( cstub, 4, 4 )
389 IID_BS_LOOKUP_NEXT_TEST( cstub, 2 )
390 IID_BS_LOOKUP_NEXT_TEST( cstub, 1 )
391 IID_BS_LOOKUP_RETURN_RESULT( cstub, 4, *pIndex )
392
393 }
394
395
396 static BOOL check_address(void *actual, void *expected)
397 {
398 static void *ole32_start = NULL;
399 static void *ole32_end = NULL;
400 static void *combase_start = NULL;
401 static void *combase_end = NULL;
402
403 if (actual == expected)
404 return TRUE;
405
406 /* On Win7, actual can be located inside ole32.dll */
407 if (ole32_start == NULL || ole32_end == NULL)
408 {
409 PIMAGE_NT_HEADERS nt_headers;
410 ole32_start = (void *) GetModuleHandleA("ole32.dll");
411 if (ole32_start == NULL)
412 return FALSE;
413 nt_headers = (PIMAGE_NT_HEADERS)((char *) ole32_start + ((PIMAGE_DOS_HEADER) ole32_start)->e_lfanew);
414 ole32_end = (void *)((char *) ole32_start + nt_headers->OptionalHeader.SizeOfImage);
415 }
416
417 if (ole32_start <= actual && actual < ole32_end)
418 return TRUE;
419
420 /* On Win8, actual can be located inside combase.dll */
421 if (combase_start == NULL || combase_end == NULL)
422 {
423 PIMAGE_NT_HEADERS nt_headers;
424 combase_start = (void *) GetModuleHandleA("combase.dll");
425 if (combase_start == NULL)
426 return FALSE;
427 nt_headers = (PIMAGE_NT_HEADERS)((char *) combase_start + ((PIMAGE_DOS_HEADER) combase_start)->e_lfanew);
428 combase_end = (void *)((char *) combase_start + nt_headers->OptionalHeader.SizeOfImage);
429 }
430
431 return (combase_start <= actual && actual < combase_end);
432 }
433
434 static const ExtendedProxyFileInfo my_proxy_file_info =
435 {
436 (const PCInterfaceProxyVtblList *) &cstub_ProxyVtblList,
437 (const PCInterfaceStubVtblList *) &cstub_StubVtblList,
438 (const PCInterfaceName *) &if_name_list,
439 (const IID **) &base_iid_list,
440 &iid_lookup,
441 4,
442 1,
443 NULL,
444 0,
445 0,
446 0
447 };
448
449 static const ProxyFileInfo *proxy_file_list[] = {
450 &my_proxy_file_info,
451 NULL
452 };
453
454
455 static IPSFactoryBuffer *test_NdrDllGetClassObject(void)
456 {
457 HMODULE rpcrt4 = GetModuleHandleA("rpcrt4.dll");
458 IPSFactoryBuffer *ppsf = NULL;
459 const PCInterfaceProxyVtblList* proxy_vtbl;
460 const PCInterfaceStubVtblList* stub_vtbl;
461 const CLSID PSDispatch = {0x20420, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
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(&PSDispatch, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
479 &CLSID_Unknown, &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(&PSDispatch, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
484 &PSDispatch, &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 r = NdrDllGetClassObject(&IID_if3, &IID_IPSFactoryBuffer, (void**)&ppsf, proxy_file_list,
607 NULL, &PSFactoryBuffer);
608 ok(r == S_OK, "ret %08x\n", r);
609 ok(ppsf != NULL, "ppsf == NULL\n");
610
611 return ppsf;
612 }
613
614 static int base_buffer_invoke_called;
615 static HRESULT WINAPI base_buffer_Invoke(IRpcStubBuffer *This, RPCOLEMESSAGE *msg, IRpcChannelBuffer *channel)
616 {
617 base_buffer_invoke_called++;
618 ok(msg == (RPCOLEMESSAGE*)0xcafebabe, "msg ptr changed\n");
619 ok(channel == (IRpcChannelBuffer*)0xdeadbeef, "channel ptr changed\n");
620 return S_OK; /* returning any failure here results in an exception */
621 }
622
623 static IRpcStubBufferVtbl base_buffer_vtbl = {
624 (void*)0xcafebab0,
625 (void*)0xcafebab1,
626 (void*)0xcafebab2,
627 (void*)0xcafebab3,
628 (void*)0xcafebab4,
629 base_buffer_Invoke,
630 (void*)0xcafebab6,
631 (void*)0xcafebab7,
632 (void*)0xcafebab8,
633 (void*)0xcafebab9
634 };
635
636 static void test_NdrStubForwardingFunction(void)
637 {
638 void *This[5];
639 void *real_this;
640 IRpcChannelBuffer *channel = (IRpcChannelBuffer*)0xdeadbeef;
641 RPC_MESSAGE *msg = (RPC_MESSAGE*)0xcafebabe;
642 DWORD *phase = (DWORD*)0x12345678;
643 IRpcStubBufferVtbl *base_buffer_vtbl_ptr = &base_buffer_vtbl;
644 IRpcStubBuffer *base_stub_buffer = (IRpcStubBuffer*)&base_buffer_vtbl_ptr;
645
646 memset(This, 0xcc, sizeof(This));
647 This[0] = base_stub_buffer;
648 real_this = &This[1];
649
650 NdrStubForwardingFunction( real_this, channel, msg, phase );
651 ok(base_buffer_invoke_called == 1, "base_buffer_invoke called %d times\n", base_buffer_invoke_called);
652
653 }
654
655 static IRpcStubBuffer *create_stub(IPSFactoryBuffer *ppsf, REFIID iid, IUnknown *obj, HRESULT expected_result)
656 {
657 IRpcStubBuffer *pstub = NULL;
658 HRESULT r;
659
660 r = IPSFactoryBuffer_CreateStub(ppsf, iid, obj, &pstub);
661 ok(r == expected_result, "CreateStub returned %08x expected %08x\n", r, expected_result);
662 return pstub;
663 }
664
665 static HRESULT WINAPI create_stub_test_QI(IUnknown *This, REFIID iid, void **ppv)
666 {
667 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n");
668 *ppv = (void*)0xdeadbeef;
669 return S_OK;
670 }
671
672 static IUnknownVtbl create_stub_test_vtbl =
673 {
674 create_stub_test_QI,
675 NULL,
676 NULL
677 };
678
679 static HRESULT WINAPI create_stub_test_fail_QI(IUnknown *This, REFIID iid, void **ppv)
680 {
681 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n");
682 *ppv = NULL;
683 return E_NOINTERFACE;
684 }
685
686 static IUnknownVtbl create_stub_test_fail_vtbl =
687 {
688 create_stub_test_fail_QI,
689 NULL,
690 NULL
691 };
692
693 struct dummy_unknown
694 {
695 IUnknown IUnknown_iface;
696 LONG ref;
697 };
698
699 static inline struct dummy_unknown *impl_from_IUnknown(IUnknown *iface)
700 {
701 return CONTAINING_RECORD(iface, struct dummy_unknown, IUnknown_iface);
702 }
703
704 static HRESULT WINAPI dummy_QueryInterface(IUnknown *This, REFIID iid, void **ppv)
705 {
706 *ppv = NULL;
707 return E_NOINTERFACE;
708 }
709
710 static ULONG WINAPI dummy_AddRef(LPUNKNOWN iface)
711 {
712 struct dummy_unknown *this = impl_from_IUnknown(iface);
713 return InterlockedIncrement( &this->ref );
714 }
715
716 static ULONG WINAPI dummy_Release(LPUNKNOWN iface)
717 {
718 struct dummy_unknown *this = impl_from_IUnknown(iface);
719 return InterlockedDecrement( &this->ref );
720 }
721
722 static IUnknownVtbl dummy_unknown_vtbl =
723 {
724 dummy_QueryInterface,
725 dummy_AddRef,
726 dummy_Release
727 };
728 static struct dummy_unknown dummy_unknown = { { &dummy_unknown_vtbl }, 0 };
729
730 static void create_proxy_test( IPSFactoryBuffer *ppsf, REFIID iid, const void *expected_vtbl )
731 {
732 IRpcProxyBuffer *proxy = NULL;
733 IUnknown *iface = NULL;
734 HRESULT r;
735 ULONG count;
736
737 r = IPSFactoryBuffer_CreateProxy(ppsf, NULL, iid, &proxy, (void **)&iface);
738 ok( r == S_OK, "IPSFactoryBuffer_CreateProxy failed %x\n", r );
739 ok( *(void **)iface == expected_vtbl, "wrong iface pointer %p/%p\n", *(void **)iface, expected_vtbl );
740 count = IUnknown_Release( iface );
741 ok( count == 1, "wrong refcount %u\n", count );
742 count = IRpcProxyBuffer_Release( proxy );
743 ok( count == 0, "wrong refcount %u\n", count );
744
745 dummy_unknown.ref = 4;
746 r = IPSFactoryBuffer_CreateProxy(ppsf, &dummy_unknown.IUnknown_iface, iid, &proxy,
747 (void **)&iface);
748 ok( r == S_OK, "IPSFactoryBuffer_CreateProxy failed %x\n", r );
749 ok( dummy_unknown.ref == 5, "wrong refcount %u\n", dummy_unknown.ref );
750 ok( *(void **)iface == expected_vtbl, "wrong iface pointer %p/%p\n", *(void **)iface, expected_vtbl );
751 count = IUnknown_Release( iface );
752 ok( count == 4, "wrong refcount %u\n", count );
753 ok( dummy_unknown.ref == 4, "wrong refcount %u\n", dummy_unknown.ref );
754 count = IRpcProxyBuffer_Release( proxy );
755 ok( count == 0, "wrong refcount %u\n", count );
756 ok( dummy_unknown.ref == 4, "wrong refcount %u\n", dummy_unknown.ref );
757 }
758
759 static void test_CreateProxy( IPSFactoryBuffer *ppsf )
760 {
761 create_proxy_test( ppsf, &IID_if1, if1_proxy_vtbl.Vtbl );
762 create_proxy_test( ppsf, &IID_if2, if2_proxy_vtbl.Vtbl );
763 create_proxy_test( ppsf, &IID_if3, if3_proxy_vtbl.Vtbl );
764 create_proxy_test( ppsf, &IID_if4, if4_proxy_vtbl.Vtbl );
765 }
766
767 static void test_CreateStub(IPSFactoryBuffer *ppsf)
768 {
769 IUnknownVtbl *vtbl = &create_stub_test_vtbl;
770 IUnknown *obj = (IUnknown*)&vtbl;
771 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
772 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
773 const CInterfaceStubHeader *header = &CONTAINING_RECORD(cstd_stub->lpVtbl, const CInterfaceStubVtbl, Vtbl)->header;
774
775 ok(IsEqualIID(header->piid, &IID_if1), "header iid differs\n");
776 ok(cstd_stub->RefCount == 1, "ref count %d\n", cstd_stub->RefCount);
777 /* 0xdeadbeef returned from create_stub_test_QI */
778 ok(cstd_stub->pvServerObject == (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub->pvServerObject);
779 ok(cstd_stub->pPSFactory != NULL, "pPSFactory was NULL\n");
780 cstd_stub->pvServerObject = NULL;
781 IRpcStubBuffer_Release(pstub);
782
783 vtbl = &create_stub_test_fail_vtbl;
784 pstub = create_stub(ppsf, &IID_if1, obj, E_NOINTERFACE);
785 ok(pstub == S_OK, "create_stub failed: %u\n", GetLastError());
786
787 }
788
789 static HRESULT WINAPI connect_test_orig_QI(IUnknown *This, REFIID iid, void **ppv)
790 {
791 ok(IsEqualIID(iid, &IID_if1) ||
792 IsEqualIID(iid, &IID_if2), "incorrect iid\n");
793 *ppv = (void*)This;
794 return S_OK;
795 }
796
797 static int connect_test_orig_release_called;
798 static ULONG WINAPI connect_test_orig_release(IUnknown *This)
799 {
800 connect_test_orig_release_called++;
801 return 0;
802 }
803
804 static IUnknownVtbl connect_test_orig_vtbl =
805 {
806 connect_test_orig_QI,
807 NULL,
808 connect_test_orig_release
809 };
810
811 static HRESULT WINAPI connect_test_new_QI(IUnknown *This, REFIID iid, void **ppv)
812 {
813 ok(IsEqualIID(iid, &IID_if1) ||
814 IsEqualIID(iid, &IID_if2), "incorrect iid\n");
815 *ppv = (void*)0xcafebabe;
816 return S_OK;
817 }
818
819 static IUnknownVtbl connect_test_new_vtbl =
820 {
821 connect_test_new_QI,
822 NULL,
823 NULL
824 };
825
826 static HRESULT WINAPI connect_test_new_fail_QI(IUnknown *This, REFIID iid, void **ppv)
827 {
828 ok(IsEqualIID(iid, &IID_if1), "incorrect iid\n");
829 *ppv = (void*)0xdeadbeef;
830 return E_NOINTERFACE;
831 }
832
833 static IUnknownVtbl connect_test_new_fail_vtbl =
834 {
835 connect_test_new_fail_QI,
836 NULL,
837 NULL
838 };
839
840 static int connect_test_base_Connect_called;
841 static HRESULT WINAPI connect_test_base_Connect(IRpcStubBuffer *pstub, IUnknown *obj)
842 {
843 connect_test_base_Connect_called++;
844 ok(*(void**)obj == (void*)0xbeefcafe, "unexpected obj %p\n", obj);
845 return S_OK;
846 }
847
848 static IRpcStubBufferVtbl connect_test_base_stub_buffer_vtbl =
849 {
850 (void*)0xcafebab0,
851 (void*)0xcafebab1,
852 (void*)0xcafebab2,
853 connect_test_base_Connect,
854 (void*)0xcafebab4,
855 (void*)0xcafebab5,
856 (void*)0xcafebab6,
857 (void*)0xcafebab7,
858 (void*)0xcafebab8,
859 (void*)0xcafebab9
860 };
861
862 static void test_Connect(IPSFactoryBuffer *ppsf)
863 {
864 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl;
865 IUnknownVtbl *new_vtbl = &connect_test_new_vtbl;
866 IUnknownVtbl *new_fail_vtbl = &connect_test_new_fail_vtbl;
867 IUnknown *obj = (IUnknown*)&orig_vtbl;
868 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
869 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
870 IRpcStubBufferVtbl *base_stub_buf_vtbl = &connect_test_base_stub_buffer_vtbl;
871 HRESULT r;
872
873 obj = (IUnknown*)&new_vtbl;
874 r = IRpcStubBuffer_Connect(pstub, obj);
875 ok(r == S_OK, "r %08x\n", r);
876 ok(connect_test_orig_release_called == 1, "release called %d\n", connect_test_orig_release_called);
877 ok(cstd_stub->pvServerObject == (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub->pvServerObject);
878
879 cstd_stub->pvServerObject = (IUnknown*)&orig_vtbl;
880 obj = (IUnknown*)&new_fail_vtbl;
881 r = IRpcStubBuffer_Connect(pstub, obj);
882 ok(r == E_NOINTERFACE, "r %08x\n", r);
883 ok(cstd_stub->pvServerObject == (void*)0xdeadbeef, "pvServerObject %p\n", cstd_stub->pvServerObject);
884 ok(connect_test_orig_release_called == 2, "release called %d\n", connect_test_orig_release_called);
885
886 /* Now use a delegated stub.
887
888 We know from the NdrStubForwardFunction test that
889 (void**)pstub-1 is the base interface stub buffer. This shows
890 that (void**)pstub-2 contains the address of a vtable that gets
891 passed to the base interface's Connect method. Note that
892 (void**)pstub-2 itself gets passed to Connect and not
893 *((void**)pstub-2), so it should contain the vtable ptr and not
894 an interface ptr. */
895
896 obj = (IUnknown*)&orig_vtbl;
897 pstub = create_stub(ppsf, &IID_if2, obj, S_OK);
898 *((void**)pstub-1) = &base_stub_buf_vtbl;
899 *((void**)pstub-2) = (void*)0xbeefcafe;
900
901 obj = (IUnknown*)&new_vtbl;
902 r = IRpcStubBuffer_Connect(pstub, obj);
903 ok(r == S_OK, "r %08x\n", r);
904 ok(connect_test_base_Connect_called == 1, "connect_test_bsae_Connect called %d times\n",
905 connect_test_base_Connect_called);
906 ok(connect_test_orig_release_called == 3, "release called %d\n", connect_test_orig_release_called);
907 cstd_stub = (CStdStubBuffer*)pstub;
908 ok(cstd_stub->pvServerObject == (void*)0xcafebabe, "pvServerObject %p\n", cstd_stub->pvServerObject);
909 }
910
911 static void test_Disconnect(IPSFactoryBuffer *ppsf)
912 {
913 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl;
914 IUnknown *obj = (IUnknown*)&orig_vtbl;
915 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
916 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
917
918 connect_test_orig_release_called = 0;
919 IRpcStubBuffer_Disconnect(pstub);
920 ok(connect_test_orig_release_called == 1, "release called %d\n", connect_test_orig_release_called);
921 ok(cstd_stub->pvServerObject == NULL, "pvServerObject %p\n", cstd_stub->pvServerObject);
922 IRpcStubBuffer_Release(pstub);
923 }
924
925
926 static int release_test_psfacbuf_release_called;
927 static ULONG WINAPI release_test_pretend_psfacbuf_release(IUnknown *pUnk)
928 {
929 release_test_psfacbuf_release_called++;
930 return 1;
931 }
932
933 static IUnknownVtbl release_test_pretend_psfacbuf_vtbl =
934 {
935 NULL,
936 NULL,
937 release_test_pretend_psfacbuf_release
938 };
939
940 static void test_Release(IPSFactoryBuffer *ppsf)
941 {
942 LONG facbuf_refs;
943 IUnknownVtbl *orig_vtbl = &connect_test_orig_vtbl;
944 IUnknown *obj = (IUnknown*)&orig_vtbl;
945 IUnknownVtbl *pretend_psfacbuf_vtbl = &release_test_pretend_psfacbuf_vtbl;
946 IUnknown *pretend_psfacbuf = (IUnknown *)&pretend_psfacbuf_vtbl;
947 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
948 CStdStubBuffer *cstd_stub = (CStdStubBuffer*)pstub;
949
950 facbuf_refs = PSFactoryBuffer.RefCount;
951
952 /* This shows that NdrCStdStubBuffer_Release doesn't call Disconnect */
953 ok(cstd_stub->RefCount == 1, "ref count %d\n", cstd_stub->RefCount);
954 connect_test_orig_release_called = 0;
955 IRpcStubBuffer_Release(pstub);
956 todo_wine {
957 ok(connect_test_orig_release_called == 0, "release called %d\n", connect_test_orig_release_called);
958 }
959 ok(PSFactoryBuffer.RefCount == facbuf_refs - 1, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs);
960
961 /* This shows that NdrCStdStubBuffer_Release calls Release on its 2nd arg, rather than on This->pPSFactory
962 (which are usually the same and indeed it's odd that _Release requires this 2nd arg). */
963 pstub = create_stub(ppsf, &IID_if1, obj, S_OK);
964 ok(PSFactoryBuffer.RefCount == facbuf_refs, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs);
965 NdrCStdStubBuffer_Release(pstub, (IPSFactoryBuffer*)pretend_psfacbuf);
966 ok(release_test_psfacbuf_release_called == 1, "pretend_psfacbuf_release called %d\n", release_test_psfacbuf_release_called);
967 ok(PSFactoryBuffer.RefCount == facbuf_refs, "factory buffer refs %d orig %d\n", PSFactoryBuffer.RefCount, facbuf_refs);
968 }
969
970 static HRESULT WINAPI delegating_invoke_test_QI(ITypeLib *pUnk, REFIID iid, void** ppv)
971 {
972
973 *ppv = pUnk;
974 return S_OK;
975 }
976
977 static ULONG WINAPI delegating_invoke_test_addref(ITypeLib *pUnk)
978 {
979 return 1;
980 }
981
982 static ULONG WINAPI delegating_invoke_test_release(ITypeLib *pUnk)
983 {
984 return 1;
985 }
986
987 static UINT WINAPI delegating_invoke_test_get_type_info_count(ITypeLib *pUnk)
988 {
989 return 0xabcdef;
990 }
991
992 static ITypeLibVtbl delegating_invoke_test_obj_vtbl =
993 {
994 delegating_invoke_test_QI,
995 delegating_invoke_test_addref,
996 delegating_invoke_test_release,
997 delegating_invoke_test_get_type_info_count,
998 NULL,
999 NULL,
1000 NULL,
1001 NULL,
1002 NULL,
1003 NULL,
1004 NULL,
1005 NULL,
1006 NULL
1007 };
1008
1009 static HRESULT WINAPI delegating_invoke_chan_query_interface(IRpcChannelBuffer *pchan,
1010 REFIID iid,
1011 void **ppv)
1012 {
1013 ok(0, "call to QueryInterface not expected\n");
1014 return E_NOINTERFACE;
1015 }
1016
1017 static ULONG WINAPI delegating_invoke_chan_add_ref(IRpcChannelBuffer *pchan)
1018 {
1019 return 2;
1020 }
1021
1022 static ULONG WINAPI delegating_invoke_chan_release(IRpcChannelBuffer *pchan)
1023 {
1024 return 1;
1025 }
1026
1027 static HRESULT WINAPI delegating_invoke_chan_get_buffer(IRpcChannelBuffer *pchan,
1028 RPCOLEMESSAGE *msg,
1029 REFIID iid)
1030 {
1031 msg->Buffer = HeapAlloc(GetProcessHeap(), 0, msg->cbBuffer);
1032 return S_OK;
1033 }
1034
1035 static HRESULT WINAPI delegating_invoke_chan_send_receive(IRpcChannelBuffer *pchan,
1036 RPCOLEMESSAGE *pMessage,
1037 ULONG *pStatus)
1038 {
1039 ok(0, "call to SendReceive not expected\n");
1040 return E_NOTIMPL;
1041 }
1042
1043 static HRESULT WINAPI delegating_invoke_chan_free_buffer(IRpcChannelBuffer *pchan,
1044 RPCOLEMESSAGE *pMessage)
1045 {
1046 ok(0, "call to FreeBuffer not expected\n");
1047 return E_NOTIMPL;
1048 }
1049
1050 static HRESULT WINAPI delegating_invoke_chan_get_dest_ctx(IRpcChannelBuffer *pchan,
1051 DWORD *pdwDestContext,
1052 void **ppvDestContext)
1053 {
1054 *pdwDestContext = MSHCTX_LOCAL;
1055 *ppvDestContext = NULL;
1056 return S_OK;
1057 }
1058
1059 static HRESULT WINAPI delegating_invoke_chan_is_connected(IRpcChannelBuffer *pchan)
1060 {
1061 ok(0, "call to IsConnected not expected\n");
1062 return E_NOTIMPL;
1063 }
1064
1065 static IRpcChannelBufferVtbl delegating_invoke_test_rpc_chan_vtbl =
1066 {
1067 delegating_invoke_chan_query_interface,
1068 delegating_invoke_chan_add_ref,
1069 delegating_invoke_chan_release,
1070 delegating_invoke_chan_get_buffer,
1071 delegating_invoke_chan_send_receive,
1072 delegating_invoke_chan_free_buffer,
1073 delegating_invoke_chan_get_dest_ctx,
1074 delegating_invoke_chan_is_connected
1075 };
1076
1077 static void test_delegating_Invoke(IPSFactoryBuffer *ppsf)
1078 {
1079 ITypeLibVtbl *obj_vtbl = &delegating_invoke_test_obj_vtbl;
1080 IUnknown *obj = (IUnknown*)&obj_vtbl;
1081 IRpcStubBuffer *pstub = create_stub(ppsf, &IID_if2, obj, S_OK);
1082 IRpcChannelBufferVtbl *pchan_vtbl = &delegating_invoke_test_rpc_chan_vtbl;
1083 IRpcChannelBuffer *pchan = (IRpcChannelBuffer *)&pchan_vtbl;
1084 HRESULT r = E_FAIL;
1085 RPCOLEMESSAGE msg;
1086
1087 memset(&msg, 0, sizeof(msg));
1088 msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
1089 msg.iMethod = 3;
1090 r = IRpcStubBuffer_Invoke(pstub, &msg, pchan);
1091 ok(r == S_OK, "ret %08x\n", r);
1092 if(r == S_OK)
1093 {
1094 ok(*(DWORD*)msg.Buffer == 0xabcdef, "buf[0] %08x\n", *(DWORD*)msg.Buffer);
1095 ok(*((DWORD*)msg.Buffer + 1) == S_OK, "buf[1] %08x\n", *((DWORD*)msg.Buffer + 1));
1096 }
1097 /* free the buffer allocated by delegating_invoke_chan_get_buffer */
1098 HeapFree(GetProcessHeap(), 0, msg.Buffer);
1099 IRpcStubBuffer_Release(pstub);
1100 }
1101 static const CInterfaceProxyVtbl *cstub_ProxyVtblList2[] =
1102 {
1103 NULL
1104 };
1105
1106 static const CInterfaceStubVtbl *cstub_StubVtblList2[] =
1107 {
1108 NULL
1109 };
1110
1111 static PCInterfaceName const if_name_list2[] =
1112 {
1113 NULL
1114 };
1115
1116 static const IID *base_iid_list2[] =
1117 {
1118 NULL,
1119 };
1120
1121 static const ExtendedProxyFileInfo my_proxy_file_info2 =
1122 {
1123 (const PCInterfaceProxyVtblList *) &cstub_ProxyVtblList2,
1124 (const PCInterfaceStubVtblList *) &cstub_StubVtblList2,
1125 (const PCInterfaceName *) &if_name_list2,
1126 (const IID **) &base_iid_list2,
1127 &iid_lookup,
1128 0,
1129 1,
1130 NULL,
1131 0,
1132 0,
1133 0
1134 };
1135
1136 static const ProxyFileInfo *proxy_file_list2[] = {
1137 &my_proxy_file_info2,
1138 NULL
1139 };
1140
1141 static void test_NdrDllRegisterProxy( void )
1142 {
1143 HRESULT res;
1144 const ExtendedProxyFileInfo *pf;
1145 HMODULE hmod = GetModuleHandleA(NULL);
1146
1147
1148 res = NdrDllRegisterProxy(NULL, NULL, NULL);
1149 ok(res == E_HANDLE, "Incorrect return code %x\n",res);
1150 pf = NULL;
1151 res = NdrDllRegisterProxy(hmod, &pf, NULL);
1152 ok(res == E_NOINTERFACE, "Incorrect return code %x\n",res);
1153 res = NdrDllRegisterProxy(hmod, proxy_file_list2, NULL);
1154 ok(res == E_NOINTERFACE, "Incorrect return code %x\n",res);
1155 /* This fails on Vista and Windows 7 due to permissions */
1156 res = NdrDllRegisterProxy(hmod, proxy_file_list, NULL);
1157 ok(res == S_OK || res == E_ACCESSDENIED, "NdrDllRegisterProxy failed %x\n",res);
1158 if (res == S_OK)
1159 {
1160 res = NdrDllUnregisterProxy(hmod,proxy_file_list, NULL);
1161 ok(res == S_OK, "NdrDllUnregisterProxy failed %x\n",res);
1162 }
1163 }
1164
1165 START_TEST( cstub )
1166 {
1167 IPSFactoryBuffer *ppsf;
1168
1169 OleInitialize(NULL);
1170
1171 ppsf = test_NdrDllGetClassObject();
1172 test_NdrStubForwardingFunction();
1173 test_CreateProxy(ppsf);
1174 test_CreateStub(ppsf);
1175 test_Connect(ppsf);
1176 test_Disconnect(ppsf);
1177 test_Release(ppsf);
1178 test_delegating_Invoke(ppsf);
1179 test_NdrDllRegisterProxy();
1180
1181 OleUninitialize();
1182 }