Commit 0d490f3a authored by Martin Storsjo's avatar Martin Storsjo Committed by Alexandre Julliard

combase: Implement functions for HSTRING_BUFFER.

parent 998006e4
...@@ -11,14 +11,14 @@ ...@@ -11,14 +11,14 @@
@ stdcall WindowsCreateString(ptr long ptr) combase.WindowsCreateString @ stdcall WindowsCreateString(ptr long ptr) combase.WindowsCreateString
@ stdcall WindowsCreateStringReference(wstr long ptr ptr) combase.WindowsCreateStringReference @ stdcall WindowsCreateStringReference(wstr long ptr ptr) combase.WindowsCreateStringReference
@ stdcall WindowsDeleteString(ptr) combase.WindowsDeleteString @ stdcall WindowsDeleteString(ptr) combase.WindowsDeleteString
@ stub WindowsDeleteStringBuffer @ stdcall WindowsDeleteStringBuffer(ptr) combase.WindowsDeleteStringBuffer
@ stdcall WindowsDuplicateString(ptr ptr) combase.WindowsDuplicateString @ stdcall WindowsDuplicateString(ptr ptr) combase.WindowsDuplicateString
@ stdcall WindowsGetStringLen(ptr) combase.WindowsGetStringLen @ stdcall WindowsGetStringLen(ptr) combase.WindowsGetStringLen
@ stdcall WindowsGetStringRawBuffer(ptr ptr) combase.WindowsGetStringRawBuffer @ stdcall WindowsGetStringRawBuffer(ptr ptr) combase.WindowsGetStringRawBuffer
@ stub WindowsInspectString @ stub WindowsInspectString
@ stdcall WindowsIsStringEmpty(ptr) combase.WindowsIsStringEmpty @ stdcall WindowsIsStringEmpty(ptr) combase.WindowsIsStringEmpty
@ stub WindowsPreallocateStringBuffer @ stdcall WindowsPreallocateStringBuffer(long ptr ptr) combase.WindowsPreallocateStringBuffer
@ stub WindowsPromoteStringBuffer @ stdcall WindowsPromoteStringBuffer(ptr ptr) combase.WindowsPromoteStringBuffer
@ stub WindowsReplaceString @ stub WindowsReplaceString
@ stdcall WindowsStringHasEmbeddedNull(ptr ptr) combase.WindowsStringHasEmbeddedNull @ stdcall WindowsStringHasEmbeddedNull(ptr ptr) combase.WindowsStringHasEmbeddedNull
@ stub WindowsSubstring @ stub WindowsSubstring
......
...@@ -292,14 +292,14 @@ ...@@ -292,14 +292,14 @@
@ stdcall WindowsCreateString(ptr long ptr) @ stdcall WindowsCreateString(ptr long ptr)
@ stdcall WindowsCreateStringReference(wstr long ptr ptr) @ stdcall WindowsCreateStringReference(wstr long ptr ptr)
@ stdcall WindowsDeleteString(ptr) @ stdcall WindowsDeleteString(ptr)
@ stub WindowsDeleteStringBuffer @ stdcall WindowsDeleteStringBuffer(ptr)
@ stdcall WindowsDuplicateString(ptr ptr) @ stdcall WindowsDuplicateString(ptr ptr)
@ stdcall WindowsGetStringLen(ptr) @ stdcall WindowsGetStringLen(ptr)
@ stdcall WindowsGetStringRawBuffer(ptr ptr) @ stdcall WindowsGetStringRawBuffer(ptr ptr)
@ stub WindowsInspectString @ stub WindowsInspectString
@ stdcall WindowsIsStringEmpty(ptr) @ stdcall WindowsIsStringEmpty(ptr)
@ stub WindowsPreallocateStringBuffer @ stdcall WindowsPreallocateStringBuffer(long ptr ptr)
@ stub WindowsPromoteStringBuffer @ stdcall WindowsPromoteStringBuffer(ptr ptr)
@ stub WindowsReplaceString @ stub WindowsReplaceString
@ stdcall WindowsStringHasEmbeddedNull(ptr ptr) @ stdcall WindowsStringHasEmbeddedNull(ptr ptr)
@ stub WindowsSubstring @ stub WindowsSubstring
......
...@@ -47,6 +47,11 @@ static inline struct hstring_private *impl_from_HSTRING_HEADER(HSTRING_HEADER *h ...@@ -47,6 +47,11 @@ static inline struct hstring_private *impl_from_HSTRING_HEADER(HSTRING_HEADER *h
return (struct hstring_private *)header; return (struct hstring_private *)header;
} }
static inline struct hstring_private *impl_from_HSTRING_BUFFER(HSTRING_BUFFER buffer)
{
return (struct hstring_private *)buffer;
}
static BOOL alloc_string(UINT32 len, HSTRING *out) static BOOL alloc_string(UINT32 len, HSTRING *out)
{ {
struct hstring_private *priv; struct hstring_private *priv;
...@@ -146,6 +151,58 @@ HRESULT WINAPI WindowsDuplicateString(HSTRING str, HSTRING *out) ...@@ -146,6 +151,58 @@ HRESULT WINAPI WindowsDuplicateString(HSTRING str, HSTRING *out)
} }
/*********************************************************************** /***********************************************************************
* WindowsPreallocateStringBuffer (combase.@)
*/
HRESULT WINAPI WindowsPreallocateStringBuffer(UINT32 len, WCHAR **outptr,
HSTRING_BUFFER *out)
{
struct hstring_private *priv;
HSTRING str;
if (outptr == NULL || out == NULL)
return E_POINTER;
if (len == 0)
{
*outptr = (LPWSTR)empty;
*out = NULL;
return S_OK;
}
if (!alloc_string(len, &str))
return E_OUTOFMEMORY;
priv = impl_from_HSTRING(str);
*outptr = priv->buffer;
*out = (HSTRING_BUFFER)str;
return S_OK;
}
/***********************************************************************
* WindowsDeleteStringBuffer (combase.@)
*/
HRESULT WINAPI WindowsDeleteStringBuffer(HSTRING_BUFFER buf)
{
return WindowsDeleteString((HSTRING)buf);
}
/***********************************************************************
* WindowsPromoteStringBuffer (combase.@)
*/
HRESULT WINAPI WindowsPromoteStringBuffer(HSTRING_BUFFER buf, HSTRING *out)
{
struct hstring_private *priv = impl_from_HSTRING_BUFFER(buf);
if (out == NULL)
return E_POINTER;
if (buf == NULL)
{
*out = NULL;
return S_OK;
}
if (priv->buffer[priv->length] != 0 || priv->reference || priv->refcount != 1)
return E_INVALIDARG;
*out = (HSTRING)buf;
return S_OK;
}
/***********************************************************************
* WindowsGetStringLen (combase.@) * WindowsGetStringLen (combase.@)
*/ */
UINT32 WINAPI WindowsGetStringLen(HSTRING str) UINT32 WINAPI WindowsGetStringLen(HSTRING str)
......
...@@ -30,10 +30,13 @@ ...@@ -30,10 +30,13 @@
static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *); static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *);
static HRESULT (WINAPI *pWindowsCreateStringReference)(LPCWSTR, UINT32, HSTRING_HEADER *, HSTRING *); static HRESULT (WINAPI *pWindowsCreateStringReference)(LPCWSTR, UINT32, HSTRING_HEADER *, HSTRING *);
static HRESULT (WINAPI *pWindowsDeleteString)(HSTRING); static HRESULT (WINAPI *pWindowsDeleteString)(HSTRING);
static HRESULT (WINAPI *pWindowsDeleteStringBuffer)(HSTRING_BUFFER);
static HRESULT (WINAPI *pWindowsDuplicateString)(HSTRING, HSTRING *); static HRESULT (WINAPI *pWindowsDuplicateString)(HSTRING, HSTRING *);
static UINT32 (WINAPI *pWindowsGetStringLen)(HSTRING); static UINT32 (WINAPI *pWindowsGetStringLen)(HSTRING);
static LPCWSTR (WINAPI *pWindowsGetStringRawBuffer)(HSTRING, UINT32 *); static LPCWSTR (WINAPI *pWindowsGetStringRawBuffer)(HSTRING, UINT32 *);
static BOOL (WINAPI *pWindowsIsStringEmpty)(HSTRING); static BOOL (WINAPI *pWindowsIsStringEmpty)(HSTRING);
static HRESULT (WINAPI *pWindowsPreallocateStringBuffer)(UINT32, WCHAR **, HSTRING_BUFFER *);
static HRESULT (WINAPI *pWindowsPromoteStringBuffer)(HSTRING_BUFFER, HSTRING *);
static HRESULT (WINAPI *pWindowsStringHasEmbeddedNull)(HSTRING, BOOL *); static HRESULT (WINAPI *pWindowsStringHasEmbeddedNull)(HSTRING, BOOL *);
#define SET(x) p##x = (void*)GetProcAddress(hmod, #x) #define SET(x) p##x = (void*)GetProcAddress(hmod, #x)
...@@ -49,10 +52,13 @@ static BOOL init_functions(void) ...@@ -49,10 +52,13 @@ static BOOL init_functions(void)
SET(WindowsCreateString); SET(WindowsCreateString);
SET(WindowsCreateStringReference); SET(WindowsCreateStringReference);
SET(WindowsDeleteString); SET(WindowsDeleteString);
SET(WindowsDeleteStringBuffer);
SET(WindowsDuplicateString); SET(WindowsDuplicateString);
SET(WindowsGetStringLen); SET(WindowsGetStringLen);
SET(WindowsGetStringRawBuffer); SET(WindowsGetStringRawBuffer);
SET(WindowsIsStringEmpty); SET(WindowsIsStringEmpty);
SET(WindowsPreallocateStringBuffer);
SET(WindowsPromoteStringBuffer);
SET(WindowsStringHasEmbeddedNull); SET(WindowsStringHasEmbeddedNull);
return TRUE; return TRUE;
} }
...@@ -181,6 +187,55 @@ static void test_access(void) ...@@ -181,6 +187,55 @@ static void test_access(void)
ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string ref\n"); ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string ref\n");
} }
static void test_string_buffer(void)
{
/* Initialize ptr to NULL to make sure it actually is set in the first
* test below. */
HSTRING_BUFFER buf = NULL;
WCHAR *ptr = NULL;
HSTRING str;
/* Test creation of an empty buffer */
ok(pWindowsPreallocateStringBuffer(0, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
ok(buf == NULL, "Empty string buffer isn't a null string\n");
ok(ptr != NULL, "Empty string didn't return a buffer pointer\n");
ok(pWindowsPromoteStringBuffer(buf, &str) == S_OK, "Failed to promote string buffer\n");
ok(str == NULL, "Empty string isn't a null string\n");
check_string(str, input_empty_string, 0, FALSE);
ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
ok(pWindowsDeleteStringBuffer(NULL) == S_OK, "Failed to delete null string buffer\n");
/* Test creation and deletion of string buffers */
ok(pWindowsPreallocateStringBuffer(6, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
ok(pWindowsDeleteStringBuffer(buf) == S_OK, "Failed to delete string buffer\n");
/* Test creation and promotion of string buffers */
ok(pWindowsPreallocateStringBuffer(6, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
ok(ptr[6] == '\0', "Preallocated string buffer didn't have null termination\n");
memcpy(ptr, input_string, 6 * sizeof(*input_string));
ok(pWindowsPromoteStringBuffer(buf, NULL) == E_POINTER, "Incorrect error handling\n");
ok(pWindowsPromoteStringBuffer(buf, &str) == S_OK, "Failed to promote string buffer\n");
check_string(str, input_string, 6, FALSE);
ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
/* Test error handling in preallocation */
ok(pWindowsPreallocateStringBuffer(6, NULL, &buf) == E_POINTER, "Incorrect error handling\n");
ok(pWindowsPreallocateStringBuffer(6, &ptr, NULL) == E_POINTER, "Incorrect error handling\n");
ok(pWindowsPreallocateStringBuffer(6, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
ptr[6] = 'a'; /* Overwrite the buffer's null termination, promotion should fail */
ok(pWindowsPromoteStringBuffer(buf, &str) == E_INVALIDARG, "Incorrect error handling\n");
ok(pWindowsDeleteStringBuffer(buf) == S_OK, "Failed to delete string buffer\n");
/* Test strings with trailing null chars */
ok(pWindowsPreallocateStringBuffer(7, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
memcpy(ptr, input_string, 7 * sizeof(*input_string));
ok(pWindowsPromoteStringBuffer(buf, &str) == S_OK, "Failed to promote string buffer\n");
check_string(str, input_string, 7, TRUE);
ok(pWindowsDeleteString(str) == S_OK, "Failed to delete string\n");
}
START_TEST(string) START_TEST(string)
{ {
if (!init_functions()) if (!init_functions())
...@@ -188,4 +243,5 @@ START_TEST(string) ...@@ -188,4 +243,5 @@ START_TEST(string)
test_create_delete(); test_create_delete();
test_duplicate(); test_duplicate();
test_access(); test_access();
test_string_buffer();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment