ReactOS 0.4.15-dev-8417-gb6b82fe
usrmarshal.c
Go to the documentation of this file.
1/*
2 * Marshaling Tests
3 *
4 * Copyright 2004 Robert Shearman
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#define COBJMACROS
22#define CONST_VTABLE
23
24#include <stdarg.h>
25
26#include "windef.h"
27#include "winbase.h"
28#include "objbase.h"
29#include "propidl.h" /* for LPSAFEARRAY_User* routines */
30
31#include "wine/test.h"
32
33#if (__STDC__ && !defined(_FORCENAMELESSUNION)) || defined(NONAMELESSUNION)
34# define V_U2(A) ((A)->n1.n2)
35#else
36# define V_U2(A) (*(A))
37#endif
38
39static HRESULT (WINAPI *pSafeArrayGetIID)(SAFEARRAY*,GUID*);
40static HRESULT (WINAPI *pSafeArrayGetVartype)(SAFEARRAY*,VARTYPE*);
41static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
42
43static inline SF_TYPE get_union_type(SAFEARRAY *psa)
44{
45 VARTYPE vt;
46 HRESULT hr;
47
48 hr = pSafeArrayGetVartype(psa, &vt);
49 if (FAILED(hr))
50 {
51 if(psa->fFeatures & FADF_VARIANT) return SF_VARIANT;
52
53 switch(psa->cbElements)
54 {
55 case 1: vt = VT_I1; break;
56 case 2: vt = VT_I2; break;
57 case 4: vt = VT_I4; break;
58 case 8: vt = VT_I8; break;
59 default: return 0;
60 }
61 }
62
63 if (psa->fFeatures & FADF_HAVEIID)
64 return SF_HAVEIID;
65
66 switch (vt)
67 {
68 case VT_I1:
69 case VT_UI1: return SF_I1;
70 case VT_BOOL:
71 case VT_I2:
72 case VT_UI2: return SF_I2;
73 case VT_INT:
74 case VT_UINT:
75 case VT_I4:
76 case VT_UI4:
77 case VT_R4: return SF_I4;
78 case VT_DATE:
79 case VT_CY:
80 case VT_R8:
81 case VT_I8:
82 case VT_UI8: return SF_I8;
83 case VT_INT_PTR:
84 case VT_UINT_PTR: return (sizeof(UINT_PTR) == 4 ? SF_I4 : SF_I8);
85 case VT_BSTR: return SF_BSTR;
86 case VT_DISPATCH: return SF_DISPATCH;
87 case VT_VARIANT: return SF_VARIANT;
88 case VT_UNKNOWN: return SF_UNKNOWN;
89 /* Note: Return a non-zero size to indicate vt is valid. The actual size
90 * of a UDT is taken from the result of IRecordInfo_GetSize().
91 */
92 case VT_RECORD: return SF_RECORD;
93 default: return SF_ERROR;
94 }
95}
96
98{
99 const SAFEARRAYBOUND* psab = psa->rgsabound;
100 USHORT cCount = psa->cDims;
101 ULONG ulNumCells = 1;
102
103 while (cCount--)
104 {
105 if (!psab->cElements)
106 return 0;
107 ulNumCells *= psab->cElements;
108 psab++;
109 }
110 return ulNumCells;
111}
112
113static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype)
114{
115 if (sftype == SF_BSTR)
116 return sizeof(DWORD);
117 else
118 return lpsa->cbElements;
119}
120
121static void check_safearray(void *buffer, LPSAFEARRAY lpsa)
122{
123 unsigned char *wiresa = buffer;
124 const SAFEARRAYBOUND *bounds;
125 VARTYPE vt;
126 SF_TYPE sftype;
127 ULONG cell_count;
128 int i;
129
130 if(!lpsa)
131 {
132 ok(*(DWORD *)wiresa == 0, "wiresa + 0x0 should be NULL instead of 0x%08x\n", *(DWORD *)wiresa);
133 return;
134 }
135
136 if (!pSafeArrayGetVartype || !pSafeArrayGetIID)
137 return;
138
139 if(FAILED(pSafeArrayGetVartype(lpsa, &vt)))
140 vt = 0;
141
142 sftype = get_union_type(lpsa);
143 cell_count = get_cell_count(lpsa);
144
145 ok(*(DWORD *)wiresa, "wiresa + 0x0 should be non-NULL instead of 0x%08x\n", *(DWORD *)wiresa); /* win2k: this is lpsa. winxp: this is 0x00000001 */
146 wiresa += sizeof(DWORD);
147 ok(*(DWORD *)wiresa == lpsa->cDims, "wiresa + 0x4 should be lpsa->cDims instead of 0x%08x\n", *(DWORD *)wiresa);
148 wiresa += sizeof(DWORD);
149 ok(*(WORD *)wiresa == lpsa->cDims, "wiresa + 0x8 should be lpsa->cDims instead of 0x%04x\n", *(WORD *)wiresa);
150 wiresa += sizeof(WORD);
151 ok(*(WORD *)wiresa == lpsa->fFeatures, "wiresa + 0xa should be lpsa->fFeatures instead of 0x%08x\n", *(WORD *)wiresa);
152 wiresa += sizeof(WORD);
153 ok(*(DWORD *)wiresa == elem_wire_size(lpsa, sftype), "wiresa + 0xc should be 0x%08x instead of 0x%08x\n", elem_wire_size(lpsa, sftype), *(DWORD *)wiresa);
154 wiresa += sizeof(DWORD);
155 ok(*(WORD *)wiresa == lpsa->cLocks, "wiresa + 0x10 should be lpsa->cLocks instead of 0x%04x\n", *(WORD *)wiresa);
156 wiresa += sizeof(WORD);
157 ok(*(WORD *)wiresa == vt, "wiresa + 0x12 should be %04x instead of 0x%04x\n", vt, *(WORD *)wiresa);
158 wiresa += sizeof(WORD);
159 ok(*(DWORD *)wiresa == sftype, "wiresa + 0x14 should be %08x instead of 0x%08x\n", (DWORD)sftype, *(DWORD *)wiresa);
160 wiresa += sizeof(DWORD);
161 ok(*(DWORD *)wiresa == cell_count, "wiresa + 0x18 should be %u instead of %u\n", cell_count, *(DWORD *)wiresa);
162 wiresa += sizeof(DWORD);
163 ok(*(DWORD *)wiresa, "wiresa + 0x1c should be non-zero instead of 0x%08x\n", *(DWORD *)wiresa);
164 wiresa += sizeof(DWORD);
165 if(sftype == SF_HAVEIID)
166 {
167 GUID guid;
168 pSafeArrayGetIID(lpsa, &guid);
169 ok(IsEqualGUID(&guid, wiresa), "guid mismatch\n");
170 wiresa += sizeof(GUID);
171 }
172
173 /* bounds are marshaled in natural dimensions order */
174 bounds = (SAFEARRAYBOUND*)wiresa;
175 for(i=0; i<lpsa->cDims; i++)
176 {
177 ok(memcmp(bounds, &lpsa->rgsabound[lpsa->cDims-i-1], sizeof(SAFEARRAYBOUND)) == 0,
178 "bounds mismatch for dimension %d, got (%d,%d), expected (%d,%d)\n", i,
179 bounds->lLbound, bounds->cElements, lpsa->rgsabound[lpsa->cDims-i-1].lLbound,
180 lpsa->rgsabound[lpsa->cDims-i-1].cElements);
181 bounds++;
182 }
183
184 wiresa += sizeof(lpsa->rgsabound[0]) * lpsa->cDims;
185
186 ok(*(DWORD *)wiresa == cell_count, "wiresa + 0x28 should be %u instead of %u\n", cell_count, *(DWORD*)wiresa);
187 wiresa += sizeof(DWORD);
188 /* elements are now pointed to by wiresa */
189}
190
192{
193 ok(0, "unexpected user_allocate call\n");
194 return CoTaskMemAlloc(size);
195}
196
197static void WINAPI user_free(void *p)
198{
199 ok(0, "unexpected user_free call\n");
201}
202
204 PMIDL_STUB_MESSAGE stub_msg,
205 PRPC_MESSAGE rpc_msg, unsigned char *buffer,
206 unsigned int size, MSHCTX context)
207{
208 memset(rpc_msg, 0, sizeof(*rpc_msg));
209 rpc_msg->Buffer = buffer;
210 rpc_msg->BufferLength = size;
211
212 memset(stub_msg, 0, sizeof(*stub_msg));
213 stub_msg->RpcMsg = rpc_msg;
214 stub_msg->Buffer = buffer;
215 stub_msg->pfnAllocate = user_allocate;
216 stub_msg->pfnFree = user_free;
217
218 memset(umcb, 0, sizeof(*umcb));
220 umcb->pStubMsg = stub_msg;
223}
224
226{
227 unsigned char *buffer, *next;
229 LPSAFEARRAY lpsa;
230 LPSAFEARRAY lpsa2 = NULL;
231 SAFEARRAYBOUND sab[2];
233 MIDL_STUB_MESSAGE stub_msg;
234 USER_MARSHAL_CB umcb;
235 HRESULT hr;
236 VARTYPE vt, vt2;
237 OLECHAR *values[10];
238 int expected_bstr_size;
239 int i;
240 LONG indices[1];
241
242 sab[0].lLbound = 5;
243 sab[0].cElements = 10;
244
245 lpsa = SafeArrayCreate(VT_I2, 1, sab);
246 *(DWORD *)lpsa->pvData = 0xcafebabe;
247
248 lpsa->cLocks = 7;
249 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
250 size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
251 expected = (44 + 1 + sizeof(ULONG) - 1) & ~(sizeof(ULONG) - 1);
252 expected += sab[0].cElements * sizeof(USHORT);
253 ok(size == expected || size == expected + 12, /* win64 */
254 "size should be %u bytes, not %u\n", expected, size);
255 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
256 size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
257 expected = 44 + sab[0].cElements * sizeof(USHORT);
258 ok(size == expected || size == expected + 12, /* win64 */
259 "size should be %u bytes, not %u\n", expected, size);
261 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
262 next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
263 ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
264 ok(lpsa->cLocks == 7, "got lock count %u\n", lpsa->cLocks);
265
266 check_safearray(buffer, lpsa);
267
268 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
269 LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
270 ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal\n");
271 if (pSafeArrayGetVartype)
272 {
273 pSafeArrayGetVartype(lpsa, &vt);
274 pSafeArrayGetVartype(lpsa2, &vt2);
275 ok(vt == vt2, "vts differ %x %x\n", vt, vt2);
276 }
277 ok(lpsa2->cLocks == 0, "got lock count %u, expected 0\n", lpsa2->cLocks);
278 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
279 LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
280 ok(!lpsa2, "lpsa2 was not set to 0 by LPSAFEARRAY_UserFree\n");
282 lpsa->cLocks = 0;
283 hr = SafeArrayDestroy(lpsa);
284 ok(hr == S_OK, "got 0x%08x\n", hr);
285
286 /* use two dimensions */
287 sab[0].lLbound = 5;
288 sab[0].cElements = 10;
289 sab[1].lLbound = 1;
290 sab[1].cElements = 2;
291
292 lpsa = SafeArrayCreate(VT_I2, 2, sab);
293 *(DWORD *)lpsa->pvData = 0xcafebabe;
294
295 lpsa->cLocks = 7;
296 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
297 size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
298 expected = (44 + 1 + +sizeof(SAFEARRAYBOUND) + sizeof(ULONG) - 1) & ~(sizeof(ULONG) - 1);
299 expected += max(sab[0].cElements, sab[1].cElements) * lpsa->cDims * sizeof(USHORT);
300 ok(size == expected || size == expected + 12, /* win64 */
301 "size should be %u bytes, not %u\n", expected, size);
302 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
303 size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
304 expected = 52 + max(sab[0].cElements, sab[1].cElements) * lpsa->cDims * sizeof(USHORT);
305 ok(size == expected || size == expected + 12, /* win64 */
306 "size should be %u bytes, not %u\n", expected, size);
308 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
309 next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
310 ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
311 ok(lpsa->cLocks == 7, "got lock count %u\n", lpsa->cLocks);
312
313 check_safearray(buffer, lpsa);
314
315 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
316 LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
317 ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal\n");
318 if (pSafeArrayGetVartype)
319 {
320 pSafeArrayGetVartype(lpsa, &vt);
321 pSafeArrayGetVartype(lpsa2, &vt2);
322 ok(vt == vt2, "vts differ %x %x\n", vt, vt2);
323 }
324 ok(lpsa2->cLocks == 0, "got lock count %u, expected 0\n", lpsa2->cLocks);
325 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
326 LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
328 lpsa->cLocks = 0;
329 hr = SafeArrayDestroy(lpsa);
330 ok(hr == S_OK, "got 0x%08x\n", hr);
331
332 /* test NULL safe array */
333 lpsa = NULL;
334
335 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
336 size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
337 expected = 4;
338 ok(size == expected, "size should be 4 bytes, not %d\n", size);
340 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
341 next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
342 ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
343 check_safearray(buffer, lpsa);
344
345 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
346 LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
347 ok(lpsa2 == NULL, "NULL LPSAFEARRAY didn't unmarshal\n");
348 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
349 LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
351
352 sab[0].lLbound = 5;
353 sab[0].cElements = 10;
354
355 lpsa = SafeArrayCreate(VT_R8, 1, sab);
356 *(double *)lpsa->pvData = 3.1415;
357
358 lpsa->cLocks = 7;
359 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
360 size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
361 expected = (44 + 1 + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
362 expected += sab[0].cElements * sizeof(double);
363 ok(size == expected || size == expected + 16, /* win64 */
364 "size should be %u bytes, not %u\n", expected, size);
365 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
366 expected = (44 + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
367 expected += sab[0].cElements * sizeof(double);
368 size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
369 ok(size == expected || size == expected + 8, /* win64 */
370 "size should be %u bytes, not %u\n", expected, size);
372 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
373 next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
374 ok(next - buffer == expected || broken(next - buffer + sizeof(DWORD) == expected),
375 "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
376
377 check_safearray(buffer, lpsa);
378
380 lpsa->cLocks = 0;
381 hr = SafeArrayDestroy(lpsa);
382 ok(hr == S_OK, "got 0x%08x\n", hr);
383
384 /* VARTYPE-less arrays can be marshaled if cbElements is 1,2,4 or 8 as type SF_In */
385 hr = SafeArrayAllocDescriptor(1, &lpsa);
386 ok(hr == S_OK, "saad failed %08x\n", hr);
387 lpsa->cbElements = 8;
388 lpsa->rgsabound[0].lLbound = 2;
389 lpsa->rgsabound[0].cElements = 48;
390 hr = SafeArrayAllocData(lpsa);
391 ok(hr == S_OK, "saad failed %08x\n", hr);
392
393 if (pSafeArrayGetVartype)
394 {
395 hr = pSafeArrayGetVartype(lpsa, &vt);
396 ok(hr == E_INVALIDARG, "ret %08x\n", hr);
397 }
398
399 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
400 size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
401 expected = (44 + lpsa->cbElements - 1) & ~(lpsa->cbElements - 1);
402 expected += lpsa->cbElements * lpsa->rgsabound[0].cElements;
403 ok(size == expected || size == expected + 8, /* win64 */
404 "size should be %u bytes, not %u\n", expected, size);
406 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
407 next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
408 ok(next - buffer == expected || broken(next - buffer + sizeof(DWORD) == expected),
409 "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
410 check_safearray(buffer, lpsa);
412 hr = SafeArrayDestroyData(lpsa);
413 ok(hr == S_OK, "got 0x%08x\n", hr);
415 ok(hr == S_OK, "got 0x%08x\n", hr);
416
417 /* Test an array of VT_BSTR */
418 sab[0].lLbound = 3;
419 sab[0].cElements = ARRAY_SIZE(values);
420
421 lpsa = SafeArrayCreate(VT_BSTR, 1, sab);
422 expected_bstr_size = 0;
423 for (i = 0; i < sab[0].cElements; i++)
424 {
425 int j;
426 WCHAR buf[128];
427 for (j = 0; j <= i; j++)
428 buf[j] = 'a' + j;
429 buf[j] = 0;
430 indices[0] = i + sab[0].lLbound;
433 ok(hr == S_OK, "Failed to put bstr element hr 0x%x\n", hr);
434 expected_bstr_size += (j * sizeof(WCHAR)) + (3 * sizeof(DWORD));
435 if (i % 2 == 0) /* Account for DWORD padding. Works so long as cElements is even */
436 expected_bstr_size += sizeof(WCHAR);
437 }
438
439 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
440 size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
441 expected = 44 + (sab[0].cElements * sizeof(DWORD)) + expected_bstr_size;
443 ok(size == expected + sizeof(DWORD) || size == (expected + sizeof(DWORD) + 12 /* win64 */),
444 "size should be %u bytes, not %u\n", expected + (ULONG) sizeof(DWORD), size);
445 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
446 size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
448 ok(size == expected || size == (expected + 12 /* win64 */),
449 "size should be %u bytes, not %u\n", expected, size);
451 memset(buffer, 0xcc, size);
452 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
453 next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
455 ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
456
457 check_safearray(buffer, lpsa);
458
459 lpsa2 = NULL;
460 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
461 next = LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
463 ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
464 ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal, result %p\n", next);
465
466 for (i = 0; i < ARRAY_SIZE(values); i++)
467 {
468 BSTR gotvalue = NULL;
469
470 if (lpsa2)
471 {
472 indices[0] = i + sab[0].lLbound;
473 hr = SafeArrayGetElement(lpsa2, indices, &gotvalue);
474 ok(hr == S_OK, "Failed to get bstr element at hres 0x%x\n", hr);
475 if (hr == S_OK)
476 {
477 if (pVarBstrCmp)
478 ok(pVarBstrCmp(values[i], gotvalue, 0, 0) == VARCMP_EQ, "String %d does not match\n", i);
479 SysFreeString(gotvalue);
480 }
481 }
482
484 }
485
486 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
487 LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
488
490 hr = SafeArrayDestroy(lpsa);
491 ok(hr == S_OK, "got 0x%08x\n", hr);
492
493 /* VARTYPE-less arrays with FADF_VARIANT */
494 hr = SafeArrayAllocDescriptor(1, &lpsa);
495 ok(hr == S_OK, "saad failed %08x\n", hr);
496 lpsa->cbElements = sizeof(VARIANT);
497 lpsa->fFeatures = FADF_VARIANT;
498 lpsa->rgsabound[0].lLbound = 2;
499 lpsa->rgsabound[0].cElements = 48;
500 hr = SafeArrayAllocData(lpsa);
501 ok(hr == S_OK, "saad failed %08x\n", hr);
502
503 if (pSafeArrayGetVartype)
504 {
505 hr = pSafeArrayGetVartype(lpsa, &vt);
506 ok(hr == E_INVALIDARG, "ret %08x\n", hr);
507 }
508
509 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
510 size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
511 expected = 44 + 28 * lpsa->rgsabound[0].cElements;
513 ok(size == expected || size == expected + 8, /* win64 */
514 "size should be %u bytes, not %u\n", expected, size);
516 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
517 next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
519 ok(next - buffer == expected || broken(next - buffer + sizeof(DWORD) == expected),
520 "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected);
521 lpsa->cbElements = 16; /* VARIANT wire size */
522 check_safearray(buffer, lpsa);
524 hr = SafeArrayDestroyData(lpsa);
525 ok(hr == S_OK, "got 0x%08x\n", hr);
527 ok(hr == S_OK, "got 0x%08x\n", hr);
528}
529
530static void check_bstr(void *buffer, BSTR b)
531{
532 DWORD *wireb = buffer;
534
535 ok(*wireb == (len + 1) / 2, "wv[0] %08x\n", *wireb);
536 wireb++;
537 if(b)
538 ok(*wireb == len, "wv[1] %08x\n", *wireb);
539 else
540 ok(*wireb == 0xffffffff, "wv[1] %08x\n", *wireb);
541 wireb++;
542 ok(*wireb == (len + 1) / 2, "wv[2] %08x\n", *wireb);
543 if(len)
544 {
545 wireb++;
546 ok(!memcmp(wireb, b, (len + 1) & ~1), "strings differ\n");
547 }
548 return;
549}
550
551static void test_marshal_BSTR(void)
552{
553 ULONG size;
555 MIDL_STUB_MESSAGE stub_msg;
556 USER_MARSHAL_CB umcb;
557 unsigned char *buffer, *next;
558 BSTR b, b2;
559 WCHAR str[] = {'m','a','r','s','h','a','l',' ','t','e','s','t','1',0};
560 DWORD len;
561
563 len = SysStringLen(b);
564 ok(len == 13, "get %d\n", len);
565
566 /* BSTRs are DWORD aligned */
567
568 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
569 size = BSTR_UserSize(&umcb.Flags, 1, &b);
570 ok(size == 42, "size %d\n", size);
571
572 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
573 size = BSTR_UserSize(&umcb.Flags, 0, &b);
574 ok(size == 38, "size %d\n", size);
575
577 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
578 next = BSTR_UserMarshal(&umcb.Flags, buffer, &b);
579 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
581
582 b2 = NULL;
583 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
585 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
586 ok(b2 != NULL, "BSTR didn't unmarshal\n");
587 ok(!memcmp(b, b2, (len + 1) * 2), "strings differ\n");
588 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
589 BSTR_UserFree(&umcb.Flags, &b2);
590
593
594 b = NULL;
595 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
596 size = BSTR_UserSize(&umcb.Flags, 0, &b);
597 ok(size == 12, "size %d\n", size);
598
600 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
601 next = BSTR_UserMarshal(&umcb.Flags, buffer, &b);
602 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
603
605 b2 = NULL;
606 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
608 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
609 ok(b2 == NULL, "NULL BSTR didn't unmarshal\n");
610 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
611 BSTR_UserFree(&umcb.Flags, &b2);
613
614 b = SysAllocStringByteLen("abc", 3);
615 *(((char*)b) + 3) = 'd';
616 len = SysStringLen(b);
617 ok(len == 1, "get %d\n", len);
619 ok(len == 3, "get %d\n", len);
620
621 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
622 size = BSTR_UserSize(&umcb.Flags, 0, &b);
623 ok(size == 16, "size %d\n", size);
624
626 memset(buffer, 0xcc, size);
627 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
628 next = BSTR_UserMarshal(&umcb.Flags, buffer, &b);
629 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
631 ok(buffer[15] == 'd', "buffer[15] %02x\n", buffer[15]);
632
633 b2 = NULL;
634 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
636 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
637 ok(b2 != NULL, "BSTR didn't unmarshal\n");
638 ok(!memcmp(b, b2, len), "strings differ\n");
639 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
640 BSTR_UserFree(&umcb.Flags, &b2);
643
644 b = SysAllocStringByteLen("", 0);
645 len = SysStringLen(b);
646 ok(len == 0, "get %d\n", len);
648 ok(len == 0, "get %d\n", len);
649
650 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
651 size = BSTR_UserSize(&umcb.Flags, 0, &b);
652 ok(size == 12, "size %d\n", size);
653
655 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
656 next = BSTR_UserMarshal(&umcb.Flags, buffer, &b);
657 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
659
660 b2 = NULL;
661 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
663 ok(next == buffer + size, "got %p expect %p\n", next, buffer + size);
664 ok(b2 != NULL, "NULL LPSAFEARRAY didn't unmarshal\n");
666 ok(len == 0, "byte len %d\n", len);
667 init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
668 BSTR_UserFree(&umcb.Flags, &b2);
671}
672
673typedef struct
674{
675 IUnknown IUnknown_iface;
676 ULONG refs;
678
680{
681 return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface);
682}
683
685{
687 {
688 IUnknown_AddRef(iface);
689 *ppv = iface;
690 return S_OK;
691 }
692 *ppv = NULL;
693 return E_NOINTERFACE;
694}
695
697{
699 return InterlockedIncrement((LONG*)&This->refs);
700}
701
703{
705 ULONG refs = InterlockedDecrement((LONG*)&This->refs);
706 if (!refs) HeapFree(GetProcessHeap(), 0, This);
707 return refs;
708}
709
710static const IUnknownVtbl HeapUnknown_Vtbl =
711{
715};
716
717typedef struct
718{
719 DWORD clSize;
720 DWORD rpcReserved;
721 USHORT vt;
722 USHORT wReserved1;
723 USHORT wReserved2;
724 USHORT wReserved3;
725 DWORD switch_is;
727
729{
730 const variant_wire_t *header = (const variant_wire_t*)wirev;
731 DWORD switch_is;
732
733 ok(header->clSize == (size + 7) >> 3, "wv[0] %08x, expected %08x\n", header->clSize, (size + 7) >> 3);
734 ok(header->rpcReserved == 0, "wv[1] %08x\n", header->rpcReserved);
735 ok(header->vt == V_VT(v), "vt %04x expected %04x\n", header->vt, V_VT(v));
736 ok(header->wReserved1 == V_U2(v).wReserved1, "res1 %04x expected %04x\n", header->wReserved1, V_U2(v).wReserved1);
737 ok(header->wReserved2 == V_U2(v).wReserved2, "res2 %04x expected %04x\n", header->wReserved2, V_U2(v).wReserved2);
738 ok(header->wReserved3 == V_U2(v).wReserved3, "res3 %04x expected %04x\n", header->wReserved3, V_U2(v).wReserved3);
739
740 switch_is = V_VT(v);
741 if(switch_is & VT_ARRAY)
742 switch_is &= ~VT_TYPEMASK;
743 ok(header->switch_is == switch_is, "switch_is %08x expected %08x\n", header->switch_is, switch_is);
744
745 return (DWORD*)((unsigned char*)wirev + sizeof(variant_wire_t));
746}
747
748/* Win9x and WinME don't always align as needed. Variants have
749 * an alignment of 8.
750 */
751static void *alloc_aligned(SIZE_T size, void **buf)
752{
753 *buf = HeapAlloc(GetProcessHeap(), 0, size + 7);
754 return (void *)(((UINT_PTR)*buf + 7) & ~7);
755}
756
757static void test_marshal_VARIANT(void)
758{
759 VARIANT v, v2, v3;
760 MIDL_STUB_MESSAGE stubMsg = { 0 };
761 RPC_MESSAGE rpcMsg = { 0 };
762 USER_MARSHAL_CB umcb = { 0 };
763 unsigned char *buffer, *next;
764 void *oldbuffer;
765 ULONG ul;
766 short s;
767 double d;
768 void *mem;
769 DWORD *wirev;
770 BSTR b, b2;
771 WCHAR str[] = {'m','a','r','s','h','a','l',' ','t','e','s','t',0};
772 SAFEARRAYBOUND sab;
773 LPSAFEARRAY lpsa, lpsa2, lpsa_copy;
774 DECIMAL dec, dec2;
775 HeapUnknown *heap_unknown;
777 HRESULT hr;
778 LONG bound, bound2;
779 VARTYPE vt, vt2;
780 IUnknown *unk;
781
782 stubMsg.RpcMsg = &rpcMsg;
783
784 umcb.Flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
785 umcb.pStubMsg = &stubMsg;
786 umcb.pReserve = NULL;
789
790 /*** I1 ***/
791 VariantInit(&v);
792 V_VT(&v) = VT_I1;
793 V_I1(&v) = 0x12;
794
795 /* check_variant_header tests wReserved[123], so initialize to unique values.
796 * (Could probably also do this by setting the variant to a known DECIMAL.)
797 */
798 V_U2(&v).wReserved1 = 0x1234;
799 V_U2(&v).wReserved2 = 0x5678;
800 V_U2(&v).wReserved3 = 0x9abc;
801
802 /* Variants have an alignment of 8 */
803 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 1, &v);
804 ok(stubMsg.BufferLength == 29, "size %d\n", stubMsg.BufferLength);
805
806 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
807 ok(stubMsg.BufferLength == 21, "size %d\n", stubMsg.BufferLength);
808
809 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
810 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
812 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
813 wirev = (DWORD*)buffer;
814
815 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
816 ok(*(char*)wirev == V_I1(&v), "wv[5] %08x\n", *wirev);
817 VariantInit(&v2);
818 stubMsg.Buffer = buffer;
820 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
821 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
822 ok(V_I1(&v) == V_I1(&v2), "got i1 %x expect %x\n", V_I1(&v), V_I1(&v2));
823
824 VARIANT_UserFree(&umcb.Flags, &v2);
825 HeapFree(GetProcessHeap(), 0, oldbuffer);
826
827 /*** I2 ***/
828 VariantInit(&v);
829 V_VT(&v) = VT_I2;
830 V_I2(&v) = 0x1234;
831
832 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
833 ok(stubMsg.BufferLength == 22, "size %d\n", stubMsg.BufferLength);
834
835 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
836 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
838 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
839 wirev = (DWORD*)buffer;
840
841 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
842 ok(*(short*)wirev == V_I2(&v), "wv[5] %08x\n", *wirev);
843 VariantInit(&v2);
844 stubMsg.Buffer = buffer;
846 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
847 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
848 ok(V_I2(&v) == V_I2(&v2), "got i2 %x expect %x\n", V_I2(&v), V_I2(&v2));
849
850 VARIANT_UserFree(&umcb.Flags, &v2);
851 HeapFree(GetProcessHeap(), 0, oldbuffer);
852
853 /*** I2 BYREF ***/
854 VariantInit(&v);
855 V_VT(&v) = VT_I2 | VT_BYREF;
856 s = 0x1234;
857 V_I2REF(&v) = &s;
858
859 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
860 ok(stubMsg.BufferLength == 26, "size %d\n", stubMsg.BufferLength);
861
862 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
863 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
865 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
866 wirev = (DWORD*)buffer;
867
868 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
869 ok(*wirev == 0x4, "wv[5] %08x\n", *wirev);
870 wirev++;
871 ok(*(short*)wirev == s, "wv[6] %08x\n", *wirev);
872 VariantInit(&v2);
873 V_VT(&v2) = VT_I2 | VT_BYREF;
874 V_BYREF(&v2) = mem = CoTaskMemAlloc(sizeof(V_I2(&v2)));
875 stubMsg.Buffer = buffer;
877 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
878 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
879 ok(V_BYREF(&v2) == mem, "didn't reuse existing memory\n");
880 ok(*V_I2REF(&v) == *V_I2REF(&v2), "got i2 ref %x expect ui4 ref %x\n", *V_I2REF(&v), *V_I2REF(&v2));
881
882 VARIANT_UserFree(&umcb.Flags, &v2);
883 HeapFree(GetProcessHeap(), 0, oldbuffer);
884
885 /*** I4 ***/
886 VariantInit(&v);
887 V_VT(&v) = VT_I4;
888 V_I4(&v) = 0x1234;
889
890 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
891 ok(stubMsg.BufferLength == 24, "size %d\n", stubMsg.BufferLength);
892
893 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
894 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
896 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
897 wirev = (DWORD*)buffer;
898
899 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
900 ok(*wirev == V_I4(&v), "wv[5] %08x\n", *wirev);
901
902 VariantInit(&v2);
903 stubMsg.Buffer = buffer;
905 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
906 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
907 ok(V_I4(&v) == V_I4(&v2), "got i4 %x expect %x\n", V_I4(&v), V_I4(&v2));
908
909 VARIANT_UserFree(&umcb.Flags, &v2);
910 HeapFree(GetProcessHeap(), 0, oldbuffer);
911
912 /*** UI4 ***/
913 VariantInit(&v);
914 V_VT(&v) = VT_UI4;
915 V_UI4(&v) = 0x1234;
916
917 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
918 ok(stubMsg.BufferLength == 24, "size %d\n", stubMsg.BufferLength);
919
920 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
921 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
923 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
924 wirev = (DWORD*)buffer;
925
926 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
927 ok(*wirev == 0x1234, "wv[5] %08x\n", *wirev);
928 VariantInit(&v2);
929 stubMsg.Buffer = buffer;
931 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
932 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
933 ok(V_UI4(&v) == V_UI4(&v2), "got ui4 %x expect %x\n", V_UI4(&v), V_UI4(&v2));
934
935 VARIANT_UserFree(&umcb.Flags, &v2);
936 HeapFree(GetProcessHeap(), 0, oldbuffer);
937
938 /*** UI4 BYREF ***/
939 VariantInit(&v);
940 V_VT(&v) = VT_UI4 | VT_BYREF;
941 ul = 0x1234;
942 V_UI4REF(&v) = &ul;
943
944 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
945 ok(stubMsg.BufferLength == 28, "size %d\n", stubMsg.BufferLength);
946
947 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
948 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
950 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
951 wirev = (DWORD*)buffer;
952
953 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
954 ok(*wirev == 0x4, "wv[5] %08x\n", *wirev);
955 wirev++;
956 ok(*wirev == ul, "wv[6] %08x\n", *wirev);
957
958 VariantInit(&v2);
959 stubMsg.Buffer = buffer;
961 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
962 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
963 ok(*V_UI4REF(&v) == *V_UI4REF(&v2), "got ui4 ref %x expect ui4 ref %x\n", *V_UI4REF(&v), *V_UI4REF(&v2));
964
965 VARIANT_UserFree(&umcb.Flags, &v2);
966 HeapFree(GetProcessHeap(), 0, oldbuffer);
967
968 /*** I8 ***/
969 VariantInit(&v);
970 V_VT(&v) = VT_I8;
971 V_I8(&v) = (LONGLONG)1000000 * 1000000;
972
973 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
974 ok(stubMsg.BufferLength == 32, "size %d\n", stubMsg.BufferLength);
975
976 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
977 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
978 memset(buffer, 0xcc, stubMsg.BufferLength);
980 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
981 wirev = (DWORD*)buffer;
982
983 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
984 ok(*wirev == 0xcccccccc, "wv[5] %08x\n", *wirev); /* pad */
985 wirev++;
986 ok(*(LONGLONG *)wirev == V_I8(&v), "wv[6] %s\n", wine_dbgstr_longlong(*(LONGLONG *)wirev));
987 VariantInit(&v2);
988 stubMsg.Buffer = buffer;
990 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
991 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
992 ok(V_I8(&v) == V_I8(&v2), "got i8 %s expect %s\n",
994
995 VARIANT_UserFree(&umcb.Flags, &v2);
996 HeapFree(GetProcessHeap(), 0, oldbuffer);
997
998 /*** R4 ***/
999 VariantInit(&v);
1000 V_VT(&v) = VT_R4;
1001 V_R8(&v) = 3.1415;
1002
1003 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1004 ok(stubMsg.BufferLength == 24, "size %d\n", stubMsg.BufferLength);
1005
1006 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1007 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1009 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1010 wirev = (DWORD*)buffer;
1011
1012 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1013 ok(*(float*)wirev == V_R4(&v), "wv[5] %08x\n", *wirev);
1014 VariantInit(&v2);
1015 stubMsg.Buffer = buffer;
1017 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1018 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1019 ok(V_R4(&v) == V_R4(&v2), "got r4 %f expect %f\n", V_R4(&v), V_R4(&v2));
1020
1021 VARIANT_UserFree(&umcb.Flags, &v2);
1022 HeapFree(GetProcessHeap(), 0, oldbuffer);
1023
1024 /*** R8 ***/
1025 VariantInit(&v);
1026 V_VT(&v) = VT_R8;
1027 V_R8(&v) = 3.1415;
1028
1029 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1030 ok(stubMsg.BufferLength == 32, "size %d\n", stubMsg.BufferLength);
1031
1032 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1033 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1034 memset(buffer, 0xcc, stubMsg.BufferLength);
1036 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1037 wirev = (DWORD*)buffer;
1038
1039 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1040 ok(*wirev == 0xcccccccc, "wv[5] %08x\n", *wirev); /* pad */
1041 wirev++;
1042 ok(*(double*)wirev == V_R8(&v), "wv[6] %08x, wv[7] %08x\n", *wirev, *(wirev+1));
1043 VariantInit(&v2);
1044 stubMsg.Buffer = buffer;
1046 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1047 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1048 ok(V_R8(&v) == V_R8(&v2), "got r8 %f expect %f\n", V_R8(&v), V_R8(&v2));
1049
1050 VARIANT_UserFree(&umcb.Flags, &v2);
1051 HeapFree(GetProcessHeap(), 0, oldbuffer);
1052
1053 /*** R8 BYREF ***/
1054 VariantInit(&v);
1055 V_VT(&v) = VT_R8 | VT_BYREF;
1056 d = 3.1415;
1057 V_R8REF(&v) = &d;
1058
1059 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1060 ok(stubMsg.BufferLength == 32, "size %d\n", stubMsg.BufferLength);
1061
1062 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1063 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1065 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1066 wirev = (DWORD*)buffer;
1067
1068 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1069 ok(*wirev == 8, "wv[5] %08x\n", *wirev);
1070 wirev++;
1071 ok(*(double*)wirev == d, "wv[6] %08x wv[7] %08x\n", *wirev, *(wirev+1));
1072 VariantInit(&v2);
1073 stubMsg.Buffer = buffer;
1075 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1076 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1077 ok(*V_R8REF(&v) == *V_R8REF(&v2), "got r8 ref %f expect %f\n", *V_R8REF(&v), *V_R8REF(&v2));
1078
1079 VARIANT_UserFree(&umcb.Flags, &v2);
1080 HeapFree(GetProcessHeap(), 0, oldbuffer);
1081
1082 /*** VARIANT_BOOL ***/
1083 VariantInit(&v);
1084 V_VT(&v) = VT_BOOL;
1085 V_BOOL(&v) = 0x1234;
1086
1087 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1088 ok(stubMsg.BufferLength == 22, "size %d\n", stubMsg.BufferLength);
1089
1090 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1091 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1093 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1094 wirev = (DWORD*)buffer;
1095
1096 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1097 ok(*(short*)wirev == V_BOOL(&v), "wv[5] %04x\n", *(WORD*)wirev);
1098 VariantInit(&v2);
1099 stubMsg.Buffer = buffer;
1101 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1102 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1103 ok(V_BOOL(&v) == V_BOOL(&v2), "got bool %x expect %x\n", V_BOOL(&v), V_BOOL(&v2));
1104
1105 VARIANT_UserFree(&umcb.Flags, &v2);
1106 HeapFree(GetProcessHeap(), 0, oldbuffer);
1107
1108 /*** DECIMAL ***/
1109 VarDecFromI4(0x12345678, &dec);
1110 dec.wReserved = 0xfedc; /* Also initialize reserved field, as we check it later */
1111 VariantInit(&v);
1112 V_DECIMAL(&v) = dec;
1113 V_VT(&v) = VT_DECIMAL;
1114
1115 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1116 ok(stubMsg.BufferLength == 40, "size %d\n", stubMsg.BufferLength);
1117
1118 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1119 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1120 memset(buffer, 0xcc, stubMsg.BufferLength);
1122 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1123 wirev = (DWORD*)buffer;
1124
1125 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1126 ok(*wirev == 0xcccccccc, "wirev[5] %08x\n", *wirev); /* pad */
1127 wirev++;
1128 dec2 = dec;
1129 dec2.wReserved = VT_DECIMAL;
1130 ok(!memcmp(wirev, &dec2, sizeof(dec2)), "wirev[6] %08x wirev[7] %08x wirev[8] %08x wirev[9] %08x\n",
1131 *wirev, *(wirev + 1), *(wirev + 2), *(wirev + 3));
1132 VariantInit(&v2);
1133 stubMsg.Buffer = buffer;
1135 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1136 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1137 ok(!memcmp(&V_DECIMAL(&v), & V_DECIMAL(&v2), sizeof(DECIMAL)), "decimals differ\n");
1138
1139 VARIANT_UserFree(&umcb.Flags, &v2);
1140 HeapFree(GetProcessHeap(), 0, oldbuffer);
1141
1142 /*** DECIMAL BYREF ***/
1143 VariantInit(&v);
1144 V_VT(&v) = VT_DECIMAL | VT_BYREF;
1145 V_DECIMALREF(&v) = &dec;
1146
1147 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1148 ok(stubMsg.BufferLength == 40, "size %d\n", stubMsg.BufferLength);
1149
1150 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1151 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1153 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1154 wirev = (DWORD*)buffer;
1155
1156 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1157 ok(*wirev == 16, "wv[5] %08x\n", *wirev);
1158 wirev++;
1159 ok(!memcmp(wirev, &dec, sizeof(dec)), "wirev[6] %08x wirev[7] %08x wirev[8] %08x wirev[9] %08x\n", *wirev, *(wirev + 1), *(wirev + 2), *(wirev + 3));
1160 VariantInit(&v2);
1161 /* check_variant_header tests wReserved[123], so initialize to unique values.
1162 * (Could probably also do this by setting the variant to a known DECIMAL.)
1163 */
1164 V_U2(&v2).wReserved1 = 0x0123;
1165 V_U2(&v2).wReserved2 = 0x4567;
1166 V_U2(&v2).wReserved3 = 0x89ab;
1167
1168 stubMsg.Buffer = buffer;
1170 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1171 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1172 ok(!memcmp(V_DECIMALREF(&v), V_DECIMALREF(&v2), sizeof(DECIMAL)), "decimals differ\n");
1173
1174 VARIANT_UserFree(&umcb.Flags, &v2);
1175 HeapFree(GetProcessHeap(), 0, oldbuffer);
1176
1177 /*** EMPTY ***/
1178 VariantInit(&v);
1179 V_VT(&v) = VT_EMPTY;
1180
1181 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1182 ok(stubMsg.BufferLength == 20, "size %d\n", stubMsg.BufferLength);
1183
1184 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1185 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1187 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1188 wirev = (DWORD*)buffer;
1189
1190 check_variant_header(wirev, &v, stubMsg.BufferLength);
1191 VariantInit(&v2);
1192 stubMsg.Buffer = buffer;
1194 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1195 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1196
1197 VARIANT_UserFree(&umcb.Flags, &v2);
1198 HeapFree(GetProcessHeap(), 0, oldbuffer);
1199
1200 /*** NULL ***/
1201 VariantInit(&v);
1202 V_VT(&v) = VT_NULL;
1203
1204 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1205 ok(stubMsg.BufferLength == 20, "size %d\n", stubMsg.BufferLength);
1206
1207 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1208 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1210 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1211 wirev = (DWORD*)buffer;
1212
1213 check_variant_header(wirev, &v, stubMsg.BufferLength);
1214 VariantInit(&v2);
1215 stubMsg.Buffer = buffer;
1217 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1218 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1219
1220 VARIANT_UserFree(&umcb.Flags, &v2);
1221 HeapFree(GetProcessHeap(), 0, oldbuffer);
1222
1223 /*** BSTR ***/
1224 b = SysAllocString(str);
1225 VariantInit(&v);
1226 V_VT(&v) = VT_BSTR;
1227 V_BSTR(&v) = b;
1228
1229 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1230 ok(stubMsg.BufferLength == 60, "size %d\n", stubMsg.BufferLength);
1231 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1232 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1234 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1235 wirev = (DWORD*)buffer;
1236
1237 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1238 ok(*wirev, "wv[5] %08x\n", *wirev); /* win2k: this is b. winxp: this is (char*)b + 1 */
1239 wirev++;
1240 check_bstr(wirev, V_BSTR(&v));
1241 VariantInit(&v2);
1242 stubMsg.Buffer = buffer;
1244 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1245 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1246 ok(SysStringByteLen(V_BSTR(&v)) == SysStringByteLen(V_BSTR(&v2)), "bstr string lens differ\n");
1247 ok(!memcmp(V_BSTR(&v), V_BSTR(&v2), SysStringByteLen(V_BSTR(&v))), "bstrs differ\n");
1248
1249 VARIANT_UserFree(&umcb.Flags, &v2);
1250 HeapFree(GetProcessHeap(), 0, oldbuffer);
1251
1252 /*** BSTR BYREF ***/
1253 VariantInit(&v);
1254 V_VT(&v) = VT_BSTR | VT_BYREF;
1255 V_BSTRREF(&v) = &b;
1256
1257 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1258 ok(stubMsg.BufferLength == 64, "size %d\n", stubMsg.BufferLength);
1259 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1260 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1262 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1263 wirev = (DWORD*)buffer;
1264
1265 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1266 ok(*wirev == 0x4, "wv[5] %08x\n", *wirev);
1267 wirev++;
1268 ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is b. winxp: this is (char*)b + 1 */
1269 wirev++;
1270 check_bstr(wirev, b);
1272 b2[0] = 0;
1273 V_VT(&v2) = VT_BSTR | VT_BYREF;
1274 V_BSTRREF(&v2) = &b2;
1275 mem = b2;
1276 VariantInit(&v2);
1277 stubMsg.Buffer = buffer;
1279 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1280 ok(mem == b2, "BSTR should be reused\n");
1281 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1282 ok(SysStringByteLen(*V_BSTRREF(&v)) == SysStringByteLen(*V_BSTRREF(&v2)), "bstr string lens differ\n");
1283 ok(!memcmp(*V_BSTRREF(&v), *V_BSTRREF(&v2), SysStringByteLen(*V_BSTRREF(&v))), "bstrs differ\n");
1284
1286 HeapFree(GetProcessHeap(), 0, oldbuffer);
1288
1289 /*** ARRAY ***/
1290 sab.lLbound = 5;
1291 sab.cElements = 10;
1292
1293 lpsa = SafeArrayCreate(VT_R8, 1, &sab);
1294 *(DWORD *)lpsa->pvData = 0xcafebabe;
1295 *((DWORD *)lpsa->pvData + 1) = 0xdeadbeef;
1296
1297 VariantInit(&v);
1298 V_VT(&v) = VT_UI4 | VT_ARRAY;
1299 V_ARRAY(&v) = lpsa;
1300
1301 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1302 expected = 152;
1303 ok(stubMsg.BufferLength == expected || stubMsg.BufferLength == expected + 8, /* win64 */
1304 "size %u instead of %u\n", stubMsg.BufferLength, expected);
1305 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1306 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1308 ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
1309 wirev = (DWORD*)buffer;
1310
1311 wirev = check_variant_header(wirev, &v, expected);
1312 ok(*wirev, "wv[5] %08x\n", *wirev); /* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
1313 wirev++;
1314 check_safearray(wirev, lpsa);
1315 VariantInit(&v2);
1316 stubMsg.Buffer = buffer;
1318 ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
1319 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1320 ok(SafeArrayGetDim(V_ARRAY(&v)) == SafeArrayGetDim(V_ARRAY(&v2)), "array dims differ\n");
1321 SafeArrayGetLBound(V_ARRAY(&v), 1, &bound);
1322 SafeArrayGetLBound(V_ARRAY(&v2), 1, &bound2);
1323 ok(bound == bound2, "array lbounds differ\n");
1324 SafeArrayGetUBound(V_ARRAY(&v), 1, &bound);
1325 SafeArrayGetUBound(V_ARRAY(&v2), 1, &bound2);
1326 ok(bound == bound2, "array ubounds differ\n");
1327 if (pSafeArrayGetVartype)
1328 {
1329 pSafeArrayGetVartype(V_ARRAY(&v), &vt);
1330 pSafeArrayGetVartype(V_ARRAY(&v2), &vt2);
1331 ok(vt == vt2, "array vts differ %x %x\n", vt, vt2);
1332 }
1333 VARIANT_UserFree(&umcb.Flags, &v2);
1334 HeapFree(GetProcessHeap(), 0, oldbuffer);
1335
1336 /*** ARRAY BYREF ***/
1337 VariantInit(&v);
1338 V_VT(&v) = VT_UI4 | VT_ARRAY | VT_BYREF;
1339 V_ARRAYREF(&v) = &lpsa;
1340
1341 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1342 expected = 152;
1343 ok(stubMsg.BufferLength == expected || stubMsg.BufferLength == expected + 16, /* win64 */
1344 "size %u instead of %u\n", stubMsg.BufferLength, expected);
1345 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1346 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1348 ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
1349 wirev = (DWORD*)buffer;
1350
1351 wirev = check_variant_header(wirev, &v, expected);
1352 ok(*wirev == 4, "wv[5] %08x\n", *wirev);
1353 wirev++;
1354 ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
1355 wirev++;
1356 check_safearray(wirev, lpsa);
1357 VariantInit(&v2);
1358 stubMsg.Buffer = buffer;
1360 ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
1361 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1362 ok(SafeArrayGetDim(*V_ARRAYREF(&v)) == SafeArrayGetDim(*V_ARRAYREF(&v2)), "array dims differ\n");
1363 SafeArrayGetLBound(*V_ARRAYREF(&v), 1, &bound);
1364 SafeArrayGetLBound(*V_ARRAYREF(&v2), 1, &bound2);
1365 ok(bound == bound2, "array lbounds differ\n");
1366 SafeArrayGetUBound(*V_ARRAYREF(&v), 1, &bound);
1367 SafeArrayGetUBound(*V_ARRAYREF(&v2), 1, &bound2);
1368 ok(bound == bound2, "array ubounds differ\n");
1369 if (pSafeArrayGetVartype)
1370 {
1371 pSafeArrayGetVartype(*V_ARRAYREF(&v), &vt);
1372 pSafeArrayGetVartype(*V_ARRAYREF(&v2), &vt2);
1373 ok(vt == vt2, "array vts differ %x %x\n", vt, vt2);
1374 }
1375 VARIANT_UserFree(&umcb.Flags, &v2);
1376 HeapFree(GetProcessHeap(), 0, oldbuffer);
1377
1378 /*** ARRAY BYREF ***/
1379 VariantInit(&v);
1380 V_VT(&v) = VT_UI4 | VT_ARRAY | VT_BYREF;
1381 V_ARRAYREF(&v) = &lpsa;
1382 lpsa->fFeatures |= FADF_STATIC;
1383
1384 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1385 expected = 152;
1386 ok(stubMsg.BufferLength == expected || stubMsg.BufferLength == expected + 16, /* win64 */
1387 "size %u instead of %u\n", stubMsg.BufferLength, expected);
1388 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1389 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1391 ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
1392 wirev = (DWORD*)buffer;
1393
1394 wirev = check_variant_header(wirev, &v, expected);
1395 ok(*wirev == 4, "wv[5] %08x\n", *wirev);
1396 wirev++;
1397 ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
1398 wirev++;
1399 check_safearray(wirev, lpsa);
1400 lpsa_copy = lpsa2 = SafeArrayCreate(VT_I8, 1, &sab);
1401 /* set FADF_STATIC feature to make sure lpsa2->pvData pointer changes if new data buffer is allocated */
1402 lpsa2->fFeatures |= FADF_STATIC;
1403 mem = lpsa2->pvData;
1404 V_VT(&v2) = VT_UI4 | VT_ARRAY | VT_BYREF;
1405 V_ARRAYREF(&v2) = &lpsa2;
1406 stubMsg.Buffer = buffer;
1408 ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
1409 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1410 ok(lpsa2 == lpsa_copy, "safearray should be reused\n");
1411 ok(mem == lpsa2->pvData, "safearray data should be reused\n");
1412 ok(SafeArrayGetDim(*V_ARRAYREF(&v)) == SafeArrayGetDim(*V_ARRAYREF(&v2)), "array dims differ\n");
1413 SafeArrayGetLBound(*V_ARRAYREF(&v), 1, &bound);
1414 SafeArrayGetLBound(*V_ARRAYREF(&v2), 1, &bound2);
1415 ok(bound == bound2, "array lbounds differ\n");
1416 SafeArrayGetUBound(*V_ARRAYREF(&v), 1, &bound);
1417 SafeArrayGetUBound(*V_ARRAYREF(&v2), 1, &bound2);
1418 ok(bound == bound2, "array ubounds differ\n");
1419 if (pSafeArrayGetVartype)
1420 {
1421 pSafeArrayGetVartype(*V_ARRAYREF(&v), &vt);
1422 pSafeArrayGetVartype(*V_ARRAYREF(&v2), &vt2);
1423 ok(vt == vt2, "array vts differ %x %x\n", vt, vt2);
1424 }
1425 lpsa2->fFeatures &= ~FADF_STATIC;
1427 ok(hr == S_OK, "got 0x%08x\n", hr);
1428 HeapFree(GetProcessHeap(), 0, oldbuffer);
1429 lpsa->fFeatures &= ~FADF_STATIC;
1430 hr = SafeArrayDestroy(lpsa);
1431 ok(hr == S_OK, "got 0x%08x\n", hr);
1432
1433 /*** VARIANT BYREF ***/
1434 VariantInit(&v);
1435 VariantInit(&v2);
1436 V_VT(&v2) = VT_R8;
1437 V_R8(&v2) = 3.1415;
1438 V_VT(&v) = VT_VARIANT | VT_BYREF;
1439 V_VARIANTREF(&v) = &v2;
1440
1441 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1442 ok(stubMsg.BufferLength == 64, "size %d\n", stubMsg.BufferLength);
1443 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1444 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1445 memset(buffer, 0xcc, stubMsg.BufferLength);
1447 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1448 wirev = (DWORD*)buffer;
1449 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1450
1451 ok(*wirev == sizeof(VARIANT), "wv[5] %08x\n", *wirev);
1452 wirev++;
1453 ok(*wirev == ('U' | 's' << 8 | 'e' << 16 | 'r' << 24), "wv[6] %08x\n", *wirev); /* 'User' */
1454 wirev++;
1455 ok(*wirev == 0xcccccccc, "wv[7] %08x\n", *wirev); /* pad */
1456 wirev++;
1457 wirev = check_variant_header(wirev, &v2, stubMsg.BufferLength - 32);
1458 ok(*wirev == 0xcccccccc, "wv[13] %08x\n", *wirev); /* pad for VT_R8 */
1459 wirev++;
1460 ok(*(double*)wirev == V_R8(&v2), "wv[6] %08x wv[7] %08x\n", *wirev, *(wirev+1));
1461 VariantInit(&v3);
1462 stubMsg.Buffer = buffer;
1464 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1465 ok(V_VT(&v) == V_VT(&v3), "got vt %d expect %d\n", V_VT(&v), V_VT(&v3));
1466 ok(V_VT(V_VARIANTREF(&v)) == V_VT(V_VARIANTREF(&v3)), "vts differ %x %x\n",
1468 ok(V_R8(V_VARIANTREF(&v)) == V_R8(V_VARIANTREF(&v3)), "r8s differ\n");
1469 VARIANT_UserFree(&umcb.Flags, &v3);
1470 HeapFree(GetProcessHeap(), 0, oldbuffer);
1471
1472 /*** UNKNOWN ***/
1473 heap_unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*heap_unknown));
1474 heap_unknown->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
1475 heap_unknown->refs = 1;
1476 VariantInit(&v);
1477 VariantInit(&v2);
1478 V_VT(&v) = VT_UNKNOWN;
1479 V_UNKNOWN(&v) = &heap_unknown->IUnknown_iface;
1480
1481 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1482 ok(stubMsg.BufferLength > 40, "size %d\n", stubMsg.BufferLength);
1483 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1484 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1485 memset(buffer, 0xcc, stubMsg.BufferLength);
1488 ok(heap_unknown->refs == 2, "got refcount %d\n", heap_unknown->refs);
1489 wirev = (DWORD*)buffer;
1490 wirev = check_variant_header(wirev, &v, next - buffer);
1491
1492 ok(*wirev == (DWORD_PTR)V_UNKNOWN(&v) /* Win9x */ ||
1493 *wirev == (DWORD_PTR)V_UNKNOWN(&v) + 1 /* NT */, "wv[5] %08x\n", *wirev);
1494 wirev++;
1495 ok(*wirev == next - buffer - 0x20, "wv[6] %08x\n", *wirev);
1496 wirev++;
1497 ok(*wirev == next - buffer - 0x20, "wv[7] %08x\n", *wirev);
1498 wirev++;
1499 ok(*wirev == 0x574f454d, "wv[8] %08x\n", *wirev);
1500 VariantInit(&v3);
1501 V_VT(&v3) = VT_UNKNOWN;
1502 V_UNKNOWN(&v3) = &heap_unknown->IUnknown_iface;
1503 IUnknown_AddRef(V_UNKNOWN(&v3));
1504 stubMsg.Buffer = buffer;
1506 ok(heap_unknown->refs == 3, "got refcount %d\n", heap_unknown->refs);
1508 ok(V_VT(&v) == V_VT(&v3), "got vt %d expect %d\n", V_VT(&v), V_VT(&v3));
1509 ok(V_UNKNOWN(&v) == V_UNKNOWN(&v3), "got %p expect %p\n", V_UNKNOWN(&v), V_UNKNOWN(&v3));
1510 VARIANT_UserFree(&umcb.Flags, &v3);
1511 ok(heap_unknown->refs == 1, "%d refcounts of IUnknown leaked\n", heap_unknown->refs - 1);
1512 IUnknown_Release(&heap_unknown->IUnknown_iface);
1513 HeapFree(GetProcessHeap(), 0, oldbuffer);
1514
1515 /*** NULL UNKNOWN ***/
1516 VariantInit(&v);
1517 V_VT(&v) = VT_UNKNOWN;
1518 V_UNKNOWN(&v) = NULL;
1519
1520 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1521 ok(stubMsg.BufferLength >= 24, "size %d\n", stubMsg.BufferLength);
1522 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1523 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1524 memset(buffer, 0xcc, stubMsg.BufferLength);
1526 wirev = (DWORD*)buffer;
1527 wirev = check_variant_header(wirev, &v, next - buffer);
1528 ok(*wirev == 0, "wv[5] %08x\n", *wirev);
1529
1530 VariantInit(&v2);
1531 stubMsg.Buffer = buffer;
1533 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
1534 ok(V_UNKNOWN(&v2) == NULL, "got %p expect NULL\n", V_UNKNOWN(&v2));
1535 VARIANT_UserFree(&umcb.Flags, &v2);
1536 HeapFree(GetProcessHeap(), 0, oldbuffer);
1537
1538 /*** UNKNOWN BYREF ***/
1539 heap_unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*heap_unknown));
1540 heap_unknown->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
1541 heap_unknown->refs = 1;
1542 VariantInit(&v);
1543 VariantInit(&v2);
1544 V_VT(&v) = VT_UNKNOWN | VT_BYREF;
1545 V_UNKNOWNREF(&v) = (IUnknown **)&heap_unknown;
1546
1547 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1548 ok(stubMsg.BufferLength >= 44, "size %d\n", stubMsg.BufferLength);
1549 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1550 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1551 memset(buffer, 0xcc, stubMsg.BufferLength);
1552 ok(heap_unknown->refs == 1, "got refcount %d\n", heap_unknown->refs);
1555 ok(heap_unknown->refs == 2, "got refcount %d\n", heap_unknown->refs);
1556 wirev = (DWORD*)buffer;
1557 wirev = check_variant_header(wirev, &v, next - buffer);
1558
1559 ok(*wirev == 4, "wv[5] %08x\n", *wirev);
1560 wirev++;
1561 ok(*wirev == (DWORD_PTR)heap_unknown /* Win9x, Win2000 */ ||
1562 *wirev == (DWORD_PTR)heap_unknown + 1 /* XP */, "wv[6] %08x\n", *wirev);
1563 wirev++;
1564 ok(*wirev == next - buffer - 0x24, "wv[7] %08x\n", *wirev);
1565 wirev++;
1566 ok(*wirev == next - buffer - 0x24, "wv[8] %08x\n", *wirev);
1567 wirev++;
1568 ok(*wirev == 0x574f454d, "wv[9] %08x\n", *wirev);
1569
1570 VariantInit(&v3);
1571 V_VT(&v3) = VT_UNKNOWN;
1572 V_UNKNOWN(&v3) = &heap_unknown->IUnknown_iface;
1573 IUnknown_AddRef(V_UNKNOWN(&v3));
1574 stubMsg.Buffer = buffer;
1576 ok(heap_unknown->refs == 2, "got refcount %d\n", heap_unknown->refs);
1577 ok(V_VT(&v) == V_VT(&v3), "got vt %d expect %d\n", V_VT(&v), V_VT(&v3));
1578 ok(*V_UNKNOWNREF(&v) == *V_UNKNOWNREF(&v3), "got %p expect %p\n", *V_UNKNOWNREF(&v), *V_UNKNOWNREF(&v3));
1579 VARIANT_UserFree(&umcb.Flags, &v3);
1580 ok(heap_unknown->refs == 1, "%d refcounts of IUnknown leaked\n", heap_unknown->refs - 1);
1581 IUnknown_Release(&heap_unknown->IUnknown_iface);
1582 HeapFree(GetProcessHeap(), 0, oldbuffer);
1583
1584 unk = NULL;
1585 VariantInit(&v);
1586 V_VT(&v) = VT_UNKNOWN | VT_BYREF;
1587 V_UNKNOWNREF(&v) = &unk;
1588
1589 rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v);
1590 ok(stubMsg.BufferLength >= 28, "size %d\n", stubMsg.BufferLength);
1591 buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer);
1592 stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength;
1593 memset(buffer, 0xcc, stubMsg.BufferLength);
1595 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1596 wirev = (DWORD*)buffer;
1597 wirev = check_variant_header(wirev, &v, stubMsg.BufferLength);
1598
1599 ok(*wirev == 4, "wv[5] %08x\n", *wirev);
1600
1601 VariantInit(&v2);
1602 stubMsg.Buffer = buffer;
1604 ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength);
1605 ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v2), V_VT(&v));
1606 ok(!*V_UNKNOWNREF(&v2), "got %p expect NULL\n", *V_UNKNOWNREF(&v2));
1607 VARIANT_UserFree(&umcb.Flags, &v2);
1608 HeapFree(GetProcessHeap(), 0, oldbuffer);
1609}
1610
1611
1612START_TEST(usrmarshal)
1613{
1614 HANDLE hOleaut32 = GetModuleHandleA("oleaut32.dll");
1615#define GETPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func)
1619#undef GETPTR
1620
1621 if (!pSafeArrayGetIID || !pSafeArrayGetVartype)
1622 win_skip("SafeArrayGetIID and/or SafeArrayGetVartype is not available, some tests will be skipped\n");
1623
1625
1629
1631}
ios_base &_STLP_CALL dec(ios_base &__s)
Definition: _ios_base.h:321
#define broken(x)
Definition: _sntprintf.h:21
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
struct tagVARIANT VARIANT
Definition: compat.h:2377
#define HeapAlloc
Definition: compat.h:733
WCHAR OLECHAR
Definition: compat.h:2292
struct tagSAFEARRAYBOUND SAFEARRAYBOUND
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
OLECHAR * BSTR
Definition: compat.h:2293
unsigned short VARTYPE
Definition: compat.h:2254
#define HeapFree(x, y, z)
Definition: compat.h:735
@ VT_UI8
Definition: compat.h:2315
@ VT_BSTR
Definition: compat.h:2303
@ VT_INT
Definition: compat.h:2316
@ VT_R4
Definition: compat.h:2299
@ VT_UINT_PTR
Definition: compat.h:2328
@ VT_NULL
Definition: compat.h:2296
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_UI2
Definition: compat.h:2312
@ VT_DECIMAL
Definition: compat.h:2309
@ VT_ARRAY
Definition: compat.h:2341
@ VT_R8
Definition: compat.h:2300
@ VT_CY
Definition: compat.h:2301
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_INT_PTR
Definition: compat.h:2327
@ VT_DATE
Definition: compat.h:2302
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_UINT
Definition: compat.h:2317
@ VT_EMPTY
Definition: compat.h:2295
@ VT_RECORD
Definition: compat.h:2326
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:86
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayDestroyDescriptor(SAFEARRAY *psa)
Definition: safearray.c:755
HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
Definition: safearray.c:947
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
Definition: safearray.c:1094
HRESULT WINAPI SafeArrayGetIID(SAFEARRAY *psa, GUID *pGuid)
Definition: safearray.c:1670
HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
Definition: safearray.c:1066
HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa)
Definition: safearray.c:1256
HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut)
Definition: safearray.c:476
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
HRESULT WINAPI SafeArrayAllocData(SAFEARRAY *psa)
Definition: safearray.c:557
HRESULT WINAPI SafeArrayGetVartype(SAFEARRAY *psa, VARTYPE *pvt)
Definition: safearray.c:1534
HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
Definition: safearray.c:864
void WINAPI VARIANT_UserFree(ULONG *pFlags, VARIANT *pvar)
Definition: usrmarshal.c:615
unsigned char *WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
Definition: usrmarshal.c:842
void WINAPI BSTR_UserFree(ULONG *pFlags, BSTR *pstr)
Definition: usrmarshal.c:189
unsigned char *WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, VARIANT *pvar)
Definition: usrmarshal.c:486
ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY *ppsa)
Definition: usrmarshal.c:754
ULONG WINAPI BSTR_UserSize(ULONG *pFlags, ULONG Start, BSTR *pstr)
Definition: usrmarshal.c:136
unsigned char *WINAPI VARIANT_UserMarshal(ULONG *pFlags, unsigned char *Buffer, VARIANT *pvar)
Definition: usrmarshal.c:388
ULONG WINAPI VARIANT_UserSize(ULONG *pFlags, ULONG Start, VARIANT *pvar)
Definition: usrmarshal.c:365
unsigned char *WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
Definition: usrmarshal.c:970
static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype)
Definition: usrmarshal.c:734
void WINAPI LPSAFEARRAY_UserFree(ULONG *pFlags, LPSAFEARRAY *ppsa)
Definition: usrmarshal.c:1134
unsigned char *WINAPI BSTR_UserMarshal(ULONG *pFlags, unsigned char *Buffer, BSTR *pstr)
Definition: usrmarshal.c:146
unsigned char *WINAPI BSTR_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, BSTR *pstr)
Definition: usrmarshal.c:168
HRESULT WINAPI VarBstrCmp(BSTR pbstrLeft, BSTR pbstrRight, LCID lcid, DWORD dwFlags)
Definition: vartype.c:7158
HRESULT WINAPI VarDecFromI4(LONG lIn, DECIMAL *pDecOut)
Definition: vartype.c:4131
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
const GLdouble * v
Definition: gl.h:2040
GLdouble s
Definition: gl.h:2039
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:6064
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define d
Definition: ke_i.h:81
#define b
Definition: ke_i.h:79
const GUID * guid
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
BOOL expected
Definition: store.c:2063
#define todo_wine
Definition: custom.c:79
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
static void WINAPI user_free(void *p)
Definition: usrmarshal.c:60
static TestUnknown * impl_from_IUnknown(IUnknown *iface)
Definition: usrmarshal.c:582
static void init_user_marshal_cb(USER_MARSHAL_CB *umcb, PMIDL_STUB_MESSAGE stub_msg, PRPC_MESSAGE rpc_msg, unsigned char *buffer, unsigned int size, MSHCTX context)
Definition: usrmarshal.c:66
static void *WINAPI user_allocate(SIZE_T size)
Definition: usrmarshal.c:53
static HMODULE hOleaut32
Definition: olefont.c:50
static void test_marshal_BSTR(void)
Definition: usrmarshal.c:551
static SF_TYPE get_union_type(SAFEARRAY *psa)
Definition: usrmarshal.c:43
static void * alloc_aligned(SIZE_T size, void **buf)
Definition: usrmarshal.c:751
static void test_marshal_LPSAFEARRAY(void)
Definition: usrmarshal.c:225
static void check_bstr(void *buffer, BSTR b)
Definition: usrmarshal.c:530
static void check_safearray(void *buffer, LPSAFEARRAY lpsa)
Definition: usrmarshal.c:121
#define GETPTR(func)
static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
Definition: usrmarshal.c:696
static DWORD * check_variant_header(DWORD *wirev, VARIANT *v, ULONG size)
Definition: usrmarshal.c:728
static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
Definition: usrmarshal.c:702
#define V_U2(A)
Definition: usrmarshal.c:36
static ULONG get_cell_count(const SAFEARRAY *psa)
Definition: usrmarshal.c:97
static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: usrmarshal.c:684
static void test_marshal_VARIANT(void)
Definition: usrmarshal.c:757
static GUID *static VARTYPE *static LCID
Definition: usrmarshal.c:41
static const IUnknownVtbl HeapUnknown_Vtbl
Definition: usrmarshal.c:710
static SCRIPT_CACHE SCRIPT_ANALYSIS * psa
Definition: usp10.c:64
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define DWORD
Definition: nt_native.h:44
UINT WINAPI SysStringByteLen(BSTR str)
Definition: oleaut.c:215
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
Definition: oleaut.c:428
#define V_I8(A)
Definition: oleauto.h:249
#define V_BOOL(A)
Definition: oleauto.h:224
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_ARRAYREF(A)
Definition: oleauto.h:223
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_UI4REF(A)
Definition: oleauto.h:271
#define VARCMP_EQ
Definition: oleauto.h:658
#define V_UNKNOWNREF(A)
Definition: oleauto.h:282
#define V_I1(A)
Definition: oleauto.h:243
#define V_VARIANTREF(A)
Definition: oleauto.h:283
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_BYREF(A)
Definition: oleauto.h:228
#define V_I4(A)
Definition: oleauto.h:247
#define V_R4(A)
Definition: oleauto.h:260
#define V_DECIMAL(A)
Definition: oleauto.h:236
#define V_UI4(A)
Definition: oleauto.h:270
#define V_R8(A)
Definition: oleauto.h:262
#define V_I2REF(A)
Definition: oleauto.h:246
#define V_DECIMALREF(A)
Definition: oleauto.h:238
#define V_R8REF(A)
Definition: oleauto.h:263
#define V_I2(A)
Definition: oleauto.h:245
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static unsigned __int64 next
Definition: rand_nt.c:6
const WCHAR * str
#define NDR_LOCAL_DATA_REPRESENTATION
Definition: rpcndr.h:107
@ USER_MARSHAL_CB_BUFFER_SIZE
Definition: rpcndr.h:324
@ USER_MARSHAL_CB_UNMARSHALL
Definition: rpcndr.h:326
#define USER_MARSHAL_CB_SIGNATURE
Definition: rpcndr.h:318
#define win_skip
Definition: test.h:163
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
IUnknown IUnknown_iface
Definition: marshal.c:2780
ULONG refs
Definition: marshal.c:2781
unsigned char * Buffer
Definition: rpcndr.h:203
ULONG BufferLength
Definition: rpcndr.h:207
unsigned char * BufferEnd
Definition: rpcndr.h:205
PRPC_MESSAGE RpcMsg
Definition: rpcndr.h:202
unsigned char * BufferStart
Definition: rpcndr.h:204
unsigned int BufferLength
Definition: rpcdcep.h:41
void * Buffer
Definition: rpcdcep.h:40
USER_MARSHAL_CB_TYPE CBType
Definition: rpcndr.h:336
PFORMAT_STRING pReserve
Definition: rpcndr.h:334
ULONG Signature
Definition: rpcndr.h:335
PMIDL_STUB_MESSAGE pStubMsg
Definition: rpcndr.h:333
Definition: http.c:7252
Definition: mem.c:156
USHORT wReserved
Definition: compat.h:2268
USHORT fFeatures
Definition: compat.h:2356
SAFEARRAYBOUND rgsabound[1]
Definition: compat.h:2360
ULONG cLocks
Definition: compat.h:2358
USHORT cDims
Definition: compat.h:2355
PVOID pvData
Definition: compat.h:2359
ULONG cbElements
Definition: compat.h:2357
#define max(a, b)
Definition: svc.c:63
uint32_t DWORD_PTR
Definition: typedefs.h:65
int64_t LONGLONG
Definition: typedefs.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
__wchar_t WCHAR
Definition: xmlstorage.h:180