From: "Bernhard Kölbl" Subject: [PATCH v6 5/5] combase: Reorder hstring_private elements. Message-Id: <20220124150923.124656-5-besentv@gmail.com> Date: Mon, 24 Jan 2022 16:09:23 +0100 In-Reply-To: <20220124150923.124656-1-besentv@gmail.com> References: <20220124150923.124656-1-besentv@gmail.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51017 Put the string buffer at the end of the struct to match the Windows behaviour and avoid unnecessary pointer arithmetic. Signed-off-by: Bernhard Kölbl --- v6: Fix incorrect buf len and move failing test into a later commit. v5: Split the patch into multiple commits and minor code changes. v4: Remove leftover debugging TRACE and minor style changes. v3: Add nested hstring_header struct to hstring_private and add a test for both. v2: I was mistaken about no reference counting being used. --- dlls/combase/string.c | 8 ++++---- dlls/combase/tests/string.c | 8 -------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/dlls/combase/string.c b/dlls/combase/string.c index 8c4d9a2cfbf..59e39f59956 100644 --- a/dlls/combase/string.c +++ b/dlls/combase/string.c @@ -40,8 +40,8 @@ struct hstring_header struct hstring_private { struct hstring_header header; - LPWSTR buffer; - LONG refcount; + LONG refcount; + WCHAR buffer[1]; }; static const WCHAR empty[1]; @@ -66,14 +66,14 @@ static inline struct hstring_private *impl_from_HSTRING_BUFFER(HSTRING_BUFFER bu static BOOL alloc_string(UINT32 len, HSTRING *out) { struct hstring_private *priv; - priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv) + (len + 1) * sizeof(*priv->buffer)); + priv = HeapAlloc(GetProcessHeap(), 0, offsetof(struct hstring_private, buffer[len+1])); if (!priv) return FALSE; priv->header.flags = 0; - priv->buffer = (LPWSTR)(priv + 1); priv->header.length = len; priv->header.str = priv->buffer; + priv->refcount = 1; priv->buffer[len] = '\0'; diff --git a/dlls/combase/tests/string.c b/dlls/combase/tests/string.c index 46cf58a271a..232d37304d6 100644 --- a/dlls/combase/tests/string.c +++ b/dlls/combase/tests/string.c @@ -513,29 +513,21 @@ static void test_hstring_struct(void) ok(prv->header.flags == 0, "Expected 0 in flags field, got %#x.\n", prv->header.flags); ok(prv->header.length == 6, "Expected 6 in length field, got %u.\n", prv->header.length); - todo_wine ok(prv->header.str == prv->buffer, "Expected str to point at buffer, instead pointing at %p.\n", prv->header.str); - todo_wine ok(prv->refcount == 1, "Expected 1 in refcount, got %u.\n", prv->refcount); - todo_wine ok(wcscmp(input_string, prv->buffer) == 0, "Expected strings to match.\n"); - todo_wine ok(prv->buffer[prv->header.length] == '\0', "Expected buffer to be null terminated.\n"); ok(WindowsDuplicateString(str, &str2) == S_OK, "Failed to duplicate string.\n"); prv2 = CONTAINING_RECORD(str2, struct hstring_private, header); - todo_wine ok(prv->refcount == 2, "Expected 2 in refcount, got %u.\n", prv->refcount); - todo_wine ok(prv2->refcount == 2, "Expected 2 in refcount, got %u.\n", prv2->refcount); - todo_wine ok(wcscmp(input_string, prv2->buffer) == 0, "Expected strings to match.\n"); ok(WindowsDeleteString(str) == S_OK, "Failed to delete string.\n"); - todo_wine ok(prv->refcount == 1, "Expected 1 in refcount, got %u.\n", prv->refcount); ok(WindowsDeleteString(str) == S_OK, "Failed to delete string.\n"); -- 2.34.1