On Mon, Dec 27, 2021 at 03:29:30PM +0100, Bernhard Kölbl wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51017
Debugging sessions and the official WinRT SDK show, that hstrings are aligned differently in memory, than they are currently used in Wine. E.g. The string buffer is stored at the end of hstring_private. Also if a string reference is created with WindowsCreateStringReference, a seperate pointer is used to point at the string-source.
Signed-off-by: Bernhard Kölbl besentv@gmail.com
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 | 126 ++++++++++++++++++++++-------------- dlls/combase/tests/string.c | 73 ++++++++++++++++++++- 2 files changed, 150 insertions(+), 49 deletions(-)
diff --git a/dlls/combase/string.c b/dlls/combase/string.c index 2092e4360a3..1677915c244 100644 --- a/dlls/combase/string.c +++ b/dlls/combase/string.c @@ -26,44 +26,58 @@
WINE_DEFAULT_DEBUG_CHANNEL(winstring);
-struct hstring_private +#define HSTRING_REFERENCE_FLAG 1
+struct hstring_header {
- LPWSTR buffer;
- UINT32 flags; UINT32 length;
- BOOL reference;
- LONG refcount;
- UINT32 padding1;
- UINT32 padding2;
- const WCHAR *ptr;
};
+struct hstring_private +{
- struct hstring_header header;
- LONG refcount;
- WCHAR buffer[1];
+};
There's quite a lot going on with this patch and it seems possible to split it up.
I'd suggest initially adding a hstring_header that contains just the flags (as well as necessary padding) and then move the elements over on at a time.
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, sizeof(*priv) + len * sizeof(*priv->buffer));
offsetof(struct hstring_private, buffer[len])
Huw.