https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4d8c4b145dcf2d9308053…
commit 4d8c4b145dcf2d93080532d369d09344ff9359d9
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Mon Feb 4 13:00:58 2019 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Mon Feb 4 13:00:58 2019 +0100
[SHELL32_WINETEST] Sync with Wine Staging 4.0. CORE-15682
---
modules/rostests/winetests/shell32/autocomplete.c | 453 ++++++-
modules/rostests/winetests/shell32/brsfolder.c | 10 +-
modules/rostests/winetests/shell32/progman_dde.c | 2 +-
modules/rostests/winetests/shell32/shelldispatch.c | 42 +-
modules/rostests/winetests/shell32/shelllink.c | 51 +-
modules/rostests/winetests/shell32/shellole.c | 21 +-
modules/rostests/winetests/shell32/shellpath.c | 1292 ++++++++++----------
modules/rostests/winetests/shell32/shlexec.c | 181 +--
modules/rostests/winetests/shell32/shlfileop.c | 227 ++--
modules/rostests/winetests/shell32/shlfolder.c | 259 ++--
modules/rostests/winetests/shell32/shlview.c | 9 +-
modules/rostests/winetests/shell32/string.c | 8 +-
12 files changed, 1542 insertions(+), 1013 deletions(-)
diff --git a/modules/rostests/winetests/shell32/autocomplete.c
b/modules/rostests/winetests/shell32/autocomplete.c
index 859734ce59..4ef124c9d2 100644
--- a/modules/rostests/winetests/shell32/autocomplete.c
+++ b/modules/rostests/winetests/shell32/autocomplete.c
@@ -25,8 +25,8 @@
#include "windows.h"
#include "shobjidl.h"
#include "shlguid.h"
-#include "initguid.h"
#include "shldisp.h"
+#include "shlobj.h"
#include "wine/heap.h"
#include "wine/test.h"
@@ -141,7 +141,7 @@ if (0)
static IAutoComplete *test_init(void)
{
HRESULT r;
- IAutoComplete *ac;
+ IAutoComplete *ac, *ac2;
IUnknown *acSource;
LONG_PTR user_data;
@@ -176,6 +176,15 @@ static IAutoComplete *test_init(void)
user_data = GetWindowLongPtrA(hEdit, GWLP_USERDATA);
ok(user_data == 0, "Expected the edit control user data to be zero\n");
+ /* bind a different object to the same edit control */
+ r = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IAutoComplete, (LPVOID*)&ac2);
+ ok(r == S_OK, "no IID_IAutoComplete (0x%08x)\n", r);
+
+ r = IAutoComplete_Init(ac2, hEdit, acSource, NULL, NULL);
+ ok(r == S_OK, "Init returned 0x%08x\n", r);
+ IAutoComplete_Release(ac2);
+
IUnknown_Release(acSource);
return ac;
@@ -227,13 +236,47 @@ static void createMainWnd(void)
CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0);
}
+static WNDPROC HijackerWndProc_prev;
+static const WCHAR HijackerWndProc_txt[] =
{'H','i','j','a','c','k','e','d',0};
+static LRESULT CALLBACK HijackerWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
lParam)
+{
+ switch(msg) {
+ case WM_GETTEXT:
+ {
+ size_t len = min(wParam, ARRAY_SIZE(HijackerWndProc_txt));
+ memcpy((void*)lParam, HijackerWndProc_txt, len * sizeof(WCHAR));
+ return len;
+ }
+ case WM_GETTEXTLENGTH:
+ return ARRAY_SIZE(HijackerWndProc_txt) - 1;
+ }
+ return CallWindowProcW(HijackerWndProc_prev, hWnd, msg, wParam, lParam);
+}
+
+static LRESULT CALLBACK HijackerWndProc2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
lParam)
+{
+ switch(msg) {
+ case EM_SETSEL:
+ lParam = wParam;
+ break;
+ case WM_SETTEXT:
+ lParam = (LPARAM)HijackerWndProc_txt;
+ break;
+ }
+ return CallWindowProcW(HijackerWndProc_prev, hWnd, msg, wParam, lParam);
+}
+
struct string_enumerator
{
IEnumString IEnumString_iface;
+ IACList IACList_iface;
LONG ref;
WCHAR **data;
int data_len;
int cur;
+ UINT num_resets;
+ UINT num_expand;
+ WCHAR last_expand[32];
};
static struct string_enumerator *impl_from_IEnumString(IEnumString *iface)
@@ -243,15 +286,19 @@ static struct string_enumerator *impl_from_IEnumString(IEnumString
*iface)
static HRESULT WINAPI string_enumerator_QueryInterface(IEnumString *iface, REFIID riid,
void **ppv)
{
+ struct string_enumerator *this = impl_from_IEnumString(iface);
if (IsEqualGUID(riid, &IID_IEnumString) || IsEqualGUID(riid, &IID_IUnknown))
+ *ppv = &this->IEnumString_iface;
+ else if (IsEqualGUID(riid, &IID_IACList))
+ *ppv = &this->IACList_iface;
+ else
{
- IUnknown_AddRef(iface);
- *ppv = iface;
- return S_OK;
+ *ppv = NULL;
+ return E_NOINTERFACE;
}
- *ppv = NULL;
- return E_NOINTERFACE;
+ IUnknown_AddRef(&this->IEnumString_iface);
+ return S_OK;
}
static ULONG WINAPI string_enumerator_AddRef(IEnumString *iface)
@@ -303,6 +350,7 @@ static HRESULT WINAPI string_enumerator_Reset(IEnumString *iface)
struct string_enumerator *this = impl_from_IEnumString(iface);
this->cur = 0;
+ this->num_resets++;
return S_OK;
}
@@ -322,7 +370,7 @@ static HRESULT WINAPI string_enumerator_Clone(IEnumString *iface,
IEnumString **
return E_NOTIMPL;
}
-static IEnumStringVtbl string_enumerator_vtlb =
+static IEnumStringVtbl string_enumerator_vtbl =
{
string_enumerator_QueryInterface,
string_enumerator_AddRef,
@@ -333,12 +381,54 @@ static IEnumStringVtbl string_enumerator_vtlb =
string_enumerator_Clone
};
+static struct string_enumerator *impl_from_IACList(IACList *iface)
+{
+ return CONTAINING_RECORD(iface, struct string_enumerator, IACList_iface);
+}
+
+static HRESULT WINAPI aclist_QueryInterface(IACList *iface, REFIID riid, void **ppv)
+{
+ return
string_enumerator_QueryInterface(&impl_from_IACList(iface)->IEnumString_iface,
riid, ppv);
+}
+
+static ULONG WINAPI aclist_AddRef(IACList *iface)
+{
+ return
string_enumerator_AddRef(&impl_from_IACList(iface)->IEnumString_iface);
+}
+
+static ULONG WINAPI aclist_Release(IACList *iface)
+{
+ return
string_enumerator_Release(&impl_from_IACList(iface)->IEnumString_iface);
+}
+
+static HRESULT WINAPI aclist_Expand(IACList *iface, const WCHAR *expand)
+{
+ struct string_enumerator *this = impl_from_IACList(iface);
+
+ /* see what we get called with and how many times,
+ don't actually do any expansion of the strings */
+ memcpy(this->last_expand, expand, min((lstrlenW(expand) + 1)*sizeof(WCHAR),
sizeof(this->last_expand)));
+ this->last_expand[ARRAY_SIZE(this->last_expand) - 1] = '\0';
+ this->num_expand++;
+
+ return S_OK;
+}
+
+static IACListVtbl aclist_vtbl =
+{
+ aclist_QueryInterface,
+ aclist_AddRef,
+ aclist_Release,
+ aclist_Expand
+};
+
static HRESULT string_enumerator_create(void **ppv, WCHAR **suggestions, int count)
{
struct string_enumerator *object;
object = heap_alloc_zero(sizeof(*object));
- object->IEnumString_iface.lpVtbl = &string_enumerator_vtlb;
+ object->IEnumString_iface.lpVtbl = &string_enumerator_vtbl;
+ object->IACList_iface.lpVtbl = &aclist_vtbl;
object->ref = 1;
object->data = suggestions;
object->data_len = count;
@@ -349,18 +439,257 @@ static HRESULT string_enumerator_create(void **ppv, WCHAR
**suggestions, int cou
return S_OK;
}
+static void dispatch_messages(void)
+{
+ MSG msg;
+ Sleep(33);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageA(&msg);
+ }
+}
+
+#define check_dropdown(acdropdown, hwnd_edit, list, list_num) check_dropdown_(__FILE__,
__LINE__, acdropdown, hwnd_edit, list, list_num)
+static void check_dropdown_(const char *file, UINT line, IAutoCompleteDropDown
*acdropdown, HWND hwnd_edit, WCHAR **list, UINT list_num)
+{
+ UINT i;
+ DWORD flags = 0;
+ LPWSTR str;
+ HRESULT hr;
+
+ hr = IAutoCompleteDropDown_GetDropDownStatus(acdropdown, &flags, &str);
+ ok_(file, line)(hr == S_OK, "IAutoCompleteDropDown_GetDropDownStatus failed:
%x\n", hr);
+ if (hr != S_OK) return;
+ if (list_num) ok_(file, line)(flags & ACDD_VISIBLE, "AutoComplete DropDown
not visible\n");
+ else
+ {
+ ok_(file, line)(!(flags & ACDD_VISIBLE), "AutoComplete DropDown
visible\n");
+ return;
+ }
+ ok_(file, line)(str == NULL, "Expected (null), got %s\n",
wine_dbgstr_w(str));
+ if (str)
+ {
+ CoTaskMemFree(str);
+ return;
+ }
+
+ for (i = 0; i <= list_num; i++)
+ {
+ flags = 0;
+ SendMessageW(hwnd_edit, WM_KEYDOWN, VK_DOWN, 0);
+ SendMessageW(hwnd_edit, WM_KEYUP, VK_DOWN, 0xc0000000);
+ hr = IAutoCompleteDropDown_GetDropDownStatus(acdropdown, &flags, &str);
+ ok_(file, line)(hr == S_OK, "IAutoCompleteDropDown_GetDropDownStatus failed:
%x\n", hr);
+ ok_(file, line)(flags & ACDD_VISIBLE, "AutoComplete DropDown not
visible\n");
+ if (hr == S_OK)
+ {
+ if (i < list_num)
+ ok_(file, line)(str && !lstrcmpW(list[i], str), "Expected
%s, got %s\n",
+ wine_dbgstr_w(list[i]), wine_dbgstr_w(str));
+ else
+ ok_(file, line)(str == NULL, "Expected (null), got %s\n",
wine_dbgstr_w(str));
+ }
+ CoTaskMemFree(str);
+ }
+}
+
+static void test_aclist_expand(HWND hwnd_edit, void *enumerator)
+{
+ struct string_enumerator *obj = (struct string_enumerator*)enumerator;
+ static WCHAR str1[] = {'t','e','s','t',0};
+ static WCHAR str1a[] =
{'t','e','s','t','\\',0};
+ static WCHAR str2[] =
{'t','e','s','t','\\','f','o','o','\\','b','a','r','\\','b','a',0};
+ static WCHAR str2a[] =
{'t','e','s','t','\\','f','o','o','\\','b','a','r','\\',0};
+ static WCHAR str2b[] =
{'t','e','s','t','\\','f','o','o','\\','b','a','r','\\','b','a','z','_','b','b','q','\\',0};
+ obj->num_resets = 0;
+
+ ok(obj->num_expand == 0, "Expected 0 expansions, got %u\n",
obj->num_expand);
+ SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str1);
+ SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(str1) - 1, ARRAY_SIZE(str1) - 1);
+ SendMessageW(hwnd_edit, WM_CHAR, '\\', 1);
+ dispatch_messages();
+ ok(obj->num_expand == 1, "Expected 1 expansion, got %u\n",
obj->num_expand);
+ ok(lstrcmpW(obj->last_expand, str1a) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str1a), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n",
obj->num_resets);
+ SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str2);
+ SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(str2) - 1, ARRAY_SIZE(str2) - 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'z', 1);
+ dispatch_messages();
+ ok(obj->num_expand == 2, "Expected 2 expansions, got %u\n",
obj->num_expand);
+ ok(lstrcmpW(obj->last_expand, str2a) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str2a), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 2, "Expected 2 resets, got %u\n",
obj->num_resets);
+ SetFocus(hwnd_edit);
+ SendMessageW(hwnd_edit, WM_CHAR, '_', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'b', 1);
+ SetFocus(0);
+ SetFocus(hwnd_edit);
+ SendMessageW(hwnd_edit, WM_CHAR, 'b', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'q', 1);
+ dispatch_messages();
+ ok(obj->num_expand == 2, "Expected 2 expansions, got %u\n",
obj->num_expand);
+ ok(obj->num_resets == 2, "Expected 2 resets, got %u\n",
obj->num_resets);
+ SendMessageW(hwnd_edit, WM_CHAR, '\\', 1);
+ dispatch_messages();
+ ok(obj->num_expand == 3, "Expected 3 expansions, got %u\n",
obj->num_expand);
+ ok(lstrcmpW(obj->last_expand, str2b) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str2b), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 3, "Expected 3 resets, got %u\n",
obj->num_resets);
+ SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(str1a) - 1, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'x', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'y', 1);
+ dispatch_messages();
+ ok(obj->num_expand == 4, "Expected 4 expansions, got %u\n",
obj->num_expand);
+ ok(lstrcmpW(obj->last_expand, str1a) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str1a), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 4, "Expected 4 resets, got %u\n",
obj->num_resets);
+ SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(str1) - 1, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'x', 1);
+ dispatch_messages();
+ ok(obj->num_expand == 4, "Expected 4 expansions, got %u\n",
obj->num_expand);
+ ok(obj->num_resets == 5, "Expected 5 resets, got %u\n",
obj->num_resets);
+}
+
+static void test_prefix_filtering(HWND hwnd_edit)
+{
+ static WCHAR htt[] = {'h','t','t',0};
+ static WCHAR www[] = {'w','w','w','.',0};
+ static WCHAR str0[] =
{'w','w','w','.','a','x',0};
+ static WCHAR str1[] =
{'h','t','t','p','s',':','/','/','w','w','w','.','a','c',0};
+ static WCHAR str2[] = {'a','a',0};
+ static WCHAR str3[] = {'a','b',0};
+ static WCHAR str4[] =
{'h','t','t','p',':','/','/','a','0',0};
+ static WCHAR str5[] =
{'h','t','t','p','s',':','/','/','h','t','a',0};
+ static WCHAR str6[] = {'h','f','o','o',0};
+ static WCHAR str7[] =
{'h','t','t','p',':','/','/','w','w','w','.','a','d','d',0};
+ static WCHAR str8[] =
{'w','w','w','.','w','w','w','.','?',0};
+ static WCHAR str9[] =
{'h','t','t','p',':','/','/','a','b','c','.','a','a','.','c','o','m',0};
+ static WCHAR str10[]=
{'f','t','p',':','/','/','a','b','c',0};
+ static WCHAR str11[]=
{'f','i','l','e',':','/','/','a','a',0};
+ static WCHAR str12[]=
{'f','t','p',':','/','/','w','w','w','.','a','a',0};
+ static WCHAR *suggestions[] = { str0, str1, str2, str3, str4, str5, str6, str7, str8,
str9, str10, str11, str12 };
+ static WCHAR *sorted1[] = { str4, str2, str3, str9, str1, str7, str0 };
+ static WCHAR *sorted2[] = { str3, str9 };
+ static WCHAR *sorted3[] = { str1, str7, str0 };
+ static WCHAR *sorted4[] = { str6, str5 };
+ static WCHAR *sorted5[] = { str5 };
+ static WCHAR *sorted6[] = { str4, str9 };
+ static WCHAR *sorted7[] = { str11, str10, str12 };
+ IUnknown *enumerator;
+ IAutoComplete2 *autocomplete;
+ IAutoCompleteDropDown *acdropdown;
+ WCHAR buffer[20];
+ HRESULT hr;
+
+ hr = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
&IID_IAutoComplete2, (void**)&autocomplete);
+ ok(hr == S_OK, "CoCreateInstance failed: %x\n", hr);
+
+ hr = IAutoComplete2_QueryInterface(autocomplete, &IID_IAutoCompleteDropDown,
(LPVOID*)&acdropdown);
+ ok(hr == S_OK, "No IAutoCompleteDropDown interface: %x\n", hr);
+
+ string_enumerator_create((void**)&enumerator, suggestions,
ARRAY_SIZE(suggestions));
+
+ hr = IAutoComplete2_SetOptions(autocomplete, ACO_FILTERPREFIXES | ACO_AUTOSUGGEST |
ACO_AUTOAPPEND);
+ ok(hr == S_OK, "IAutoComplete2_SetOptions failed: %x\n", hr);
+ hr = IAutoComplete2_Init(autocomplete, hwnd_edit, enumerator, NULL, NULL);
+ ok(hr == S_OK, "IAutoComplete_Init failed: %x\n", hr);
+
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str4 + 7, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str4 + 7), wine_dbgstr_w(buffer));
+ check_dropdown(acdropdown, hwnd_edit, sorted1, ARRAY_SIZE(sorted1));
+
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'b', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str3, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str3), wine_dbgstr_w(buffer));
+ check_dropdown(acdropdown, hwnd_edit, sorted2, ARRAY_SIZE(sorted2));
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'b', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'c', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str9 + 7, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str9 + 7), wine_dbgstr_w(buffer));
+
+ SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)www);
+ SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(www) - 1, ARRAY_SIZE(www) - 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str1 + 8, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str1 + 8), wine_dbgstr_w(buffer));
+ check_dropdown(acdropdown, hwnd_edit, sorted3, ARRAY_SIZE(sorted3));
+ SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)www);
+ SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(www) - 1, ARRAY_SIZE(www) - 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'w', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str8, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str8), wine_dbgstr_w(buffer));
+
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'h', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str6, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str6), wine_dbgstr_w(buffer));
+ check_dropdown(acdropdown, hwnd_edit, sorted4, ARRAY_SIZE(sorted4));
+ SendMessageW(hwnd_edit, WM_CHAR, 't', 1);
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str5 + 8, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str5 + 8), wine_dbgstr_w(buffer));
+ check_dropdown(acdropdown, hwnd_edit, sorted5, ARRAY_SIZE(sorted5));
+ SendMessageW(hwnd_edit, WM_CHAR, 't', 1);
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(htt, buffer) == 0, "Expected %s, got %s\n", wine_dbgstr_w(htt),
wine_dbgstr_w(buffer));
+ check_dropdown(acdropdown, hwnd_edit, NULL, 0);
+ SendMessageW(hwnd_edit, WM_CHAR, 'p', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, ':', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, '/', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, '/', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str4, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str4), wine_dbgstr_w(buffer));
+ check_dropdown(acdropdown, hwnd_edit, sorted6, ARRAY_SIZE(sorted6));
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, 2);
+ SendMessageW(hwnd_edit, WM_CHAR, 'H', 1);
+ dispatch_messages();
+ check_dropdown(acdropdown, hwnd_edit, NULL, 0);
+ SendMessageW(hwnd_edit, WM_CHAR, 't', 1);
+ dispatch_messages();
+ check_dropdown(acdropdown, hwnd_edit, sorted6, ARRAY_SIZE(sorted6));
+
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'F', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ check_dropdown(acdropdown, hwnd_edit, sorted7, ARRAY_SIZE(sorted7));
+ SendMessageW(hwnd_edit, WM_CHAR, 'i', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'L', 1);
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ check_dropdown(acdropdown, hwnd_edit, sorted7, 1);
+
+ IAutoCompleteDropDown_Release(acdropdown);
+ IAutoComplete2_Release(autocomplete);
+ IUnknown_Release(enumerator);
+}
+
static void test_custom_source(void)
{
static WCHAR str_alpha[] =
{'t','e','s','t','1',0};
static WCHAR str_alpha2[] =
{'t','e','s','t','2',0};
static WCHAR str_beta[] = {'a','u','t','o','
','c','o','m','p','l','e','t','e',0};
+ static WCHAR str_au[] = {'a','u',0};
+ static WCHAR str_aut[] = {'a','u','t',0};
static WCHAR *suggestions[] = { str_alpha, str_alpha2, str_beta };
+ struct string_enumerator *obj;
IUnknown *enumerator;
IAutoComplete2 *autocomplete;
+ IAutoCompleteDropDown *acdropdown;
HWND hwnd_edit;
+ DWORD flags = 0;
WCHAR buffer[20];
HRESULT hr;
- MSG msg;
ShowWindow(hMainWnd, SW_SHOW);
@@ -369,24 +698,100 @@ static void test_custom_source(void)
hr = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
&IID_IAutoComplete2, (void**)&autocomplete);
ok(hr == S_OK, "CoCreateInstance failed: %x\n", hr);
- string_enumerator_create((void**)&enumerator, suggestions, sizeof(suggestions) /
sizeof(*suggestions));
+ hr = IAutoComplete2_QueryInterface(autocomplete, &IID_IAutoCompleteDropDown,
(LPVOID*)&acdropdown);
+ ok(hr == S_OK, "No IAutoCompleteDropDown interface: %x\n", hr);
+
+ string_enumerator_create((void**)&enumerator, suggestions,
ARRAY_SIZE(suggestions));
+ obj = (struct string_enumerator*)enumerator;
hr = IAutoComplete2_SetOptions(autocomplete, ACO_AUTOSUGGEST | ACO_AUTOAPPEND);
ok(hr == S_OK, "IAutoComplete2_SetOptions failed: %x\n", hr);
+ hr = IAutoCompleteDropDown_ResetEnumerator(acdropdown);
+ ok(hr == S_OK, "IAutoCompleteDropDown_ResetEnumerator failed: %x\n", hr);
hr = IAutoComplete2_Init(autocomplete, hwnd_edit, enumerator, NULL, NULL);
ok(hr == S_OK, "IAutoComplete_Init failed: %x\n", hr);
+ SetFocus(hwnd_edit);
SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
- /* Send a keyup message since wine doesn't handle WM_CHAR yet */
- SendMessageW(hwnd_edit, WM_KEYUP, 'u', 1);
- Sleep(100);
- while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessageA(&msg);
- }
- SendMessageW(hwnd_edit, WM_GETTEXT, sizeof(buffer) / sizeof(*buffer),
(LPARAM)buffer);
+ SendMessageW(hwnd_edit, WM_CHAR, 'u', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str_beta, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str_beta), wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n",
obj->num_resets);
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, '\b', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(buffer[0] == '\0', "Expected empty string, got %s\n",
wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n",
obj->num_resets);
+ hr = IAutoCompleteDropDown_ResetEnumerator(acdropdown);
+ ok(hr == S_OK, "IAutoCompleteDropDown_ResetEnumerator failed: %x\n", hr);
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n",
obj->num_resets);
+ obj->num_resets = 0;
+
+ /* hijack the window procedure */
+ HijackerWndProc_prev = (WNDPROC)SetWindowLongPtrW(hwnd_edit, GWLP_WNDPROC,
(LONG_PTR)HijackerWndProc);
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(HijackerWndProc_txt, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(HijackerWndProc_txt), wine_dbgstr_w(buffer));
+
+ SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'u', 1);
+ SetWindowLongPtrW(hwnd_edit, GWLP_WNDPROC, (LONG_PTR)HijackerWndProc_prev);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str_au, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str_au), wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n",
obj->num_resets);
+ SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
+ SendMessageW(hwnd_edit, WM_CHAR, '\b', 1);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(buffer[0] == '\0', "Expected empty string, got %s\n",
wine_dbgstr_w(buffer));
+ hr = IAutoCompleteDropDown_ResetEnumerator(acdropdown);
+ ok(hr == S_OK, "IAutoCompleteDropDown_ResetEnumerator failed: %x\n", hr);
+
+ HijackerWndProc_prev = (WNDPROC)SetWindowLongPtrW(hwnd_edit, GWLP_WNDPROC,
(LONG_PTR)HijackerWndProc2);
+ SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
+ SendMessageW(hwnd_edit, WM_CHAR, 'u', 1);
+ SetWindowLongPtrW(hwnd_edit, GWLP_WNDPROC, (LONG_PTR)HijackerWndProc_prev);
+ dispatch_messages();
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
ok(lstrcmpW(str_beta, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str_beta), wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 2, "Expected 2 resets, got %u\n",
obj->num_resets);
+ /* end of hijacks */
+
+ hr = IAutoCompleteDropDown_GetDropDownStatus(acdropdown, &flags, NULL);
+ ok(hr == S_OK, "IAutoCompleteDropDown_GetDropDownStatus failed: %x\n",
hr);
+ ok(flags & ACDD_VISIBLE, "AutoComplete DropDown should be visible\n");
+ SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str_au);
+ dispatch_messages();
+ hr = IAutoCompleteDropDown_GetDropDownStatus(acdropdown, &flags, NULL);
+ ok(hr == S_OK, "IAutoCompleteDropDown_GetDropDownStatus failed: %x\n",
hr);
+ ok(!(flags & ACDD_VISIBLE), "AutoComplete DropDown should have been
hidden\n");
+ SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str_aut);
+ dispatch_messages();
+ hr = IAutoCompleteDropDown_GetDropDownStatus(acdropdown, &flags, NULL);
+ ok(hr == S_OK, "IAutoCompleteDropDown_GetDropDownStatus failed: %x\n",
hr);
+ ok(!(flags & ACDD_VISIBLE), "AutoComplete DropDown should be
hidden\n");
+ SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(lstrcmpW(str_aut, buffer) == 0, "Expected %s, got %s\n",
wine_dbgstr_w(str_aut), wine_dbgstr_w(buffer));
+
+ test_aclist_expand(hwnd_edit, enumerator);
+ obj->num_resets = 0;
+
+ hr = IAutoCompleteDropDown_ResetEnumerator(acdropdown);
+ ok(hr == S_OK, "IAutoCompleteDropDown_ResetEnumerator failed: %x\n", hr);
+ SendMessageW(hwnd_edit, WM_CHAR, 'x', 1);
+ dispatch_messages();
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n",
obj->num_resets);
+ SendMessageW(hwnd_edit, WM_CHAR, 'x', 1);
+ dispatch_messages();
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n",
obj->num_resets);
+
+ IAutoCompleteDropDown_Release(acdropdown);
+ IAutoComplete2_Release(autocomplete);
+ IUnknown_Release(enumerator);
+
+ test_prefix_filtering(hwnd_edit);
ShowWindow(hMainWnd, SW_HIDE);
DestroyWindow(hwnd_edit);
@@ -397,6 +802,8 @@ START_TEST(autocomplete)
HRESULT r;
MSG msg;
IAutoComplete* ac;
+ RECT win_rect;
+ POINT orig_pos;
r = CoInitialize(NULL);
ok(r == S_OK, "CoInitialize failed (0x%08x). Tests aborted.\n", r);
@@ -407,6 +814,11 @@ START_TEST(autocomplete)
ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n");
if (!hMainWnd) return;
+ /* Move the cursor away from the dropdown listbox */
+ GetWindowRect(hMainWnd, &win_rect);
+ GetCursorPos(&orig_pos);
+ SetCursorPos(win_rect.left, win_rect.top);
+
test_invalid_init();
ac = test_init();
if (!ac)
@@ -424,6 +836,7 @@ START_TEST(autocomplete)
IAutoComplete_Release(ac);
cleanup:
+ SetCursorPos(orig_pos.x, orig_pos.y);
DestroyWindow(hEdit);
DestroyWindow(hMainWnd);
diff --git a/modules/rostests/winetests/shell32/brsfolder.c
b/modules/rostests/winetests/shell32/brsfolder.c
index bf29d1169f..0888cfa468 100644
--- a/modules/rostests/winetests/shell32/brsfolder.c
+++ b/modules/rostests/winetests/shell32/brsfolder.c
@@ -44,8 +44,8 @@ static int get_number_of_folders(LPCSTR path)
WIN32_FIND_DATAA find_data;
HANDLE find_handle;
- lstrcpynA(path_search_string, path, MAX_PATH);
- strncat(path_search_string, "*", 1);
+ lstrcpynA(path_search_string, path, MAX_PATH - 1);
+ strcat(path_search_string, "*");
find_handle = FindFirstFileA(path_search_string, &find_data);
if (find_handle == INVALID_HANDLE_VALUE)
@@ -186,9 +186,9 @@ static void test_click_make_new_folder_button(void)
{
skip("GetCurrentDirectoryA failed %u\n", GetLastError());
}
- strncat(test_folder_path, "\\", 1);
- strncat(test_folder_path, title, MAX_PATH-1);
- strncat(test_folder_path, "\\", 1);
+ strcat(test_folder_path, "\\");
+ strcat(test_folder_path, title);
+ strcat(test_folder_path, "\\");
/* Avoid conflicts by creating a test folder. */
if (!CreateDirectoryA(title, NULL))
diff --git a/modules/rostests/winetests/shell32/progman_dde.c
b/modules/rostests/winetests/shell32/progman_dde.c
index 62ed413ad0..2d19404a76 100644
--- a/modules/rostests/winetests/shell32/progman_dde.c
+++ b/modules/rostests/winetests/shell32/progman_dde.c
@@ -166,7 +166,7 @@ static BOOL check_window_exists(const char *name)
for (i = 0; i < 20; i++)
{
- Sleep(100);
+ Sleep(100 * i);
if ((window = FindWindowA("ExplorerWClass", title)) ||
(window = FindWindowA("CabinetWClass", title)))
{
diff --git a/modules/rostests/winetests/shell32/shelldispatch.c
b/modules/rostests/winetests/shell32/shelldispatch.c
index cc00757840..e9948ae630 100644
--- a/modules/rostests/winetests/shell32/shelldispatch.c
+++ b/modules/rostests/winetests/shell32/shelldispatch.c
@@ -161,7 +161,7 @@ static void test_namespace(void)
ok(folder == NULL, "expected NULL, got %p\n", folder);
/* test valid folder ids */
- for (i = 0; i < sizeof(special_folders)/sizeof(special_folders[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(special_folders); i++)
{
V_VT(&var) = VT_I4;
V_I4(&var) = special_folders[i];
@@ -382,7 +382,7 @@ static void test_items(void)
FolderItems3 *items3 = NULL;
FolderItem *item = (FolderItem*)0xdeadbeef, *item2;
FolderItemVerbs *verbs = (FolderItemVerbs*)0xdeadbeef;
- VARIANT var, int_index, str_index, str_index2;
+ VARIANT var, var2, int_index, str_index, str_index2;
IDispatch *disp, *disp2;
LONG count = -1;
IUnknown *unk;
@@ -474,7 +474,7 @@ static void test_items(void)
ok(!item, "item is not null\n");
/* create test files */
- for (i = 0; i < sizeof(file_defs)/sizeof(file_defs[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(file_defs); i++)
{
switch (file_defs[i].type)
{
@@ -541,15 +541,16 @@ static void test_items(void)
count = -1;
r = FolderItems_get_Count(items, &count);
ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
- ok(count == sizeof(file_defs)/sizeof(file_defs[0]),
- "expected %d files, got %d\n",
(LONG)(sizeof(file_defs)/sizeof(file_defs[0])), count);
+ ok(count == ARRAY_SIZE(file_defs), "got %d files\n", count);
+ /* VT_EMPTY */
V_VT(&var) = VT_EMPTY;
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, var, &item);
ok(r == E_NOTIMPL, "expected E_NOTIMPL, got %08x\n", r);
ok(!item, "item is not null\n");
+ /* VT_I2 */
V_VT(&var) = VT_I2;
V_I2(&var) = 0;
@@ -572,6 +573,20 @@ static void test_items(void)
FolderItem_Release(item);
+ /* VT_VARIANT | VT_BYREF */
+ V_VT(&var2) = VT_I2;
+ V_I2(&var2) = 0;
+
+ V_VT(&var) = VT_BYREF | VT_VARIANT;
+ V_VARIANTREF(&var) = &var2;
+
+ item = NULL;
+ r = FolderItems_Item(items, var, &item);
+ ok(r == S_OK, "FolderItems::Item failed: %08x\n", r);
+ ok(!!item, "item is null\n");
+ FolderItem_Release(item);
+
+ /* VT_I4 */
V_VT(&var) = VT_I4;
V_I4(&var) = 0;
item = NULL;
@@ -606,7 +621,7 @@ static void test_items(void)
V_VT(&int_index) = VT_I4;
/* test the folder item corresponding to each file */
- for (i = 0; i < sizeof(file_defs)/sizeof(file_defs[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(file_defs); i++)
{
VARIANT_BOOL b;
BSTR name;
@@ -730,7 +745,7 @@ static void test_items(void)
}
/* test that there are only as many folder items as there were files */
- V_I4(&int_index) = sizeof(file_defs)/sizeof(file_defs[0]);
+ V_I4(&int_index) = ARRAY_SIZE(file_defs);
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, int_index, &item);
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
@@ -976,7 +991,7 @@ if (0) /* crashes on pre-vista */ {
IShellView_Release(view);
/* Try with some other folder, that's not a desktop */
- GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW);
+ GetTempPathW(ARRAY_SIZE(pathW), pathW);
hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, pathW, NULL, &pidl,
NULL);
ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -1015,10 +1030,9 @@ static void test_ShellWindows(void)
if (hr != S_OK)
return;
-if (0) /* NULL out argument - currently crashes on Wine */ {
hr = IShellWindows_Register(shellwindows, NULL, 0, SWC_EXPLORER, NULL);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "got 0x%08x\n", hr);
-}
+
hr = IShellWindows_Register(shellwindows, NULL, 0, SWC_EXPLORER, &cookie);
todo_wine
ok(hr == E_POINTER, "got 0x%08x\n", hr);
@@ -1096,9 +1110,6 @@ todo_wine {
IUnknown *unk;
ok(disp != NULL, "got %p\n", disp);
-
- if (disp == NULL) goto skip_disp_tests;
-
ok(ret != HandleToUlong(hwnd), "got %d\n", ret);
/* IDispatch-related tests */
@@ -1176,7 +1187,6 @@ if (hr == S_OK) {
IServiceProvider_Release(sp);
IDispatch_Release(disp);
}
-skip_disp_tests:
disp = (void*)0xdeadbeef;
ret = 0xdead;
@@ -1219,7 +1229,7 @@ static void test_ParseName(void)
&IID_IShellDispatch, (void**)&sd);
ok(hr == S_OK, "got 0x%08x\n", hr);
- GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW);
+ GetTempPathW(ARRAY_SIZE(pathW), pathW);
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = SysAllocString(pathW);
hr = IShellDispatch_NameSpace(sd, v, &folder);
@@ -1288,7 +1298,7 @@ static void test_Verbs(void)
&IID_IShellDispatch, (void**)&sd);
ok(hr == S_OK, "got 0x%08x\n", hr);
- GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW);
+ GetTempPathW(ARRAY_SIZE(pathW), pathW);
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = SysAllocString(pathW);
hr = IShellDispatch_NameSpace(sd, v, &folder);
diff --git a/modules/rostests/winetests/shell32/shelllink.c
b/modules/rostests/winetests/shell32/shelllink.c
index 444fdcc417..3a2068cae5 100644
--- a/modules/rostests/winetests/shell32/shelllink.c
+++ b/modules/rostests/winetests/shell32/shelllink.c
@@ -977,6 +977,7 @@ static void test_shdefextracticon(void)
static void test_GetIconLocation(void)
{
+ IShellLinkW *slW;
IShellLinkA *sl;
const char *str;
char buffer[INFOTIPSIZE], mypath[MAX_PATH];
@@ -1030,8 +1031,34 @@ static void test_GetIconLocation(void)
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
ok(lstrcmpiA(buffer,str) == 0, "GetIconLocation returned '%s'\n",
buffer);
- ok(i == 0xbabecafe, "GetIconLocation returned %d'\n", i);
+ ok(i == 0xbabecafe, "GetIconLocation returned %#x.\n", i);
+ r = IShellLinkA_SetIconLocation(sl, NULL, 0xcafefe);
+ ok(r == S_OK, "SetIconLocation failed (0x%08x)\n", r);
+
+ i = 0xdeadbeef;
+ r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
+ ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
+ ok(!*buffer, "GetIconLocation returned '%s'\n", buffer);
+ ok(i == 0xcafefe, "GetIconLocation returned %#x.\n", i);
+
+ r = IShellLinkA_QueryInterface(sl, &IID_IShellLinkW, (void **)&slW);
+ ok(SUCCEEDED(r), "Failed to get IShellLinkW, hr %#x.\n", r);
+
+ str = "c:\\nonexistent\\file";
+ r = IShellLinkA_SetIconLocation(sl, str, 0xbabecafe);
+ ok(r == S_OK, "SetIconLocation failed (0x%08x)\n", r);
+
+ r = IShellLinkA_SetIconLocation(sl, NULL, 0xcafefe);
+ ok(r == S_OK, "SetIconLocation failed (0x%08x)\n", r);
+
+ i = 0xdeadbeef;
+ r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
+ ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
+ ok(!*buffer, "GetIconLocation returned '%s'\n", buffer);
+ ok(i == 0xcafefe, "GetIconLocation returned %#x.\n", i);
+
+ IShellLinkW_Release(slW);
IShellLinkA_Release(sl);
}
@@ -1116,6 +1143,21 @@ static void test_SHGetStockIconInfo(void)
/* there is a NULL check for the struct */
hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, NULL);
ok(hr == E_INVALIDARG, "NULL: got 0x%x\n", hr);
+
+ for(i = 0; i < 140; i++) /* highest on wvista, i > 140 gives E_INVALIDARG,
win7 can go higher */
+ {
+ memset(buffer, 0, sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO);
+ hr = pSHGetStockIconInfo(i, SHGSI_ICON | SHGSI_SMALLICON, sii);
+ ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
+ ok(sii->hIcon != NULL, "got NULL, expected an icon handle\n");
+ ok(sii->iIcon != 0, "got unexpected 0 for SIID %d\n", i); /* howto
find out exact sii->iIcon value??? */
+ ok(sii->iSysImageIndex == -1, "got %d (expected -1)\n",
sii->iSysImageIndex);
+ ok(DestroyIcon(sii->hIcon), "DestroyIcon failed\n");
+ if (winetest_debug > 1)
+ trace("%3d: got iSysImageIndex %3d, iIcon %3d and %s\n", i,
sii->iSysImageIndex,
+ sii->iIcon, wine_dbgstr_w(sii->szPath));
+ }
}
static void test_SHExtractIcons(void)
@@ -1291,7 +1333,7 @@ if (0)
ok(hicon == NULL, "Got icon %p\n", hicon);
/* Create a temporary non-executable file */
- GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW);
+ GetTempPathW(ARRAY_SIZE(pathW), pathW);
lstrcatW(pathW, nameW);
file = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "Failed to create a test file\n");
@@ -1421,9 +1463,8 @@ static void test_SHGetImageList(void)
for (i = 0; i <= SHIL_LAST; i++)
{
hr = SHGetImageList( i, &IID_IImageList, (void **)&list );
- ok( hr == S_OK ||
- broken( i == SHIL_JUMBO && hr == E_INVALIDARG ), /* XP and 2003 */
- "%d: got %08x\n", i, hr );
+ ok( hr == S_OK || broken( i == SHIL_JUMBO && hr == E_INVALIDARG ), /* XP
and 2003 */
+ "%d: got %08x\n", i, hr );
if (FAILED(hr)) continue;
IImageList_GetIconSize( list, &width, &height );
switch (i)
diff --git a/modules/rostests/winetests/shell32/shellole.c
b/modules/rostests/winetests/shell32/shellole.c
index e79d666699..27964afcd3 100644
--- a/modules/rostests/winetests/shell32/shellole.c
+++ b/modules/rostests/winetests/shell32/shellole.c
@@ -864,8 +864,15 @@ static void test_DragQueryFile(void)
static void test_SHCreateSessionKey(void)
{
+ static const WCHAR session_format[] = {
+
'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+
'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+
'E','x','p','l','o','r','e','r','\\','S','e','s','s','i','o','n','I','n','f','o','\\','%','u',0};
HKEY hkey, hkey2;
HRESULT hr;
+ DWORD session;
+ WCHAR sessionW[ARRAY_SIZE(session_format) + 16];
+ LONG ret;
if (!pSHCreateSessionKey)
{
@@ -878,8 +885,8 @@ static void test_SHCreateSessionKey(void)
hkey = (HKEY)0xdeadbeef;
hr = pSHCreateSessionKey(0, &hkey);
- todo_wine ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr);
- todo_wine ok(hkey == NULL, "got %p\n", hkey);
+ ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr);
+ ok(hkey == NULL, "got %p\n", hkey);
hr = pSHCreateSessionKey(KEY_READ, &hkey);
ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -890,6 +897,16 @@ static void test_SHCreateSessionKey(void)
RegCloseKey(hkey);
RegCloseKey(hkey2);
+
+ /* check the registry */
+ ProcessIdToSessionId( GetCurrentProcessId(), &session);
+ if (session)
+ {
+ wsprintfW(sessionW, session_format, session);
+ ret = RegOpenKeyW(HKEY_CURRENT_USER, sessionW, &hkey);
+ ok(!ret, "key not found\n");
+ RegCloseKey(hkey);
+ }
}
static void test_dragdrophelper(void)
diff --git a/modules/rostests/winetests/shell32/shellpath.c
b/modules/rostests/winetests/shell32/shellpath.c
index f6674313f8..38b56f01d3 100644
--- a/modules/rostests/winetests/shell32/shellpath.c
+++ b/modules/rostests/winetests/shell32/shellpath.c
@@ -43,10 +43,6 @@
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) ( sizeof(x) / sizeof((x)[0]) )
-#endif
-
/* from pidl.h, not included here: */
#ifndef PT_CPL /* Guess, Win7 uses this for CSIDL_CONTROLS */
#define PT_CPL 0x01 /* no path */
@@ -118,7 +114,7 @@ static const BYTE printersType[] = { PT_YAGUID, PT_SHELLEXT, 0x71 };
static const BYTE ieSpecialType[] = { PT_IESPECIAL2 };
static const BYTE shellExtType[] = { PT_SHELLEXT };
static const BYTE workgroupType[] = { PT_WORKGRP };
-#define DECLARE_TYPE(x, y) { x, sizeof(y) / sizeof(y[0]), y }
+#define DECLARE_TYPE(x, y) { x, ARRAY_SIZE(y), y }
static const struct shellExpectedValues requiredShellValues[] = {
DECLARE_TYPE(CSIDL_BITBUCKET, guidType),
DECLARE_TYPE(CSIDL_CONTROLS, controlPanelType),
@@ -308,626 +304,41 @@ static const char *getFolderName(int folder)
}
}
-static void test_parameters(void)
-{
- LPITEMIDLIST pidl = NULL;
- char path[MAX_PATH];
- HRESULT hr;
-
- if (pSHGetFolderLocation)
- {
- /* check a bogus CSIDL: */
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, 0xeeee, NULL, 0, &pidl);
- ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
- if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
-
- /* check a bogus user token: */
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, (HANDLE)2, 0, &pidl);
- ok(hr == E_FAIL || hr == E_HANDLE, "got 0x%08x, expected E_FAIL or
E_HANDLE\n", hr);
- if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
-
- /* a NULL pidl pointer crashes, so don't test it */
- }
-
- if (pSHGetSpecialFolderLocation)
- {
- if (0)
- /* crashes */
- SHGetSpecialFolderLocation(NULL, 0, NULL);
-
- hr = pSHGetSpecialFolderLocation(NULL, 0xeeee, &pidl);
- ok(hr == E_INVALIDARG, "got returned 0x%08x\n", hr);
- }
-
- if (pSHGetFolderPathA)
- {
- /* expect 2's a bogus handle, especially since we didn't open it */
- hr = pSHGetFolderPathA(NULL, CSIDL_DESKTOP, (HANDLE)2, SHGFP_TYPE_DEFAULT,
path);
- ok(hr == E_FAIL || hr == E_HANDLE || /* Vista and 2k8 */
- broken(hr == S_OK), /* W2k and Me */ "got 0x%08x, expected
E_FAIL\n", hr);
-
- hr = pSHGetFolderPathA(NULL, 0xeeee, NULL, SHGFP_TYPE_DEFAULT, path);
- ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
- }
-
- if (pSHGetSpecialFolderPathA)
- {
- BOOL ret;
-
- if (0)
- pSHGetSpecialFolderPathA(NULL, NULL, CSIDL_BITBUCKET, FALSE);
-
- /* odd but true: calling with a NULL path still succeeds if it's a real
- * dir (on some windows platform). on winME it generates exception.
- */
- ret = pSHGetSpecialFolderPathA(NULL, path, CSIDL_PROGRAMS, FALSE);
- ok(ret, "got %d\n", ret);
-
- ret = pSHGetSpecialFolderPathA(NULL, path, 0xeeee, FALSE);
- ok(!ret, "got %d\n", ret);
- }
-}
-
-/* Returns the folder's PIDL type, or 0xff if one can't be found. */
-static BYTE testSHGetFolderLocation(int folder)
-{
- LPITEMIDLIST pidl;
- HRESULT hr;
- BYTE ret = 0xff;
-
- /* treat absence of function as success */
- if (!pSHGetFolderLocation) return TRUE;
-
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
- if (hr == S_OK)
- {
- if (pidl)
- {
- LPITEMIDLIST pidlLast = pILFindLastID(pidl);
-
- ok(pidlLast != NULL, "%s: ILFindLastID failed\n",
- getFolderName(folder));
- if (pidlLast)
- ret = pidlLast->mkid.abID[0];
- IMalloc_Free(pMalloc, pidl);
- }
- }
- return ret;
-}
-
-/* Returns the folder's PIDL type, or 0xff if one can't be found. */
-static BYTE testSHGetSpecialFolderLocation(int folder)
-{
- LPITEMIDLIST pidl;
- HRESULT hr;
- BYTE ret = 0xff;
-
- /* treat absence of function as success */
- if (!pSHGetSpecialFolderLocation) return TRUE;
-
- pidl = NULL;
- hr = pSHGetSpecialFolderLocation(NULL, folder, &pidl);
- if (hr == S_OK)
- {
- if (pidl)
- {
- LPITEMIDLIST pidlLast = pILFindLastID(pidl);
-
- ok(pidlLast != NULL,
- "%s: ILFindLastID failed\n", getFolderName(folder));
- if (pidlLast)
- ret = pidlLast->mkid.abID[0];
- IMalloc_Free(pMalloc, pidl);
- }
- }
- return ret;
-}
-
-static void test_SHGetFolderPath(BOOL optional, int folder)
-{
- char path[MAX_PATH];
- HRESULT hr;
-
- if (!pSHGetFolderPathA) return;
-
- hr = pSHGetFolderPathA(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path);
- ok(hr == S_OK || optional,
- "SHGetFolderPathA(NULL, %s, NULL, SHGFP_TYPE_CURRENT, path) failed:
0x%08x\n", getFolderName(folder), hr);
-}
-
-static void test_SHGetSpecialFolderPath(BOOL optional, int folder)
-{
- char path[MAX_PATH];
- BOOL ret;
-
- if (!pSHGetSpecialFolderPathA) return;
-
- ret = pSHGetSpecialFolderPathA(NULL, path, folder, FALSE);
- if (ret && winetest_interactive)
- printf("%s: %s\n", getFolderName(folder), path);
- ok(ret || optional,
- "SHGetSpecialFolderPathA(NULL, path, %s, FALSE) failed\n",
- getFolderName(folder));
-}
-
-static void test_ShellValues(const struct shellExpectedValues testEntries[],
- int numEntries, BOOL optional)
-{
- int i;
-
- for (i = 0; i < numEntries; i++)
- {
- BYTE type;
- int j;
- BOOL foundTypeMatch = FALSE;
-
- if (pSHGetFolderLocation)
- {
- type = testSHGetFolderLocation(testEntries[i].folder);
- for (j = 0; !foundTypeMatch && j < testEntries[i].numTypes; j++)
- if (testEntries[i].types[j] == type)
- foundTypeMatch = TRUE;
- ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
- "%s has unexpected type %d (0x%02x)\n",
- getFolderName(testEntries[i].folder), type, type);
- }
- type = testSHGetSpecialFolderLocation(testEntries[i].folder);
- for (j = 0, foundTypeMatch = FALSE; !foundTypeMatch &&
- j < testEntries[i].numTypes; j++)
- if (testEntries[i].types[j] == type)
- foundTypeMatch = TRUE;
- ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
- "%s has unexpected type %d (0x%02x)\n",
- getFolderName(testEntries[i].folder), type, type);
- switch (type)
- {
- case PT_FOLDER:
- case PT_DRIVE:
- case PT_DRIVE2:
- case PT_IESPECIAL2:
- test_SHGetFolderPath(optional, testEntries[i].folder);
- test_SHGetSpecialFolderPath(optional, testEntries[i].folder);
- break;
- }
- }
-}
-
-/* Attempts to verify that the folder path corresponding to the folder CSIDL
- * value has the same value as the environment variable with name envVar.
- * Doesn't mind if SHGetSpecialFolderPath fails for folder or if envVar isn't
- * set in this environment; different OS and shell version behave differently.
- * However, if both are present, fails if envVar's value is not the same
- * (byte-for-byte) as what SHGetSpecialFolderPath returns.
- */
-static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
-{
- char path[MAX_PATH];
-
- if (!pSHGetSpecialFolderPathA) return;
+/* Standard CSIDL values (and their flags) uses only two less-significant bytes */
+#define NO_CSIDL 0x10000
+#define WINE_ATTRIBUTES_OPTIONAL 0x20000
+#define KNOWN_FOLDER(id, csidl, name, category, parent1, parent2, relative_path,
parsing_name, attributes, definitionFlags) \
+ { &id, # id, csidl, # csidl, name, category, {&parent1, &parent2},
relative_path, parsing_name, attributes, definitionFlags, __LINE__ }
- if (pSHGetSpecialFolderPathA(NULL, path, folder, FALSE))
- {
- char *envVal = getenv(envVar);
+/* non-published known folders test */
+static const GUID _FOLDERID_CryptoKeys = {0xB88F4DAA, 0xE7BD, 0x49A9, {0xB7,
0x4D, 0x02, 0x88, 0x5A, 0x5D, 0xC7, 0x65} };
+static const GUID _FOLDERID_DpapiKeys = {0x10C07CD0, 0xEF91, 0x4567, {0xB8,
0x50, 0x44, 0x8B, 0x77, 0xCB, 0x37, 0xF9} };
+static const GUID _FOLDERID_SystemCertificates = {0x54EED2E0, 0xE7CA, 0x4FDB, {0x91,
0x48, 0x0F, 0x42, 0x47, 0x29, 0x1C, 0xFA} };
+static const GUID _FOLDERID_CredentialManager = {0x915221FB, 0x9EFE, 0x4BDA, {0x8F,
0xD7, 0xF7, 0x8D, 0xCA, 0x77, 0x4F, 0x87} };
- ok(!envVal || !lstrcmpiA(envVal, path),
- "%%%s%% does not match SHGetSpecialFolderPath:\n"
- "%%%s%% is %s\nSHGetSpecialFolderPath returns %s\n",
- envVar, envVar, envVal, path);
- }
-}
+struct knownFolderDef {
+ const KNOWNFOLDERID *folderId;
+ const char *sFolderId;
+ const int csidl;
+ const char *sCsidl;
+ const char *sName;
+ const KF_CATEGORY category;
+ const KNOWNFOLDERID *fidParents[2];
+ const char *sRelativePath;
+ const char *sParsingName;
+ const DWORD attributes;
+ const KF_DEFINITION_FLAGS definitionFlags;
+ const int line;
+};
-/* Attempts to match the GUID returned by SHGetFolderLocation for folder with
- * GUID. Assumes the type of the returned PIDL is in fact a GUID, but doesn't
- * fail if it isn't--that check should already have been done.
- * Fails if the returned PIDL is a GUID whose value does not match guid.
- */
-static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
-{
- LPITEMIDLIST pidl;
- HRESULT hr;
-
- if (!pSHGetFolderLocation) return;
- if (!guid) return;
-
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
- if (hr == S_OK)
- {
- LPITEMIDLIST pidlLast = pILFindLastID(pidl);
-
- if (pidlLast && (pidlLast->mkid.abID[0] == PT_SHELLEXT ||
- pidlLast->mkid.abID[0] == PT_GUID))
- {
- GUID *shellGuid = (GUID *)(pidlLast->mkid.abID + 2);
-
- if (!guid_alt)
- ok(IsEqualIID(shellGuid, guid),
- "%s: got GUID %s, expected %s\n", getFolderName(folder),
- wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid));
- else
- ok(IsEqualIID(shellGuid, guid) ||
- IsEqualIID(shellGuid, guid_alt),
- "%s: got GUID %s, expected %s or %s\n", getFolderName(folder),
- wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid),
wine_dbgstr_guid(guid_alt));
- }
- IMalloc_Free(pMalloc, pidl);
- }
-}
-
-/* Checks the PIDL type of all the known values. */
-static void test_PidlTypes(void)
-{
- /* Desktop */
- test_SHGetFolderPath(FALSE, CSIDL_DESKTOP);
- test_SHGetSpecialFolderPath(FALSE, CSIDL_DESKTOP);
-
- test_ShellValues(requiredShellValues, ARRAY_SIZE(requiredShellValues), FALSE);
- test_ShellValues(optionalShellValues, ARRAY_SIZE(optionalShellValues), TRUE);
-}
-
-/* FIXME: Should be in shobjidl.idl */
-DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73,
0x67, 0xFC, 0x96, 0xEF, 0x3C);
-DEFINE_GUID(_CLSID_Documents, 0xA8CDFF1C, 0x4878, 0x43be, 0xB5, 0xFD, 0xF8, 0x09, 0x1C,
0x1C, 0x60, 0xD0);
-
-/* Verifies various shell virtual folders have the correct well-known GUIDs. */
-static void test_GUIDs(void)
-{
- matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin, NULL);
- matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel, NULL);
- matchGUID(CSIDL_DRIVES, &CLSID_MyComputer, NULL);
- matchGUID(CSIDL_INTERNET, &CLSID_Internet, NULL);
- matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces, &CLSID_NetworkExplorerFolder);
/* Vista and higher */
- matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, &_CLSID_Documents /* win8 */);
- matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments, NULL);
- matchGUID(CSIDL_PRINTERS, &CLSID_Printers, NULL);
-}
-
-/* Verifies various shell paths match the environment variables to which they
- * correspond.
- */
-static void test_EnvVars(void)
-{
- matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES, "ProgramFiles");
- matchSpecialFolderPathToEnv(CSIDL_APPDATA, "APPDATA");
- matchSpecialFolderPathToEnv(CSIDL_PROFILE, "USERPROFILE");
- matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "SystemRoot");
- matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "windir");
- matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES_COMMON,
"CommonProgramFiles");
- /* this is only set on Wine, but can't hurt to verify it: */
- matchSpecialFolderPathToEnv(CSIDL_SYSTEM, "winsysdir");
-}
-
-/* Loosely based on PathRemoveBackslashA from dlls/shlwapi/path.c */
-static BOOL myPathIsRootA(LPCSTR lpszPath)
-{
- if (lpszPath && *lpszPath &&
- lpszPath[1] == ':' && lpszPath[2] == '\\' &&
lpszPath[3] == '\0')
- return TRUE; /* X:\ */
- return FALSE;
-}
-static LPSTR myPathRemoveBackslashA( LPSTR lpszPath )
-{
- LPSTR szTemp = NULL;
-
- if(lpszPath)
- {
- szTemp = CharPrevA(lpszPath, lpszPath + strlen(lpszPath));
- if (!myPathIsRootA(lpszPath) && *szTemp == '\\')
- *szTemp = '\0';
- }
- return szTemp;
-}
-
-/* Verifies the shell path for CSIDL_WINDOWS matches the return from
- * GetWindowsDirectory. If SHGetSpecialFolderPath fails, no harm, no foul--not
- * every shell32 version supports CSIDL_WINDOWS.
- */
-static void testWinDir(void)
-{
- char windowsShellPath[MAX_PATH], windowsDir[MAX_PATH] = { 0 };
-
- if (!pSHGetSpecialFolderPathA) return;
-
- if (pSHGetSpecialFolderPathA(NULL, windowsShellPath, CSIDL_WINDOWS, FALSE))
- {
- myPathRemoveBackslashA(windowsShellPath);
- GetWindowsDirectoryA(windowsDir, sizeof(windowsDir));
- myPathRemoveBackslashA(windowsDir);
- ok(!lstrcmpiA(windowsDir, windowsShellPath),
- "GetWindowsDirectory returns %s SHGetSpecialFolderPath returns %s\n",
- windowsDir, windowsShellPath);
- }
-}
-
-/* Verifies the shell path for CSIDL_SYSTEM matches the return from
- * GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
- * no foul--not every shell32 version supports CSIDL_SYSTEM.
- */
-static void testSystemDir(void)
-{
- char systemShellPath[MAX_PATH], systemDir[MAX_PATH], systemDirx86[MAX_PATH];
-
- if (!pSHGetSpecialFolderPathA) return;
-
- GetSystemDirectoryA(systemDir, sizeof(systemDir));
- myPathRemoveBackslashA(systemDir);
- if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEM, FALSE))
- {
- myPathRemoveBackslashA(systemShellPath);
- ok(!lstrcmpiA(systemDir, systemShellPath),
- "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
- systemDir, systemShellPath);
- }
-
- if (!pGetSystemWow64DirectoryA || !pGetSystemWow64DirectoryA(systemDirx86,
sizeof(systemDirx86)))
- GetSystemDirectoryA(systemDirx86, sizeof(systemDirx86));
- myPathRemoveBackslashA(systemDirx86);
- if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
- {
- myPathRemoveBackslashA(systemShellPath);
- ok(!lstrcmpiA(systemDirx86, systemShellPath) || broken(!lstrcmpiA(systemDir,
systemShellPath)),
- "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
- systemDir, systemShellPath);
- }
-}
-
-/* Globals used by subprocesses */
-static int myARGC;
-static char **myARGV;
-static char base[MAX_PATH];
-static char selfname[MAX_PATH];
-
-static BOOL init(void)
-{
- myARGC = winetest_get_mainargs(&myARGV);
- if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE;
- strcpy(selfname, myARGV[0]);
- return TRUE;
-}
-
-static void doChild(const char *arg)
-{
- char path[MAX_PATH];
- HRESULT hr;
-
- if (arg[0] == '1')
- {
- LPITEMIDLIST pidl;
- char *p;
-
- /* test what happens when CSIDL_FAVORITES is set to a nonexistent directory */
-
- /* test some failure cases first: */
- hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path);
- ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
- "SHGetFolderPath returned 0x%08x, expected 0x80070002\n", hr);
-
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0, &pidl);
- ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
- "SHGetFolderLocation returned 0x%08x\n", hr);
- if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
-
- ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
- "SHGetSpecialFolderPath succeeded, expected failure\n");
-
- pidl = NULL;
- hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
- ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
- "SHGetFolderLocation returned 0x%08x\n", hr);
-
- if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
-
- /* now test success: */
- hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
- SHGFP_TYPE_CURRENT, path);
- ok (hr == S_OK, "got 0x%08x\n", hr);
- if (hr == S_OK)
- {
- BOOL ret;
-
- trace("CSIDL_FAVORITES was changed to %s\n", path);
- ret = CreateDirectoryA(path, NULL);
- ok(!ret, "expected failure with ERROR_ALREADY_EXISTS\n");
- if (!ret)
- ok(GetLastError() == ERROR_ALREADY_EXISTS,
- "got %d, expected ERROR_ALREADY_EXISTS\n", GetLastError());
-
- p = path + strlen(path);
- strcpy(p, "\\desktop.ini");
- DeleteFileA(path);
- *p = 0;
- SetFileAttributesA( path, FILE_ATTRIBUTE_NORMAL );
- ret = RemoveDirectoryA(path);
- ok( ret, "failed to remove %s error %u\n", path, GetLastError() );
- }
- }
- else if (arg[0] == '2')
- {
- /* make sure SHGetFolderPath still succeeds when the
- original value of CSIDL_FAVORITES is restored. */
- hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
- SHGFP_TYPE_CURRENT, path);
- ok(hr == S_OK, "SHGetFolderPath failed: 0x%08x\n", hr);
- }
-}
-
-/* Tests the return values from the various shell functions both with and
- * without the use of the CSIDL_FLAG_CREATE flag. This flag only appeared in
- * version 5 of the shell, so don't test unless it's at least version 5.
- * The test reads a value from the registry, modifies it, calls
- * SHGetFolderPath once with the CSIDL_FLAG_CREATE flag, and immediately
- * afterward without it. Then it restores the registry and deletes the folder
- * that was created.
- * One oddity with respect to restoration: shell32 caches somehow, so it needs
- * to be reloaded in order to see the correct (restored) value.
- * Some APIs unrelated to the ones under test may fail, but I expect they're
- * covered by other unit tests; I just print out something about failure to
- * help trace what's going on.
- */
-static void test_NonExistentPath(void)
-{
- static const char userShellFolders[] =
- "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell
Folders";
- char originalPath[MAX_PATH], modifiedPath[MAX_PATH];
- HKEY key;
-
- if (!pSHGetFolderPathA) return;
- if (!pSHGetFolderLocation) return;
- if (!pSHGetSpecialFolderPathA) return;
- if (!pSHGetSpecialFolderLocation) return;
- if (!pSHFileOperationA) return;
- if (shellVersion.dwMajorVersion < 5) return;
-
- if (!RegOpenKeyExA(HKEY_CURRENT_USER, userShellFolders, 0, KEY_ALL_ACCESS,
- &key))
- {
- DWORD len, type;
-
- len = sizeof(originalPath);
- if (!RegQueryValueExA(key, "Favorites", NULL, &type,
- (LPBYTE)&originalPath, &len))
- {
- size_t len = strlen(originalPath);
-
- memcpy(modifiedPath, originalPath, len);
- modifiedPath[len++] = '2';
- modifiedPath[len++] = '\0';
- trace("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
- if (!RegSetValueExA(key, "Favorites", 0, type,
- (LPBYTE)modifiedPath, len))
- {
- char buffer[MAX_PATH+20];
- STARTUPINFOA startup;
- PROCESS_INFORMATION info;
-
- sprintf(buffer, "%s tests/shellpath.c 1", selfname);
- memset(&startup, 0, sizeof(startup));
- startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = SW_SHOWNORMAL;
- CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
- &startup, &info);
- winetest_wait_child_process( info.hProcess );
-
- /* restore original values: */
- trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);
- RegSetValueExA(key, "Favorites", 0, type, (LPBYTE)
originalPath,
- strlen(originalPath) + 1);
- RegFlushKey(key);
-
- sprintf(buffer, "%s tests/shellpath.c 2", selfname);
- memset(&startup, 0, sizeof(startup));
- startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = SW_SHOWNORMAL;
- CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
- &startup, &info);
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
- "child process termination\n");
- }
- }
- else skip("RegQueryValueExA(key, Favorites, ...) failed\n");
- if (key)
- RegCloseKey(key);
- }
- else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n",
userShellFolders);
-}
-
-static void test_SHGetFolderPathEx(void)
-{
- HRESULT hr;
- WCHAR buffer[MAX_PATH], *path;
- DWORD len;
-
- if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx)
- {
- win_skip("SHGetKnownFolderPath or SHGetFolderPathEx not available\n");
- return;
- }
-
-if (0) { /* crashes */
- hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, NULL);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-}
- /* non-existent folder id */
- path = (void *)0xdeadbeef;
- hr = pSHGetKnownFolderPath(&IID_IOleObject, 0, NULL, &path);
- ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
- ok(path == NULL, "got %p\n", path);
-
- path = NULL;
- hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL,
&path);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
- ok(path != NULL, "expected path != NULL\n");
- CoTaskMemFree(path);
-
- path = NULL;
- hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
- ok(path != NULL, "expected path != NULL\n");
-
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
- ok(!lstrcmpiW(path, buffer), "expected equal paths\n");
- len = lstrlenW(buffer);
- CoTaskMemFree(path);
-
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-
-if (0) { /* crashes */
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-
- hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-}
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len);
- ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got
0x%08x\n", hr);
-
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
-}
-
-/* Standard CSIDL values (and their flags) uses only two less-significant bytes */
-#define NO_CSIDL 0x10000
-#define WINE_ATTRIBUTES_OPTIONAL 0x20000
-#define KNOWN_FOLDER(id, csidl, name, category, parent1, parent2, relative_path,
parsing_name, attributes, definitionFlags) \
- { &id, # id, csidl, # csidl, name, category, {&parent1, &parent2},
relative_path, parsing_name, attributes, definitionFlags, __LINE__ }
-
-/* non-published known folders test */
-static const GUID _FOLDERID_CryptoKeys = {0xB88F4DAA, 0xE7BD, 0x49A9, {0xB7,
0x4D, 0x02, 0x88, 0x5A, 0x5D, 0xC7, 0x65} };
-static const GUID _FOLDERID_DpapiKeys = {0x10C07CD0, 0xEF91, 0x4567, {0xB8,
0x50, 0x44, 0x8B, 0x77, 0xCB, 0x37, 0xF9} };
-static const GUID _FOLDERID_SystemCertificates = {0x54EED2E0, 0xE7CA, 0x4FDB, {0x91,
0x48, 0x0F, 0x42, 0x47, 0x29, 0x1C, 0xFA} };
-static const GUID _FOLDERID_CredentialManager = {0x915221FB, 0x9EFE, 0x4BDA, {0x8F,
0xD7, 0xF7, 0x8D, 0xCA, 0x77, 0x4F, 0x87} };
-
-struct knownFolderDef {
- const KNOWNFOLDERID *folderId;
- const char *sFolderId;
- const int csidl;
- const char *sCsidl;
- const char *sName;
- const KF_CATEGORY category;
- const KNOWNFOLDERID *fidParents[2];
- const char *sRelativePath;
- const char *sParsingName;
- const DWORD attributes;
- const KF_DEFINITION_FLAGS definitionFlags;
- const int line;
-};
-
-/* Note: content of parsing name may vary between Windows versions.
- * As a base, values from 6.0 (Vista) were used. Some entries may contain
- * alternative values. In that case, Windows version where the value was
- * found is noted.
- *
- * The list of values for parsing name was encoded as a number of null-
- * terminated strings placed one by one (separated by null byte only).
- * End of list is marked by two consecutive null bytes.
+/* Note: content of parsing name may vary between Windows versions.
+ * As a base, values from 6.0 (Vista) were used. Some entries may contain
+ * alternative values. In that case, Windows version where the value was
+ * found is noted.
+ *
+ * The list of values for parsing name was encoded as a number of null-
+ * terminated strings placed one by one (separated by null byte only).
+ * End of list is marked by two consecutive null bytes.
*/
static const struct knownFolderDef known_folders[] = {
KNOWN_FOLDER(FOLDERID_AddNewPrograms,
@@ -1895,10 +1306,630 @@ static const struct knownFolderDef known_folders[] = {
NULL,
0,
0),
- { 0 }
};
#undef KNOWN_FOLDER
-BOOL known_folder_found[ARRAY_SIZE(known_folders)-1];
+BOOL known_folder_found[ARRAY_SIZE(known_folders)];
+
+static void test_parameters(void)
+{
+ LPITEMIDLIST pidl = NULL;
+ char path[MAX_PATH];
+ HRESULT hr;
+
+ if (pSHGetFolderLocation)
+ {
+ /* check a bogus CSIDL: */
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, 0xeeee, NULL, 0, &pidl);
+ ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
+ if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
+
+ /* check a bogus user token: */
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, (HANDLE)2, 0, &pidl);
+ ok(hr == E_FAIL || hr == E_HANDLE, "got 0x%08x, expected E_FAIL or
E_HANDLE\n", hr);
+ if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
+
+ /* a NULL pidl pointer crashes, so don't test it */
+ }
+
+ if (pSHGetSpecialFolderLocation)
+ {
+ if (0)
+ /* crashes */
+ SHGetSpecialFolderLocation(NULL, 0, NULL);
+
+ hr = pSHGetSpecialFolderLocation(NULL, 0xeeee, &pidl);
+ ok(hr == E_INVALIDARG, "got returned 0x%08x\n", hr);
+ }
+
+ if (pSHGetFolderPathA)
+ {
+ /* expect 2's a bogus handle, especially since we didn't open it */
+ hr = pSHGetFolderPathA(NULL, CSIDL_DESKTOP, (HANDLE)2, SHGFP_TYPE_DEFAULT,
path);
+ ok(hr == E_FAIL || hr == E_HANDLE || /* Vista and 2k8 */
+ broken(hr == S_OK), /* W2k and Me */ "got 0x%08x, expected
E_FAIL\n", hr);
+
+ hr = pSHGetFolderPathA(NULL, 0xeeee, NULL, SHGFP_TYPE_DEFAULT, path);
+ ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
+ }
+
+ if (pSHGetSpecialFolderPathA)
+ {
+ BOOL ret;
+
+ if (0)
+ pSHGetSpecialFolderPathA(NULL, NULL, CSIDL_BITBUCKET, FALSE);
+
+ /* odd but true: calling with a NULL path still succeeds if it's a real
+ * dir (on some windows platform). on winME it generates exception.
+ */
+ ret = pSHGetSpecialFolderPathA(NULL, path, CSIDL_PROGRAMS, FALSE);
+ ok(ret, "got %d\n", ret);
+
+ ret = pSHGetSpecialFolderPathA(NULL, path, 0xeeee, FALSE);
+ ok(!ret, "got %d\n", ret);
+ }
+}
+
+/* Returns the folder's PIDL type, or 0xff if one can't be found. */
+static BYTE testSHGetFolderLocation(int folder)
+{
+ LPITEMIDLIST pidl;
+ HRESULT hr;
+ BYTE ret = 0xff;
+
+ /* treat absence of function as success */
+ if (!pSHGetFolderLocation) return TRUE;
+
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
+ if (hr == S_OK)
+ {
+ if (pidl)
+ {
+ LPITEMIDLIST pidlLast = pILFindLastID(pidl);
+
+ ok(pidlLast != NULL, "%s: ILFindLastID failed\n",
+ getFolderName(folder));
+ if (pidlLast)
+ ret = pidlLast->mkid.abID[0];
+ IMalloc_Free(pMalloc, pidl);
+ }
+ }
+ return ret;
+}
+
+/* Returns the folder's PIDL type, or 0xff if one can't be found. */
+static BYTE testSHGetSpecialFolderLocation(int folder)
+{
+ LPITEMIDLIST pidl;
+ HRESULT hr;
+ BYTE ret = 0xff;
+
+ /* treat absence of function as success */
+ if (!pSHGetSpecialFolderLocation) return TRUE;
+
+ pidl = NULL;
+ hr = pSHGetSpecialFolderLocation(NULL, folder, &pidl);
+ if (hr == S_OK)
+ {
+ if (pidl)
+ {
+ LPITEMIDLIST pidlLast = pILFindLastID(pidl);
+
+ ok(pidlLast != NULL,
+ "%s: ILFindLastID failed\n", getFolderName(folder));
+ if (pidlLast)
+ ret = pidlLast->mkid.abID[0];
+ IMalloc_Free(pMalloc, pidl);
+ }
+ }
+ return ret;
+}
+
+static void test_SHGetFolderPath(BOOL optional, int folder)
+{
+ char path[MAX_PATH];
+ HRESULT hr;
+
+ if (!pSHGetFolderPathA) return;
+
+ hr = pSHGetFolderPathA(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path);
+ ok(hr == S_OK || optional,
+ "SHGetFolderPathA(NULL, %s, NULL, SHGFP_TYPE_CURRENT, path) failed:
0x%08x\n", getFolderName(folder), hr);
+}
+
+static void test_SHGetSpecialFolderPath(BOOL optional, int folder)
+{
+ char path[MAX_PATH];
+ BOOL ret;
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ ret = pSHGetSpecialFolderPathA(NULL, path, folder, FALSE);
+ if (ret && winetest_interactive)
+ printf("%s: %s\n", getFolderName(folder), path);
+ ok(ret || optional,
+ "SHGetSpecialFolderPathA(NULL, path, %s, FALSE) failed\n",
+ getFolderName(folder));
+}
+
+static void test_ShellValues(const struct shellExpectedValues testEntries[],
+ int numEntries, BOOL optional)
+{
+ int i;
+
+ for (i = 0; i < numEntries; i++)
+ {
+ BYTE type;
+ int j;
+ BOOL foundTypeMatch = FALSE;
+
+ if (pSHGetFolderLocation)
+ {
+ type = testSHGetFolderLocation(testEntries[i].folder);
+ for (j = 0; !foundTypeMatch && j < testEntries[i].numTypes; j++)
+ if (testEntries[i].types[j] == type)
+ foundTypeMatch = TRUE;
+ ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
+ "%s has unexpected type %d (0x%02x)\n",
+ getFolderName(testEntries[i].folder), type, type);
+ }
+ type = testSHGetSpecialFolderLocation(testEntries[i].folder);
+ for (j = 0, foundTypeMatch = FALSE; !foundTypeMatch &&
+ j < testEntries[i].numTypes; j++)
+ if (testEntries[i].types[j] == type)
+ foundTypeMatch = TRUE;
+ ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
+ "%s has unexpected type %d (0x%02x)\n",
+ getFolderName(testEntries[i].folder), type, type);
+ switch (type)
+ {
+ case PT_FOLDER:
+ case PT_DRIVE:
+ case PT_DRIVE2:
+ case PT_IESPECIAL2:
+ test_SHGetFolderPath(optional, testEntries[i].folder);
+ test_SHGetSpecialFolderPath(optional, testEntries[i].folder);
+ break;
+ }
+ }
+}
+
+/* Attempts to verify that the folder path corresponding to the folder CSIDL
+ * value has the same value as the environment variable with name envVar.
+ * Doesn't mind if SHGetSpecialFolderPath fails for folder or if envVar isn't
+ * set in this environment; different OS and shell version behave differently.
+ * However, if both are present, fails if envVar's value is not the same
+ * (byte-for-byte) as what SHGetSpecialFolderPath returns.
+ */
+static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
+{
+ char path[MAX_PATH];
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ if (pSHGetSpecialFolderPathA(NULL, path, folder, FALSE))
+ {
+ char *envVal = getenv(envVar);
+
+ ok(!envVal || !lstrcmpiA(envVal, path),
+ "%%%s%% does not match SHGetSpecialFolderPath:\n"
+ "%%%s%% is %s\nSHGetSpecialFolderPath returns %s\n",
+ envVar, envVar, envVal, path);
+ }
+}
+
+/* Attempts to match the GUID returned by SHGetFolderLocation for folder with
+ * GUID. Assumes the type of the returned PIDL is in fact a GUID, but doesn't
+ * fail if it isn't--that check should already have been done.
+ * Fails if the returned PIDL is a GUID whose value does not match guid.
+ */
+static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
+{
+ LPITEMIDLIST pidl;
+ HRESULT hr;
+
+ if (!pSHGetFolderLocation) return;
+ if (!guid) return;
+
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
+ if (hr == S_OK)
+ {
+ LPITEMIDLIST pidlLast = pILFindLastID(pidl);
+
+ if (pidlLast && (pidlLast->mkid.abID[0] == PT_SHELLEXT ||
+ pidlLast->mkid.abID[0] == PT_GUID))
+ {
+ GUID *shellGuid = (GUID *)(pidlLast->mkid.abID + 2);
+
+ if (!guid_alt)
+ ok(IsEqualIID(shellGuid, guid),
+ "%s: got GUID %s, expected %s\n", getFolderName(folder),
+ wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid));
+ else
+ ok(IsEqualIID(shellGuid, guid) ||
+ IsEqualIID(shellGuid, guid_alt),
+ "%s: got GUID %s, expected %s or %s\n", getFolderName(folder),
+ wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid),
wine_dbgstr_guid(guid_alt));
+ }
+ IMalloc_Free(pMalloc, pidl);
+ }
+}
+
+/* Checks the PIDL type of all the known values. */
+static void test_PidlTypes(void)
+{
+ /* Desktop */
+ test_SHGetFolderPath(FALSE, CSIDL_DESKTOP);
+ test_SHGetSpecialFolderPath(FALSE, CSIDL_DESKTOP);
+
+ test_ShellValues(requiredShellValues, ARRAY_SIZE(requiredShellValues), FALSE);
+ test_ShellValues(optionalShellValues, ARRAY_SIZE(optionalShellValues), TRUE);
+}
+
+/* FIXME: Should be in shobjidl.idl */
+DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73,
0x67, 0xFC, 0x96, 0xEF, 0x3C);
+DEFINE_GUID(_CLSID_Documents, 0xA8CDFF1C, 0x4878, 0x43be, 0xB5, 0xFD, 0xF8, 0x09, 0x1C,
0x1C, 0x60, 0xD0);
+
+/* Verifies various shell virtual folders have the correct well-known GUIDs. */
+static void test_GUIDs(void)
+{
+ matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin, NULL);
+ matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel, NULL);
+ matchGUID(CSIDL_DRIVES, &CLSID_MyComputer, NULL);
+ matchGUID(CSIDL_INTERNET, &CLSID_Internet, NULL);
+ matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces, &CLSID_NetworkExplorerFolder);
/* Vista and higher */
+ matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, &_CLSID_Documents /* win8 */);
+ matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments, NULL);
+ matchGUID(CSIDL_PRINTERS, &CLSID_Printers, NULL);
+}
+
+/* Verifies various shell paths match the environment variables to which they
+ * correspond.
+ */
+static void test_EnvVars(void)
+{
+ matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES, "ProgramFiles");
+ matchSpecialFolderPathToEnv(CSIDL_APPDATA, "APPDATA");
+ matchSpecialFolderPathToEnv(CSIDL_PROFILE, "USERPROFILE");
+ matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "SystemRoot");
+ matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "windir");
+ matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES_COMMON,
"CommonProgramFiles");
+ /* this is only set on Wine, but can't hurt to verify it: */
+ matchSpecialFolderPathToEnv(CSIDL_SYSTEM, "winsysdir");
+}
+
+/* Loosely based on PathRemoveBackslashA from dlls/shlwapi/path.c */
+static BOOL myPathIsRootA(LPCSTR lpszPath)
+{
+ if (lpszPath && *lpszPath &&
+ lpszPath[1] == ':' && lpszPath[2] == '\\' &&
lpszPath[3] == '\0')
+ return TRUE; /* X:\ */
+ return FALSE;
+}
+static LPSTR myPathRemoveBackslashA( LPSTR lpszPath )
+{
+ LPSTR szTemp = NULL;
+
+ if(lpszPath)
+ {
+ szTemp = CharPrevA(lpszPath, lpszPath + strlen(lpszPath));
+ if (!myPathIsRootA(lpszPath) && *szTemp == '\\')
+ *szTemp = '\0';
+ }
+ return szTemp;
+}
+
+/* Verifies the shell path for CSIDL_WINDOWS matches the return from
+ * GetWindowsDirectory. If SHGetSpecialFolderPath fails, no harm, no foul--not
+ * every shell32 version supports CSIDL_WINDOWS.
+ */
+static void testWinDir(void)
+{
+ char windowsShellPath[MAX_PATH], windowsDir[MAX_PATH] = { 0 };
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ if (pSHGetSpecialFolderPathA(NULL, windowsShellPath, CSIDL_WINDOWS, FALSE))
+ {
+ myPathRemoveBackslashA(windowsShellPath);
+ GetWindowsDirectoryA(windowsDir, sizeof(windowsDir));
+ myPathRemoveBackslashA(windowsDir);
+ ok(!lstrcmpiA(windowsDir, windowsShellPath),
+ "GetWindowsDirectory returns %s SHGetSpecialFolderPath returns %s\n",
+ windowsDir, windowsShellPath);
+ }
+}
+
+/* Verifies the shell path for CSIDL_SYSTEM matches the return from
+ * GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
+ * no foul--not every shell32 version supports CSIDL_SYSTEM.
+ */
+static void testSystemDir(void)
+{
+ char systemShellPath[MAX_PATH], systemDir[MAX_PATH], systemDirx86[MAX_PATH];
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ GetSystemDirectoryA(systemDir, sizeof(systemDir));
+ myPathRemoveBackslashA(systemDir);
+ if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEM, FALSE))
+ {
+ myPathRemoveBackslashA(systemShellPath);
+ ok(!lstrcmpiA(systemDir, systemShellPath),
+ "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
+ systemDir, systemShellPath);
+ }
+
+ if (!pGetSystemWow64DirectoryA || !pGetSystemWow64DirectoryA(systemDirx86,
sizeof(systemDirx86)))
+ GetSystemDirectoryA(systemDirx86, sizeof(systemDirx86));
+ myPathRemoveBackslashA(systemDirx86);
+ if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
+ {
+ myPathRemoveBackslashA(systemShellPath);
+ ok(!lstrcmpiA(systemDirx86, systemShellPath) || broken(!lstrcmpiA(systemDir,
systemShellPath)),
+ "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
+ systemDir, systemShellPath);
+ }
+}
+
+/* Globals used by subprocesses */
+static int myARGC;
+static char **myARGV;
+static char base[MAX_PATH];
+static char selfname[MAX_PATH];
+
+static BOOL init(void)
+{
+ myARGC = winetest_get_mainargs(&myARGV);
+ if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE;
+ strcpy(selfname, myARGV[0]);
+ return TRUE;
+}
+
+static void doChild(const char *arg)
+{
+ char path[MAX_PATH];
+ HRESULT hr;
+
+ if (arg[0] == '1')
+ {
+ LPITEMIDLIST pidl;
+ char *p;
+
+ /* test what happens when CSIDL_FAVORITES is set to a nonexistent directory */
+
+ /* test some failure cases first: */
+ hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+ "SHGetFolderPath returned 0x%08x, expected 0x80070002\n", hr);
+
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0, &pidl);
+ ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+ "SHGetFolderLocation returned 0x%08x\n", hr);
+ if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
+
+ ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
+ "SHGetSpecialFolderPath succeeded, expected failure\n");
+
+ pidl = NULL;
+ hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
+ ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+ "SHGetFolderLocation returned 0x%08x\n", hr);
+
+ if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
+
+ /* now test success: */
+ hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
+ SHGFP_TYPE_CURRENT, path);
+ ok (hr == S_OK, "got 0x%08x\n", hr);
+ if (hr == S_OK)
+ {
+ BOOL ret;
+
+ trace("CSIDL_FAVORITES was changed to %s\n", path);
+ ret = CreateDirectoryA(path, NULL);
+ ok(!ret, "expected failure with ERROR_ALREADY_EXISTS\n");
+ if (!ret)
+ ok(GetLastError() == ERROR_ALREADY_EXISTS,
+ "got %d, expected ERROR_ALREADY_EXISTS\n", GetLastError());
+
+ p = path + strlen(path);
+ strcpy(p, "\\desktop.ini");
+ DeleteFileA(path);
+ *p = 0;
+ SetFileAttributesA( path, FILE_ATTRIBUTE_NORMAL );
+ ret = RemoveDirectoryA(path);
+ ok( ret, "failed to remove %s error %u\n", path, GetLastError() );
+ }
+ }
+ else if (arg[0] == '2')
+ {
+ /* make sure SHGetFolderPath still succeeds when the
+ original value of CSIDL_FAVORITES is restored. */
+ hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
+ SHGFP_TYPE_CURRENT, path);
+ ok(hr == S_OK, "SHGetFolderPath failed: 0x%08x\n", hr);
+ }
+}
+
+/* Tests the return values from the various shell functions both with and
+ * without the use of the CSIDL_FLAG_CREATE flag. This flag only appeared in
+ * version 5 of the shell, so don't test unless it's at least version 5.
+ * The test reads a value from the registry, modifies it, calls
+ * SHGetFolderPath once with the CSIDL_FLAG_CREATE flag, and immediately
+ * afterward without it. Then it restores the registry and deletes the folder
+ * that was created.
+ * One oddity with respect to restoration: shell32 caches somehow, so it needs
+ * to be reloaded in order to see the correct (restored) value.
+ * Some APIs unrelated to the ones under test may fail, but I expect they're
+ * covered by other unit tests; I just print out something about failure to
+ * help trace what's going on.
+ */
+static void test_NonExistentPath(void)
+{
+ static const char userShellFolders[] =
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell
Folders";
+ char originalPath[MAX_PATH], modifiedPath[MAX_PATH];
+ HKEY key;
+
+ if (!pSHGetFolderPathA) return;
+ if (!pSHGetFolderLocation) return;
+ if (!pSHGetSpecialFolderPathA) return;
+ if (!pSHGetSpecialFolderLocation) return;
+ if (!pSHFileOperationA) return;
+ if (shellVersion.dwMajorVersion < 5) return;
+
+ if (!RegOpenKeyExA(HKEY_CURRENT_USER, userShellFolders, 0, KEY_ALL_ACCESS,
+ &key))
+ {
+ DWORD len, type;
+
+ len = sizeof(originalPath);
+ if (!RegQueryValueExA(key, "Favorites", NULL, &type,
+ (LPBYTE)&originalPath, &len))
+ {
+ size_t len = strlen(originalPath);
+
+ memcpy(modifiedPath, originalPath, len);
+ modifiedPath[len++] = '2';
+ modifiedPath[len++] = '\0';
+ trace("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
+ if (!RegSetValueExA(key, "Favorites", 0, type,
+ (LPBYTE)modifiedPath, len))
+ {
+ char buffer[MAX_PATH+20];
+ STARTUPINFOA startup;
+ PROCESS_INFORMATION info;
+
+ sprintf(buffer, "%s tests/shellpath.c 1", selfname);
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWNORMAL;
+ CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
+ &startup, &info);
+ winetest_wait_child_process( info.hProcess );
+
+ /* restore original values: */
+ trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);
+ RegSetValueExA(key, "Favorites", 0, type, (LPBYTE)
originalPath,
+ strlen(originalPath) + 1);
+ RegFlushKey(key);
+
+ sprintf(buffer, "%s tests/shellpath.c 2", selfname);
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWNORMAL;
+ CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
+ &startup, &info);
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
+ "child process termination\n");
+ }
+ }
+ else skip("RegQueryValueExA(key, Favorites, ...) failed\n");
+ if (key)
+ RegCloseKey(key);
+ }
+ else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n",
userShellFolders);
+}
+
+static void test_SHGetFolderPathEx(void)
+{
+ WCHAR buffer[MAX_PATH], *path, *path2;
+ unsigned int i;
+ HRESULT hr;
+ DWORD len;
+
+ if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx)
+ {
+ win_skip("SHGetKnownFolderPath or SHGetFolderPathEx not available\n");
+ return;
+ }
+
+if (0) { /* crashes */
+ hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, NULL);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+}
+ /* non-existent folder id */
+ path = (void *)0xdeadbeef;
+ hr = pSHGetKnownFolderPath(&IID_IOleObject, 0, NULL, &path);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
+ ok(path == NULL, "got %p\n", path);
+
+ path = NULL;
+ hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL,
&path);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path != NULL, "expected path != NULL\n");
+ CoTaskMemFree(path);
+
+ for (i = 0; i < ARRAY_SIZE(known_folders); ++i)
+ {
+ const KNOWNFOLDERID *folder_id = known_folders[i].folderId;
+
+ path = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DEFAULT, NULL, &path);
+ if (FAILED(hr))
+ continue;
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path != NULL, "expected path != NULL\n");
+
+ path2 = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST, NULL, &path2);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path2 != NULL, "expected path != NULL\n");
+ ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n",
wine_dbgstr_w(path), wine_dbgstr_w(path2));
+ CoTaskMemFree(path2);
+
+ path2 = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DONT_UNEXPAND, NULL, &path2);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path2 != NULL, "expected path != NULL\n");
+ ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n",
wine_dbgstr_w(path), wine_dbgstr_w(path2));
+ CoTaskMemFree(path2);
+
+ path2 = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST |
KF_FLAG_DONT_UNEXPAND, NULL, &path2);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path2 != NULL, "expected path != NULL\n");
+ ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n",
wine_dbgstr_w(path), wine_dbgstr_w(path2));
+ CoTaskMemFree(path2);
+
+ CoTaskMemFree(path);
+ }
+
+ path = NULL;
+ hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path != NULL, "expected path != NULL\n");
+
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(!lstrcmpiW(path, buffer), "expected equal paths\n");
+ len = lstrlenW(buffer);
+ CoTaskMemFree(path);
+
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+
+if (0) { /* crashes */
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+
+ hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+}
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len);
+ ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got
0x%08x\n", hr);
+
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+}
static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
{
@@ -1933,19 +1964,20 @@ static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId)
{
HRESULT hr;
- const struct knownFolderDef *known_folder = &known_folders[0];
int csidl, expectedCsidl, ret;
KNOWNFOLDER_DEFINITION kfd;
IKnownFolder *folder;
WCHAR sName[1024];
- BOOL *current_known_folder_found = &known_folder_found[0];
BOOL found = FALSE;
+ unsigned int i;
- while(known_folder->folderId != NULL)
+ for (i = 0; i < ARRAY_SIZE(known_folders); ++i)
{
+ const struct knownFolderDef *known_folder = &known_folders[i];
+
if(IsEqualGUID(known_folder->folderId, folderId))
{
- *current_known_folder_found = TRUE;
+ known_folder_found[i] = TRUE;
found = TRUE;
/* verify CSIDL */
if(!(known_folder->csidl & NO_CSIDL))
@@ -1997,8 +2029,6 @@ static void check_known_folder(IKnownFolderManager *mgr,
KNOWNFOLDERID *folderId
break;
}
- known_folder++;
- current_known_folder_found++;
}
if(!found)
@@ -2549,7 +2579,7 @@ static void test_DoEnvironmentSubst(void)
"%HOMEDRIVE%%HOMEPATH%",
"%OS% %windir%"}; /* always the last entry in the
table */
- for (i = 0; i < (sizeof(names)/sizeof(LPSTR)); i++)
+ for (i = 0; i < (ARRAY_SIZE(names)); i++)
{
memset(bufferA, '#', MAX_PATH - 1);
bufferA[MAX_PATH - 1] = 0;
diff --git a/modules/rostests/winetests/shell32/shlexec.c
b/modules/rostests/winetests/shell32/shlexec.c
index a8aabac734..b140280a5e 100644
--- a/modules/rostests/winetests/shell32/shlexec.c
+++ b/modules/rostests/winetests/shell32/shlexec.c
@@ -760,7 +760,7 @@ static LSTATUS myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
dwMaxSubkeyLen++;
dwMaxValueLen++;
dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
- if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR))
+ if (dwMaxLen > ARRAY_SIZE(szNameBuf))
{
/* Name too big: alloc a buffer for it */
if (!(lpszName = heap_alloc(dwMaxLen*sizeof(CHAR))))
@@ -1331,7 +1331,7 @@ static BOOL test_one_cmdline(const cmdline_tests_t* test)
int i, count;
/* trace("----- cmd='%s'\n", test->cmd); */
- MultiByteToWideChar(CP_ACP, 0, test->cmd, -1, cmdW, sizeof(cmdW)/sizeof(*cmdW));
+ MultiByteToWideChar(CP_ACP, 0, test->cmd, -1, cmdW, ARRAY_SIZE(cmdW));
argsW = cl2a = CommandLineToArgvW(cmdW, &cl2a_count);
if (argsW == NULL && cl2a_count == -1)
{
@@ -1351,7 +1351,7 @@ static BOOL test_one_cmdline(const cmdline_tests_t* test)
{
if (i < count)
{
- MultiByteToWideChar(CP_ACP, 0, test->args[i], -1, argW,
sizeof(argW)/sizeof(*argW));
+ MultiByteToWideChar(CP_ACP, 0, test->args[i], -1, argW,
ARRAY_SIZE(argW));
todo_wine_if(test->todo & (1 << (i+4)))
ok(!lstrcmpW(*argsW, argW), "%s: arg[%d] expected %s but got
%s\n", test->cmd, i, wine_dbgstr_w(argW), wine_dbgstr_w(*argsW));
}
@@ -1397,7 +1397,7 @@ static void test_commandline2argv(void)
"expected NULL-terminated list of commandline arguments\n");
if (numargs == 1)
{
- GetModuleFileNameW(NULL, strW, sizeof(strW)/sizeof(*strW));
+ GetModuleFileNameW(NULL, strW, ARRAY_SIZE(strW));
ok(!lstrcmpW(args[0], strW), "wrong path to the current executable: %s
instead of %s\n", wine_dbgstr_w(args[0]), wine_dbgstr_w(strW));
}
if (args) LocalFree(args);
@@ -1420,8 +1420,8 @@ typedef struct
const char* verb;
const char* params;
int todo;
- cmdline_tests_t cmd;
- cmdline_tests_t broken;
+ const char *cmd;
+ const char *broken;
} argify_tests_t;
static const argify_tests_t argify_tests[] =
@@ -1431,33 +1431,28 @@ static const argify_tests_t argify_tests[] =
* parameters string, including the trailing spaces, no matter what
* arguments have already been used.
*/
- {"Params232S", "p2 p3 p4 ", 0xc2,
- {" p2 p3 \"p2\" \"p2 p3 p4 \"",
- {"", "p2", "p3", "p2", "p2 p3 p4
", NULL}, 0}},
+ {"Params232S", "p2 p3 p4 ", TRUE,
+ " p2 p3 \"p2\" \"p2 p3 p4 \""},
/* Unquoted argument references like %2 don't automatically quote their
* argument. Similarly, when they are quoted they don't escape the quotes
* that their argument may contain.
*/
- {"Params232S", "\"p two\" p3 p4 ", 0x3f3,
- {" p two p3 \"p two\" \"\"p two\" p3 p4
\"",
- {"", "p", "two", "p3", "p two",
"p", "two p3 p4 ", NULL}, 0}},
+ {"Params232S", "\"p two\" p3 p4 ", TRUE,
+ " p two p3 \"p two\" \"\"p two\" p3 p4
\""},
/* Only single digits are supported so only %1 to %9. Shown here with %20
* because %10 is a pain.
*/
- {"Params20", "p", 0,
- {" \"p0\"",
- {"", "p0", NULL}, 0}},
+ {"Params20", "p", FALSE,
+ " \"p0\""},
/* Only (double-)quotes have a special meaning. */
- {"Params23456", "'p2 p3` p4\\ $even", 0x40,
- {" \"'p2\" \"p3`\" \"p4\\\"
\"$even\" \"\"",
- {"", "'p2", "p3`", "p4\" $even
\"", NULL}, 0}},
+ {"Params23456", "'p2 p3` p4\\ $even", FALSE,
+ " \"'p2\" \"p3`\" \"p4\\\"
\"$even\" \"\""},
- {"Params23456", "p=2 p-3 p4\tp4\rp4\np4", 0x1c2,
- {" \"p=2\" \"p-3\" \"p4\tp4\rp4\np4\"
\"\" \"\"",
- {"", "p=2", "p-3", "p4\tp4\rp4\np4",
"", "", NULL}, 0}},
+ {"Params23456", "p=2 p-3 p4\tp4\rp4\np4", TRUE,
+ " \"p=2\" \"p-3\" \"p4\tp4\rp4\np4\"
\"\" \"\""},
/* In unquoted strings, quotes are treated are a parameter separator just
* like spaces! However they can be doubled to get a literal quote.
@@ -1465,125 +1460,102 @@ static const argify_tests_t argify_tests[] =
* 2n quotes -> n quotes
* 2n+1 quotes -> n quotes and a parameter separator
*/
- {"Params23456789", "one\"quote \"p four\"
one\"quote p7", 0xff3,
- {" \"one\" \"quote\" \"p four\" \"one\"
\"quote\" \"p7\" \"\" \"\"",
- {"", "one", "quote", "p four",
"one", "quote", "p7", "", "", NULL},
0}},
+ {"Params23456789", "one\"quote \"p four\"
one\"quote p7", TRUE,
+ " \"one\" \"quote\" \"p four\" \"one\"
\"quote\" \"p7\" \"\" \"\""},
- {"Params23456789", "two\"\"quotes \"p three\"
two\"\"quotes p5", 0xf2,
- {" \"two\"quotes\" \"p three\"
\"two\"quotes\" \"p5\" \"\" \"\"
\"\" \"\"",
- {"", "twoquotes p", "three twoquotes",
"p5", "", "", "", "", NULL}, 0}},
+ {"Params23456789", "two\"\"quotes \"p three\"
two\"\"quotes p5", TRUE,
+ " \"two\"quotes\" \"p three\"
\"two\"quotes\" \"p5\" \"\" \"\"
\"\" \"\""},
- {"Params23456789", "three\"\"\"quotes \"p
four\" three\"\"\"quotes p6", 0xff3,
- {" \"three\"\" \"quotes\" \"p four\"
\"three\"\" \"quotes\" \"p6\" \"\"
\"\"",
- {"", "three\"", "quotes", "p four",
"three\"", "quotes", "p6", "", "",
NULL}, 0}},
+ {"Params23456789", "three\"\"\"quotes \"p
four\" three\"\"\"quotes p6", TRUE,
+ " \"three\"\" \"quotes\" \"p four\"
\"three\"\" \"quotes\" \"p6\" \"\"
\"\""},
- {"Params23456789", "four\"\"\"\"quotes \"p
three\" four\"\"\"\"quotes p5", 0xf3,
- {" \"four\"\"quotes\" \"p three\"
\"four\"\"quotes\" \"p5\" \"\" \"\"
\"\" \"\"",
- {"", "four\"quotes p", "three fourquotes p5
\"", "", "", "", NULL}, 0}},
+ {"Params23456789", "four\"\"\"\"quotes \"p
three\" four\"\"\"\"quotes p5", TRUE,
+ " \"four\"\"quotes\" \"p three\"
\"four\"\"quotes\" \"p5\" \"\" \"\"
\"\" \"\""},
/* Quoted strings cannot be continued by tacking on a non space character
* either.
*/
- {"Params23456", "\"p two\"p3 \"p four\"p5
p6", 0x1f3,
- {" \"p two\" \"p3\" \"p four\" \"p5\"
\"p6\"",
- {"", "p two", "p3", "p four",
"p5", "p6", NULL}, 0}},
+ {"Params23456", "\"p two\"p3 \"p four\"p5
p6", TRUE,
+ " \"p two\" \"p3\" \"p four\" \"p5\"
\"p6\""},
/* In quoted strings, the quotes are halved and an odd number closes the
* string. Specifically:
* 2n quotes -> n quotes
* 2n+1 quotes -> n quotes and closes the string and hence the parameter
*/
- {"Params23456789", "\"one q\"uote \"p four\"
\"one q\"uote p7", 0xff3,
- {" \"one q\" \"uote\" \"p four\" \"one
q\" \"uote\" \"p7\" \"\" \"\"",
- {"", "one q", "uote", "p four", "one
q", "uote", "p7", "", "", NULL}, 0}},
+ {"Params23456789", "\"one q\"uote \"p four\"
\"one q\"uote p7", TRUE,
+ " \"one q\" \"uote\" \"p four\" \"one
q\" \"uote\" \"p7\" \"\" \"\""},
- {"Params23456789", "\"two \"\" quotes\" \"p
three\" \"two \"\" quotes\" p5", 0x1ff3,
- {" \"two \" quotes\" \"p three\" \"two \"
quotes\" \"p5\" \"\" \"\" \"\"
\"\"",
- {"", "two ", "quotes p", "three two",
" quotes", "p5", "", "", "",
"", NULL}, 0}},
+ {"Params23456789", "\"two \"\" quotes\" \"p
three\" \"two \"\" quotes\" p5", TRUE,
+ " \"two \" quotes\" \"p three\" \"two \"
quotes\" \"p5\" \"\" \"\" \"\"
\"\""},
- {"Params23456789", "\"three q\"\"\"uotes \"p
four\" \"three q\"\"\"uotes p7", 0xff3,
- {" \"three q\"\" \"uotes\" \"p four\"
\"three q\"\" \"uotes\" \"p7\" \"\"
\"\"",
- {"", "three q\"", "uotes", "p four",
"three q\"", "uotes", "p7", "", "",
NULL}, 0}},
+ {"Params23456789", "\"three q\"\"\"uotes \"p
four\" \"three q\"\"\"uotes p7", TRUE,
+ " \"three q\"\" \"uotes\" \"p four\"
\"three q\"\" \"uotes\" \"p7\" \"\"
\"\""},
- {"Params23456789", "\"four \"\"\"\"
quotes\" \"p three\" \"four \"\"\"\" quotes\"
p5", 0xff3,
- {" \"four \"\" quotes\" \"p three\" \"four
\"\" quotes\" \"p5\" \"\" \"\" \"\"
\"\"",
- {"", "four \"", "quotes p", "three
four", "", "quotes p5 \"", "", "",
"", NULL}, 0}},
+ {"Params23456789", "\"four \"\"\"\"
quotes\" \"p three\" \"four \"\"\"\" quotes\"
p5", TRUE,
+ " \"four \"\" quotes\" \"p three\" \"four
\"\" quotes\" \"p5\" \"\" \"\" \"\"
\"\""},
/* The quoted string rules also apply to consecutive quotes at the start
* of a parameter but don't count the opening quote!
*/
- {"Params23456789", "\"\"twoquotes \"p four\"
\"\"twoquotes p7", 0xbf3,
- {" \"\" \"twoquotes\" \"p four\" \"\"
\"twoquotes\" \"p7\" \"\" \"\"",
- {"", "", "twoquotes", "p four",
"", "twoquotes", "p7", "", "", NULL},
0}},
+ {"Params23456789", "\"\"twoquotes \"p four\"
\"\"twoquotes p7", TRUE,
+ " \"\" \"twoquotes\" \"p four\" \"\"
\"twoquotes\" \"p7\" \"\" \"\""},
- {"Params23456789", "\"\"\"three quotes\" \"p
three\" \"\"\"three quotes\" p5", 0x6f3,
- {" \"\"three quotes\" \"p three\" \"\"three
quotes\" \"p5\" \"\" \"\" \"\"
\"\"",
- {"", "three", "quotes p", "three
\"three", "quotes p5 \"", "", "",
"", NULL}, 0}},
+ {"Params23456789", "\"\"\"three quotes\" \"p
three\" \"\"\"three quotes\" p5", TRUE,
+ " \"\"three quotes\" \"p three\" \"\"three
quotes\" \"p5\" \"\" \"\" \"\"
\"\""},
- {"Params23456789", "\"\"\"\"fourquotes \"p
four\" \"\"\"\"fourquotes p7", 0xbf3,
- {" \"\"\" \"fourquotes\" \"p four\"
\"\"\" \"fourquotes\" \"p7\" \"\"
\"\"",
- {"", "\"", "fourquotes", "p four",
"\"", "fourquotes", "p7", "", "",
NULL}, 0}},
+ {"Params23456789", "\"\"\"\"fourquotes \"p
four\" \"\"\"\"fourquotes p7", TRUE,
+ " \"\"\" \"fourquotes\" \"p four\"
\"\"\" \"fourquotes\" \"p7\" \"\"
\"\""},
/* An unclosed quoted string gets lost! */
- {"Params23456", "p2 \"p3\" \"p4 is lost", 0x1c3,
- {" \"p2\" \"p3\" \"\" \"\"
\"\"",
- {"", "p2", "p3", "", "",
"", NULL}, 0},
- {" \"p2\" \"p3\" \"p3\" \"\"
\"\"",
- {"", "p2", "p3", "p3", "",
"", NULL}, 0}},
+ {"Params23456", "p2 \"p3\" \"p4 is lost", TRUE,
+ " \"p2\" \"p3\" \"\" \"\"
\"\"",
+ " \"p2\" \"p3\" \"p3\" \"\"
\"\""}, /* NT4/2k */
/* Backslashes have no special meaning even when preceding quotes. All
* they do is start an unquoted string.
*/
- {"Params23456", "\\\"p\\three \"pfour\\\" pfive",
0x73,
- {" \"\\\" \"p\\three\" \"pfour\\\"
\"pfive\" \"\"",
- {"", "\" p\\three pfour\"", "pfive",
"", NULL}, 0}},
+ {"Params23456", "\\\"p\\three \"pfour\\\" pfive",
TRUE,
+ " \"\\\" \"p\\three\" \"pfour\\\"
\"pfive\" \"\""},
/* Environment variables are left untouched. */
- {"Params23456", "%TMPDIR% %t %c", 0,
- {" \"%TMPDIR%\" \"%t\" \"%c\" \"\"
\"\"",
- {"", "%TMPDIR%", "%t", "%c", "",
"", NULL}, 0}},
+ {"Params23456", "%TMPDIR% %t %c", FALSE,
+ " \"%TMPDIR%\" \"%t\" \"%c\" \"\"
\"\""},
/* %~2 is equivalent to %*. However %~3 and higher include the spaces
* before the parameter!
* (but not the previous parameter's closing quote fortunately)
*/
- {"Params2345Etc", "p2 p3 \"p4\" p5 p6 ", 0x3f3,
- {" ~2=\"p2 p3 \"p4\" p5 p6 \" ~3=\" p3
\"p4\" p5 p6 \" ~4=\" \"p4\" p5 p6 \" ~5= p5 p6
",
- {"", "~2=p2 p3 p4 p5 p6 ", "~3= p3 p4 p5 p6 ",
"~4= p4 p5 p6 ", "~5=", "p5", "p6", NULL}, 0}},
+ {"Params2345Etc", "p2 p3 \"p4\" p5 p6 ", TRUE,
+ " ~2=\"p2 p3 \"p4\" p5 p6 \" ~3=\" p3
\"p4\" p5 p6 \" ~4=\" \"p4\" p5 p6 \" ~5= p5 p6
"},
/* %~n works even if there is no nth parameter. */
- {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 ", 0x12,
- {" ~9=\" \"",
- {"", "~9= ", NULL}, 0}},
+ {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 ", TRUE,
+ " ~9=\" \""},
- {"Params9Etc", "p2 p3 p4 p5 p6 p7 ", 0x12,
- {" ~9=\"\"",
- {"", "~9=", NULL}, 0}},
+ {"Params9Etc", "p2 p3 p4 p5 p6 p7 ", TRUE,
+ " ~9=\"\""},
/* The %~n directives also transmit the tenth parameter and beyond. */
- {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 and beyond!",
0x12,
- {" ~9=\" p9 p10 p11 and beyond!\"",
- {"", "~9= p9 p10 p11 and beyond!", NULL}, 0}},
+ {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 and beyond!",
TRUE,
+ " ~9=\" p9 p10 p11 and beyond!\""},
/* Bad formatting directives lose their % sign, except those followed by
* a tilde! Environment variables are not expanded but lose their % sign.
*/
- {"ParamsBad", "p2 p3 p4 p5", 0x12,
- {" \"% - %~ %~0 %~1 %~a %~* a b c TMPDIR\"",
- {"", "% - %~ %~0 %~1 %~a %~* a b c TMPDIR", NULL}, 0}},
+ {"ParamsBad", "p2 p3 p4 p5", TRUE,
+ " \"% - %~ %~0 %~1 %~a %~* a b c TMPDIR\""},
- {NULL, NULL, 0, {NULL, {NULL}, 0}}
+ {0}
};
static void test_argify(void)
{
- BOOL has_cl2a = TRUE;
char fileA[MAX_PATH], params[2*MAX_PATH+12];
INT_PTR rc;
const argify_tests_t* test;
- const cmdline_tests_t *bad;
+ const char *bad;
const char* cmd;
- unsigned i, count;
/* Test with a long parameter */
for (rc = 0; rc < MAX_PATH; rc++)
@@ -1616,21 +1588,11 @@ static void test_argify(void)
test = argify_tests;
while (test->params)
{
- bad = test->broken.cmd ? &test->broken : &test->cmd;
+ bad = test->broken ? test->broken : test->cmd;
- /* trace("***** verb='%s' params='%s'\n",
test->verb, test->params); */
rc = shell_execute_ex(SEE_MASK_DOENVSUBST, test->verb, fileA, test->params,
NULL, NULL);
okShell(rc > 32, "failed: rc=%lu\n", rc);
- count = 0;
- while (test->cmd.args[count])
- count++;
- /* +4 for the shlexec arguments, -1 because of the added ""
- * argument for the CommandLineToArgvW() tests.
- */
- todo_wine_if(test->todo & 0x1)
- okChildInt("argcA", 4 + count - 1);
-
cmd = getChildString("Child", "cmdlineA");
/* Our commands are such that the verb immediately precedes the
* part we are interested in.
@@ -1638,20 +1600,9 @@ static void test_argify(void)
if (cmd) cmd = strstr(cmd, test->verb);
if (cmd) cmd += strlen(test->verb);
if (!cmd) cmd = "(null)";
- todo_wine_if(test->todo & 0x2)
- okShell(!strcmp(cmd, test->cmd.cmd) || broken(!strcmp(cmd, bad->cmd)),
- "the cmdline is '%s' instead of '%s'\n",
cmd, test->cmd.cmd);
-
- for (i = 0; i < count - 1; i++)
- {
- char argname[18];
- sprintf(argname, "argvA%d", 4 + i);
- todo_wine_if(test->todo & (1 << (i+4)))
- okChildStringBroken(argname, test->cmd.args[i+1], bad->args[i+1]);
- }
-
- if (has_cl2a)
- has_cl2a = test_one_cmdline(&(test->cmd));
+ todo_wine_if(test->todo)
+ okShell(!strcmp(cmd, test->cmd) || broken(!strcmp(cmd, bad)),
+ "expected '%s', got '%s'\n", cmd,
test->cmd);
test++;
}
}
@@ -1861,7 +1812,7 @@ static void test_fileurls(void)
return;
}
- get_long_path_name(tmpdir, longtmpdir, sizeof(longtmpdir)/sizeof(*longtmpdir));
+ get_long_path_name(tmpdir, longtmpdir, ARRAY_SIZE(longtmpdir));
SetEnvironmentVariableA("urlprefix", "file:///");
test=fileurl_tests;
@@ -2781,7 +2732,7 @@ static void init_test(void)
/* Setup the test shortcuts */
sprintf(filename, "%s\\test_shortcut_shlexec.lnk", tmpdir);
- MultiByteToWideChar(CP_ACP, 0, filename, -1, lnkfile,
sizeof(lnkfile)/sizeof(*lnkfile));
+ MultiByteToWideChar(CP_ACP, 0, filename, -1, lnkfile, ARRAY_SIZE(lnkfile));
desc.description=NULL;
desc.workdir=NULL;
sprintf(filename, "%s\\test file.shlexec", tmpdir);
@@ -2795,7 +2746,7 @@ static void init_test(void)
create_lnk(lnkfile, &desc, 0);
sprintf(filename, "%s\\test_shortcut_exe.lnk", tmpdir);
- MultiByteToWideChar(CP_ACP, 0, filename, -1, lnkfile,
sizeof(lnkfile)/sizeof(*lnkfile));
+ MultiByteToWideChar(CP_ACP, 0, filename, -1, lnkfile, ARRAY_SIZE(lnkfile));
desc.description=NULL;
desc.workdir=NULL;
desc.path=argv0;
diff --git a/modules/rostests/winetests/shell32/shlfileop.c
b/modules/rostests/winetests/shell32/shlfileop.c
index 72ca1e7e36..9768e18de3 100644
--- a/modules/rostests/winetests/shell32/shlfileop.c
+++ b/modules/rostests/winetests/shell32/shlfileop.c
@@ -60,25 +60,6 @@ static const WCHAR UNICODE_PATH[] =
{'c',':','\\',0x00ae,'\0','\0'};
/* "c:\®" can be used in all codepages */
/* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */
-static HMODULE hshell32;
-static int (WINAPI *pSHCreateDirectoryExA)(HWND, LPCSTR, LPSECURITY_ATTRIBUTES);
-static int (WINAPI *pSHCreateDirectoryExW)(HWND, LPCWSTR, LPSECURITY_ATTRIBUTES);
-static int (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
-static DWORD_PTR (WINAPI *pSHGetFileInfoW)(LPCWSTR, DWORD , SHFILEINFOW*, UINT, UINT);
-static int (WINAPI *pSHPathPrepareForWriteA)(HWND, IUnknown*, LPCSTR, DWORD);
-static int (WINAPI *pSHPathPrepareForWriteW)(HWND, IUnknown*, LPCWSTR, DWORD);
-
-static void InitFunctionPointers(void)
-{
- hshell32 = GetModuleHandleA("shell32.dll");
- pSHCreateDirectoryExA = (void*)GetProcAddress(hshell32,
"SHCreateDirectoryExA");
- pSHCreateDirectoryExW = (void*)GetProcAddress(hshell32,
"SHCreateDirectoryExW");
- pSHFileOperationW = (void*)GetProcAddress(hshell32, "SHFileOperationW");
- pSHGetFileInfoW = (void*)GetProcAddress(hshell32, "SHGetFileInfoW");
- pSHPathPrepareForWriteA = (void*)GetProcAddress(hshell32,
"SHPathPrepareForWriteA");
- pSHPathPrepareForWriteW = (void*)GetProcAddress(hshell32,
"SHPathPrepareForWriteW");
-}
-
/* creates a file with the specified name for tests */
static void createTestFile(const CHAR *name)
{
@@ -196,6 +177,7 @@ static void test_get_file_info(void)
SHFILEINFOA shfi, shfi2;
SHFILEINFOW shfiw;
char notepad[MAX_PATH];
+ HANDLE unset_icon;
/* Test whether fields of SHFILEINFOA are always cleared */
memset(&shfi, 0xcf, sizeof(shfi));
@@ -211,23 +193,15 @@ static void test_get_file_info(void)
broken(shfi.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this
field */
"SHGetFileInfoA('' | 0) should not clear dwAttributes\n");
- if (pSHGetFileInfoW)
- {
- HANDLE unset_icon;
- /* Test whether fields of SHFILEINFOW are always cleared */
- memset(&shfiw, 0xcf, sizeof(shfiw));
- memset(&unset_icon, 0xcf, sizeof(unset_icon));
- rc=pSHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0);
- ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n");
- ok(shfiw.hIcon == unset_icon, "SHGetFileInfoW(NULL | 0) should not clear
hIcon\n");
- ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not
clear szDisplayName[0]\n");
- ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear
szTypeName[0]\n");
- ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear
iIcon\n");
- ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not
clear dwAttributes\n");
- }
- else
- win_skip("SHGetFileInfoW is not available\n");
-
+ memset(&shfiw, 0xcf, sizeof(shfiw));
+ memset(&unset_icon, 0xcf, sizeof(unset_icon));
+ rc = SHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0);
+ ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n");
+ ok(shfiw.hIcon == unset_icon, "SHGetFileInfoW(NULL | 0) should not clear
hIcon\n");
+ ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear
szDisplayName[0]\n");
+ ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear
szTypeName[0]\n");
+ ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear
iIcon\n");
+ ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear
dwAttributes\n");
/* Test some flag combinations that MSDN claims are not allowed,
* but which work anyway
@@ -396,22 +370,9 @@ static void test_get_file_info_iconlist(void)
"SHGetFileInfoA(CSIDL_DESKTOP,
SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL), unexpected dwAttributes\n");
/* Don't release hSysImageList here (and in similar places below) because of the
broken reference behaviour of XP and 2003. */
- if (!pSHGetFileInfoW)
- {
- win_skip("SHGetFileInfoW is not available\n");
- ILFree(pidList);
- return;
- }
-
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST) pSHGetFileInfoW((const WCHAR *)pidList, 0,
- &shInfow, sizeof(shInfow),
- SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
- if (!hSysImageList)
- {
- win_skip("SHGetFileInfoW is not implemented\n");
- return;
- }
+ hSysImageList = (HIMAGELIST) SHGetFileInfoW((const WCHAR *)pidList, 0,
+ &shInfow, sizeof(shInfow), SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
SHGFI_PIDL);
ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n",
hSysImageList, small_list);
todo_wine ok(shInfow.hIcon == 0, "SHGetFileInfoW(CSIDL_DESKTOP,
SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
ok(shInfow.szTypeName[0] == 0, "SHGetFileInfoW(CSIDL_DESKTOP,
SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
@@ -422,7 +383,7 @@ static void test_get_file_info_iconlist(void)
/* Various suposidly invalid flag testing */
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n",
hSysImageList, small_list);
ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
@@ -431,7 +392,7 @@ static void test_get_file_info_iconlist(void)
"unexpected dwAttributes\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
ok(hr != 0, " SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON
Failed\n");
ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
@@ -440,7 +401,7 @@ static void test_get_file_info_iconlist(void)
todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
ok(hr != 0, "SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON
Failed\n");
ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
@@ -449,7 +410,7 @@ static void test_get_file_info_iconlist(void)
todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n",
hSysImageList, small_list);
ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
@@ -458,28 +419,28 @@ static void test_get_file_info_iconlist(void)
"unexpected dwAttributes\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
ok(hr != 0, "SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON
Failed\n");
todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
ok(hr != 0,
"SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON
Failed\n");
todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
ok(hr != 0,
"SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON
Failed\n");
todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
SHGFI_ATTRIBUTES);
ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n",
hSysImageList, small_list);
@@ -487,7 +448,7 @@ static void test_get_file_info_iconlist(void)
ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
SHGFI_EXETYPE);
todo_wine ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n",
hSysImageList, small_list);
@@ -497,21 +458,21 @@ static void test_get_file_info_iconlist(void)
"unexpected dwAttributes\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE);
todo_wine ok(hr != 0,
"SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE Failed\n");
todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES);
ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES
Failed\n");
todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|
SHGFI_ATTRIBUTES);
ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n",
hSysImageList, large_list);
@@ -520,7 +481,7 @@ static void test_get_file_info_iconlist(void)
ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
todo_wine ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n",
hSysImageList, large_list);
ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
@@ -529,21 +490,21 @@ static void test_get_file_info_iconlist(void)
"unexpected dwAttributes\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE
Failed\n");
todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+ hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES);
ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES
Failed\n");
todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_SHELLICONSIZE|SHGFI_ICON);
ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n",
hSysImageList, small_list);
ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
@@ -551,7 +512,7 @@ static void test_get_file_info_iconlist(void)
DestroyIcon( shInfow.hIcon );
memset(&shInfow, 0xcf, sizeof(shInfow));
- hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
+ hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow,
sizeof(shInfow),
SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SHELLICONSIZE|SHGFI_ICON);
ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n",
hSysImageList, small_list);
ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
@@ -1912,6 +1873,28 @@ static void test_copy(void)
ok(retval != ERROR_SUCCESS, "Unexpected ERROR_SUCCESS\n");
ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n",
GetLastError());
+
+ /* test with / */
+ CreateDirectoryA("dir", NULL);
+ CreateDirectoryA("dir\\subdir", NULL);
+ createTestFile("dir\\subdir\\aa.txt");
+ shfo.pFrom = "dir/subdir/aa.txt\0";
+ shfo.pTo = "dir\\destdir/aa.txt\0";
+ shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT | FOF_NOERRORUI;
+ retval = SHFileOperationA(&shfo);
+ if (dir_exists("dir\\destdir"))
+ {
+ ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n",
retval);
+ ok(DeleteFileA("dir\\destdir\\aa.txt"), "Expected file to
exist\n");
+ ok(RemoveDirectoryA("dir\\destdir"), "Expected dir to
exist\n");
+ }
+ else
+ {
+ expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* WinXp, Win2k */);
+ }
+ ok(DeleteFileA("dir\\subdir\\aa.txt"), "Expected file to
exist\n");
+ ok(RemoveDirectoryA("dir\\subdir"), "Expected dir to exist\n");
+ ok(RemoveDirectoryA("dir"), "Expected dir to exist\n");
}
/* tests the FO_MOVE action */
@@ -1964,6 +1947,30 @@ static void test_move(void)
clean_after_shfo_tests();
init_shfo_tests();
+ /* same tests above, but with / */
+ set_curr_dir_path(from, "testdir2/*.*\0");
+ set_curr_dir_path(to, "test4.txt\0");
+ retval = SHFileOperationA(&shfo);
+ ok(retval == ERROR_SUCCESS ||
+ broken(retval == ERROR_FILE_NOT_FOUND), /* WinXp, Win2k3 */
+ "Expected ERROR_SUCCESS, got %d\n", retval);
+ if (retval == ERROR_SUCCESS)
+ {
+ ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n",
shfo.fAnyOperationsAborted);
+
+ ok(dir_exists("testdir2"), "dir should not be moved\n");
+ ok(!file_exists("testdir2\\one.txt"), "file should be
moved\n");
+ ok(!dir_exists("testdir2\\nested"), "dir should be
moved\n");
+ ok(!file_exists("testdir2\\nested\\two.txt"), "file should be
moved\n");
+
+ ok(file_exists("test4.txt\\one.txt"), "file should
exist\n");
+ ok(dir_exists("test4.txt\\nested"), "dir should exist\n");
+ ok(file_exists("test4.txt\\nested\\two.txt"), "file should
exist\n");
+ }
+
+ clean_after_shfo_tests();
+ init_shfo_tests();
+
shfo.hwnd = NULL;
shfo.wFunc = FO_MOVE;
shfo.pFrom = from;
@@ -2343,22 +2350,16 @@ static void test_sh_create_dir(void)
CHAR path[MAX_PATH];
int ret;
- if(!pSHCreateDirectoryExA)
- {
- win_skip("skipping SHCreateDirectoryExA tests\n");
- return;
- }
-
set_curr_dir_path(path, "testdir2\\test4.txt\0");
- ret = pSHCreateDirectoryExA(NULL, path, NULL);
+ ret = SHCreateDirectoryExA(NULL, path, NULL);
ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory
recursively, ret = %d\n", ret);
ok(file_exists("testdir2"), "The first directory is not
created\n");
ok(file_exists("testdir2\\test4.txt"), "The second directory is not
created\n");
- ret = pSHCreateDirectoryExA(NULL, path, NULL);
+ ret = SHCreateDirectoryExA(NULL, path, NULL);
ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create
existing directory, ret = %d\n", ret);
- ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
+ ret = SHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory, ret =
%d\n", ret);
ok(file_exists("c:\\testdir3"), "The directory is not
created\n");
}
@@ -2370,43 +2371,37 @@ static void test_sh_path_prepare(void)
CHAR UNICODE_PATH_A[MAX_PATH];
BOOL UsedDefaultChar;
- if(!pSHPathPrepareForWriteA)
- {
- win_skip("skipping SHPathPrepareForWriteA tests\n");
- return;
- }
-
/* directory exists, SHPPFW_NONE */
set_curr_dir_path(path, "testdir2\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
/* directory exists, SHPPFW_IGNOREFILENAME */
set_curr_dir_path(path, "testdir2\\test4.txt\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
/* directory exists, SHPPFW_DIRCREATE */
set_curr_dir_path(path, "testdir2\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
/* directory exists, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
set_curr_dir_path(path, "testdir2\\test4.txt\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but
shouldn't\n");
/* file exists, SHPPFW_NONE */
set_curr_dir_path(path, "test1.txt\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
"Unexpected result : 0x%08x\n", res);
/* file exists, SHPPFW_DIRCREATE */
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
@@ -2414,53 +2409,47 @@ static void test_sh_path_prepare(void)
/* file exists, SHPPFW_NONE, trailing \ */
set_curr_dir_path(path, "test1.txt\\\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
"Unexpected result : 0x%08x\n", res);
/* relative path exists, SHPPFW_DIRCREATE */
- res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE);
ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
/* relative path doesn't exist, SHPPFW_DIRCREATE -- Windows does not create the
directory in this case */
- res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt",
SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt",
SHPPFW_DIRCREATE);
ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected
HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
ok(!file_exists(".\\testdir2\\test4.txt\\"), ".\\testdir2\\test4.txt\\
exists but shouldn't\n");
/* directory doesn't exist, SHPPFW_NONE */
set_curr_dir_path(path, "nonexistent\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected
HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
/* directory doesn't exist, SHPPFW_IGNOREFILENAME */
set_curr_dir_path(path, "nonexistent\\notreal\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected
HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
ok(!file_exists("nonexistent\\notreal"), "nonexistent\\notreal exists
but shouldn't\n");
ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but
shouldn't\n");
/* directory doesn't exist, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
set_curr_dir_path(path, "testdir2\\test4.txt\\\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
ok(file_exists("testdir2\\test4.txt\\"), "testdir2\\test4.txt
doesn't exist but should\n");
/* nested directory doesn't exist, SHPPFW_DIRCREATE */
set_curr_dir_path(path, "nonexistent\\notreal\0");
- res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal
doesn't exist but should\n");
/* SHPPFW_ASKDIRCREATE, SHPPFW_NOWRITECHECK, and SHPPFW_MEDIACHECKONLY are untested
*/
- if(!pSHPathPrepareForWriteW)
- {
- win_skip("Skipping SHPathPrepareForWriteW tests\n");
- return;
- }
-
SetLastError(0xdeadbeef);
UsedDefaultChar = FALSE;
if (WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, UNICODE_PATH, -1,
UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, &UsedDefaultChar) == 0)
@@ -2476,22 +2465,22 @@ static void test_sh_path_prepare(void)
/* unicode directory doesn't exist, SHPPFW_NONE */
RemoveDirectoryA(UNICODE_PATH_A);
- res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
+ res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08x, expected
HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
ok(!file_exists(UNICODE_PATH_A), "unicode path was created but shouldn't
be\n");
RemoveDirectoryA(UNICODE_PATH_A);
/* unicode directory doesn't exist, SHPPFW_DIRCREATE */
- res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
ok(res == S_OK, "res == %08x, expected S_OK\n", res);
ok(file_exists(UNICODE_PATH_A), "unicode path should've been
created\n");
/* unicode directory exists, SHPPFW_NONE */
- res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
+ res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
/* unicode directory exists, SHPPFW_DIRCREATE */
- res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
+ res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
RemoveDirectoryA(UNICODE_PATH_A);
}
@@ -2559,12 +2548,6 @@ static void test_unicode(void)
HANDLE file;
static const WCHAR UNICODE_PATH_TO[] =
{'c',':','\\',0x00ae,0x00ae,'\0'};
- if (!pSHFileOperationW)
- {
- skip("SHFileOperationW() is missing\n");
- return;
- }
-
shfoW.hwnd = NULL;
shfoW.wFunc = FO_DELETE;
shfoW.pFrom = UNICODE_PATH;
@@ -2594,7 +2577,7 @@ static void test_unicode(void)
/* Try to delete a file with unicode filename */
ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
- ret = pSHFileOperationW(&shfoW);
+ ret = SHFileOperationW(&shfoW);
ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
@@ -2602,31 +2585,25 @@ static void test_unicode(void)
createTestFileW(UNICODE_PATH);
shfoW.fFlags |= FOF_ALLOWUNDO;
ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
- ret = pSHFileOperationW(&shfoW);
+ ret = SHFileOperationW(&shfoW);
ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
- if(!pSHCreateDirectoryExW)
- {
- skip("Skipping SHCreateDirectoryExW tests\n");
- return;
- }
-
/* Try to delete a directory with unicode filename */
- ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
+ ret = SHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
ok(file_existsW(UNICODE_PATH), "The directory is not created\n");
shfoW.fFlags &= ~FOF_ALLOWUNDO;
- ret = pSHFileOperationW(&shfoW);
+ ret = SHFileOperationW(&shfoW);
ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
ok(!file_existsW(UNICODE_PATH), "The directory should have been
removed\n");
/* Try to trash a directory with unicode filename */
- ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
+ ret = SHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
ok(file_existsW(UNICODE_PATH), "The directory was not created\n");
shfoW.fFlags |= FOF_ALLOWUNDO;
- ret = pSHFileOperationW(&shfoW);
+ ret = SHFileOperationW(&shfoW);
ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
ok(!file_existsW(UNICODE_PATH), "The directory should have been
removed\n");
@@ -2711,8 +2688,6 @@ static BOOL is_old_shell32(void)
START_TEST(shlfileop)
{
- InitFunctionPointers();
-
clean_after_shfo_tests();
init_shfo_tests();
diff --git a/modules/rostests/winetests/shell32/shlfolder.c
b/modules/rostests/winetests/shell32/shlfolder.c
index 2ee91ef7d6..f2bd6408ab 100644
--- a/modules/rostests/winetests/shell32/shlfolder.c
+++ b/modules/rostests/winetests/shell32/shlfolder.c
@@ -63,6 +63,10 @@ static HRESULT (WINAPI
*pSHGetItemFromObject)(IUnknown*,REFIID,void**);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static HRESULT (WINAPI *pSHCreateDefaultContextMenu)(const
DEFCONTEXTMENU*,REFIID,void**);
static BOOL (WINAPI
*pSHGetPathFromIDListEx)(PCIDLIST_ABSOLUTE,WCHAR*,DWORD,GPFIDL_FLAGS);
+#ifdef __REACTOS__
+typedef SHFOLDERCUSTOMSETTINGSW SHFOLDERCUSTOMSETTINGS, *LPSHFOLDERCUSTOMSETTINGS;
+#endif
+static HRESULT (WINAPI
*pSHGetSetFolderCustomSettings)(LPSHFOLDERCUSTOMSETTINGS,PCWSTR,DWORD);
static WCHAR *make_wstr(const char *str)
{
@@ -116,6 +120,7 @@ static void init_function_pointers(void)
MAKEFUNC(SHGetItemFromObject);
MAKEFUNC(SHCreateDefaultContextMenu);
MAKEFUNC(SHGetPathFromIDListEx);
+ MAKEFUNC(SHGetSetFolderCustomSettings);
#undef MAKEFUNC
/* test named exports */
@@ -172,108 +177,103 @@ static LPWSTR myPathAddBackslashW( LPWSTR lpszPath )
return lpszPath;
}
+static struct
+{
+ WCHAR path[MAX_PATH];
+ HRESULT hr;
+ int todo;
+} parse_tests[] = {
+ {{'c',':','\\',0}, S_OK},
+ {{'c',':','\\','\\',0}, E_INVALIDARG, 1},
+
{{'c',':','\\','f','a','k','e',0},
0x80070002}, /* ERROR_FILE_NOT_FOUND */
+ {{'c',':','f','a','k','e',0},
E_INVALIDARG, 1},
+ {{'c',':','/',0}, E_INVALIDARG, 1},
+
{{'c',':','\\','w','i','n','d','o','w','s',0},
S_OK},
+
{{'c',':','\\','w','i','n','d','o','w','s','\\',0},
S_OK},
+
{{'c',':','\\','w','i','n','d','o','w','s','\\','.',0},
E_INVALIDARG, 1},
+
{{'c',':','\\','w','i','n','d','o','w','s','\\','.','.',0},
E_INVALIDARG, 1},
+ {{'.',0}, E_INVALIDARG, 1},
+ {{'.','.',0}, E_INVALIDARG, 1},
+ {{'t','e','s','t',0}, 0x80070002},
+ {{'t','e','s','t','\\',0}, 0x80070002},
+
{{'s','u','b','\\','d','i','r',0},
0x80070002},
+
{{'s','u','b','/','d','i','r',0},
E_INVALIDARG, 1},
+ {{'h','t','t','p',':',0}, S_OK, 1},
+
{{'h','t','t','p',':','t','e','s','t',0},
S_OK, 1},
+
{{'h','t','t','p',':','\\','t','e','s','t',0},
S_OK, 1},
+ {{'x','x',':',0}, S_OK, 1},
+};
+
static void test_ParseDisplayName(void)
{
+ static WCHAR testdirW[] =
{'p','a','r','s','e','t','e','s','t',0};
+ static WCHAR backslashW[] = {'\\',0};
+ WCHAR buffer[MAX_PATH], buffer2[MAX_PATH];
+ IShellFolder *desktop;
+ ITEMIDLIST *pidl;
HRESULT hr;
- IShellFolder *IDesktopFolder;
- static const char *cNonExistDir1A = "c:\\nonexist_subdir";
- static const char *cNonExistDir2A = "c:\\\\nonexist_subdir";
- static const char *cInetTestA = "http:\\yyy";
- static const char *cInetTest2A = "xx:yyy";
- DWORD res;
- WCHAR cTestDirW [MAX_PATH] = {0};
- ITEMIDLIST *newPIDL;
BOOL bRes;
+ int i;
- hr = SHGetDesktopFolder(&IDesktopFolder);
+ hr = SHGetDesktopFolder(&desktop);
ok(hr == S_OK, "Expected SHGetDesktopFolder to return S_OK, got 0x%08x\n",
hr);
- if(hr != S_OK) return;
-
- if (pSHCreateShellItem)
- {
- if (0)
- {
- /* null name and pidl, crashes on Windows 8 */
- hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL,
- NULL, NULL, NULL, 0);
- ok(hr == E_INVALIDARG, "returned %08x, expected E_INVALIDARG\n",
hr);
- }
-
- /* null name */
- newPIDL = (ITEMIDLIST*)0xdeadbeef;
- hr = IShellFolder_ParseDisplayName(IDesktopFolder,
- NULL, NULL, NULL, NULL, &newPIDL, 0);
- ok(newPIDL == 0, "expected null, got %p\n", newPIDL);
- ok(hr == E_INVALIDARG, "returned %08x, expected E_INVALIDARG\n", hr);
- }
- else
- win_skip("SHCreateShellItem requires XP SP1 or later\n");
-
- MultiByteToWideChar(CP_ACP, 0, cInetTestA, -1, cTestDirW, MAX_PATH);
- hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cTestDirW, NULL,
&newPIDL, 0);
- todo_wine ok(hr == S_OK, "ParseDisplayName returned %08x, expected
SUCCESS\n", hr);
- if (hr == S_OK)
- {
- ok(ILFindLastID(newPIDL)->mkid.abID[0] == 0x61, "Last pidl should be of
type "
- "PT_IESPECIAL1, but is: %02x\n",
ILFindLastID(newPIDL)->mkid.abID[0]);
- IMalloc_Free(ppM, newPIDL);
- }
- MultiByteToWideChar(CP_ACP, 0, cInetTest2A, -1, cTestDirW, MAX_PATH);
- hr = IShellFolder_ParseDisplayName(IDesktopFolder,
- NULL, NULL, cTestDirW, NULL, &newPIDL, 0);
- todo_wine ok(hr == S_OK, "ParseDisplayName returned %08x, expected
SUCCESS\n", hr);
- if (hr == S_OK)
- {
- ok(ILFindLastID(newPIDL)->mkid.abID[0] == 0x61, "Last pidl should be of
type "
- "PT_IESPECIAL1, but is: %02x\n",
ILFindLastID(newPIDL)->mkid.abID[0]);
- IMalloc_Free(ppM, newPIDL);
- }
+ hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, NULL, NULL, &pidl,
NULL);
+ ok(hr == E_INVALIDARG, "got %#x\n", hr);
- res = GetFileAttributesA(cNonExistDir1A);
- if(res != INVALID_FILE_ATTRIBUTES)
+ for (i = 0; i < ARRAY_SIZE(parse_tests); i++)
{
- skip("Test directory unexpectedly exists\n");
- goto finished;
+ hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, parse_tests[i].path,
NULL, &pidl, NULL);
+todo_wine_if(parse_tests[i].todo)
+ ok(hr == parse_tests[i].hr, "%s: expected %#x, got %#x\n",
+ wine_dbgstr_w(parse_tests[i].path), parse_tests[i].hr, hr);
+ if (SUCCEEDED(hr))
+ CoTaskMemFree(pidl);
}
- MultiByteToWideChar(CP_ACP, 0, cNonExistDir1A, -1, cTestDirW, MAX_PATH);
- hr = IShellFolder_ParseDisplayName(IDesktopFolder,
- NULL, NULL, cTestDirW, NULL, &newPIDL, 0);
- ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
- "ParseDisplayName returned %08x, expected 0x80070002\n", hr);
-
- res = GetFileAttributesA(cNonExistDir2A);
- if(res != INVALID_FILE_ATTRIBUTES)
- {
- skip("Test directory unexpectedly exists\n");
- goto finished;
- }
-
- MultiByteToWideChar(CP_ACP, 0, cNonExistDir2A, -1, cTestDirW, MAX_PATH);
- hr = IShellFolder_ParseDisplayName(IDesktopFolder,
- NULL, NULL, cTestDirW, NULL, &newPIDL, 0);
- todo_wine ok(hr == E_INVALIDARG, "ParseDisplayName returned %08x, expected
E_INVALIDARG\n", hr);
-
/* I thought that perhaps the DesktopFolder's ParseDisplayName would recognize
the
* path corresponding to CSIDL_PERSONAL and return a CLSID_MyDocuments PIDL. Turns
* out it doesn't. The magic seems to happen in the file dialogs, then. */
- bRes = SHGetSpecialFolderPathW(NULL, cTestDirW, CSIDL_PERSONAL, FALSE);
+ bRes = SHGetSpecialFolderPathW(NULL, buffer, CSIDL_PERSONAL, FALSE);
ok(bRes, "SHGetSpecialFolderPath(CSIDL_PERSONAL) failed! %u\n",
GetLastError());
- if (!bRes) goto finished;
- hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cTestDirW, NULL,
&newPIDL, 0);
+ hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, buffer, NULL, &pidl, 0);
ok(hr == S_OK, "DesktopFolder->ParseDisplayName failed. hr = %08x.\n",
hr);
- if (hr != S_OK) goto finished;
- ok(ILFindLastID(newPIDL)->mkid.abID[0] == 0x31,
+ ok(ILFindLastID(pidl)->mkid.abID[0] == 0x31,
"Last pidl should be of type PT_FOLDER, but is: %02x\n",
- ILFindLastID(newPIDL)->mkid.abID[0]);
- IMalloc_Free(ppM, newPIDL);
+ ILFindLastID(pidl)->mkid.abID[0]);
+ CoTaskMemFree(pidl);
-finished:
- IShellFolder_Release(IDesktopFolder);
+ /* Relative paths are interpreted relative to the desktop. */
+ GetTempPathW(ARRAY_SIZE(buffer), buffer);
+ GetLongPathNameW(buffer, buffer, ARRAY_SIZE(buffer));
+ SetCurrentDirectoryW(buffer);
+ CreateDirectoryW(testdirW, NULL);
+
+ hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, testdirW, NULL, &pidl,
NULL);
+ ok(hr == 0x80070002, "got %#x\n", hr);
+
+ RemoveDirectoryW(testdirW);
+
+ hr = SHGetSpecialFolderPathW(NULL, buffer, CSIDL_DESKTOP, FALSE);
+ ok(hr == S_FALSE, "got %#x\n", hr);
+ SetCurrentDirectoryW(buffer);
+ CreateDirectoryW(testdirW, NULL);
+
+ hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, testdirW, NULL, &pidl,
NULL);
+ ok(hr == S_OK, "got %#x\n", hr);
+
+ ok(SHGetPathFromIDListW(pidl, buffer2), "SHGetPathFromIDList failed\n");
+ lstrcatW(buffer, backslashW);
+ lstrcatW(buffer, testdirW);
+ ok(!lstrcmpW(buffer, buffer2), "expected %s, got %s\n",
wine_dbgstr_w(buffer), wine_dbgstr_w(buffer2));
+
+ RemoveDirectoryW(testdirW);
+ CoTaskMemFree(pidl);
+
+ IShellFolder_Release(desktop);
}
/* creates a file with the specified name for tests */
@@ -1962,7 +1962,7 @@ static void test_LocalizedNames(void)
hr = IShellFolder_GetDisplayNameOf(testIShellFolder, newPIDL, SHGDN_INFOLDER,
&strret);
ok(hr == S_OK, "GetDisplayNameOf failed %08x\n", hr);
- hr = StrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR));
+ hr = StrRetToBufW(&strret, newPIDL, tempbufW, ARRAY_SIZE(tempbufW));
ok (hr == S_OK, "StrRetToBufW failed! hr = %08x\n", hr);
todo_wine
ok (!lstrcmpiW(tempbufW, folderdisplayW), "GetDisplayNameOf returned %s\n",
wine_dbgstr_w(tempbufW));
@@ -1971,7 +1971,7 @@ static void test_LocalizedNames(void)
hr = IShellFolder_GetDisplayNameOf(testIShellFolder, newPIDL,
SHGDN_INFOLDER|SHGDN_FOREDITING, &strret);
ok(hr == S_OK, "GetDisplayNameOf failed %08x\n", hr);
- hr = StrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR));
+ hr = StrRetToBufW(&strret, newPIDL, tempbufW, ARRAY_SIZE(tempbufW));
ok (hr == S_OK, "StrRetToBufW failed! hr = %08x\n", hr);
todo_wine
ok (!lstrcmpiW(tempbufW, folderdisplayW), "GetDisplayNameOf returned %s\n",
wine_dbgstr_w(tempbufW));
@@ -1980,7 +1980,7 @@ static void test_LocalizedNames(void)
hr = IShellFolder_GetDisplayNameOf(testIShellFolder, newPIDL,
SHGDN_INFOLDER|SHGDN_FORPARSING, &strret);
ok(hr == S_OK, "GetDisplayNameOf failed %08x\n", hr);
- hr = StrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR));
+ hr = StrRetToBufW(&strret, newPIDL, tempbufW, ARRAY_SIZE(tempbufW));
ok (hr == S_OK, "StrRetToBufW failed! hr = %08x\n", hr);
ok (!lstrcmpiW(tempbufW, foldernameW), "GetDisplayNameOf returned %s\n",
wine_dbgstr_w(tempbufW));
@@ -4978,7 +4978,8 @@ static void test_SHChangeNotify(BOOL test_new_delivery)
SHCNE_ALLEVENTS, WM_USER_NOTIFY, 1, entries);
ok(notifyID != 0, "Failed to register a window for change
notifications\n");
- for(i = 0; i < sizeof(chnotify_tests) / sizeof(*chnotify_tests); ++i){
+ for (i = 0; i < ARRAY_SIZE(chnotify_tests); ++i)
+ {
exp_data = chnotify_tests + i;
exp_data->missing_events = exp_data->notify_count;
@@ -5170,7 +5171,7 @@ static void test_GetDefaultColumn(void)
CoInitialize(NULL);
- for (i = 0; i < sizeof(folders)/sizeof(folders[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(folders); i++)
{
IShellFolder2 *folder;
ULONG sort, display;
@@ -5199,6 +5200,8 @@ static void test_GetDefaultColumn(void)
hr = IShellFolder2_GetDefaultColumn(folder, 0, &sort, NULL);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
ok(sort == 123, "Unexpected default column.\n");
+
+ IShellFolder2_Release(folder);
}
CoUninitialize();
@@ -5221,7 +5224,7 @@ static void test_GetDefaultSearchGUID(void)
CoInitialize(NULL);
- for (i = 0; i < sizeof(folders)/sizeof(folders[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(folders); i++)
{
IShellFolder2 *folder;
GUID guid;
@@ -5252,6 +5255,86 @@ static void test_GetDefaultSearchGUID(void)
CoUninitialize();
}
+static void test_SHLimitInputEdit(void)
+{
+ IShellFolder *desktop;
+ HRESULT hr;
+ HWND hwnd;
+
+ hr = SHGetDesktopFolder(&desktop);
+ ok(hr == S_OK, "Failed to get desktop folder, hr %#x.\n", hr);
+
+ hr = SHLimitInputEdit(NULL, desktop);
+todo_wine
+ ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
+
+ hwnd = CreateWindowA("EDIT", NULL, WS_VISIBLE, 0, 0, 100, 30, NULL, NULL,
NULL, NULL);
+ ok(hwnd != NULL, "Failed to create Edit control.\n");
+
+ hr = SHLimitInputEdit(hwnd, desktop);
+todo_wine
+ ok(hr == S_OK, "Failed to set input limits, hr %#x.\n", hr);
+
+ hr = SHLimitInputEdit(hwnd, desktop);
+todo_wine
+ ok(hr == S_OK, "Failed to set input limits, hr %#x.\n", hr);
+
+ DestroyWindow(hwnd);
+ IShellFolder_Release(desktop);
+}
+
+static void test_SHGetSetFolderCustomSettings(void)
+{
+ HRESULT hr;
+ SHFOLDERCUSTOMSETTINGS fcs;
+ WCHAR pathW[MAX_PATH];
+ WCHAR bufferW[MAX_PATH];
+ WCHAR iconpathW[MAX_PATH];
+ static const WCHAR somedirW[] =
{'s','o','m','e','_','d','i','r',0};
+ static const WCHAR iconW[] =
{'\\','s','o','m','e','_','i','c','o','n','.','i','c','o',0};
+ static const WCHAR desktop_iniW[] =
{'\\','D','e','s','k','t','o','p','.','i','n','i',0};
+
+ if (!pSHGetSetFolderCustomSettings)
+ {
+ win_skip("SHGetSetFolderCustomSetting not exported by name (only by ordinal)
for version XP/win2003\n");
+ return;
+ }
+
+ GetTempPathW(MAX_PATH, pathW);
+ lstrcatW(pathW, somedirW);
+ CreateDirectoryW(pathW, NULL);
+
+ lstrcpyW(iconpathW, pathW);
+ lstrcatW(iconpathW, iconW);
+
+ memset(&fcs, 0, sizeof(fcs));
+ fcs.dwSize = sizeof(fcs);
+ fcs.dwMask = FCSM_ICONFILE;
+ fcs.pszIconFile = iconpathW;
+
+ hr = pSHGetSetFolderCustomSettings(&fcs, pathW, FCS_FORCEWRITE); /*creates and
writes to a Desktop.ini*/
+ ok(hr == S_OK, "Expected S_OK, got %#x\n", hr);
+
+ memset(&fcs, 0, sizeof(fcs));
+ fcs.dwSize = sizeof(fcs);
+ fcs.dwMask = FCSM_ICONFILE;
+ fcs.cchIconFile = MAX_PATH;
+ fcs.pszIconFile = bufferW;
+ bufferW[0] = 0;
+
+ hr = pSHGetSetFolderCustomSettings(&fcs, pathW, FCS_READ);
+ todo_wine ok(hr == S_OK, "Expected S_OK, got %#x\n", hr);
+ todo_wine ok(!lstrcmpiW(iconpathW, fcs.pszIconFile), "Expected %s, got
%s\n", wine_dbgstr_w(iconpathW), wine_dbgstr_w(fcs.pszIconFile));
+
+ hr = pSHGetSetFolderCustomSettings(&fcs, NULL, FCS_READ);
+ ok(hr == E_FAIL, "Expected E_FAIL, got %#x\n", hr);
+
+ lstrcpyW(bufferW, pathW);
+ lstrcatW(bufferW, desktop_iniW);
+ DeleteFileW(bufferW);
+ RemoveDirectoryW(pathW);
+}
+
START_TEST(shlfolder)
{
init_function_pointers();
@@ -5293,6 +5376,8 @@ START_TEST(shlfolder)
test_DataObject();
test_GetDefaultColumn();
test_GetDefaultSearchGUID();
+ test_SHLimitInputEdit();
+ test_SHGetSetFolderCustomSettings();
OleUninitialize();
}
diff --git a/modules/rostests/winetests/shell32/shlview.c
b/modules/rostests/winetests/shell32/shlview.c
index 36fa759719..abc3e16826 100644
--- a/modules/rostests/winetests/shell32/shlview.c
+++ b/modules/rostests/winetests/shell32/shlview.c
@@ -1483,7 +1483,6 @@ static void test_newmenu(void)
HRESULT hr;
hr = CoCreateInstance(&CLSID_NewMenu, NULL, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk);
-todo_wine
ok(hr == S_OK, "Failed to create NewMenu object, hr %#x.\n", hr);
if (hr != S_OK)
{
@@ -1495,6 +1494,14 @@ todo_wine
ok(hr == S_OK, "Failed to get IShellExtInit, hr %#x.\n", hr);
IUnknown_Release(unk2);
+ hr = IUnknown_QueryInterface(unk, &IID_IContextMenu, (void **)&unk2);
+ ok(hr == S_OK, "Failed to get IContextMenu, hr %#x.\n", hr);
+ IUnknown_Release(unk2);
+
+ hr = IUnknown_QueryInterface(unk, &IID_IContextMenu2, (void **)&unk2);
+ ok(hr == S_OK, "Failed to get IContextMenu2, hr %#x.\n", hr);
+ IUnknown_Release(unk2);
+
hr = IUnknown_QueryInterface(unk, &IID_IContextMenu3, (void **)&unk2);
ok(hr == S_OK, "Failed to get IContextMenu3, hr %#x.\n", hr);
IUnknown_Release(unk2);
diff --git a/modules/rostests/winetests/shell32/string.c
b/modules/rostests/winetests/shell32/string.c
index 6cdb386eba..5fd589300b 100644
--- a/modules/rostests/winetests/shell32/string.c
+++ b/modules/rostests/winetests/shell32/string.c
@@ -67,14 +67,14 @@ static void test_StrRetToStringNW(void)
strret.uType = STRRET_WSTR;
U(strret).pOleStr = CoDupStrW("Test");
memset(buff, 0xff, sizeof(buff));
- ret = pStrRetToStrNAW(buff, sizeof(buff)/sizeof(WCHAR), &strret, NULL);
+ ret = pStrRetToStrNAW(buff, ARRAY_SIZE(buff), &strret, NULL);
ok(ret == TRUE && !strcmpW(buff, szTestW),
"STRRET_WSTR: dup failed, ret=%d\n", ret);
strret.uType = STRRET_CSTR;
lstrcpyA(U(strret).cStr, "Test");
memset(buff, 0xff, sizeof(buff));
- ret = pStrRetToStrNAW(buff, sizeof(buff)/sizeof(WCHAR), &strret, NULL);
+ ret = pStrRetToStrNAW(buff, ARRAY_SIZE(buff), &strret, NULL);
ok(ret == TRUE && !strcmpW(buff, szTestW),
"STRRET_CSTR: dup failed, ret=%d\n", ret);
@@ -82,7 +82,7 @@ static void test_StrRetToStringNW(void)
U(strret).uOffset = 1;
strcpy((char*)&iidl, " Test");
memset(buff, 0xff, sizeof(buff));
- ret = pStrRetToStrNAW(buff, sizeof(buff)/sizeof(WCHAR), &strret, iidl);
+ ret = pStrRetToStrNAW(buff, ARRAY_SIZE(buff), &strret, iidl);
ok(ret == TRUE && !strcmpW(buff, szTestW),
"STRRET_OFFSET: dup failed, ret=%d\n", ret);
@@ -92,7 +92,7 @@ if (0)
/* Invalid dest - should return FALSE, except NT4 does not, so we don't check.
*/
strret.uType = STRRET_WSTR;
U(strret).pOleStr = CoDupStrW("Test");
- pStrRetToStrNAW(NULL, sizeof(buff)/sizeof(WCHAR), &strret, NULL);
+ pStrRetToStrNAW(NULL, ARRAY_SIZE(buff), &strret, NULL);
trace("NULL dest: ret=%d\n", ret);
}
}