From: Vibhav Pant vibhavp@gmail.com
--- dlls/oleaut32/tests/Makefile.in | 2 +- dlls/oleaut32/tests/usrmarshal.c | 103 +++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/dlls/oleaut32/tests/Makefile.in b/dlls/oleaut32/tests/Makefile.in index b8e7615a04e..bc90ca78271 100644 --- a/dlls/oleaut32/tests/Makefile.in +++ b/dlls/oleaut32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = oleaut32.dll -IMPORTS = oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 +IMPORTS = oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 combase
SOURCES = \ dispatch.c \ diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index 922736b1591..e6d41a30268 100644 --- a/dlls/oleaut32/tests/usrmarshal.c +++ b/dlls/oleaut32/tests/usrmarshal.c @@ -28,6 +28,8 @@ #include "objbase.h" #include "propidl.h" /* for LPSAFEARRAY_User* routines */
+#include "winstring.h" +#include "inspectable.h" #include "wine/test.h"
typedef struct @@ -807,6 +809,106 @@ static void test_marshal_BSTR(void) SysFreeString(b); }
+#define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align)) +#define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align)) +#define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align) +#define ALIGN_POINTER( _Ptr, _Align ) _Ptr = ALIGNED_POINTER( _Ptr, _Align ) + +static void test_marshal_HSTRING(void) +{ + static const WCHAR str_buf[] = L"marshal_test1"; + static const struct test { + const WCHAR *buf; + MSHCTX ctx; + ULONG offset; + ULONG size; + } tests[] = { + {L"", MSHCTX_INPROC, 0, sizeof(HSTRING)*2}, + {L"", MSHCTX_INPROC, 1, ALIGNED_LENGTH(1 + sizeof(HSTRING) * 2, 7)}, + {L"", MSHCTX_LOCAL, 0, 8 }, + {L"", MSHCTX_LOCAL, 1, 16 }, + {L"", MSHCTX_NOSHAREDMEM, 0, 8 }, + {L"", MSHCTX_NOSHAREDMEM, 1, 16 }, + {str_buf, MSHCTX_INPROC, 0, sizeof(HSTRING) * 2 }, + {str_buf, MSHCTX_LOCAL, 0, 8 + (ARRAY_SIZE(str_buf) - 1) * sizeof(WCHAR)}, + {str_buf, MSHCTX_LOCAL, 1, 8 + 8 + (ARRAY_SIZE(str_buf) - 1) * sizeof(WCHAR)}, + {str_buf, MSHCTX_NOSHAREDMEM, 0, 8 + (ARRAY_SIZE(str_buf) - 1) * sizeof(WCHAR)}, + {str_buf, MSHCTX_NOSHAREDMEM, 1, 8 + 8 + (ARRAY_SIZE(str_buf) - 1) * sizeof(WCHAR)} + }; + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { +#ifdef _WIN64 + const ULONG exp_prefix = WDT_INPROC64_CALL; +#else + const ULONG exp_prefix = WDT_INPROC_CALL; +#endif + const struct test *test = &tests[i]; + MIDL_STUB_MESSAGE stub_msg; + BYTE *buffer, *next, *ptr; + HSTRING str, str2 = NULL; + USER_MARSHAL_CB umcb; + RPC_MESSAGE rpc_msg; + int order = -1; + ULONG size; + HRESULT hr; + BOOL empty = !wcslen(test->buf); + + winetest_push_context("tests[%Iu]", i); + hr = WindowsCreateString(test->buf, wcslen(test->buf), &str); + ok(hr == S_OK, "got hr %#lx.\n", hr); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, test->ctx); + size = HSTRING_UserSize(&umcb.Flags, test->offset, &str); + todo_wine ok(size == test->size, "got size %lu != %lu\n", size, test->size); + + if (size != test->size) + { + WindowsDeleteString(str); + winetest_pop_context(); + continue; + } + + buffer = calloc(1, size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, test->ctx); + next = HSTRING_UserMarshal(&umcb.Flags, &buffer[test->offset], &str); + todo_wine ok(next == buffer + size, "got next %p != %p\n", next, buffer + size); + ptr = ALIGNED_POINTER(&buffer[test->offset], 7); + todo_wine ok(*(ULONG *)ptr == exp_prefix, "got unexpected prefix %lx\n", *(ULONG *)ptr); + ptr += sizeof(ULONG); + if (test->ctx == MSHCTX_INPROC) + { + ALIGN_POINTER(ptr, sizeof(HSTRING) - 1); + todo_wine_if(!empty) ok(*(DWORD_PTR *)ptr == (DWORD_PTR)str, "got unexpected address %Ix\n", *(DWORD_PTR *)ptr); + } + else + { + ULONG size; + + size = *(ULONG *)ptr; + todo_wine_if(!empty) ok(size == wcslen(test->buf) * sizeof(WCHAR), "got unexpected size %lu\n", *(ULONG *)ptr); + ptr += sizeof(ULONG); + if (size == wcslen(test->buf) * sizeof(WCHAR)) + todo_wine_if(size) ok(!memcmp(ptr, test->buf, size), "got unexpected buffer %s\n", debugstr_wn((WCHAR *)ptr, size)); + } + + next = HSTRING_UserUnmarshal(&umcb.Flags, &buffer[test->offset], &str2); + todo_wine ok(next == buffer + size, "got next %p != %p\n", next, buffer + size); + if (test->ctx == MSHCTX_INPROC || empty) + todo_wine_if(!empty) ok(str2 == str, "got str2 %p != %p\n", str2, str); + else + todo_wine_if(str2) ok(str2 != str, "got str2 %p != %p\n", str2, str); + hr = WindowsCompareStringOrdinal(str, str2, &order); + todo_wine_if(!empty) ok(!order, "got str2 %s != %s\n", debugstr_hstring(str2), debugstr_hstring(str)); + HSTRING_UserFree(&umcb.Flags, &str2); + + free(buffer); + WindowsDeleteString(str); + winetest_pop_context(); + } +} + static inline HeapUnknown *impl_from_IUnknown(IUnknown *iface) { return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface); @@ -1758,6 +1860,7 @@ START_TEST(usrmarshal) test_marshal_LPSAFEARRAY(); test_marshal_BSTR(); test_marshal_VARIANT(); + test_marshal_HSTRING();
CoUninitialize(); }