From: Vibhav Pant vibhavp@gmail.com
--- dlls/combase/tests/string.c | 30 ++++++++++++------------------ dlls/combase/usrmarshal.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/dlls/combase/tests/string.c b/dlls/combase/tests/string.c index bfeaa828c1f..cf0b97892c6 100644 --- a/dlls/combase/tests/string.c +++ b/dlls/combase/tests/string.c @@ -642,9 +642,8 @@ static void test_marshal(void) /* INPROC marshaling just consists of increasing the refcount and copying the address. */ ok(wire->str == str, "got unexpected address %p\n", wire->str); next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); - if (size == exp_size) - todo_wine ok(next == &buffer[size], "got next %p != %p\n", next, &buffer[size]); - todo_wine ok(str2 == str, "got str2 %p != %p\n", str2, str); + ok(next == &buffer[size], "got next %p != %p\n", next, &buffer[size]); + ok(str2 == str, "got str2 %p != %p\n", str2, str); HSTRING_UserFree(&umcb.Flags, &str2);
/* Test alignment */ @@ -660,9 +659,8 @@ static void test_marshal(void) ok(wire->context == exp_prefix, "got unexpected prefix %#lx != %#lx\n", wire->context, exp_prefix); ok(wire->str == str, "got unexpected address %p\n", wire->str); next = HSTRING_UserUnmarshal(&umcb.Flags, &buffer[1], &str2); - if (size == exp_size) - todo_wine ok(next == &buffer[size], "got next %p != %p\n", next, &buffer[size]); - todo_wine ok(str2 == str, "got str2 %p != %p\n", str2, str); + ok(next == &buffer[size], "got next %p != %p\n", next, &buffer[size]); + ok(str2 == str, "got str2 %p != %p\n", str2, str); HSTRING_UserFree(&umcb.Flags, &str2);
/* INPROC marshaling with empty/NULL HSTRING */ @@ -679,8 +677,7 @@ static void test_marshal(void) ok(!wire->str, "got unexpected address %p\n", wire->str); str2 = NULL; next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); - if (size == exp_size) - 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]); ok(!str2, "got str2 %p\n", str2); HSTRING_UserFree(&umcb.Flags, &str2);
@@ -699,13 +696,12 @@ static void test_marshal(void) str2 = NULL; next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); wire = (struct hstring_wire *)buffer; - if (size == exp_size) - 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]); /* A new HSTRING should be allocated */ - todo_wine_if(str2) ok(str2 != str, "got str2 %p\n", str2); + ok(str2 != str, "got str2 %p\n", str2); hr = WindowsCompareStringOrdinal(str2, str, &order); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine 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);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); @@ -720,13 +716,12 @@ static void test_marshal(void) ok(wire->buf.size == str_bytes, "got buf.size %lu != %lu\n", wire->buf.size, str_bytes); ok(!memcmp(wire->buf.data, str_buf, str_bytes), "got buf.data %s\n", debugstr_wn(wire->buf.data, str_bytes)); next = HSTRING_UserUnmarshal(&umcb.Flags, &buffer[1], &str2); - if (size == exp_size) - todo_wine ok(next == &buffer[size], "got next %p != %p\n", next, &buffer[size]); - todo_wine_if(str2) ok(str2 != str, "got str2 %p\n", str2); + ok(next == &buffer[size], "got next %p != %p\n", next, &buffer[size]); + ok(str2 != str, "got str2 %p\n", str2); order = -1; hr = WindowsCompareStringOrdinal(str2, str, &order); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine 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);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); @@ -741,8 +736,7 @@ static void test_marshal(void) ok(!wire->buf.size, "got buf.size %lu\n", wire->buf.size); str2 = NULL; next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); - if (size == exp_size) - 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]); ok(!str2, "got str2 %p\n", str2); HSTRING_UserFree(&umcb.Flags, &str2);
diff --git a/dlls/combase/usrmarshal.c b/dlls/combase/usrmarshal.c index 810cd3b31ea..07b7726f77d 100644 --- a/dlls/combase/usrmarshal.c +++ b/dlls/combase/usrmarshal.c @@ -1109,7 +1109,36 @@ 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); + const struct hstring_wire *wire; +#ifdef _WIN64 + static const ULONG prefix = WDT_INPROC64_CALL; +#else + static const ULONG prefix = WDT_INPROC_CALL; +#endif + + TRACE("%p, %p, %p\n", debugstr_user_flags(flags), buf, str); + + ALIGN_POINTER(buf, 7); + wire = (const struct hstring_wire *)buf; + if (wire->context != prefix) + RpcRaiseException(RPC_S_INVALID_TAG); + if (LOWORD(*flags) == MSHCTX_INPROC) + { + *str = wire->str; + TRACE("str=%s\n", debugstr_hstring(*str)); + buf = (BYTE *)(&wire->str + 1); + } + else + { + UINT32 len; + + if (wire->buf.size % 2) + RpcRaiseException(RPC_S_INVALID_BOUND); + len = wire->buf.size/sizeof(WCHAR); + WindowsCreateString(wire->buf.data, len, str); + buf = (BYTE *)&wire->buf.data[len]; + } + return buf; }
@@ -1118,5 +1147,8 @@ 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); + TRACE("%s, %s.\n", debugstr_user_flags(flags), debugstr_hstring(*str)); + + if (LOWORD(*flags) == MSHCTX_INPROC) + WindowsDeleteString(*str); }