mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
391 lines
14 KiB
Diff
391 lines
14 KiB
Diff
From 0eaebb31a43736c90862d24f979c5a4dbe976d7d Mon Sep 17 00:00:00 2001
|
|
From: Martin Storsjo <martin@martin.st>
|
|
Date: Tue, 9 Dec 2014 10:36:48 +0200
|
|
Subject: combase: Implement creation and deletion of HSTRING objects.
|
|
|
|
---
|
|
configure.ac | 1 +
|
|
.../api-ms-win-core-winrt-string-l1-1-0.spec | 8 +-
|
|
dlls/combase/Makefile.in | 3 +-
|
|
dlls/combase/combase.spec | 8 +-
|
|
dlls/combase/string.c | 143 +++++++++++++++++++++
|
|
dlls/combase/tests/Makefile.in | 4 +
|
|
dlls/combase/tests/string.c | 128 ++++++++++++++++++
|
|
tools/make_specfiles | 1 +
|
|
8 files changed, 287 insertions(+), 9 deletions(-)
|
|
create mode 100644 dlls/combase/string.c
|
|
create mode 100644 dlls/combase/tests/Makefile.in
|
|
create mode 100644 dlls/combase/tests/string.c
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 400ee61..e214189 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -2758,6 +2758,7 @@ WINE_CONFIG_DLL(cards,,[implib])
|
|
WINE_CONFIG_DLL(cfgmgr32,,[implib])
|
|
WINE_CONFIG_DLL(clusapi,,[implib])
|
|
WINE_CONFIG_DLL(combase)
|
|
+WINE_CONFIG_TEST(dlls/combase/tests)
|
|
WINE_CONFIG_DLL(comcat)
|
|
WINE_CONFIG_TEST(dlls/comcat/tests)
|
|
WINE_CONFIG_DLL(comctl32,,[implib,po])
|
|
diff --git a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec
|
|
index bc9035c..7658867 100644
|
|
--- a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec
|
|
+++ b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec
|
|
@@ -8,11 +8,11 @@
|
|
@ stub HSTRING_UserUnmarshal64
|
|
@ stub WindowsCompareStringOrdinal
|
|
@ stub WindowsConcatString
|
|
-@ stub WindowsCreateString
|
|
-@ stub WindowsCreateStringReference
|
|
-@ stub WindowsDeleteString
|
|
+@ stdcall WindowsCreateString(ptr long ptr) combase.WindowsCreateString
|
|
+@ stdcall WindowsCreateStringReference(wstr long ptr ptr) combase.WindowsCreateStringReference
|
|
+@ stdcall WindowsDeleteString(ptr) combase.WindowsDeleteString
|
|
@ stub WindowsDeleteStringBuffer
|
|
-@ stub WindowsDuplicateString
|
|
+@ stdcall WindowsDuplicateString(ptr ptr) combase.WindowsDuplicateString
|
|
@ stub WindowsGetStringLen
|
|
@ stub WindowsGetStringRawBuffer
|
|
@ stub WindowsInspectString
|
|
diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in
|
|
index 79d22a1..c5ab8d2 100644
|
|
--- a/dlls/combase/Makefile.in
|
|
+++ b/dlls/combase/Makefile.in
|
|
@@ -2,4 +2,5 @@ MODULE = combase.dll
|
|
IMPORTS = ole32
|
|
|
|
C_SRCS = \
|
|
- roapi.c
|
|
+ roapi.c \
|
|
+ string.c
|
|
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec
|
|
index 652eff6..f399d25 100644
|
|
--- a/dlls/combase/combase.spec
|
|
+++ b/dlls/combase/combase.spec
|
|
@@ -289,11 +289,11 @@
|
|
@ stub WdtpInterfacePointer_UserUnmarshal64
|
|
@ stub WindowsCompareStringOrdinal
|
|
@ stub WindowsConcatString
|
|
-@ stub WindowsCreateString
|
|
-@ stub WindowsCreateStringReference
|
|
-@ stub WindowsDeleteString
|
|
+@ stdcall WindowsCreateString(ptr long ptr)
|
|
+@ stdcall WindowsCreateStringReference(wstr long ptr ptr)
|
|
+@ stdcall WindowsDeleteString(ptr)
|
|
@ stub WindowsDeleteStringBuffer
|
|
-@ stub WindowsDuplicateString
|
|
+@ stdcall WindowsDuplicateString(ptr ptr)
|
|
@ stub WindowsGetStringLen
|
|
@ stub WindowsGetStringRawBuffer
|
|
@ stub WindowsInspectString
|
|
diff --git a/dlls/combase/string.c b/dlls/combase/string.c
|
|
new file mode 100644
|
|
index 0000000..ee2f5c0
|
|
--- /dev/null
|
|
+++ b/dlls/combase/string.c
|
|
@@ -0,0 +1,143 @@
|
|
+/*
|
|
+ * Copyright 2014 Martin Storsjo
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
+ */
|
|
+
|
|
+#include "winerror.h"
|
|
+#include "hstring.h"
|
|
+#include "windows.h"
|
|
+#include "wine/debug.h"
|
|
+#include <string.h>
|
|
+
|
|
+WINE_DEFAULT_DEBUG_CHANNEL(combase);
|
|
+
|
|
+struct hstring_private
|
|
+{
|
|
+ LPWSTR buffer;
|
|
+ UINT32 length;
|
|
+ BOOL reference;
|
|
+ LONG refcount;
|
|
+};
|
|
+
|
|
+C_ASSERT(sizeof(struct hstring_private) <= sizeof(HSTRING_HEADER));
|
|
+
|
|
+static inline struct hstring_private *impl_from_HSTRING(HSTRING string)
|
|
+{
|
|
+ return (struct hstring_private *)string;
|
|
+}
|
|
+
|
|
+static inline struct hstring_private *impl_from_HSTRING_HEADER(HSTRING_HEADER *header)
|
|
+{
|
|
+ return (struct hstring_private *)header;
|
|
+}
|
|
+
|
|
+static BOOL alloc_string(UINT32 len, HSTRING *out)
|
|
+{
|
|
+ struct hstring_private *priv;
|
|
+ priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv) + (len + 1) * sizeof(*priv->buffer));
|
|
+ if (!priv)
|
|
+ return FALSE;
|
|
+ priv->buffer = (LPWSTR)(priv + 1);
|
|
+ priv->length = len;
|
|
+ priv->reference = FALSE;
|
|
+ priv->refcount = 1;
|
|
+ priv->buffer[len] = '\0';
|
|
+ *out = (HSTRING)priv;
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+/***********************************************************************
|
|
+ * WindowsCreateString (combase.@)
|
|
+ */
|
|
+HRESULT WINAPI WindowsCreateString(LPCWSTR ptr, UINT32 len,
|
|
+ HSTRING *out)
|
|
+{
|
|
+ struct hstring_private *priv;
|
|
+ if (out == NULL)
|
|
+ return E_INVALIDARG;
|
|
+ if (ptr == NULL && len > 0)
|
|
+ return E_POINTER;
|
|
+ if (len == 0)
|
|
+ {
|
|
+ *out = NULL;
|
|
+ return S_OK;
|
|
+ }
|
|
+ if (!alloc_string(len, out))
|
|
+ return E_OUTOFMEMORY;
|
|
+ priv = impl_from_HSTRING(*out);
|
|
+ memcpy(priv->buffer, ptr, len * sizeof(*priv->buffer));
|
|
+ return S_OK;
|
|
+}
|
|
+
|
|
+/***********************************************************************
|
|
+ * WindowsCreateStringReference (combase.@)
|
|
+ */
|
|
+HRESULT WINAPI WindowsCreateStringReference(LPCWSTR ptr, UINT32 len,
|
|
+ HSTRING_HEADER *header, HSTRING *out)
|
|
+{
|
|
+ struct hstring_private *priv = impl_from_HSTRING_HEADER(header);
|
|
+ if (out == NULL || header == NULL)
|
|
+ return E_INVALIDARG;
|
|
+ if (ptr == NULL && len > 0)
|
|
+ return E_POINTER;
|
|
+ if (ptr[len] != '\0')
|
|
+ return E_INVALIDARG;
|
|
+ if (len == 0)
|
|
+ {
|
|
+ *out = NULL;
|
|
+ return S_OK;
|
|
+ }
|
|
+ priv->buffer = (LPWSTR)ptr;
|
|
+ priv->length = len;
|
|
+ priv->reference = TRUE;
|
|
+ *out = (HSTRING)header;
|
|
+ return S_OK;
|
|
+}
|
|
+
|
|
+/***********************************************************************
|
|
+ * WindowsDeleteString (combase.@)
|
|
+ */
|
|
+HRESULT WINAPI WindowsDeleteString(HSTRING str)
|
|
+{
|
|
+ struct hstring_private *priv = impl_from_HSTRING(str);
|
|
+ if (str == NULL)
|
|
+ return S_OK;
|
|
+ if (priv->reference)
|
|
+ return S_OK;
|
|
+ if (InterlockedDecrement(&priv->refcount) == 0)
|
|
+ HeapFree(GetProcessHeap(), 0, priv);
|
|
+ return S_OK;
|
|
+}
|
|
+
|
|
+/***********************************************************************
|
|
+ * WindowsDuplicateString (combase.@)
|
|
+ */
|
|
+HRESULT WINAPI WindowsDuplicateString(HSTRING str, HSTRING *out)
|
|
+{
|
|
+ struct hstring_private *priv = impl_from_HSTRING(str);
|
|
+ if (out == NULL)
|
|
+ return E_INVALIDARG;
|
|
+ if (str == NULL)
|
|
+ {
|
|
+ *out = NULL;
|
|
+ return S_OK;
|
|
+ }
|
|
+ if (priv->reference)
|
|
+ return WindowsCreateString(priv->buffer, priv->length, out);
|
|
+ InterlockedIncrement(&priv->refcount);
|
|
+ *out = str;
|
|
+ return S_OK;
|
|
+}
|
|
diff --git a/dlls/combase/tests/Makefile.in b/dlls/combase/tests/Makefile.in
|
|
new file mode 100644
|
|
index 0000000..3e7ecab
|
|
--- /dev/null
|
|
+++ b/dlls/combase/tests/Makefile.in
|
|
@@ -0,0 +1,4 @@
|
|
+TESTDLL = combase.dll
|
|
+
|
|
+C_SRCS = \
|
|
+ string.c
|
|
diff --git a/dlls/combase/tests/string.c b/dlls/combase/tests/string.c
|
|
new file mode 100644
|
|
index 0000000..01a63f7
|
|
--- /dev/null
|
|
+++ b/dlls/combase/tests/string.c
|
|
@@ -0,0 +1,128 @@
|
|
+/*
|
|
+ * Unit tests for Windows String functions
|
|
+ *
|
|
+ * Copyright (c) 2014 Martin Storsjo
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
+ */
|
|
+
|
|
+#include <stdarg.h>
|
|
+
|
|
+#include "windef.h"
|
|
+#include "winbase.h"
|
|
+#include "winerror.h"
|
|
+#include "winstring.h"
|
|
+
|
|
+#include "wine/test.h"
|
|
+
|
|
+static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *);
|
|
+static HRESULT (WINAPI *pWindowsCreateStringReference)(LPCWSTR, UINT32, HSTRING_HEADER *, HSTRING *);
|
|
+static HRESULT (WINAPI *pWindowsDeleteString)(HSTRING);
|
|
+static HRESULT (WINAPI *pWindowsDuplicateString)(HSTRING, HSTRING *);
|
|
+
|
|
+#define SET(x) p##x = (void*)GetProcAddress(hmod, #x)
|
|
+
|
|
+static BOOL init_functions(void)
|
|
+{
|
|
+ HMODULE hmod = LoadLibraryA("combase.dll");
|
|
+ if (!hmod)
|
|
+ {
|
|
+ win_skip("Failed to load combase.dll, skipping tests\n");
|
|
+ return FALSE;
|
|
+ }
|
|
+ SET(WindowsCreateString);
|
|
+ SET(WindowsCreateStringReference);
|
|
+ SET(WindowsDeleteString);
|
|
+ SET(WindowsDuplicateString);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+#undef SET
|
|
+
|
|
+
|
|
+static const WCHAR input_string[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0' };
|
|
+static const WCHAR input_empty_string[] = { '\0' };
|
|
+
|
|
+static void test_create_delete(void)
|
|
+{
|
|
+ HSTRING str;
|
|
+ HSTRING_HEADER header;
|
|
+
|
|
+ /* Test normal creation of a string */
|
|
+ ok(pWindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
|
|
+ ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
|
|
+ /* Test error handling in WindowsCreateString */
|
|
+ ok(pWindowsCreateString(input_string, 6, NULL) == E_INVALIDARG, "Incorrect error handling\n");
|
|
+ ok(pWindowsCreateString(NULL, 6, &str) == E_POINTER, "Incorrect error handling\n");
|
|
+
|
|
+ /* Test handling of a NULL string */
|
|
+ ok(pWindowsDeleteString(NULL) == S_OK, "Failed to delete null string\n");
|
|
+
|
|
+ /* Test creation of a string reference */
|
|
+ ok(pWindowsCreateStringReference(input_string, 6, &header, &str) == S_OK, "Failed to create string ref\n");
|
|
+ ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string ref\n");
|
|
+
|
|
+ /* Test error handling in WindowsCreateStringReference */
|
|
+ /* Strings to CreateStringReference must be null terminated with the correct
|
|
+ * length. According to MSDN this should be E_INVALIDARG, but it returns
|
|
+ * 0x80000017 in practice. */
|
|
+ ok(FAILED(pWindowsCreateStringReference(input_string, 5, &header, &str)), "Incorrect error handling\n");
|
|
+ ok(pWindowsCreateStringReference(input_string, 6, NULL, &str) == E_INVALIDARG, "Incorrect error handling\n");
|
|
+ ok(pWindowsCreateStringReference(input_string, 6, &header, NULL) == E_INVALIDARG, "Incorrect error handling\n");
|
|
+ ok(pWindowsCreateStringReference(NULL, 6, &header, &str) == E_POINTER, "Incorrect error handling\n");
|
|
+
|
|
+ /* Test creating a string without a null-termination at the specified length */
|
|
+ ok(pWindowsCreateString(input_string, 3, &str) == S_OK, "Failed to create string\n");
|
|
+ ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
|
|
+
|
|
+ /* Test an empty string */
|
|
+ ok(pWindowsCreateString(input_empty_string, 0, &str) == S_OK, "Failed to create string\n");
|
|
+ ok(str == NULL, "Empty string not a null string\n");
|
|
+ ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
|
|
+
|
|
+ ok(pWindowsCreateStringReference(input_empty_string, 0, &header, &str) == S_OK, "Failed to create string\n");
|
|
+ ok(str == NULL, "Empty string not a null string\n");
|
|
+ ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
|
|
+}
|
|
+
|
|
+static void test_duplicate(void)
|
|
+{
|
|
+ HSTRING str, str2;
|
|
+ HSTRING_HEADER header;
|
|
+ ok(pWindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
|
|
+ ok(pWindowsDuplicateString(str, NULL) == E_INVALIDARG, "Incorrect error handling\n");
|
|
+ ok(pWindowsDuplicateString(str, &str2) == S_OK, "Failed to duplicate string\n");
|
|
+ ok(str == str2, "Duplicated string created new string\n");
|
|
+ ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
|
|
+ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
|
|
+
|
|
+ ok(pWindowsCreateStringReference(input_string, 6, &header, &str) == S_OK, "Failed to create string ref\n");
|
|
+ ok(pWindowsDuplicateString(str, &str2) == S_OK, "Failed to duplicate string\n");
|
|
+ ok(str != str2, "Duplicated string ref didn't create new string\n");
|
|
+ ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
|
|
+ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n");
|
|
+
|
|
+ ok(pWindowsDuplicateString(NULL, &str2) == S_OK, "Failed to duplicate NULL string\n");
|
|
+ ok(str2 == NULL, "Duplicated string created new string\n");
|
|
+ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
|
|
+}
|
|
+
|
|
+START_TEST(string)
|
|
+{
|
|
+ if (!init_functions())
|
|
+ return;
|
|
+ test_create_delete();
|
|
+ test_duplicate();
|
|
+}
|
|
diff --git a/tools/make_specfiles b/tools/make_specfiles
|
|
index 6e2f3d7..794d00c 100755
|
|
--- a/tools/make_specfiles
|
|
+++ b/tools/make_specfiles
|
|
@@ -207,6 +207,7 @@ my @dll_groups =
|
|
[
|
|
"combase",
|
|
"api-ms-win-core-winrt-l1-1-0",
|
|
+ "api-ms-win-core-winrt-string-l1-1-0",
|
|
],
|
|
);
|
|
|
|
--
|
|
2.1.3
|
|
|