Skip to content

Commit 42aaad4

Browse files
[OLEAUT32][OLEAUT32_WINETEST] Import LPSAFEARRAY user marshal interface marshaling support from Wine (reactos#8121)
Import the following Wine commits: oleaut32: Implement LPSAFEARRAY user marshal interface marshaling. https://gitlab.winehq.org/wine/wine/-/commit/a1f2b44a1bf9ecbcf772aa8509f87c2be1ccc415 oleaut32/tests: Add tests for LPSAFEARRAY user marshal interface marshaling. https://gitlab.winehq.org/wine/wine/-/commit/b2574278f7ab6709b920f562bb03f23073827327 containing the implementation itself and a test for it. Fixes: 1) improperly displayed comboboxes with OS type and version selection, 2) failure to save/load virtual machine settings in/from XML file in VirtualBox 3.0.0 - 4.0.36 versions and 3) improperly displayed comboboxes in 3DMark2001. As result, this also allows to create and start a virtual machine(s) in VirtualBox up to 3.0.8 version. For newer VirtualBox versions, another fix is required. CORE-8418, CORE-11254, CORE-14507, CORE-17980, CORE-18496, CORE-20015
1 parent 4e7702a commit 42aaad4

File tree

2 files changed

+365
-0
lines changed

2 files changed

+365
-0
lines changed

dll/win32/oleaut32/usrmarshal.c

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,11 @@ static unsigned int get_type_alignment(ULONG *pFlags, VARTYPE vt)
268268
}
269269

270270
/* WdtpInterfacePointer_UserSize takes care of 2 additional DWORDs to store marshalling buffer size */
271+
#ifdef __REACTOS__
272+
static unsigned interface_user_size(ULONG *pFlags, ULONG Start, REFIID riid, IUnknown *punk)
273+
#else
271274
static unsigned interface_variant_size(ULONG *pFlags, REFIID riid, IUnknown *punk)
275+
#endif
272276
{
273277
ULONG size = 0;
274278

@@ -283,7 +287,11 @@ static unsigned interface_variant_size(ULONG *pFlags, REFIID riid, IUnknown *pun
283287
}
284288
size += sizeof(ULONG);
285289
TRACE("wire-size extra of interface variant is %d\n", size);
290+
#ifdef __REACTOS__
291+
return Start + size;
292+
#else
286293
return size;
294+
#endif
287295
}
288296

289297
static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar)
@@ -304,13 +312,29 @@ static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar)
304312
case VT_VARIANT | VT_BYREF:
305313
return VARIANT_UserSize(pFlags, Start, V_VARIANTREF(pvar));
306314
case VT_UNKNOWN:
315+
#ifdef __REACTOS__
316+
return interface_user_size(pFlags, Start, &IID_IUnknown, V_UNKNOWN(pvar));
317+
#else
307318
return Start + interface_variant_size(pFlags, &IID_IUnknown, V_UNKNOWN(pvar));
319+
#endif
308320
case VT_UNKNOWN | VT_BYREF:
321+
#ifdef __REACTOS__
322+
return interface_user_size(pFlags, Start, &IID_IUnknown, *V_UNKNOWNREF(pvar));
323+
#else
309324
return Start + interface_variant_size(pFlags, &IID_IUnknown, *V_UNKNOWNREF(pvar));
325+
#endif
310326
case VT_DISPATCH:
327+
#ifdef __REACTOS__
328+
return interface_user_size(pFlags, Start, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar));
329+
#else
311330
return Start + interface_variant_size(pFlags, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar));
331+
#endif
312332
case VT_DISPATCH | VT_BYREF:
333+
#ifdef __REACTOS__
334+
return interface_user_size(pFlags, Start, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar));
335+
#else
313336
return Start + interface_variant_size(pFlags, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar));
337+
#endif
314338
case VT_RECORD:
315339
FIXME("wire-size record\n");
316340
return Start;
@@ -324,7 +348,11 @@ static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar)
324348
}
325349

326350
/* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer */
351+
#ifdef __REACTOS__
352+
static unsigned char* interface_user_marshal(ULONG *pFlags, unsigned char *Buffer,
353+
#else
327354
static unsigned char* interface_variant_marshal(ULONG *pFlags, unsigned char *Buffer,
355+
#endif
328356
REFIID riid, IUnknown *punk)
329357
{
330358
TRACE("pFlags=%d, Buffer=%p, pUnk=%p\n", *pFlags, Buffer, punk);
@@ -345,7 +373,11 @@ static unsigned char* interface_variant_marshal(ULONG *pFlags, unsigned char *Bu
345373
}
346374

347375
/* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer */
376+
#ifdef __REACTOS__
377+
static unsigned char *interface_user_unmarshal(ULONG *pFlags, unsigned char *Buffer,
378+
#else
348379
static unsigned char *interface_variant_unmarshal(ULONG *pFlags, unsigned char *Buffer,
380+
#endif
349381
REFIID riid, IUnknown **ppunk)
350382
{
351383
DWORD ptr;
@@ -459,16 +491,32 @@ unsigned char * WINAPI VARIANT_UserMarshal(ULONG *pFlags, unsigned char *Buffer,
459491
Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar));
460492
break;
461493
case VT_UNKNOWN:
494+
#ifdef __REACTOS__
495+
Pos = interface_user_marshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWN(pvar));
496+
#else
462497
Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWN(pvar));
498+
#endif
463499
break;
464500
case VT_UNKNOWN | VT_BYREF:
501+
#ifdef __REACTOS__
502+
Pos = interface_user_marshal(pFlags, Pos, &IID_IUnknown, *V_UNKNOWNREF(pvar));
503+
#else
465504
Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, *V_UNKNOWNREF(pvar));
505+
#endif
466506
break;
467507
case VT_DISPATCH:
508+
#ifdef __REACTOS__
509+
Pos = interface_user_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar));
510+
#else
468511
Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar));
512+
#endif
469513
break;
470514
case VT_DISPATCH | VT_BYREF:
515+
#ifdef __REACTOS__
516+
Pos = interface_user_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar));
517+
#else
471518
Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar));
519+
#endif
472520
break;
473521
case VT_RECORD:
474522
FIXME("handle BRECORD by val\n");
@@ -590,16 +638,32 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
590638
Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar));
591639
break;
592640
case VT_UNKNOWN:
641+
#ifdef __REACTOS__
642+
Pos = interface_user_unmarshal(pFlags, Pos, &IID_IUnknown, &V_UNKNOWN(pvar));
643+
#else
593644
Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, &V_UNKNOWN(pvar));
645+
#endif
594646
break;
595647
case VT_UNKNOWN | VT_BYREF:
648+
#ifdef __REACTOS__
649+
Pos = interface_user_unmarshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWNREF(pvar));
650+
#else
596651
Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWNREF(pvar));
652+
#endif
597653
break;
598654
case VT_DISPATCH:
655+
#ifdef __REACTOS__
656+
Pos = interface_user_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)&V_DISPATCH(pvar));
657+
#else
599658
Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)&V_DISPATCH(pvar));
659+
#endif
600660
break;
601661
case VT_DISPATCH | VT_BYREF:
662+
#ifdef __REACTOS__
663+
Pos = interface_user_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)V_DISPATCHREF(pvar));
664+
#else
602665
Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)V_DISPATCHREF(pvar));
666+
#endif
603667
break;
604668
case VT_RECORD:
605669
FIXME("handle BRECORD by val\n");
@@ -733,22 +797,68 @@ static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa)
733797

734798
static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype)
735799
{
800+
#ifdef __REACTOS__
801+
switch (sftype)
802+
{
803+
case SF_BSTR:
804+
case SF_HAVEIID:
805+
case SF_UNKNOWN:
806+
case SF_DISPATCH:
807+
#else
736808
if (sftype == SF_BSTR)
809+
#endif
737810
return sizeof(DWORD);
811+
#ifdef __REACTOS__
812+
813+
case SF_VARIANT:
814+
#else
738815
else if (sftype == SF_VARIANT)
816+
#endif
739817
return sizeof(variant_wire_t) - sizeof(DWORD);
818+
#ifdef __REACTOS__
819+
820+
default:
821+
#else
740822
else
823+
#endif
741824
return lpsa->cbElements;
825+
#ifdef __REACTOS__
826+
}
827+
#endif
742828
}
743829

744830
static DWORD elem_mem_size(wireSAFEARRAY wiresa, SF_TYPE sftype)
745831
{
832+
#ifdef __REACTOS__
833+
switch (sftype)
834+
{
835+
case SF_HAVEIID:
836+
case SF_UNKNOWN:
837+
case SF_DISPATCH:
838+
return sizeof(void *);
839+
840+
case SF_BSTR:
841+
#else
746842
if (sftype == SF_BSTR)
843+
#endif
747844
return sizeof(BSTR);
845+
#ifdef __REACTOS__
846+
847+
case SF_VARIANT:
848+
#else
748849
else if (sftype == SF_VARIANT)
850+
#endif
749851
return sizeof(VARIANT);
852+
#ifdef __REACTOS__
853+
854+
default:
855+
#else
750856
else
857+
#endif
751858
return wiresa->cbElements;
859+
#ifdef __REACTOS__
860+
}
861+
#endif
752862
}
753863

754864
ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY *ppsa)
@@ -795,8 +905,28 @@ ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY
795905
case SF_DISPATCH:
796906
case SF_UNKNOWN:
797907
case SF_HAVEIID:
908+
#ifdef __REACTOS__
909+
{
910+
IUnknown **lpUnk;
911+
GUID guid;
912+
913+
if (sftype == SF_HAVEIID)
914+
SafeArrayGetIID(psa, &guid);
915+
else if (sftype == SF_UNKNOWN)
916+
guid = IID_IUnknown;
917+
else
918+
guid = IID_IDispatch;
919+
920+
for (lpUnk = psa->pvData; ulCellCount; ulCellCount--, lpUnk++)
921+
size = interface_user_size(pFlags, size, &guid, *lpUnk);
922+
923+
#else
798924
FIXME("size interfaces\n");
925+
#endif
799926
break;
927+
#ifdef __REACTOS__
928+
}
929+
#endif
800930
case SF_VARIANT:
801931
{
802932
VARIANT* lpVariant;
@@ -870,7 +1000,11 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf
8701000
Buffer += sizeof(ULONG);
8711001

8721002
hr = SafeArrayGetVartype(psa, &vt);
1003+
#ifdef __REACTOS__
1004+
if ((psa->fFeatures & FADF_HAVEIID) || FAILED(hr)) vt = 0;
1005+
#else
8731006
if (FAILED(hr)) vt = 0;
1007+
#endif
8741008

8751009
*(ULONG *)Buffer = (USHORT)psa->cLocks | (vt << 16);
8761010
Buffer += sizeof(ULONG);
@@ -916,8 +1050,28 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf
9161050
case SF_DISPATCH:
9171051
case SF_UNKNOWN:
9181052
case SF_HAVEIID:
1053+
#ifdef __REACTOS__
1054+
{
1055+
IUnknown **lpUnk;
1056+
const GUID *iid;
1057+
1058+
if (sftype == SF_HAVEIID)
1059+
iid = &guid;
1060+
else if (sftype == SF_UNKNOWN)
1061+
iid = &IID_IUnknown;
1062+
else
1063+
iid = &IID_IDispatch;
1064+
1065+
for (lpUnk = psa->pvData; ulCellCount; ulCellCount--, lpUnk++)
1066+
Buffer = interface_user_marshal(pFlags, Buffer, iid, *lpUnk);
1067+
1068+
#else
9191069
FIXME("marshal interfaces\n");
1070+
#endif
9201071
break;
1072+
#ifdef __REACTOS__
1073+
}
1074+
#endif
9211075
case SF_VARIANT:
9221076
{
9231077
VARIANT* lpVariant;
@@ -1093,8 +1247,28 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
10931247
case SF_DISPATCH:
10941248
case SF_UNKNOWN:
10951249
case SF_HAVEIID:
1250+
#ifdef __REACTOS__
1251+
{
1252+
IUnknown **lpUnk;
1253+
const GUID *iid;
1254+
1255+
if (sftype == SF_HAVEIID)
1256+
iid = &guid;
1257+
else if (sftype == SF_UNKNOWN)
1258+
iid = &IID_IUnknown;
1259+
else
1260+
iid = &IID_IDispatch;
1261+
1262+
for (lpUnk = (*ppsa)->pvData; cell_count; cell_count--, lpUnk++)
1263+
Buffer = interface_user_unmarshal(pFlags, Buffer, iid, lpUnk);
1264+
1265+
#else
10961266
FIXME("marshal interfaces\n");
1267+
#endif
10971268
break;
1269+
#ifdef __REACTOS__
1270+
}
1271+
#endif
10981272
case SF_VARIANT:
10991273
{
11001274
VARIANT* lpVariant;

0 commit comments

Comments
 (0)