From: Vibhav Pant vibhavp@gmail.com
--- dlls/combase/tests/string.c | 48 ++++++++++++++++--------------------- dlls/combase/usrmarshal.c | 32 ++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 29 deletions(-)
diff --git a/dlls/combase/tests/string.c b/dlls/combase/tests/string.c index 87e90ab8e3d..21f477365ed 100644 --- a/dlls/combase/tests/string.c +++ b/dlls/combase/tests/string.c @@ -625,12 +625,11 @@ static void test_marshal(void) ok(size == exp_size, "got size %lu != %lu\n", size, exp_size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); next = HSTRING_UserMarshal(&umcb.Flags, buffer, &str); - 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]); inproc = (struct hstring_wire_inproc *)buffer; - todo_wine ok(inproc->context == exp_context, "got unexpected prefix %#lx != %#lx\n", inproc->context, exp_context); + ok(inproc->context == exp_context, "got unexpected prefix %#lx != %#lx\n", inproc->context, exp_context); /* INPROC marshaling just consists of increasing the refcount and copying the address. */ - todo_wine ok(inproc->str == str, "got unexpected address %p\n", inproc->str); + ok(inproc->str == str, "got unexpected address %p\n", inproc->str); inproc->context = 0xdeadbeef; /* The context value is not validated. */ next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); if (size == exp_size) @@ -646,11 +645,10 @@ static void test_marshal(void) memset(buffer, 0, 80); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); next = HSTRING_UserMarshal(&umcb.Flags, &buffer[1], &str); - 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]); inproc = ALIGNED_POINTER(&buffer[1], 7); - todo_wine ok(inproc->context == exp_context, "got unexpected prefix %#lx != %#lx\n", inproc->context, exp_context); - todo_wine ok(inproc->str == str, "got unexpected address %p\n", inproc->str); + ok(inproc->context == exp_context, "got unexpected prefix %#lx != %#lx\n", inproc->context, exp_context); + ok(inproc->str == str, "got unexpected address %p\n", inproc->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]); @@ -665,11 +663,10 @@ static void test_marshal(void) memset(buffer, 0xff, 80); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); next = HSTRING_UserMarshal(&umcb.Flags, buffer, &str_empty); - 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]); inproc = (struct hstring_wire_inproc *)buffer; - todo_wine ok(inproc->context == exp_context, "got unexpected prefix %#lx != %#lx\n", inproc->context, exp_context); - todo_wine ok(!inproc->str, "got unexpected address %p\n", inproc->str); + ok(inproc->context == exp_context, "got unexpected prefix %#lx != %#lx\n", inproc->context, exp_context); + ok(!inproc->str, "got unexpected address %p\n", inproc->str); str2 = NULL; next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); if (size == exp_size) @@ -685,13 +682,11 @@ static void test_marshal(void) memset(buffer, 0, 80); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); next = HSTRING_UserMarshal(&umcb.Flags, buffer, &str); - 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]); local = (struct hstring_wire_local *)buffer; - todo_wine ok(local->size == str_bytes, "got buf.size %lu != %lu\n", local->size, str_bytes); - todo_wine ok(local->context == exp_context, "got unexpected prefix %#lx != %#lx\n", local->context, exp_context); - if (size == exp_size) - todo_wine ok(!memcmp(local->data, str_buf, str_bytes), "got buf.data %s\n", debugstr_wn(local->data, str_bytes)); + ok(local->size == str_bytes, "got buf.size %lu != %lu\n", local->size, str_bytes); + ok(local->context == exp_context, "got unexpected prefix %#lx != %#lx\n", local->context, exp_context); + ok(!memcmp(local->data, str_buf, str_bytes), "got buf.data %s\n", debugstr_wn(local->data, str_bytes)); str2 = NULL; local->context = 0xdeadbeef; /* The context value is not validated. */ next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); @@ -711,13 +706,11 @@ static void test_marshal(void) memset(buffer, 0, 80); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); next = HSTRING_UserMarshal(&umcb.Flags, &buffer[1], &str); - 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]); local = ALIGNED_POINTER(&buffer[1], 7); - todo_wine ok(local->size == str_bytes, "got buf.size %lu != %lu\n", local->size, str_bytes); - todo_wine ok(local->context == exp_context, "got unexpected prefix %#lx != %#lx\n", local->context, exp_context); - if (size == exp_size) - todo_wine ok(!memcmp(local->data, str_buf, str_bytes), "got buf.data %s\n", debugstr_wn(local->data, str_bytes)); + ok(local->size == str_bytes, "got buf.size %lu != %lu\n", local->size, str_bytes); + ok(local->context == exp_context, "got unexpected prefix %#lx != %#lx\n", local->context, exp_context); + ok(!memcmp(local->data, str_buf, str_bytes), "got buf.data %s\n", debugstr_wn(local->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]); @@ -735,11 +728,10 @@ static void test_marshal(void) memset(buffer, 0xff, 80); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); next = HSTRING_UserMarshal(&umcb.Flags, buffer, &str_empty); - 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]); local = (struct hstring_wire_local *)buffer; - todo_wine ok(local->context == exp_context, "got unexpected prefix %#lx != %#lx\n", local->context, exp_context); - todo_wine ok(!local->size, "got buf.size %lu\n", local->size); + ok(local->context == exp_context, "got unexpected prefix %#lx != %#lx\n", local->context, exp_context); + ok(!local->size, "got buf.size %lu\n", local->size); str2 = NULL; next = HSTRING_UserUnmarshal(&umcb.Flags, buffer, &str2); if (size == exp_size) diff --git a/dlls/combase/usrmarshal.c b/dlls/combase/usrmarshal.c index 10193dd3b9e..e152683d0a9 100644 --- a/dlls/combase/usrmarshal.c +++ b/dlls/combase/usrmarshal.c @@ -1061,7 +1061,37 @@ ULONG __RPC_USER HSTRING_UserSize(ULONG *flags, ULONG size, HSTRING *str) */ BYTE * __RPC_USER HSTRING_UserMarshal(ULONG *flags, BYTE *buf, HSTRING *str) { - FIXME("%p, %p, %p: stub\n", flags, buf, str); + const ULONG context = sizeof(*str) == 8 ? WDT_INPROC64_CALL : WDT_INPROC_CALL; + + TRACE("%s, %p, %s.\n", debugstr_user_flags(flags), buf, debugstr_hstring(*str)); + + if (LOWORD(*flags) == MSHCTX_DIFFERENTMACHINE) + { + FIXME("MSHCTX_DIFFERENTMACHINE is not supported yet.\n"); + RpcRaiseException(RPC_S_INVALID_TAG); + } + + if (LOWORD(*flags) == MSHCTX_INPROC) + { + struct hstring_wire_inproc *wire = ALIGNED_POINTER(buf, 7); + + wire->context = context; + WindowsDuplicateString(*str, &wire->str); + buf = (BYTE *)(wire + 1); + } + else + { + struct hstring_wire_local *wire = ALIGNED_POINTER(buf, 7); + const WCHAR *str_buf; + UINT32 len; + + wire->context = context; + str_buf = WindowsGetStringRawBuffer(*str, &len); + wire->size = len * sizeof(WCHAR); + memcpy(wire->data, str_buf, wire->size); + buf = (BYTE *)&wire->data[len]; + } + return buf; }