From: Vibhav Pant vibhavp@gmail.com
--- dlls/combase/usrmarshal.c | 33 ++++++++++++++++++++++++++++++-- dlls/oleaut32/tests/usrmarshal.c | 8 ++++---- 2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/dlls/combase/usrmarshal.c b/dlls/combase/usrmarshal.c index 5e4e49c0e6e..5c8bb805386 100644 --- a/dlls/combase/usrmarshal.c +++ b/dlls/combase/usrmarshal.c @@ -1093,7 +1093,35 @@ BYTE * __RPC_USER HSTRING_UserMarshal(ULONG *flags, BYTE *buf, HSTRING *str) */ BYTE * __RPC_USER HSTRING_UserUnmarshal(ULONG *flags, BYTE *buf, HSTRING *str) { - FIXME("%p, %p, %p: stub\n", flags, buf, str); +#ifdef _WIN64 + static const ULONG prefix = WDT_INPROC64_CALL; +#else + static const ULONG prefix = WDT_INPROC_CALL; +#endif + TRACE("%p, %p, %p\n", flags, buf, str); + + ALIGN_POINTER(buf, 7); + if (*(ULONG *)buf != prefix) + RpcRaiseException(RPC_S_INVALID_TAG); + buf += sizeof(ULONG); + if (LOWORD(*flags) == MSHCTX_INPROC) + { + ALIGN_POINTER(buf, sizeof(*str) - 1); + *str = *(HSTRING *)buf; + buf += sizeof(*str); + } + else + { + UINT32 size; + + size = *(ULONG *)buf; + buf += sizeof(ULONG); + if (size % 2) + RpcRaiseException(RPC_S_INVALID_BOUND); + WindowsCreateString((WCHAR *)buf, size/sizeof(WCHAR), str); + buf += size; + } + return buf; }
@@ -1102,5 +1130,6 @@ BYTE * __RPC_USER HSTRING_UserUnmarshal(ULONG *flags, BYTE *buf, HSTRING *str) */ void __RPC_USER HSTRING_UserFree(ULONG *flags, HSTRING *str) { - FIXME("%p, %p: stub\n", flags, str); + if (LOWORD(*flags) == MSHCTX_INPROC) + WindowsDeleteString(*str); } diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index 0f2ce7dd70d..fa9da1f8d4f 100644 --- a/dlls/oleaut32/tests/usrmarshal.c +++ b/dlls/oleaut32/tests/usrmarshal.c @@ -894,13 +894,13 @@ static void test_marshal_HSTRING(void) }
next = HSTRING_UserUnmarshal(&umcb.Flags, &buffer[test->offset], &str2); - todo_wine ok(next == buffer + size, "got next %p != %p\n", next, buffer + size); + 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); + 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); + 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)); + ok(!order, "got str2 %s != %s\n", debugstr_hstring(str2), debugstr_hstring(str)); HSTRING_UserFree(&umcb.Flags, &str2);
free(buffer);