From: "Bernhard Kölbl" Subject: [PATCH v6 2/5] combase: Introduce a hstring_header struct to hstring_private. Message-Id: <20220124150923.124656-2-besentv@gmail.com> Date: Mon, 24 Jan 2022 16:09:20 +0100 In-Reply-To: <20220124150923.124656-1-besentv@gmail.com> References: <20220124150923.124656-1-besentv@gmail.com> Also move the reference flag to the hstring_header struct. Signed-off-by: Bernhard Kölbl --- dlls/combase/string.c | 44 +++++++++++++++++++++++++------------ dlls/combase/tests/string.c | 2 -- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/dlls/combase/string.c b/dlls/combase/string.c index 2092e4360a3..796fe607ad0 100644 --- a/dlls/combase/string.c +++ b/dlls/combase/string.c @@ -26,31 +26,38 @@ WINE_DEFAULT_DEBUG_CHANNEL(winstring); +#define HSTRING_REFERENCE_FLAG 1 + +struct hstring_header +{ + UINT32 flags; +}; + struct hstring_private { + struct hstring_header header; LPWSTR buffer; UINT32 length; - BOOL reference; LONG refcount; }; static const WCHAR empty[1]; -C_ASSERT(sizeof(struct hstring_private) <= sizeof(HSTRING_HEADER)); +C_ASSERT(sizeof(struct hstring_header) <= sizeof(HSTRING_HEADER)); static inline struct hstring_private *impl_from_HSTRING(HSTRING string) { - return (struct hstring_private *)string; + return (struct hstring_private *)string; } static inline struct hstring_private *impl_from_HSTRING_HEADER(HSTRING_HEADER *header) { - return (struct hstring_private *)header; + return CONTAINING_RECORD(header, struct hstring_private, header); } static inline struct hstring_private *impl_from_HSTRING_BUFFER(HSTRING_BUFFER buffer) { - return (struct hstring_private *)buffer; + return CONTAINING_RECORD(buffer, struct hstring_private, buffer); } static BOOL alloc_string(UINT32 len, HSTRING *out) @@ -59,11 +66,13 @@ static BOOL alloc_string(UINT32 len, HSTRING *out) priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv) + (len + 1) * sizeof(*priv->buffer)); if (!priv) return FALSE; + + priv->header.flags = 0; priv->buffer = (LPWSTR)(priv + 1); priv->length = len; - priv->reference = FALSE; priv->refcount = 1; priv->buffer[len] = '\0'; + *out = (HSTRING)priv; return TRUE; } @@ -115,10 +124,12 @@ HRESULT WINAPI WindowsCreateStringReference(LPCWSTR ptr, UINT32 len, } if (ptr == NULL) return E_POINTER; + priv->buffer = (LPWSTR)ptr; priv->length = len; - priv->reference = TRUE; - *out = (HSTRING)header; + priv->header.flags = HSTRING_REFERENCE_FLAG; + + *out = (HSTRING)priv; return S_OK; } @@ -133,7 +144,7 @@ HRESULT WINAPI WindowsDeleteString(HSTRING str) if (str == NULL) return S_OK; - if (priv->reference) + if (priv->header.flags & HSTRING_REFERENCE_FLAG) return S_OK; if (InterlockedDecrement(&priv->refcount) == 0) HeapFree(GetProcessHeap(), 0, priv); @@ -156,7 +167,7 @@ HRESULT WINAPI WindowsDuplicateString(HSTRING str, HSTRING *out) *out = NULL; return S_OK; } - if (priv->reference) + if (priv->header.flags & HSTRING_REFERENCE_FLAG) return WindowsCreateString(priv->buffer, priv->length, out); InterlockedIncrement(&priv->refcount); *out = str; @@ -187,7 +198,7 @@ HRESULT WINAPI WindowsPreallocateStringBuffer(UINT32 len, WCHAR **outptr, return E_OUTOFMEMORY; priv = impl_from_HSTRING(str); *outptr = priv->buffer; - *out = (HSTRING_BUFFER)str; + *out = (HSTRING_BUFFER)&priv->buffer; return S_OK; } @@ -196,9 +207,14 @@ HRESULT WINAPI WindowsPreallocateStringBuffer(UINT32 len, WCHAR **outptr, */ HRESULT WINAPI WindowsDeleteStringBuffer(HSTRING_BUFFER buf) { + struct hstring_private *priv = NULL; + TRACE("(%p)\n", buf); - return WindowsDeleteString((HSTRING)buf); + if(buf) + priv = impl_from_HSTRING_BUFFER(buf); + + return WindowsDeleteString((HSTRING)priv); } /*********************************************************************** @@ -217,9 +233,9 @@ HRESULT WINAPI WindowsPromoteStringBuffer(HSTRING_BUFFER buf, HSTRING *out) *out = NULL; return S_OK; } - if (priv->buffer[priv->length] != 0 || priv->reference || priv->refcount != 1) + if (priv->buffer[priv->length] != 0 || priv->header.flags & HSTRING_REFERENCE_FLAG || priv->refcount != 1) return E_INVALIDARG; - *out = (HSTRING)buf; + *out = (HSTRING)priv; return S_OK; } diff --git a/dlls/combase/tests/string.c b/dlls/combase/tests/string.c index 799a79017fc..ea3285f6008 100644 --- a/dlls/combase/tests/string.c +++ b/dlls/combase/tests/string.c @@ -511,7 +511,6 @@ static void test_hstring_struct(void) prv = CONTAINING_RECORD(str, struct hstring_private, header); - todo_wine ok(prv->header.flags == 0, "Expected 0 in flags field, got %#x.\n", prv->header.flags); todo_wine ok(prv->header.str == prv->buffer, "Expected str to point at buffer, instead pointing at %p.\n", prv->header.str); @@ -546,7 +545,6 @@ static void test_hstring_struct(void) prv2 = CONTAINING_RECORD(str, struct hstring_private, header); ok(prv == prv2, "Pointers not identical.\n"); - todo_wine ok(prv2->header.flags == 1, "Expected HSTRING_REFERENCE_FLAG to be set, got %#x.\n", prv2->header.flags); todo_wine ok(prv2->header.str == input_string, "Expected str to point at input_string, instead pointing at %p.\n", prv2->header.str); -- 2.34.1