[SHELL32_WINETEST] Sync with Wine Staging 1.7.55. CORE-10536
authorAmine Khaldi <amine.khaldi@reactos.org>
Tue, 8 Dec 2015 10:33:14 +0000 (10:33 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Tue, 8 Dec 2015 10:33:14 +0000 (10:33 +0000)
svn path=/trunk/; revision=70295

13 files changed:
rostests/winetests/shell32/appbar.c
rostests/winetests/shell32/assoc.c
rostests/winetests/shell32/ebrowser.c
rostests/winetests/shell32/progman_dde.c
rostests/winetests/shell32/shelldispatch.c
rostests/winetests/shell32/shelllink.c
rostests/winetests/shell32/shellole.c
rostests/winetests/shell32/shellpath.c
rostests/winetests/shell32/shlexec.c
rostests/winetests/shell32/shlfileop.c
rostests/winetests/shell32/shlfolder.c
rostests/winetests/shell32/string.c
rostests/winetests/shell32/systray.c

index 7675493..8138131 100644 (file)
@@ -29,6 +29,7 @@
 static const CHAR testwindow_class[] = "testwindow";
 
 static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD);
+static HRESULT (WINAPI *pGetCurrentProcessExplicitAppUserModelID)(PWSTR*);
 
 typedef BOOL (*boolean_function)(void);
 
@@ -430,15 +431,39 @@ static void test_appbarget(void)
     return;
 }
 
+static void test_GetCurrentProcessExplicitAppUserModelID(void)
+{
+    WCHAR *appid;
+    HRESULT hr;
+
+    if (!pGetCurrentProcessExplicitAppUserModelID)
+    {
+        win_skip("GetCurrentProcessExplicitAppUserModelID() is not supported.\n");
+        return;
+    }
+
+if (0) /* crashes on native */
+    hr = pGetCurrentProcessExplicitAppUserModelID(NULL);
+
+    appid = (void*)0xdeadbeef;
+    hr = pGetCurrentProcessExplicitAppUserModelID(&appid);
+todo_wine
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+    ok(appid == NULL, "got %p\n", appid);
+}
+
 START_TEST(appbar)
 {
-    HMODULE huser32;
+    HMODULE huser32, hshell32;
 
     huser32 = GetModuleHandleA("user32.dll");
+    hshell32 = GetModuleHandleA("shell32.dll");
     pMonitorFromWindow = (void*)GetProcAddress(huser32, "MonitorFromWindow");
+    pGetCurrentProcessExplicitAppUserModelID = (void*)GetProcAddress(hshell32, "GetCurrentProcessExplicitAppUserModelID");
 
     register_testwindow_class();
 
     test_setpos();
     test_appbarget();
+    test_GetCurrentProcessExplicitAppUserModelID();
 }
index 0092081..8aa2535 100644 (file)
@@ -192,7 +192,7 @@ static void test_IApplicationAssociationRegistration_QueryCurrentDefault(IApplic
     ok(hr == E_INVALIDARG, "got 0x%x\n", hr);
 
     hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, spacetxtW, AT_FILEEXTENSION, AL_EFFECTIVE, &assocprog);
-    ok(hr == E_INVALIDARG || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /* Win8 */, "got 0x%x\n", hr);
+    ok(hr == E_INVALIDARG || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /*Win8*/, "got 0x%x\n", hr);
 
     hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, httpW, AT_URLPROTOCOL, AL_EFFECTIVE, NULL);
     ok(hr == E_INVALIDARG, "got 0x%x\n", hr);
@@ -212,13 +212,14 @@ static void test_IApplicationAssociationRegistration_QueryCurrentDefault(IApplic
     hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, httpW, AT_URLPROTOCOL, AL_EFFECTIVE, &assocprog);
     todo_wine ok(hr == S_OK, "got 0x%x\n", hr);
     trace("%s\n", wine_dbgstr_w(assocprog));
+
     CoTaskMemFree(assocprog);
 }
 
 START_TEST(assoc)
 {
     IQueryAssociations *qa;
-    IApplicationAssociationRegistration *appreg;
+    IApplicationAssociationRegistration *appreg = NULL;
     HRESULT hr;
 
     CoInitialize(NULL);
@@ -238,7 +239,7 @@ START_TEST(assoc)
 
     /* this works since Vista */
     hr = CoCreateInstance(&CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC_SERVER,
-                          &IID_IApplicationAssociationRegistration, (LPVOID *)&appreg);
+                          &IID_IApplicationAssociationRegistration, (LPVOID*)&appreg);
     if (hr == S_OK)
     {
         test_IApplicationAssociationRegistration_QueryInterface(appreg);
index 4c255a1..7a01d56 100644 (file)
@@ -759,8 +759,10 @@ static void test_initialization(void)
 {
     IExplorerBrowser *peb;
     IShellBrowser *psb;
+    HWND eb_hwnd;
     HRESULT hr;
     ULONG lres;
+    LONG style;
     RECT rc;
 
     ebrowser_instantiate(&peb);
@@ -807,10 +809,9 @@ static void test_initialization(void)
     ok(hr == S_OK, "Got 0x%08x\n", hr);
     if(SUCCEEDED(hr))
     {
-        HWND eb_hwnd;
         RECT eb_rc;
         char buf[1024];
-        LONG style, expected_style;
+        LONG expected_style;
         static const RECT exp_rc = {0, 0, 48, 58};
 
         hr = IShellBrowser_GetWindow(psb, &eb_hwnd);
@@ -856,6 +857,29 @@ static void test_initialization(void)
         ok(lres == 0, "Got refcount %d\n", lres);
     }
 
+    /* check window style with EBO_NOBORDER */
+    ebrowser_instantiate(&peb);
+    hr = IExplorerBrowser_SetOptions(peb, EBO_NOBORDER);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    rc.left = 50; rc.top = 20; rc.right = 100; rc.bottom = 80;
+
+    hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+
+    hr = IShellBrowser_GetWindow(psb, &eb_hwnd);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+
+    style = GetWindowLongPtrW(eb_hwnd, GWL_STYLE);
+    ok(!(style & WS_BORDER) || broken(style & WS_BORDER) /* before win8 */, "got style 0x%08x\n", style);
+
+    IShellBrowser_Release(psb);
+    IExplorerBrowser_Destroy(peb);
+    IExplorerBrowser_Release(peb);
+
+    /* empty rectangle */
     ebrowser_instantiate(&peb);
     rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0;
     hr = IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
@@ -1469,7 +1493,7 @@ static void test_navigation(void)
         test_browse_pidl_sb(peb2, &ebev, pidl_relative, SBSP_RELATIVE, S_OK, 1, 1, 0, 1);
 
         ILFree(pidl_relative);
-        /* IShellFolder_Release(psf); */
+        IShellFolder_Release(psf);
         IFolderView_Release(pfv);
     }
 
index 5b22387..a3faa83 100644 (file)
@@ -363,7 +363,7 @@ static void DdeExecuteCommand(DWORD instance, HCONV hConv, const char *strCmd, H
  * window creation happened were not encouraging (not including
  * SetWindowsHookEx).
  */
-static void CheckWindowCreated(const char *winName, BOOL closeWindow, int testParams)
+static HWND CheckWindowCreated(const char *winName, BOOL closeWindow, int testParams)
 {
     HWND window = NULL;
     int i;
@@ -381,7 +381,9 @@ static void CheckWindowCreated(const char *winName, BOOL closeWindow, int testPa
     if (window != NULL && closeWindow)
     {
         SendMessageA(window, WM_SYSCOMMAND, SC_CLOSE, 0);
+        window = NULL;
     }
+    return window;
 }
 
 /* Check for Existence (or non-existence) of a file or group
@@ -468,11 +470,12 @@ static void CreateGroupTest(DWORD instance, HCONV hConv, const char *command, UI
  *   if expected_result is DMLERR_NO_ERROR, test
  *        1. window is open
  */
-static void ShowGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
+static HWND ShowGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
                           const char *groupName, const char *windowTitle, BOOL closeAfterShowing, int testParams)
 {
     HDDEDATA hData;
     UINT error;
+    HWND hwnd = 0;
 
     DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
 /* todo_wine...  Is expected to fail, wine stubbed functions DO fail */
@@ -494,8 +497,9 @@ static void ShowGroupTest(DWORD instance, HCONV hConv, const char *command, UINT
     if (error == DMLERR_NO_ERROR)
     {
         /* Check if Window is Open (polling) */
-        CheckWindowCreated(windowTitle, closeAfterShowing, testParams);
+        hwnd = CheckWindowCreated(windowTitle, closeAfterShowing, testParams);
     }
+    return hwnd;
 }
 
 /* Delete Group Test.
@@ -582,12 +586,13 @@ static void DeleteItemTest(DWORD instance, HCONV hConv, const char *command, UIN
  *   All samples I've seen using Compound were of this form (CreateGroup,
  *   AddItems) so this covers minimum expected functionality.
  */
-static void CompoundCommandTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
+static HWND CompoundCommandTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
                                 const char *groupName, const char *windowTitle, const char *fileName1,
                                 const char *fileName2, int testParams)
 {
     HDDEDATA hData;
     UINT error;
+    HWND hwnd = 0;
 
     DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
     todo_wine
@@ -601,10 +606,11 @@ static void CompoundCommandTest(DWORD instance, HCONV hConv, const char *command
     {
         /* Check that File exists */
         CheckFileExistsInProgramGroups(groupName, TRUE, TRUE, NULL, testParams);
-        CheckWindowCreated(windowTitle, FALSE, testParams);
+        hwnd = CheckWindowCreated(windowTitle, FALSE, testParams);
         CheckFileExistsInProgramGroups(fileName1, TRUE, FALSE, groupName, testParams);
         CheckFileExistsInProgramGroups(fileName2, TRUE, FALSE, groupName, testParams);
     }
+    return hwnd;
 }
 
 static void CreateAddItemText(char *itemtext, const char *cmdline, const char *name)
@@ -626,6 +632,7 @@ static int DdeTestProgman(DWORD instance, HCONV hConv)
     char f1g1[MAX_PATH], f2g1[MAX_PATH], f3g1[MAX_PATH], f1g3[MAX_PATH], f2g3[MAX_PATH];
     char itemtext[MAX_PATH + 20];
     char comptext[2 * (MAX_PATH + 20) + 21];
+    HWND hwnd;
 
     testnum = 1;
     /* Invalid Command */
@@ -658,10 +665,11 @@ static int DdeTestProgman(DWORD instance, HCONV hConv)
     ShowGroupTest(instance, hConv, "[ShowGroup(Group1)]", DMLERR_NOTPROCESSED, "Group1", Group1Title, TRUE, DDE_TEST_SHOWGROUP|testnum++);
     DeleteItemTest(instance, hConv, "[DeleteItem(f3g1Name)]", DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++);
     ShowGroupTest(instance, hConv, "[ShowGroup(Startup,0)]", DMLERR_NO_ERROR, "Startup", StartupTitle, TRUE, DDE_TEST_SHOWGROUP|testnum++);
-    ShowGroupTest(instance, hConv, "[ShowGroup(Group1,0)]", DMLERR_NO_ERROR, "Group1", Group1Title, FALSE, DDE_TEST_SHOWGROUP|testnum++);
+    hwnd = ShowGroupTest(instance, hConv, "[ShowGroup(Group1,0)]", DMLERR_NO_ERROR, "Group1", Group1Title, FALSE, DDE_TEST_SHOWGROUP|testnum++);
 
     /* DeleteGroup Test - Note that Window is Open for this test */
     DeleteGroupTest(instance, hConv, "[DeleteGroup(Group1)]", DMLERR_NO_ERROR, "Group1", DDE_TEST_DELETEGROUP|testnum++);
+    if (hwnd) SendMessageA(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
 
     /* Compound Execute String Command */
     lstrcpyA(comptext, "[CreateGroup(Group3)]");
@@ -669,9 +677,10 @@ static int DdeTestProgman(DWORD instance, HCONV hConv)
     lstrcatA(comptext, itemtext);
     CreateAddItemText(itemtext, f2g3, "f2g3Name");
     lstrcatA(comptext, itemtext);
-    CompoundCommandTest(instance, hConv, comptext, DMLERR_NO_ERROR, "Group3", Group3Title, "f1g3Name.lnk", "f2g3Name.lnk", DDE_TEST_COMPOUND|testnum++);
+    hwnd = CompoundCommandTest(instance, hConv, comptext, DMLERR_NO_ERROR, "Group3", Group3Title, "f1g3Name.lnk", "f2g3Name.lnk", DDE_TEST_COMPOUND|testnum++);
 
     DeleteGroupTest(instance, hConv, "[DeleteGroup(Group3)]", DMLERR_NO_ERROR, "Group3", DDE_TEST_DELETEGROUP|testnum++);
+    if (hwnd) SendMessageA(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
 
     /* Full Parameters of Add Item */
     /* AddItem(CmdLine[,Name[,IconPath[,IconIndex[,xPos,yPos[,DefDir[,HotKey[,fMinimize[fSeparateSpace]]]]]]]) */
index 0c49674..d7834f3 100644 (file)
@@ -363,6 +363,511 @@ static void test_service(void)
     IShellDispatch2_Release(sd);
 }
 
+static void test_dispatch_typeinfo(IDispatch *disp, REFIID *riid)
+{
+    ITypeInfo *typeinfo;
+    TYPEATTR *typeattr;
+    UINT count;
+    HRESULT hr;
+
+    count = 10;
+    hr = IDispatch_GetTypeInfoCount(disp, &count);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(count == 1, "got %u\n", count);
+
+    hr = IDispatch_GetTypeInfo(disp, 0, LOCALE_SYSTEM_DEFAULT, &typeinfo);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    while (!IsEqualGUID(*riid, &IID_NULL)) {
+        if (IsEqualGUID(&typeattr->guid, *riid))
+            break;
+        riid++;
+    }
+    ok(IsEqualGUID(&typeattr->guid, *riid), "unexpected type guid %s\n", wine_dbgstr_guid(&typeattr->guid));
+
+    ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
+    ITypeInfo_Release(typeinfo);
+}
+
+static void test_ShellFolderViewDual(void)
+{
+    static const IID *shelldisp_riids[] = {
+        &IID_IShellDispatch6,
+        &IID_IShellDispatch5,
+        &IID_IShellDispatch4,
+        &IID_IShellDispatch2,
+        &IID_NULL
+    };
+    IShellFolderViewDual *viewdual;
+    IShellFolder *desktop, *tmpdir;
+    IShellView *view, *view2;
+    IDispatch *disp, *disp2;
+    WCHAR pathW[MAX_PATH];
+    LPITEMIDLIST pidl;
+    HRESULT hr;
+
+    /* IShellFolderViewDual is not an IShellView extension */
+    hr = SHGetDesktopFolder(&desktop);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IShellView_QueryInterface(view, &IID_IShellFolderViewDual, (void**)&viewdual);
+    ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+    hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IDispatch, (void**)&disp);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IDispatch, (void**)&disp2);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(disp2 == disp, "got %p, %p\n", disp2, disp);
+    IDispatch_Release(disp2);
+
+    hr = IDispatch_QueryInterface(disp, &IID_IShellFolderViewDual, (void**)&viewdual);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(disp == (IDispatch*)viewdual, "got %p, expected %p\n", viewdual, disp);
+
+    hr = IShellFolderViewDual_QueryInterface(viewdual, &IID_IShellView, (void**)&view2);
+    ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+    /* get_Application() */
+
+if (0) /* crashes on pre-vista */ {
+    hr = IShellFolderViewDual_get_Application(viewdual, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+}
+    hr = IShellFolderViewDual_get_Application(viewdual, &disp2);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(disp2 != (IDispatch*)viewdual, "got %p, %p\n", disp2, viewdual);
+    test_dispatch_typeinfo(disp2, shelldisp_riids);
+    IDispatch_Release(disp2);
+
+    IShellFolderViewDual_Release(viewdual);
+    IDispatch_Release(disp);
+
+    disp = (void*)0xdeadbeef;
+    hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IShellFolderViewDual, (void**)&disp);
+    ok(hr == E_NOINTERFACE || broken(hr == E_NOTIMPL) /* win2k */, "got 0x%08x\n", hr);
+    ok(disp == NULL, "got %p\n", disp);
+    IShellView_Release(view);
+
+    /* Try with some other folder, that's not a desktop */
+    GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW);
+    hr = IShellFolder_ParseDisplayName(desktop, NULL, NULL, pathW, NULL, &pidl, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IShellFolder_BindToObject(desktop, pidl, NULL, &IID_IShellFolder, (void**)&tmpdir);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    CoTaskMemFree(pidl);
+
+    hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&view);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IShellView_QueryInterface(view, &IID_IShellFolderViewDual, (void**)&viewdual);
+    ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+    hr = IShellView_GetItemObject(view, SVGIO_BACKGROUND, &IID_IDispatch, (void**)&disp);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IDispatch_Release(disp);
+    IShellView_Release(view);
+
+    IShellFolder_Release(tmpdir);
+    IShellFolder_Release(desktop);
+}
+
+static void test_ShellWindows(void)
+{
+    IShellWindows *shellwindows;
+    LONG cookie, cookie2, ret;
+    IDispatch *disp;
+    VARIANT v, v2;
+    HRESULT hr;
+    HWND hwnd;
+
+    hr = CoCreateInstance(&CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER,
+        &IID_IShellWindows, (void**)&shellwindows);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    /* TODO: remove when explorer startup with clean prefix is fixed */
+    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);
+
+    hr = IShellWindows_Register(shellwindows, (IDispatch*)shellwindows, 0, SWC_EXPLORER, &cookie);
+todo_wine
+    ok(hr == E_POINTER, "got 0x%08x\n", hr);
+
+    hr = IShellWindows_Register(shellwindows, (IDispatch*)shellwindows, 0, SWC_EXPLORER, &cookie);
+todo_wine
+    ok(hr == E_POINTER, "got 0x%08x\n", hr);
+
+    hwnd = CreateWindowExA(0, "button", "test", BS_CHECKBOX | WS_VISIBLE | WS_POPUP,
+                           0, 0, 50, 14, 0, 0, 0, NULL);
+    ok(hwnd != NULL, "got %p, error %d\n", hwnd, GetLastError());
+
+    cookie = 0;
+    hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_EXPLORER, &cookie);
+todo_wine {
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(cookie != 0, "got %d\n", cookie);
+}
+    cookie2 = 0;
+    hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_EXPLORER, &cookie2);
+todo_wine {
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(cookie2 != 0 && cookie2 != cookie, "got %d\n", cookie2);
+}
+    hr = IShellWindows_Revoke(shellwindows, cookie);
+todo_wine
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = IShellWindows_Revoke(shellwindows, cookie2);
+todo_wine
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IShellWindows_Revoke(shellwindows, 0);
+todo_wine
+    ok(hr == S_FALSE, "got 0x%08x\n", hr);
+
+    /* we can register ourselves as desktop, but FindWindowSW still returns real desktop window */
+    cookie = 0;
+    hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_DESKTOP, &cookie);
+todo_wine {
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(cookie != 0, "got %d\n", cookie);
+}
+    disp = (void*)0xdeadbeef;
+    ret = 0xdead;
+    VariantInit(&v);
+    hr = IShellWindows_FindWindowSW(shellwindows, &v, &v, SWC_DESKTOP, &ret, SWFO_NEEDDISPATCH, &disp);
+    ok(hr == S_OK || broken(hr == S_FALSE), "got 0x%08x\n", hr);
+    if (hr == S_FALSE) /* winxp and earlier */ {
+        win_skip("SWC_DESKTOP is not supported, some tests will be skipped.\n");
+        /* older versions allowed to regiser SWC_DESKTOP and access it with FindWindowSW */
+        ok(disp == NULL, "got %p\n", disp);
+        ok(ret == 0, "got %d\n", ret);
+    }
+    else {
+        static const IID *browser_riids[] = {
+            &IID_IWebBrowser2,
+            &IID_NULL
+        };
+
+        static const IID *viewdual_riids[] = {
+            &IID_IShellFolderViewDual3,
+            &IID_NULL
+        };
+
+        IShellFolderViewDual *view;
+        IShellBrowser *sb, *sb2;
+        IServiceProvider *sp;
+        IDispatch *doc, *app;
+        IWebBrowser2 *wb;
+        IShellView *sv;
+        IUnknown *unk;
+
+        ok(disp != NULL, "got %p\n", disp);
+        ok(ret != HandleToUlong(hwnd), "got %d\n", ret);
+
+        /* IDispatch-related tests */
+        test_dispatch_typeinfo(disp, browser_riids);
+
+        /* IWebBrowser2 */
+        hr = IDispatch_QueryInterface(disp, &IID_IWebBrowser2, (void**)&wb);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IWebBrowser2_Refresh(wb);
+todo_wine
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IWebBrowser2_get_Application(wb, &app);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(disp == app, "got %p, %p\n", app, disp);
+        IDispatch_Release(app);
+
+        hr = IWebBrowser2_get_Document(wb, &doc);
+todo_wine
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+if (hr == S_OK)
+        test_dispatch_typeinfo(doc, viewdual_riids);
+
+        IWebBrowser2_Release(wb);
+
+        /* IServiceProvider */
+        hr = IDispatch_QueryInterface(disp, &IID_IShellFolderViewDual, (void**)&view);
+        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+        hr = IDispatch_QueryInterface(disp, &IID_IServiceProvider, (void**)&sp);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IShellBrowser, (void**)&sb);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IShellBrowser, (void**)&sb2);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(sb == sb2, "got %p, %p\n", sb, sb2);
+
+        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IOleWindow, (void**)&unk);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        IUnknown_Release(unk);
+
+        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IExplorerBrowser, (void**)&unk);
+        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+        hr = IShellBrowser_QueryInterface(sb, &IID_IExplorerBrowser, (void**)&unk);
+        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+        hr = IShellBrowser_QueryInterface(sb, &IID_IWebBrowser2, (void**)&unk);
+        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+        hr = IShellBrowser_QueryInterface(sb, &IID_IDispatch, (void**)&unk);
+        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+        hr = IShellBrowser_QueryActiveShellView(sb, &sv);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        IShellView_Release(sv);
+
+        IShellBrowser_Release(sb2);
+        IShellBrowser_Release(sb);
+
+        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IUnknown, (void**)&unk);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IUnknown_QueryInterface(unk, &IID_IShellBrowser, (void**)&sb2);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        IShellBrowser_Release(sb2);
+        IUnknown_Release(unk);
+
+        hr = IServiceProvider_QueryService(sp, &SID_STopLevelBrowser, &IID_IShellView, (void**)&sv);
+        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+        IServiceProvider_Release(sp);
+        IDispatch_Release(disp);
+    }
+
+    disp = (void*)0xdeadbeef;
+    ret = 0xdead;
+    VariantInit(&v);
+    hr = IShellWindows_FindWindowSW(shellwindows, &v, &v, SWC_DESKTOP, &ret, 0, &disp);
+    ok(hr == S_OK || broken(hr == S_FALSE) /* winxp */, "got 0x%08x\n", hr);
+    ok(disp == NULL, "got %p\n", disp);
+    ok(ret != HandleToUlong(hwnd), "got %d\n", ret);
+
+    disp = (void*)0xdeadbeef;
+    ret = 0xdead;
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = cookie;
+    VariantInit(&v2);
+    hr = IShellWindows_FindWindowSW(shellwindows, &v, &v2, SWC_BROWSER, &ret, SWFO_COOKIEPASSED, &disp);
+todo_wine
+    ok(hr == S_FALSE, "got 0x%08x\n", hr);
+    ok(disp == NULL, "got %p\n", disp);
+    ok(ret == 0, "got %d\n", ret);
+
+    hr = IShellWindows_Revoke(shellwindows, cookie);
+todo_wine
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    DestroyWindow(hwnd);
+    IShellWindows_Release(shellwindows);
+}
+
+static void test_ParseName(void)
+{
+    static const WCHAR cadabraW[] = {'c','a','d','a','b','r','a',0};
+    WCHAR pathW[MAX_PATH];
+    IShellDispatch *sd;
+    FolderItem *item;
+    Folder *folder;
+    HRESULT hr;
+    VARIANT v;
+    BSTR str;
+
+    hr = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER,
+        &IID_IShellDispatch, (void**)&sd);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW);
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = SysAllocString(pathW);
+    hr = IShellDispatch_NameSpace(sd, v, &folder);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    VariantClear(&v);
+
+    item = (void*)0xdeadbeef;
+    hr = Folder_ParseName(folder, NULL, &item);
+    ok(hr == S_FALSE || broken(hr == E_INVALIDARG) /* win2k */, "got 0x%08x\n", hr);
+    ok(item == NULL, "got %p\n", item);
+
+    /* empty name */
+    str = SysAllocStringLen(NULL, 0);
+    item = (void*)0xdeadbeef;
+    hr = Folder_ParseName(folder, str, &item);
+    ok(hr == S_FALSE || broken(hr == E_INVALIDARG) /* win2k */, "got 0x%08x\n", hr);
+    ok(item == NULL, "got %p\n", item);
+    SysFreeString(str);
+
+    /* path doesn't exist */
+    str = SysAllocString(cadabraW);
+    item = (void*)0xdeadbeef;
+    hr = Folder_ParseName(folder, str, &item);
+    ok(hr == S_FALSE || broken(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) /* win2k */,
+        "got 0x%08x\n", hr);
+    ok(item == NULL, "got %p\n", item);
+    SysFreeString(str);
+
+    lstrcatW(pathW, cadabraW);
+    CreateDirectoryW(pathW, NULL);
+
+    str = SysAllocString(cadabraW);
+    item = NULL;
+    hr = Folder_ParseName(folder, str, &item);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(item != NULL, "got %p\n", item);
+    SysFreeString(str);
+
+    hr = FolderItem_get_Path(item, &str);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(str[0] != 0, "path %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    RemoveDirectoryW(pathW);
+    FolderItem_Release(item);
+    Folder_Release(folder);
+    IShellDispatch_Release(sd);
+}
+
+static void test_Verbs(void)
+{
+    FolderItemVerbs *verbs;
+    WCHAR pathW[MAX_PATH];
+    FolderItemVerb *verb;
+    IShellDispatch *sd;
+    FolderItem *item;
+    Folder2 *folder2;
+    Folder *folder;
+    HRESULT hr;
+    LONG count, i;
+    VARIANT v;
+    BSTR str;
+
+    hr = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER,
+        &IID_IShellDispatch, (void**)&sd);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    GetTempPathW(sizeof(pathW)/sizeof(pathW[0]), pathW);
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = SysAllocString(pathW);
+    hr = IShellDispatch_NameSpace(sd, v, &folder);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    VariantClear(&v);
+
+    hr = Folder_QueryInterface(folder, &IID_Folder2, (void**)&folder2);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    Folder_Release(folder);
+
+    hr = Folder2_get_Self(folder2, &item);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    Folder2_Release(folder2);
+
+if (0) { /* crashes on some systems */
+    hr = FolderItem_Verbs(item, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+}
+    hr = FolderItem_Verbs(item, &verbs);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+if (0) { /* crashes on winxp/win2k3 */
+    hr = FolderItemVerbs_get_Count(verbs, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+}
+    count = 0;
+    hr = FolderItemVerbs_get_Count(verbs, &count);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(count > 0, "got count %d\n", count);
+
+if (0) { /* crashes on winxp/win2k3 */
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = 0;
+    hr = FolderItemVerbs_Item(verbs, v, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+}
+    /* there's always one item more, so you can access [0,count],
+       instead of actual [0,count) */
+    for (i = 0; i <= count; i++) {
+        V_VT(&v) = VT_I4;
+        V_I4(&v) = i;
+        hr = FolderItemVerbs_Item(verbs, v, &verb);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        hr = FolderItemVerb_get_Name(verb, &str);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(str != NULL, "%d: name %s\n", i, wine_dbgstr_w(str));
+        if (i == count)
+            ok(str[0] == 0, "%d: got teminating item %s\n", i, wine_dbgstr_w(str));
+
+        SysFreeString(str);
+        FolderItemVerb_Release(verb);
+    }
+
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = count+1;
+    verb = NULL;
+    hr = FolderItemVerbs_Item(verbs, v, &verb);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(verb == NULL, "got %p\n", verb);
+
+    FolderItemVerbs_Release(verbs);
+    FolderItem_Release(item);
+    IShellDispatch_Release(sd);
+}
+
+static void test_ShellExecute(void)
+{
+    HRESULT hr;
+    IShellDispatch2 *sd;
+    BSTR name;
+    VARIANT args, dir, op, show;
+
+    static const WCHAR regW[] = {'r','e','g',0};
+
+    hr = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER,
+        &IID_IShellDispatch2, (void**)&sd);
+    if (hr != S_OK)
+    {
+        win_skip("IShellDispatch2 not supported\n");
+        return;
+    }
+
+    VariantInit(&args);
+    VariantInit(&dir);
+    VariantInit(&op);
+    VariantInit(&show);
+
+    V_VT(&show) = VT_I4;
+    V_I4(&show) = 0;
+
+    name = SysAllocString(regW);
+
+    hr = IShellDispatch2_ShellExecute(sd, name, args, dir, op, show);
+    ok(hr == S_OK, "ShellExecute failed: %08x\n", hr);
+
+    /* test invalid value for show */
+    V_VT(&show) = VT_BSTR;
+    V_BSTR(&show) = name;
+
+    hr = IShellDispatch2_ShellExecute(sd, name, args, dir, op, show);
+    ok(hr == S_OK, "ShellExecute failed: %08x\n", hr);
+
+    SysFreeString(name);
+}
+
 START_TEST(shelldispatch)
 {
     HRESULT r;
@@ -376,5 +881,17 @@ START_TEST(shelldispatch)
     test_namespace();
     test_service();
 
+    if (!winetest_interactive)
+        skip("ROSTESTS-209: Skipping test_ShellFolderViewDual(), test_ShellWindows(), test_ParseName() and test_Verbs().\n");
+    else
+    {
+        test_ShellFolderViewDual();
+        test_ShellWindows();
+        test_ParseName();
+        test_Verbs();
+    }
+
+    test_ShellExecute();
+
     CoUninitialize();
 }
index b258052..41fac48 100755 (executable)
@@ -993,7 +993,6 @@ static void test_SHGetStockIconInfo(void)
 {
     BYTE buffer[sizeof(SHSTOCKICONINFO) + 16];
     SHSTOCKICONINFO *sii = (SHSTOCKICONINFO *) buffer;
-    BOOL atleast_win7;
     HRESULT hr;
     INT i;
 
@@ -1007,11 +1006,11 @@ static void test_SHGetStockIconInfo(void)
     /* negative values are handled */
     memset(buffer, '#', sizeof(buffer));
     sii->cbSize = sizeof(SHSTOCKICONINFO);
-    hr = pSHGetStockIconInfo(-1, SHGSI_ICONLOCATION, sii);
+    hr = pSHGetStockIconInfo(SIID_INVALID, SHGSI_ICONLOCATION, sii);
     ok(hr == E_INVALIDARG, "-1: got 0x%x (expected E_INVALIDARG)\n", hr);
 
     /* max. id for vista is 140 (no definition exists for this value) */
-    for (i = 0; i <= 140; i++)
+    for (i = SIID_DOCNOASSOC; i <= SIID_CLUSTEREDDRIVE; i++)
     {
         memset(buffer, '#', sizeof(buffer));
         sii->cbSize = sizeof(SHSTOCKICONINFO);
@@ -1026,38 +1025,17 @@ static void test_SHGetStockIconInfo(void)
                   sii->iIcon, wine_dbgstr_w(sii->szPath));
     }
 
-    /* there are more icons since win7 */
-    memset(buffer, '#', sizeof(buffer));
-    sii->cbSize = sizeof(SHSTOCKICONINFO);
-    hr = pSHGetStockIconInfo(i, SHGSI_ICONLOCATION, sii);
-    atleast_win7 = (!hr);
-
-    for (; i < (SIID_MAX_ICONS + 25) ; i++)
+    /* test invalid icons indices that are invalid for all platforms */
+    for (i = SIID_MAX_ICONS; i < (SIID_MAX_ICONS + 25) ; i++)
     {
         memset(buffer, '#', sizeof(buffer));
         sii->cbSize = sizeof(SHSTOCKICONINFO);
         hr = pSHGetStockIconInfo(i, SHGSI_ICONLOCATION, sii);
-
-        if (atleast_win7 && (i == (SIID_MAX_ICONS - 1)) && broken(hr == E_INVALIDARG))
-        {
-            /* Off by one windows bug: there are SIID_MAX_ICONS icons from 0
-             * up to SIID_MAX_ICONS-1 on Windows 8, but the last one is missing
-             * on Windows 7.
-             */
-            trace("%3d: got E_INVALIDARG (windows bug: off by one)\n", i);
-        }
-        else if (atleast_win7 && (i < (SIID_MAX_ICONS)))
-        {
-            ok(hr == S_OK,
-                "%3d: got 0x%x, iSysImageIndex: 0x%x, iIcon: 0x%x (expected S_OK)\n",
-                i, hr, sii->iSysImageIndex, sii->iIcon);
-
-            if ((hr == S_OK) && (winetest_debug > 1))
-                trace("%3d: got iSysImageIndex %3d, iIcon %3d and %s\n", i, sii->iSysImageIndex,
-                      sii->iIcon, wine_dbgstr_w(sii->szPath));
-        }
-        else
-            ok(hr == E_INVALIDARG, "%3d: got 0x%x (expected E_INVALIDARG)\n", i, hr);
+        ok(hr == E_INVALIDARG, "%3d: got 0x%x (expected E_INVALIDARG)\n", i, hr);
+    todo_wine {
+        ok(sii->iSysImageIndex == -1, "%d: got iSysImageIndex %d\n", i, sii->iSysImageIndex);
+        ok(sii->iIcon == -1, "%d: got iIcon %d\n", i, sii->iIcon);
+    }
     }
 
     /* test more returned SHSTOCKICONINFO elements without extra flags */
index 3f0b490..5335385 100644 (file)
@@ -742,10 +742,126 @@ static void test_SHCreateQueryCancelAutoPlayMoniker(void)
     IMoniker_Release(mon);
 }
 
+#define DROPTEST_FILENAME "c:\\wintest.bin"
+struct DragParam {
+    HWND hwnd;
+    HANDLE ready;
+};
+
+static LRESULT WINAPI drop_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    switch (msg) {
+    case WM_DROPFILES:
+    {
+        HDROP hDrop = (HDROP)wparam;
+        char filename[MAX_PATH] = "dummy";
+        UINT num;
+        num = DragQueryFileA(hDrop, 0xffffffff, NULL, 0);
+        ok(num == 1, "expected 1, got %u\n", num);
+        num = DragQueryFileA(hDrop, 0xffffffff, (char*)0xdeadbeef, 0xffffffff);
+        ok(num == 1, "expected 1, got %u\n", num);
+        num = DragQueryFileA(hDrop, 0, filename, sizeof(filename));
+        ok(num == strlen(DROPTEST_FILENAME), "got %u\n", num);
+        ok(!strcmp(filename, DROPTEST_FILENAME), "got %s\n", filename);
+        DragFinish(hDrop);
+        return 0;
+    }
+    }
+    return DefWindowProcA(hwnd, msg, wparam, lparam);
+}
+
+static DWORD WINAPI drop_window_therad(void *arg)
+{
+    struct DragParam *param = arg;
+    WNDCLASSA cls;
+    WINDOWINFO info;
+    BOOL r;
+    MSG msg;
+
+    memset(&cls, 0, sizeof(cls));
+    cls.lpfnWndProc = drop_window_proc;
+    cls.hInstance = GetModuleHandleA(NULL);
+    cls.lpszClassName = "drop test";
+    RegisterClassA(&cls);
+
+    param->hwnd = CreateWindowA("drop test", NULL, 0, 0, 0, 0, 0,
+                                NULL, 0, NULL, 0);
+    ok(param->hwnd != NULL, "CreateWindow failed: %d\n", GetLastError());
+
+    memset(&info, 0, sizeof(info));
+    info.cbSize = sizeof(info);
+    r = GetWindowInfo(param->hwnd, &info);
+    ok(r, "got %d\n", r);
+    ok(!(info.dwExStyle & WS_EX_ACCEPTFILES), "got %08x\n", info.dwExStyle);
+
+    DragAcceptFiles(param->hwnd, TRUE);
+
+    memset(&info, 0, sizeof(info));
+    info.cbSize = sizeof(info);
+    r = GetWindowInfo(param->hwnd, &info);
+    ok(r, "got %d\n", r);
+    ok((info.dwExStyle & WS_EX_ACCEPTFILES), "got %08x\n", info.dwExStyle);
+
+    SetEvent(param->ready);
+
+    while ((r = GetMessageA(&msg, NULL, 0, 0)) != 0) {
+        if (r == (BOOL)-1) {
+            ok(0, "unexpected return value, got %d\n", r);
+            break;
+        }
+        DispatchMessageA(&msg);
+    }
+
+    DestroyWindow(param->hwnd);
+    UnregisterClassA("drop test", GetModuleHandleA(NULL));
+    return 0;
+}
+
+static void test_DragQueryFile(void)
+{
+    struct DragParam param;
+    HANDLE hThread;
+    DWORD rc;
+    HGLOBAL hDrop;
+    DROPFILES *pDrop;
+    int ret;
+    BOOL r;
+
+    param.ready = CreateEventA(NULL, FALSE, FALSE, NULL);
+    ok(param.ready != NULL, "can't create event\n");
+    hThread = CreateThread(NULL, 0, drop_window_therad, &param, 0, NULL);
+
+    rc = WaitForSingleObject(param.ready, 5000);
+    ok(rc == WAIT_OBJECT_0, "got %u\n", rc);
+
+    hDrop = GlobalAlloc(GHND, sizeof(DROPFILES) + (strlen(DROPTEST_FILENAME) + 2) * sizeof(WCHAR));
+    pDrop = GlobalLock(hDrop);
+    pDrop->pFiles = sizeof(DROPFILES);
+    ret = MultiByteToWideChar(CP_ACP, 0, DROPTEST_FILENAME, -1,
+                              (LPWSTR)(pDrop + 1), strlen(DROPTEST_FILENAME) + 1);
+    ok(ret > 0, "got %d\n", ret);
+    pDrop->fWide = TRUE;
+    GlobalUnlock(hDrop);
+
+    r = PostMessageA(param.hwnd, WM_DROPFILES, (WPARAM)hDrop, 0);
+    ok(r, "got %d\n", r);
+
+    r = PostMessageA(param.hwnd, WM_QUIT, 0, 0);
+    ok(r, "got %d\n", r);
+
+    rc = WaitForSingleObject(hThread, 5000);
+    ok(rc == WAIT_OBJECT_0, "got %d\n", rc);
+
+    CloseHandle(param.ready);
+    CloseHandle(hThread);
+}
+#undef DROPTEST_FILENAME
+
 START_TEST(shellole)
 {
     init();
 
     test_SHPropStg_functions();
     test_SHCreateQueryCancelAutoPlayMoniker();
+    test_DragQueryFile();
 }
index 64b7c08..78539e6 100644 (file)
@@ -102,6 +102,7 @@ static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE,
 static HRESULT (WINAPI *pSHSetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR);
 static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD);
 static BOOL (WINAPI *pPathYetAnotherMakeUniqueName)(PWSTR, PCWSTR, PCWSTR, PCWSTR);
+static HRESULT (WINAPI *pSHGetKnownFolderIDList)(REFKNOWNFOLDERID, DWORD, HANDLE, PIDLIST_ABSOLUTE*);
 
 static DLLVERSIONINFO shellVersion = { 0 };
 static LPMALLOC pMalloc;
@@ -111,7 +112,7 @@ static const BYTE folderType[] = { PT_FOLDER, PT_FOLDERW };
 static const BYTE favoritesType[] = { PT_FOLDER, PT_FOLDERW, 0, PT_IESPECIAL2 /* Win98 */ };
 static const BYTE folderOrSpecialType[] = { PT_FOLDER, PT_IESPECIAL2 };
 static const BYTE personalType[] = { PT_FOLDER, PT_GUID, PT_DRIVE, 0xff /* Win9x */,
- PT_IESPECIAL2 /* Win98 */, 0 /* Vista */ };
+ PT_IESPECIAL2 /* Win98 */, 0 /* Vista */, PT_SHELLEXT /* win8 */ };
 /* FIXME: don't know the type of 0x71 returned by Vista/2008 for printers */
 static const BYTE printersType[] = { PT_YAGUID, PT_SHELLEXT, 0x71 };
 static const BYTE ieSpecialType[] = { PT_IESPECIAL2 };
@@ -209,6 +210,7 @@ static void loadShell32(void)
     GET_PROC(SHFileOperationA)
     GET_PROC(SHGetMalloc)
     GET_PROC(PathYetAnotherMakeUniqueName)
+    GET_PROC(SHGetKnownFolderIDList)
 
     ok(pSHGetMalloc != NULL, "shell32 is missing SHGetMalloc\n");
     if (pSHGetMalloc)
@@ -568,6 +570,7 @@ static void test_PidlTypes(void)
 
 /* 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)
@@ -577,7 +580,7 @@ static void test_GUIDs(void)
     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, NULL);
+    matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, &_CLSID_Documents /* win8 */);
     matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments, NULL);
     matchGUID(CSIDL_PRINTERS, &CLSID_Printers, NULL);
 }
@@ -891,9 +894,9 @@ if (0) { /* crashes */
 
 /* Standard CSIDL values (and their flags) uses only two less-significant bytes */
 #define NO_CSIDL 0x10000
-#define CSIDL_TODO_WINE 0x20000
-#define KNOWN_FOLDER(id, csidl, name, category, parent, relative_path, parsing_name, attributes, definitionFlags) \
-    { &id, # id, csidl, # csidl, name, category, &parent, # parent, relative_path, parsing_name, attributes, definitionFlags, __LINE__ }
+#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} };
@@ -908,8 +911,7 @@ struct knownFolderDef {
     const char *sCsidl;
     const char *sName;
     const KF_CATEGORY category;
-    const KNOWNFOLDERID *fidParent;
-    const char *sParent;
+    const KNOWNFOLDERID *fidParents[2];
     const char *sRelativePath;
     const char *sParsingName;
     const DWORD attributes;
@@ -931,7 +933,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "AddNewProgramsFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{15eae92e-f17a-4431-9f28-805e482dafd4}\0"
                 "shell:::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{15eae92e-f17a-4431-9f28-805e482dafd4}\0\0" /* 6.1 */,
@@ -941,7 +943,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_ADMINTOOLS,
                  "Administrative Tools",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Programs,
+                 FOLDERID_Programs, GUID_NULL,
                  "Administrative Tools",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -950,7 +952,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "AppUpdatesFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\\::{d450a8a1-9568-45c7-9c0e-b4f9fb4537bd}\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\\::{d450a8a1-9568-45c7-9c0e-b4f9fb4537bd}\0\0" /* 6.1 */,
@@ -960,7 +962,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_CDBURN_AREA,
                  "CD Burning",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
+                 FOLDERID_LocalAppData, GUID_NULL,
                  "Microsoft\\Windows\\Burn\\Burn",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -969,7 +971,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "ChangeRemoveProgramsFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\0\0" /* 6.1 */,
@@ -979,15 +981,16 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_ADMINTOOLS,
                  "Common Administrative Tools",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_CommonPrograms,
+                 FOLDERID_CommonPrograms, GUID_NULL,
                  "Administrative Tools",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
     KNOWN_FOLDER(FOLDERID_CommonOEMLinks,
-                 CSIDL_COMMON_OEM_LINKS,"OEM Links",
+                 CSIDL_COMMON_OEM_LINKS,
+                 "OEM Links",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_ProgramData,
+                 FOLDERID_ProgramData, GUID_NULL,
                  "OEM Links",
                  NULL,
                  0,
@@ -996,7 +999,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_PROGRAMS,
                  "Common Programs",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_CommonStartMenu,
+                 FOLDERID_CommonStartMenu, GUID_NULL,
                  "Programs",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -1005,8 +1008,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_STARTMENU,
                  "Common Start Menu",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_ProgramData,
-                 "Microsoft\\Windows\\Start Menu",
+                 FOLDERID_ProgramData, GUID_NULL,
+                 "Microsoft\\Windows\\Start Menu\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1014,7 +1017,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_STARTUP,
                  "Common Startup",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_CommonPrograms,
+                 FOLDERID_CommonPrograms, GUID_NULL,
                  "StartUp",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -1023,8 +1026,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_TEMPLATES,
                  "Common Templates",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_ProgramData,
-                 "Microsoft\\Windows\\Templates",
+                 FOLDERID_ProgramData, GUID_NULL,
+                 "Microsoft\\Windows\\Templates\0",
                  NULL,
                  0,
                  0),
@@ -1032,7 +1035,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_DRIVES,
                  "MyComputerFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\0\0",
                  0,
@@ -1041,7 +1044,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "ConflictFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{E413D040-6788-4C22-957E-175D1C513A34},\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{E413D040-6788-4C22-957E-175D1C513A34},\0\0" /* 6.1 */,
@@ -1051,7 +1054,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_CONNECTIONS,
                  "ConnectionsFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\0\0" /* 6.1 */,
@@ -1061,7 +1064,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Contacts",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
+                 FOLDERID_Profile, GUID_NULL,
                  "Contacts",
                  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{56784854-C6CB-462B-8169-88E350ACB882}\0\0",
                  FILE_ATTRIBUTE_READONLY,
@@ -1070,7 +1073,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_CONTROLS,
                  "ControlPanelFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\0\0" /* 6.1 */,
@@ -1080,8 +1083,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COOKIES,
                  "Cookies",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\Cookies",
+                 FOLDERID_RoamingAppData, FOLDERID_LocalAppData,
+                 "Microsoft\\Windows\\Cookies\0Microsoft\\Windows\\INetCookies\0" /* win8 */,
                  NULL,
                  0,
                  0),
@@ -1089,7 +1092,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_DESKTOP,
                  "Desktop",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
+                 FOLDERID_Profile, GUID_NULL,
                  "Desktop",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -1098,8 +1101,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Device Metadata Store",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_ProgramData,
-                 "Microsoft\\Windows\\DeviceMetadataStore",
+                 FOLDERID_ProgramData, GUID_NULL,
+                 "Microsoft\\Windows\\DeviceMetadataStore\0",
                  NULL,
                  0,
                  0),
@@ -1107,17 +1110,17 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_MYDOCUMENTS,
                  "Personal",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Documents",
-                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{FDD39AD0-238F-46AF-ADB4-6C85480369C7}\0\0",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Documents\0",
+                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{FDD39AD0-238F-46AF-ADB4-6C85480369C7}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{A8CDFF1C-4878-43be-B5FD-F8091C1C60D0}\0\0", /* win8 */
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE),
     KNOWN_FOLDER(FOLDERID_DocumentsLibrary,
                  NO_CSIDL,
                  "DocumentsLibrary",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Libraries,
-                 "Documents.library-ms",
+                 FOLDERID_Libraries, GUID_NULL,
+                 "Documents.library-ms\0",
                  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{7b0db17d-9cd2-4a93-9733-46cc89022e7c}\0\0",
                  0,
                  KFDF_PRECREATE | KFDF_STREAM),
@@ -1125,17 +1128,17 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Downloads",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Downloads",
-                 NULL,
+                 FOLDERID_Profile, GUID_NULL,
+                 "Downloads\0",
+                 "(null)\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{374DE290-123F-4565-9164-39C4925E467B}\0\0", /* win8 */
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE | KFDF_PUBLISHEXPANDEDPATH),
     KNOWN_FOLDER(FOLDERID_Favorites,
                  CSIDL_FAVORITES,
                  "Favorites",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Favorites",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Favorites\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE | KFDF_PUBLISHEXPANDEDPATH),
@@ -1143,7 +1146,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_FONTS,
                  "Fonts",
                  KF_CATEGORY_FIXED,
-                 FOLDERID_Windows,
+                 FOLDERID_Windows, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1152,7 +1155,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Games",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{ED228FDF-9EA8-4870-83b1-96b02CFE0D52}\0\0",
                  0,
@@ -1161,8 +1164,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "GameTasks",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
-                 "Microsoft\\Windows\\GameExplorer",
+                 FOLDERID_LocalAppData, GUID_NULL,
+                 "Microsoft\\Windows\\GameExplorer\0",
                  NULL,
                  0,
                  KFDF_LOCAL_REDIRECT_ONLY),
@@ -1170,8 +1173,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_HISTORY,
                  "History",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
-                 "Microsoft\\Windows\\History",
+                 FOLDERID_LocalAppData, GUID_NULL,
+                 "Microsoft\\Windows\\History\0",
                  NULL,
                  0,
                  KFDF_LOCAL_REDIRECT_ONLY),
@@ -1179,7 +1182,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "HomeGroupFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{B4FB3F98-C1EA-428d-A78A-D1F5659CBA93}\0\0",
                  0,
@@ -1188,8 +1191,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "ImplicitAppShortcuts",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_UserPinned,
-                 "ImplicitAppShortcuts",
+                 FOLDERID_UserPinned, GUID_NULL,
+                 "ImplicitAppShortcuts\0",
                  NULL,
                  0,
                  KFDF_PRECREATE),
@@ -1197,8 +1200,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_INTERNET_CACHE,
                  "Cache",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
-                 "Microsoft\\Windows\\Temporary Internet Files",
+                 FOLDERID_LocalAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Temporary Internet Files\0Microsoft\\Windows\\INetCache\0\0", /* win8 */
                  NULL,
                  0,
                  KFDF_LOCAL_REDIRECT_ONLY),
@@ -1206,7 +1209,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_INTERNET,
                  "InternetFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{871C5380-42A0-1069-A2EA-08002B30309D}\0\0",
                  0,
@@ -1215,8 +1218,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Libraries",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\Libraries",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Libraries\0",
                  NULL,
                  0,
                  KFDF_PRECREATE | KFDF_PUBLISHEXPANDEDPATH),
@@ -1224,8 +1227,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Links",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Links",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Links\0",
                  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968}\0\0",
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE | KFDF_PUBLISHEXPANDEDPATH),
@@ -1233,8 +1236,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_LOCAL_APPDATA,
                  "Local AppData",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "AppData\\Local",
+                 FOLDERID_Profile, GUID_NULL,
+                 "AppData\\Local\0",
                  NULL,
                  0,
                  KFDF_LOCAL_REDIRECT_ONLY | KFDF_PUBLISHEXPANDEDPATH),
@@ -1242,8 +1245,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "LocalAppDataLow",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "AppData\\LocalLow",
+                 FOLDERID_Profile, GUID_NULL,
+                 "AppData\\LocalLow\0",
                  NULL,
                  FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
                  KFDF_LOCAL_REDIRECT_ONLY | KFDF_PRECREATE | KFDF_PUBLISHEXPANDEDPATH),
@@ -1251,7 +1254,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_RESOURCES_LOCALIZED,
                  "LocalizedResourcesDir",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1260,17 +1263,17 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_MYMUSIC,
                  "My Music",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Music",
-                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{4BD8D571-6D19-48D3-BE97-422220080E43}\0\0",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Music\0",
+                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{4BD8D571-6D19-48D3-BE97-422220080E43}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{1CF1260C-4DD0-4EBB-811F-33C572699FDE}\0\0", /* win8 */
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE),
     KNOWN_FOLDER(FOLDERID_MusicLibrary,
                  NO_CSIDL,
                  "MusicLibrary",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Libraries,
-                 "Music.library-ms",
+                 FOLDERID_Libraries, GUID_NULL,
+                 "Music.library-ms\0",
                  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{2112AB0A-C86A-4ffe-A368-0DE96E47012E}\0\0",
                  0,
                  KFDF_PRECREATE | KFDF_STREAM),
@@ -1278,8 +1281,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_NETHOOD,
                  "NetHood",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\Network Shortcuts",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Network Shortcuts\0",
                  NULL,
                  0,
                  0),
@@ -1287,7 +1290,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_NETWORK,
                  "NetworkPlacesFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}\0\0",
                  0,
@@ -1296,8 +1299,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Original Images",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
-                 "Microsoft\\Windows Photo Gallery\\Original Images",
+                 FOLDERID_LocalAppData, GUID_NULL,
+                 "Microsoft\\Windows Photo Gallery\\Original Images\0",
                  NULL,
                  0,
                  0),
@@ -1305,8 +1308,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "PhotoAlbums",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Pictures,
-                 "Slide Shows",
+                 FOLDERID_Pictures, GUID_NULL,
+                 "Slide Shows\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  0),
@@ -1314,17 +1317,17 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_MYPICTURES,
                  "My Pictures",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Pictures",
-                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{33E28130-4E1E-4676-835A-98395C3BC3BB}\0\0",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Pictures\0",
+                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{33E28130-4E1E-4676-835A-98395C3BC3BB}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{3ADD1653-EB32-4CB0-BBD7-DFA0ABB5ACCA}\0\0", /* win8 */
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE),
     KNOWN_FOLDER(FOLDERID_PicturesLibrary,
                  NO_CSIDL,
                  "PicturesLibrary",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Libraries,
-                 "Pictures.library-ms",
+                 FOLDERID_Libraries, GUID_NULL,
+                 "Pictures.library-ms\0",
                  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{A990AE9F-A03B-4e80-94BC-9912D7504104}\0\0",
                  0,
                  KFDF_PRECREATE | KFDF_STREAM),
@@ -1332,8 +1335,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Playlists",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Music,
-                 "Playlists",
+                 FOLDERID_Music, GUID_NULL,
+                 "Playlists\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  0),
@@ -1341,7 +1344,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_PRINTERS,
                  "PrintersFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}\0\0",
                  0,
@@ -1350,8 +1353,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_PRINTHOOD,
                  "PrintHood",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\Printer Shortcuts",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Printer Shortcuts\0",
                  NULL,
                  0,
                  0),
@@ -1359,7 +1362,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_PROFILE,
                  "Profile",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1368,7 +1371,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_APPDATA,
                  "Common AppData",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1377,7 +1380,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_PROGRAM_FILES,
                  "ProgramFiles",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -1387,7 +1390,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_PROGRAM_FILES_COMMON,
                  "ProgramFilesCommon",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1396,7 +1399,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "ProgramFilesCommonX64",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1405,7 +1408,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "ProgramFilesCommonX86",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1414,7 +1417,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "ProgramFilesX64",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1423,7 +1426,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_PROGRAM_FILESX86,
                  "ProgramFilesX86",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -1432,8 +1435,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_PROGRAMS,
                  "Programs",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_StartMenu,
-                 "Programs",
+                 FOLDERID_StartMenu, GUID_NULL,
+                 "Programs\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1441,7 +1444,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Public",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{4336a54d-038b-4685-ab02-99bb52d3fb8b}\0"
                  "(null)\0\0" /* 6.1 */,
@@ -1451,8 +1454,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_DESKTOPDIRECTORY,
                  "Common Desktop",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_Public,
-                 "Desktop",
+                 FOLDERID_Public, GUID_NULL,
+                 "Desktop\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN,
                  KFDF_PRECREATE),
@@ -1460,8 +1463,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_DOCUMENTS,
                  "Common Documents",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_Public,
-                 "Documents",
+                 FOLDERID_Public, GUID_NULL,
+                 "Documents\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1469,8 +1472,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "CommonDownloads",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_Public,
-                 "Downloads",
+                 FOLDERID_Public, GUID_NULL,
+                 "Downloads\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1478,8 +1481,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "PublicGameTasks",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_ProgramData,
-                 "Microsoft\\Windows\\GameExplorer",
+                 FOLDERID_ProgramData, GUID_NULL,
+                 "Microsoft\\Windows\\GameExplorer\0",
                  NULL,
                  0,
                  KFDF_LOCAL_REDIRECT_ONLY),
@@ -1487,8 +1490,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "PublicLibraries",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_Public,
-                 "Libraries",
+                 FOLDERID_Public, GUID_NULL,
+                 "Libraries\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN,
                  KFDF_PRECREATE),
@@ -1496,8 +1499,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_MUSIC,
                  "CommonMusic",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_Public,
-                 "Music",
+                 FOLDERID_Public, GUID_NULL,
+                 "Music\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1505,8 +1508,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_PICTURES,
                  "CommonPictures",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_Public,
-                 "Pictures",
+                 FOLDERID_Public, GUID_NULL,
+                 "Pictures\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1514,8 +1517,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "CommonRingtones",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_ProgramData,
-                 "Microsoft\\Windows\\Ringtones",
+                 FOLDERID_ProgramData, GUID_NULL,
+                 "Microsoft\\Windows\\Ringtones\0",
                  NULL,
                  0,
                  KFDF_PRECREATE),
@@ -1523,8 +1526,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_COMMON_VIDEO,
                  "CommonVideo",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_Public,
-                 "Videos",
+                 FOLDERID_Public, GUID_NULL,
+                 "Videos\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1532,8 +1535,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Quick Launch",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Internet Explorer\\Quick Launch",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Internet Explorer\\Quick Launch\0",
                  NULL,
                  0,
                  0),
@@ -1541,8 +1544,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_RECENT,
                  "Recent",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\Recent",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Recent\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1550,8 +1553,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "RecordedTVLibrary",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_PublicLibraries,
-                 "RecordedTV.library-ms",
+                 FOLDERID_PublicLibraries, GUID_NULL,
+                 "RecordedTV.library-ms\0",
                  NULL,
                  0,
                  KFDF_PRECREATE | KFDF_STREAM),
@@ -1559,7 +1562,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_BITBUCKET,
                  "RecycleBinFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{645FF040-5081-101B-9F08-00AA002F954E}\0\0",
                  0,
@@ -1568,7 +1571,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_RESOURCES,
                  "ResourceDir",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1577,8 +1580,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Ringtones",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
-                 "Microsoft\\Windows\\Ringtones",
+                 FOLDERID_LocalAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Ringtones\0",
                  NULL,
                  0,
                  KFDF_PRECREATE),
@@ -1586,26 +1589,26 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_APPDATA,
                  "AppData",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "AppData\\Roaming",
+                 FOLDERID_Profile, GUID_NULL,
+                 "AppData\\Roaming\0",
                  NULL,
                  0,
                  0),
     KNOWN_FOLDER(FOLDERID_SampleMusic,
-                 NO_CSIDL,
+                 NO_CSIDL|WINE_ATTRIBUTES_OPTIONAL /* win8 */,
                  "SampleMusic",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_PublicMusic,
-                 "Sample Music",
+                 FOLDERID_PublicMusic, GUID_NULL,
+                 "Sample Music\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
     KNOWN_FOLDER(FOLDERID_SamplePictures,
-                 NO_CSIDL,
+                 NO_CSIDL|WINE_ATTRIBUTES_OPTIONAL /* win8 */,
                  "SamplePictures",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_PublicPictures,
-                 "Sample Pictures",
+                 FOLDERID_PublicPictures, GUID_NULL,
+                 "Sample Pictures\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1613,17 +1616,17 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "SamplePlaylists",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_PublicMusic,
-                 "Sample Playlists",
+                 FOLDERID_PublicMusic, GUID_NULL,
+                 "Sample Playlists\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  0),
     KNOWN_FOLDER(FOLDERID_SampleVideos,
-                 NO_CSIDL,
+                 NO_CSIDL|WINE_ATTRIBUTES_OPTIONAL /* win8 */,
                  "SampleVideos",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_PublicVideos,
-                 "Sample Videos",
+                 FOLDERID_PublicVideos, GUID_NULL,
+                 "Sample Videos\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1631,8 +1634,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "SavedGames",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Saved Games",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Saved Games\0",
                  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}\0\0",
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE | KFDF_PUBLISHEXPANDEDPATH),
@@ -1640,8 +1643,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Searches",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Searches",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Searches\0",
                  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{7d1d3a04-debb-4115-95cf-2f29da2920da}\0\0",
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE | KFDF_PUBLISHEXPANDEDPATH),
@@ -1649,7 +1652,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "CSCFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "shell:::{BD7A2E7B-21CB-41b2-A086-B309680C6B7E}\\*\0\0",
                  0,
@@ -1658,7 +1661,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "SearchHomeFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{9343812e-1c37-4a49-a12e-4b2d810d956b}\0\0",
                  0,
@@ -1667,7 +1670,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "MAPIFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "shell:::{89D83576-6BD1-4C86-9454-BEB04E94C819}\\*\0\0",
                  0,
@@ -1676,8 +1679,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_SENDTO,
                  "SendTo",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\SendTo",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Windows\\SendTo\0",
                  NULL,
                  0,
                  0),
@@ -1685,8 +1688,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Default Gadgets",
                  KF_CATEGORY_COMMON,
-                 FOLDERID_ProgramFiles,
-                 "Windows Sidebar\\Gadgets",
+                 FOLDERID_ProgramFiles, GUID_NULL,
+                 "Windows Sidebar\\Gadgets\0",
                  NULL,
                  0,
                  0),
@@ -1694,8 +1697,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "Gadgets",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
-                 "Microsoft\\Windows Sidebar\\Gadgets",
+                 FOLDERID_LocalAppData, GUID_NULL,
+                 "Microsoft\\Windows Sidebar\\Gadgets\0",
                  NULL,
                  0,
                  0),
@@ -1703,8 +1706,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_STARTMENU,
                  "Start Menu",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\Start Menu",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Start Menu\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1712,8 +1715,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_STARTUP,
                  "Startup",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Programs,
-                 "StartUp",
+                 FOLDERID_Programs, GUID_NULL,
+                 "StartUp\0",
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_PRECREATE),
@@ -1721,7 +1724,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "SyncCenterFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\0\0" /* 6.1 */,
@@ -1731,7 +1734,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "SyncResultsFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{BC48B32F-5910-47F5-8570-5074A8A5636A},\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{BC48B32F-5910-47F5-8570-5074A8A5636A},\0\0",
@@ -1741,7 +1744,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "SyncSetupFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{F1390A9A-A3F4-4E5D-9C5F-98F3BD8D935C},\0"
                  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{F1390A9A-A3F4-4E5D-9C5F-98F3BD8D935C},\0\0" /* 6.1 */,
@@ -1751,7 +1754,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_SYSTEM,
                  "System",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1760,7 +1763,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_SYSTEMX86,
                  "SystemX86",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1769,8 +1772,8 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_TEMPLATES,
                  "Templates",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_RoamingAppData,
-                 "Microsoft\\Windows\\Templates",
+                 FOLDERID_RoamingAppData, GUID_NULL,
+                 "Microsoft\\Windows\\Templates\0",
                  NULL,
                  0,
                  0),
@@ -1778,8 +1781,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "User Pinned",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_QuickLaunch,
-                 "User Pinned",
+                 FOLDERID_QuickLaunch, GUID_NULL,
+                 "User Pinned\0",
                  NULL,
                  FILE_ATTRIBUTE_HIDDEN,
                  KFDF_PRECREATE),
@@ -1787,7 +1790,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "UserProfiles",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  FILE_ATTRIBUTE_READONLY,
@@ -1796,8 +1799,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "UserProgramFiles",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_LocalAppData,
-                 "Programs",
+                 FOLDERID_LocalAppData, GUID_NULL,
+                 "Programs\0",
                  NULL,
                  0,
                  0),
@@ -1805,8 +1808,8 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "UserProgramFilesCommon",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_UserProgramFiles,
-                 "Common",
+                 FOLDERID_UserProgramFiles, GUID_NULL,
+                 "Common\0",
                  NULL,
                  0,
                  0),
@@ -1814,7 +1817,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "UsersFilesFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\0\0",
                  0,
@@ -1823,7 +1826,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "UsersLibrariesFolder",
                  KF_CATEGORY_VIRTUAL,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\0\0",
                  0,
@@ -1832,17 +1835,17 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_MYVIDEO,
                  "My Video",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Profile,
-                 "Videos",
-                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{18989B1D-99B5-455B-841C-AB7C74E4DDFC}\0\0",
+                 FOLDERID_Profile, GUID_NULL,
+                 "Videos\0",
+                 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{18989B1D-99B5-455B-841C-AB7C74E4DDFC}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{A0953C92-50DC-43BF-BE83-3742FED03C9C}\0\0", /* win8 */
                  FILE_ATTRIBUTE_READONLY,
                  KFDF_ROAMABLE | KFDF_PRECREATE),
     KNOWN_FOLDER(FOLDERID_VideosLibrary,
                  NO_CSIDL,
                  "VideosLibrary",
                  KF_CATEGORY_PERUSER,
-                 FOLDERID_Libraries,
-                 "Videos.library-ms",
+                 FOLDERID_Libraries, GUID_NULL,
+                 "Videos.library-ms\0",
                  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{491E922F-5643-4af4-A7EB-4E7A138D8174}\0\0",
                  0,
                  KFDF_PRECREATE | KFDF_STREAM),
@@ -1850,7 +1853,7 @@ static const struct knownFolderDef known_folders[] = {
                  CSIDL_WINDOWS,
                  "Windows",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1859,7 +1862,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "CredentialManager",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1868,7 +1871,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "CryptoKeys",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1877,7 +1880,7 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "DpapiKeys",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
@@ -1886,16 +1889,46 @@ static const struct knownFolderDef known_folders[] = {
                  NO_CSIDL,
                  "SystemCertificates",
                  KF_CATEGORY_FIXED,
-                 GUID_NULL,
+                 GUID_NULL, GUID_NULL,
                  NULL,
                  NULL,
                  0,
                  0),
-    { NULL, NULL, 0, NULL, NULL, 0, 0 }
+    { 0 }
 };
 #undef KNOWN_FOLDER
 BOOL known_folder_found[sizeof(known_folders)/sizeof(known_folders[0])-1];
 
+static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
+{
+    WCHAR wstr[MAX_PATH];
+
+    if(!needle && !hay)
+        return TRUE;
+
+    while(hay && *hay)
+    {
+        DWORD ret;
+
+        if(strcmp(hay, "(null)") == 0 && !needle)
+            return TRUE;
+
+        ret = MultiByteToWideChar(CP_ACP, 0, hay, -1, wstr, sizeof(wstr)/sizeof(wstr[0]));
+        if(ret == 0)
+        {
+            ok(0, "Failed to convert string\n");
+            return FALSE;
+        }
+
+        if(lstrcmpW(wstr, needle) == 0)
+            return TRUE;
+
+        hay += strlen(hay) + 1;
+    }
+
+    return FALSE;
+}
+
 static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId)
 {
     HRESULT hr;
@@ -1903,11 +1936,9 @@ static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId
     int csidl, expectedCsidl, ret;
     KNOWNFOLDER_DEFINITION kfd;
     IKnownFolder *folder;
-    WCHAR sName[1024], sRelativePath[MAX_PATH], sParsingName[MAX_PATH];
-    BOOL validPath;
+    WCHAR sName[1024];
     BOOL *current_known_folder_found = &known_folder_found[0];
     BOOL found = FALSE;
-    const char *srcParsingName;
 
     while(known_folder->folderId != NULL)
     {
@@ -1916,17 +1947,15 @@ static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId
             *current_known_folder_found = TRUE;
             found = TRUE;
             /* verify CSIDL */
-            if(known_folder->csidl != NO_CSIDL)
+            if(!(known_folder->csidl & NO_CSIDL))
             {
-                expectedCsidl = known_folder->csidl & (~CSIDL_TODO_WINE);
+                /* mask off winetest flags */
+                expectedCsidl = known_folder->csidl & 0xFFFF;
 
                 hr = IKnownFolderManager_FolderIdToCsidl(mgr, folderId, &csidl);
                 ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot retrieve CSIDL for folder %s\n", known_folder->sFolderId);
 
-                if(known_folder->csidl & CSIDL_TODO_WINE)
-                    todo_wine ok_(__FILE__, known_folder->line)(csidl == expectedCsidl, "invalid CSIDL retrieved for folder %s. %d (%s) expected, but %d found\n", known_folder->sFolderId, expectedCsidl, known_folder->sCsidl, csidl);
-                else
-                    ok_(__FILE__, known_folder->line)(csidl == expectedCsidl, "invalid CSIDL retrieved for folder %s. %d (%s) expected, but %d found\n", known_folder->sFolderId, expectedCsidl, known_folder->sCsidl, csidl);
+                ok_(__FILE__, known_folder->line)(csidl == expectedCsidl, "invalid CSIDL retrieved for folder %s. %d (%s) expected, but %d found\n", known_folder->sFolderId, expectedCsidl, known_folder->sCsidl, csidl);
             }
 
             hr = IKnownFolderManager_GetFolder(mgr, folderId, &folder);
@@ -1934,61 +1963,28 @@ static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId
             if(SUCCEEDED(hr))
             {
                 hr = IKnownFolder_GetFolderDefinition(folder, &kfd);
-                todo_wine
                 ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder definition for %s\n", known_folder->sFolderId);
                 if(SUCCEEDED(hr))
                 {
                     ret = MultiByteToWideChar(CP_ACP, 0, known_folder->sName, -1,  sName, sizeof(sName)/sizeof(sName[0]));
                     ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder name \"%s\" to wide characters\n", known_folder->sName);
 
-                    todo_wine
                     ok_(__FILE__, known_folder->line)(lstrcmpW(kfd.pszName, sName)==0, "invalid known folder name returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(sName), wine_dbgstr_w(kfd.pszName));
 
                     ok_(__FILE__, known_folder->line)(kfd.category == known_folder->category, "invalid known folder category for %s: %d expected, but %d retrieved\n", known_folder->sFolderId, known_folder->category, kfd.category);
 
-                    ok_(__FILE__, known_folder->line)(IsEqualGUID(known_folder->fidParent, &kfd.fidParent),
-                                                      "invalid known folder parent for %s: %s expected, but %s retrieved\n",
-                                                      known_folder->sFolderId, known_folder->sParent, wine_dbgstr_guid(&kfd.fidParent));
-
-                    if(!known_folder->sRelativePath)
-                        validPath = (kfd.pszRelativePath==NULL);
-                    else
-                    {
-                        ret = MultiByteToWideChar(CP_ACP, 0, known_folder->sRelativePath, -1, sRelativePath, sizeof(sRelativePath)/sizeof(sRelativePath[0]));
-                        ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder path \"%s\" to wide characters\n", known_folder->sRelativePath);
-
-                        validPath = (lstrcmpW(kfd.pszRelativePath, sRelativePath)==0);
-                    }
-
-                    ok_(__FILE__, known_folder->line)(validPath, "invalid known folder relative path returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, known_folder->sRelativePath, wine_dbgstr_w(kfd.pszRelativePath));
+                    ok_(__FILE__, known_folder->line)(IsEqualGUID(known_folder->fidParents[0], &kfd.fidParent) ||
+                                                              IsEqualGUID(known_folder->fidParents[1], &kfd.fidParent),
+                                                      "invalid known folder parent for %s: %s retrieved\n",
+                                                      known_folder->sFolderId, wine_dbgstr_guid(&kfd.fidParent));
 
-                    /* to check parsing name, we need to iterate list */
-                    srcParsingName = known_folder->sParsingName;
+                    ok_(__FILE__, known_folder->line)(is_in_strarray(kfd.pszRelativePath, known_folder->sRelativePath), "invalid known folder relative path returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, known_folder->sRelativePath, wine_dbgstr_w(kfd.pszRelativePath));
 
-                    /* if we expect NULL, then we don't even check the list */
-                    validPath = (srcParsingName==NULL) && (kfd.pszParsingName==NULL);
+                    ok_(__FILE__, known_folder->line)(is_in_strarray(kfd.pszParsingName, known_folder->sParsingName), "invalid known folder parsing name returned for %s: %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(kfd.pszParsingName));
 
-                    if(srcParsingName)
-                        while(*srcParsingName && !validPath)
-                        {
-                            /* when NULL is only one of possible value, we mark path as valid */
-                            validPath = (strcmp(srcParsingName, "(null)")==0) && (kfd.pszParsingName==NULL);
-
-                            /* in the other case, we compare string from list with retrieved value */
-                            if(!validPath)
-                            {
-                                ret = MultiByteToWideChar(CP_ACP, 0, srcParsingName, -1, sParsingName, sizeof(sParsingName)/sizeof(sParsingName[0]));
-                                ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder path \"%s\" to wide characters\n", srcParsingName);
-
-                                validPath = (lstrcmpW(kfd.pszParsingName, sParsingName)==0);
-                            }
-
-                            srcParsingName += strlen(srcParsingName)+1;
-                        }
-
-                    ok_(__FILE__, known_folder->line)(validPath, "invalid known folder parsing name returned for %s: %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(kfd.pszParsingName));
-
-                    ok_(__FILE__, known_folder->line)(known_folder->attributes == kfd.dwAttributes, "invalid known folder attributes for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->attributes, kfd.dwAttributes);
+                    ok_(__FILE__, known_folder->line)(known_folder->attributes == kfd.dwAttributes ||
+                            (known_folder->csidl & WINE_ATTRIBUTES_OPTIONAL && kfd.dwAttributes == 0),
+                            "invalid known folder attributes for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->attributes, kfd.dwAttributes);
 
                     ok_(__FILE__, known_folder->line)(!(kfd.kfdFlags & (~known_folder->definitionFlags)), "invalid known folder flags for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->definitionFlags, kfd.kfdFlags);
 
@@ -2038,7 +2034,6 @@ static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId
     }
 }
 #undef NO_CSIDL
-#undef CSIDL_TODO_WINE
 
 static void test_knownFolders(void)
 {
@@ -2087,8 +2082,13 @@ static void test_knownFolders(void)
         win_skip("IKnownFolderManager unavailable\n");
     else
     {
+        IUnknown *unk;
+
         ok(hr == S_OK, "failed to create KnownFolderManager instance: 0x%08x\n", hr);
 
+        hr = IKnownFolderManager_QueryInterface(mgr, &IID_IMarshal, (void**)&unk);
+        ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
         hr = IKnownFolderManager_FolderIdFromCsidl(mgr, CSIDL_WINDOWS, &folderId);
         ok(hr == S_OK, "failed to convert CSIDL to KNOWNFOLDERID: 0x%08x\n", hr);
         ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
@@ -2101,10 +2101,11 @@ static void test_knownFolders(void)
         ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
         if(SUCCEEDED(hr))
         {
+            hr = IKnownFolder_QueryInterface(folder, &IID_IMarshal, (void**)&unk);
+            ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
             hr = IKnownFolder_GetCategory(folder, &cat);
-            todo_wine
             ok(hr == S_OK, "failed to get folder category: 0x%08x\n", hr);
-            todo_wine
             ok(cat==KF_CATEGORY_FIXED, "invalid folder category: %d\n", cat);
 
             hr = IKnownFolder_GetId(folder, &folderId);
@@ -2112,6 +2113,7 @@ static void test_knownFolders(void)
             ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
 
             hr = IKnownFolder_GetPath(folder, 0, &folderPath);
+            ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
             ok(lstrcmpiW(sWinDir, folderPath)==0, "invalid path returned: \"%s\", expected: \"%s\"\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sWinDir));
             CoTaskMemFree(folderPath);
 
@@ -2126,15 +2128,11 @@ static void test_knownFolders(void)
             ok(hr == E_INVALIDARG, "unexpected value from SetPath: 0x%08x\n", hr);
 
             hr = IKnownFolder_GetFolderDefinition(folder, &kfDefinition);
-            todo_wine
             ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
             if(SUCCEEDED(hr))
             {
-                todo_wine
                 ok(kfDefinition.category==KF_CATEGORY_FIXED, "invalid folder category: 0x%08x\n", kfDefinition.category);
-                todo_wine
                 ok(lstrcmpW(kfDefinition.pszName, sWindows)==0, "invalid folder name: %s\n", wine_dbgstr_w(kfDefinition.pszName));
-                todo_wine
                 ok(kfDefinition.dwAttributes==0, "invalid folder attributes: %d\n", kfDefinition.dwAttributes);
                 FreeKnownFolderDefinitionFields(&kfDefinition);
             }
@@ -2468,6 +2466,26 @@ static void test_knownFolders(void)
 
                     hr = IKnownFolder_Release(folder);
                     ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
+
+                    /* update the folder */
+                    CoTaskMemFree(kfDefinition.pszName);
+                    kfDefinition.pszName = CoTaskMemAlloc(sizeof(sExample2));
+                    lstrcpyW(kfDefinition.pszName, sExample2);
+                    hr = IKnownFolderManager_RegisterFolder(mgr, &newFolderId, &kfDefinition);
+                    ok(hr == S_OK, "failed to re-register known folder: 0x%08x\n", hr);
+
+                    hr = IKnownFolderManager_GetFolder(mgr, &newFolderId, &folder);
+                    ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
+
+                    hr = IKnownFolder_GetFolderDefinition(folder, &kfSubDefinition);
+                    ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
+                    ok(!memcmp(kfDefinition.pszName, kfSubDefinition.pszName, sizeof(sExample2)),
+                            "Got wrong updated name: %s\n", wine_dbgstr_w(kfSubDefinition.pszName));
+
+                    FreeKnownFolderDefinitionFields(&kfSubDefinition);
+
+                    hr = IKnownFolder_Release(folder);
+                    ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
                 }
 
                 hr = IKnownFolderManager_UnregisterFolder(mgr, &newFolderId);
@@ -2717,6 +2735,38 @@ if (0)
     ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
 }
 
+static void test_SHGetKnownFolderIDList(void)
+{
+    PIDLIST_ABSOLUTE pidl;
+    HRESULT hr;
+
+    if (!pSHGetKnownFolderIDList)
+    {
+        win_skip("SHGetKnownFolderIDList is not available.\n");
+        return;
+    }
+
+    hr = pSHGetKnownFolderIDList(NULL, 0, NULL, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+if (0) { /* crashes on native */
+    pidl = (void*)0xdeadbeef;
+    hr = pSHGetKnownFolderIDList(NULL, 0, NULL, &pidl);
+}
+    /* not a known folder */
+    pidl = (void*)0xdeadbeef;
+    hr = pSHGetKnownFolderIDList(&IID_IUnknown, 0, NULL, &pidl);
+    ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
+    ok(pidl == NULL, "got %p\n", pidl);
+
+    hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, &pidl);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    CoTaskMemFree(pidl);
+}
+
 START_TEST(shellpath)
 {
     if (!init()) return;
@@ -2746,5 +2796,6 @@ START_TEST(shellpath)
         test_knownFolders();
         test_DoEnvironmentSubst();
         test_PathYetAnotherMakeUniqueName();
+        test_SHGetKnownFolderIDList();
     }
 }
index 2b3947e..3d95b41 100755 (executable)
@@ -127,6 +127,8 @@ static INT_PTR shell_execute(LPCSTR verb, LPCSTR file, LPCSTR parameters, LPCSTR
         if (wait_rc == WAIT_TIMEOUT)
         {
             HWND wnd = FindWindowA("#32770", "Windows");
+            if (!wnd)
+                wnd = FindWindowA("Shell_Flyout", "");
             if (wnd != NULL)
             {
                 SendMessageA(wnd, WM_CLOSE, 0, 0);
@@ -857,7 +859,6 @@ static const char* testfiles[]=
     "%s\\masked",
     "%s\\test file.sde",
     "%s\\test file.exe",
-    "%s\\test file two.exe",
     "%s\\test2.exe",
     "%s\\simple.shlexec",
     "%s\\drawback_file.noassoc",
@@ -901,9 +902,11 @@ static filename_tests_t filename_tests[]=
     {"QuotedUpperL", "%s\\test file.shlexec",   0x0, 33},
 
     /* Test file masked due to space */
-    {NULL,           "%s\\masked file.shlexec",   0x1, 33},
+    {NULL,           "%s\\masked file.shlexec",   0x0, 33},
     /* Test if quoting prevents the masking */
     {NULL,           "%s\\masked file.shlexec",   0x40, 33},
+    /* Test with incorrect quote */
+    {NULL,           "\"%s\\masked file.shlexec",   0x0, SE_ERR_FNF},
 
     {NULL, NULL, 0}
 };
@@ -1220,7 +1223,7 @@ static void test_commandline2argv(void)
 
     *strW = 0;
     args = CommandLineToArgvW(strW, &numargs);
-    ok(numargs == 1, "expected 1 args, got %d\n", numargs);
+    ok(numargs == 1 || broken(numargs > 1), "expected 1 args, got %d\n", numargs);
     ok(!args || (!args[numargs] || broken(args[numargs] != NULL) /* before Vista */),
        "expected NULL-terminated list of commandline arguments\n");
     if (numargs == 1)
@@ -1541,18 +1544,10 @@ static void test_filename(void)
         }
         if (rc > 32)
             rc=33;
-        if ((test->todo & 0x1)==0)
-        {
-            ok(rc==test->rc ||
-               broken(quotedfile && rc == SE_ERR_FNF), /* NT4 */
-               "%s failed: rc=%ld err=%u\n", shell_call,
-               rc, GetLastError());
-        }
-        else
-        {
-            ok(rc==test->rc, "%s failed: rc=%ld err=%u\n", shell_call,
-               rc, GetLastError());
-        }
+        ok(rc==test->rc ||
+           broken(quotedfile && rc == SE_ERR_FNF), /* NT4 */
+           "%s failed: rc=%ld err=%u\n", shell_call,
+           rc, GetLastError());
         if (rc == 33)
         {
             const char* verb;
@@ -2095,7 +2090,6 @@ static void test_exes(void)
 {
     char filename[MAX_PATH];
     char params[1024];
-    DWORD retval;
     INT_PTR rc;
 
     sprintf(params, "shlexec \"%s\" Exec", child_file);
@@ -2123,31 +2117,14 @@ static void test_exes(void)
         win_skip("Skipping shellexecute of file with unassociated extension\n");
     }
 
-    /* the directory with the test programs contain "test file.exe"
-     * and "test file two.exe". Check we do not start the first
-     * when we specify to start the second (see bug 19666)
-     */
-    sprintf(filename, "%s\\test file.exe", tmpdir);
-    retval = CopyFileA(argv0, filename, FALSE);
-    ok(retval, "CopyFile(\"%s\",\"%s\",FALSE) failed\n", argv0, filename);
-    sprintf(filename, "%s\\test file two.exe", tmpdir);
-    retval = CopyFileA(argv0, filename, FALSE);
-    ok(retval, "CopyFile(\"%s\",\"%s\",FALSE) failed\n", argv0, filename);
-    rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, params, NULL, NULL);
-    ok(rc > 32, "%s returned %lu\n", shell_call, rc);
-    okChildInt("argcA", 4);
-    okChildString("argvA0", filename);
-    okChildString("argvA3", "Exec");
+    /* test combining executable and parameters */
+    sprintf(filename, "%s shlexec \"%s\" Exec", argv0, child_file);
+    rc = shell_execute(NULL, filename, NULL, NULL);
+    ok(rc == SE_ERR_FNF, "%s returned %lu\n", shell_call, rc);
 
-    /* check quoted filename */
-    sprintf(filename, "\"%s\\test file two.exe\"", tmpdir);
-    rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, params, NULL, NULL);
-    ok(rc > 32, "%s returned %lu\n", shell_call, rc);
-    okChildInt("argcA", 4);
-    /* strip the quotes for the compare */
-    sprintf(filename, "%s\\test file two.exe", tmpdir);
-    okChildString("argvA0", filename);
-    okChildString("argvA3", "Exec");
+    sprintf(filename, "\"%s\" shlexec \"%s\" Exec", argv0, child_file);
+    rc = shell_execute(NULL, filename, NULL, NULL);
+    ok(rc == SE_ERR_FNF, "%s returned %lu\n", shell_call, rc);
 }
 
 typedef struct
@@ -2551,7 +2528,12 @@ static void init_test(void)
            "unable to find argv0!\n");
     }
 
-    GetTempPathA(sizeof(filename), filename);
+    /* Older versions (win 2k) fail tests if there is a space in
+       the path. */
+    if (dllver.dwMajorVersion <= 5)
+        strcpy(filename, "c:\\");
+    else
+        GetTempPathA(sizeof(filename), filename);
     GetTempFileNameA(filename, "wt", 0, tmpdir);
     GetLongPathNameA(tmpdir, tmpdir, sizeof(tmpdir));
     DeleteFileA( tmpdir );
index 07e4ee2..108d65e 100644 (file)
@@ -164,6 +164,9 @@ static void clean_after_shfo_tests(void)
     DeleteFileA("test4.txt\\test1.txt");
     DeleteFileA("test4.txt\\test2.txt");
     DeleteFileA("test4.txt\\test3.txt");
+    DeleteFileA("test4.txt\\one.txt");
+    DeleteFileA("test4.txt\\nested\\two.txt");
+    RemoveDirectoryA("test4.txt\\nested");
     RemoveDirectoryA("test4.txt");
     DeleteFileA("testdir2\\one.txt");
     DeleteFileA("testdir2\\test1.txt");
@@ -1826,6 +1829,48 @@ static void test_move(void)
     CHAR to[5*MAX_PATH];
     DWORD retval;
 
+    clean_after_shfo_tests();
+    init_shfo_tests();
+
+    shfo.hwnd = NULL;
+    shfo.wFunc = FO_MOVE;
+    shfo.pFrom = from;
+    shfo.pTo = to;
+    shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR;
+    shfo.hNameMappings = NULL;
+    shfo.lpszProgressTitle = NULL;
+    shfo.fAnyOperationsAborted = FALSE;
+
+    set_curr_dir_path(from, "testdir2\\*.*\0");
+    set_curr_dir_path(to, "test4.txt\\*.*\0");
+    retval = SHFileOperationA(&shfo);
+    ok(retval != 0, "SHFileOperation should fail\n");
+    ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
+
+    ok(file_exists("testdir2"), "dir should not be moved\n");
+    ok(file_exists("testdir2\\one.txt"), "file should not be moved\n");
+    ok(file_exists("testdir2\\nested"), "dir should not be moved\n");
+    ok(file_exists("testdir2\\nested\\two.txt"), "file should not be moved\n");
+
+    set_curr_dir_path(from, "testdir2\\*.*\0");
+    set_curr_dir_path(to, "test4.txt\0");
+    retval = SHFileOperationA(&shfo);
+    ok(!retval, "SHFileOperation error %#x\n", retval);
+    ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
+
+    ok(file_exists("testdir2"), "dir should not be moved\n");
+    ok(!file_exists("testdir2\\one.txt"), "file should be moved\n");
+    ok(!file_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"), "dir should exist\n");
+    ok(file_exists("test4.txt\\one.txt"), "file should exist\n");
+    ok(file_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;
@@ -2160,13 +2205,13 @@ static void test_move(void)
         ok(!DeleteFileA("d.txt"), "Expected d.txt to not exist\n");
     }
 
-    /* FO_MOVE does not create dest directories */
+    /* FO_MOVE should create dest directories */
     shfo.pFrom = "test2.txt\0";
     shfo.pTo = "dir1\\dir2\\test2.txt\0";
     retval = SHFileOperationA(&shfo);
     if (dir_exists("dir1"))
     {
-        /* Vista and W2K8 (broken or new behavior ?) */
+        /* New behavior on Vista or later */
         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
         ok(DeleteFileA("dir1\\dir2\\test2.txt"), "Expected dir1\\dir2\\test2.txt to exist\n");
         RemoveDirectoryA("dir1\\dir2");
@@ -2429,7 +2474,7 @@ static void test_unicode(void)
     shfoW.hwnd = NULL;
     shfoW.wFunc = FO_DELETE;
     shfoW.pFrom = UNICODE_PATH;
-    shfoW.pTo = '\0';
+    shfoW.pTo = NULL;
     shfoW.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
     shfoW.hNameMappings = NULL;
     shfoW.lpszProgressTitle = NULL;
index 1b457bb..975e73d 100644 (file)
@@ -75,6 +75,7 @@ static UINT (WINAPI *pGetSystemWow64DirectoryW)(LPWSTR, UINT);
 static HRESULT (WINAPI *pSHCreateDefaultContextMenu)(const DEFCONTEXTMENU*,REFIID,void**);
 static HRESULT (WINAPI *pSHCreateShellFolderView)(const SFV_CREATE *pcsfv, IShellView **ppsv);
 static HRESULT (WINAPI *pSHCreateShellFolderViewEx)(LPCSFV psvcbi, IShellView **ppv);
+static HRESULT (WINAPI *pSHILCreateFromPath)(LPCWSTR, LPITEMIDLIST *,DWORD*);
 
 static WCHAR *make_wstr(const char *str)
 {
@@ -140,6 +141,7 @@ static void init_function_pointers(void)
     MAKEFUNC_ORD(ILFindLastID, 16);
     MAKEFUNC_ORD(ILIsEqual, 21);
     MAKEFUNC_ORD(ILCombine, 25);
+    MAKEFUNC_ORD(SHILCreateFromPath, 28);
     MAKEFUNC_ORD(ILFree, 155);
     MAKEFUNC_ORD(SHSimpleIDListFromPathAW, 162);
 #undef MAKEFUNC_ORD
@@ -4235,12 +4237,34 @@ static void test_ShellItemArrayGetAttributes(void)
     Cleanup();
 }
 
+static WCHAR *get_empty_cddrive(void)
+{
+    static WCHAR cdrom_drive[] = {'A',':','\\',0};
+    DWORD drives = GetLogicalDrives();
+
+    cdrom_drive[0] = 'A';
+    while (drives)
+    {
+        if ((drives & 1) &&
+            GetDriveTypeW(cdrom_drive) == DRIVE_CDROM &&
+            GetFileAttributesW(cdrom_drive) == INVALID_FILE_ATTRIBUTES)
+        {
+            return cdrom_drive;
+        }
+
+        drives = drives >> 1;
+        cdrom_drive[0]++;
+    }
+    return NULL;
+}
+
 static void test_SHParseDisplayName(void)
 {
     LPITEMIDLIST pidl1, pidl2;
     IShellFolder *desktop;
     WCHAR dirW[MAX_PATH];
     WCHAR nameW[10];
+    WCHAR *cdrom;
     HRESULT hr;
     BOOL ret, is_wow64;
 
@@ -4312,6 +4336,16 @@ if (0)
     }
 
     IShellFolder_Release(desktop);
+
+    cdrom = get_empty_cddrive();
+    if (!cdrom)
+        skip("No empty cdrom drive found, skipping test\n");
+    else
+    {
+        hr = pSHParseDisplayName(cdrom, NULL, &pidl1, 0, NULL);
+        ok(hr == S_OK, "failed %08x\n", hr);
+        if (SUCCEEDED(hr)) pILFree(pidl1);
+    }
 }
 
 static void test_desktop_IPersist(void)
@@ -4974,9 +5008,9 @@ static void test_SHChangeNotify(BOOL test_new_delivery)
 
     entries[0].pidl = NULL;
     if(has_unicode)
-        hr = SHILCreateFromPath(root_dirW, (LPITEMIDLIST*)&entries[0].pidl, 0);
+        hr = pSHILCreateFromPath(root_dirW, (LPITEMIDLIST*)&entries[0].pidl, 0);
     else
-        hr = SHILCreateFromPath((LPCVOID)root_dirA, (LPITEMIDLIST*)&entries[0].pidl, 0);
+        hr = pSHILCreateFromPath((LPCVOID)root_dirA, (LPITEMIDLIST*)&entries[0].pidl, 0);
     ok(hr == S_OK, "SHILCreateFromPath failed: 0x%08x\n", hr);
     entries[0].fRecursive = TRUE;
 
index 81f4754..6cdb386 100755 (executable)
@@ -32,7 +32,7 @@
 #include "wine/test.h"
 
 static HMODULE hShell32;
-static HRESULT (WINAPI *pStrRetToStrNAW)(LPVOID,DWORD,LPSTRRET,const ITEMIDLIST *);
+static BOOL (WINAPI *pStrRetToStrNAW)(LPVOID,DWORD,LPSTRRET,const ITEMIDLIST *);
 
 static WCHAR *CoDupStrW(const char* src)
 {
index c554262..4af10f0 100644 (file)
@@ -44,6 +44,7 @@ static void test_cbsize(void)
         nidW.hIcon = LoadIconA(NULL, (LPSTR)IDI_APPLICATION);
         nidW.uCallbackMessage = WM_USER+17;
         ret = pShell_NotifyIconW(NIM_ADD, &nidW);
+        ok(ret, "NIM_ADD failed!\n");
         /* using an invalid cbSize does work */
         nidW.cbSize = 3;
         nidW.hWnd = hMainWnd;