[PATCH v5 5/5] combase: Reorder hstring_private elements.

Bernhard Kölbl besentv at gmail.com
Wed Jan 12 17:34:18 CST 2022


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 <besentv at gmail.com>
---
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 24d1e4dd8f9..fa35262fbf9 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]));
     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




More information about the wine-devel mailing list