From 5fa9fa1a7e641cf5e39ac42c871688498902183f Mon Sep 17 00:00:00 2001
From: Jiangyi Chen <chenjiangyi@uniontech.com>
Date: Wed, 9 Sep 2020 09:48:29 +0000
Subject: [PATCH] comdlg32/tests: Add test for overwrite when IFileDialog set
 FOS_PICKFOLDERS option.

Signed-off-by: Jiangyi Chen <chenjiangyi@uniontech.com>
---
 dlls/comdlg32/tests/itemdlg.c | 193 +++++++++++++++++++++++++++++++++-
 1 file changed, 192 insertions(+), 1 deletion(-)

diff --git a/dlls/comdlg32/tests/itemdlg.c b/dlls/comdlg32/tests/itemdlg.c
index 6ee0d5fc3d..cebf920287 100644
--- a/dlls/comdlg32/tests/itemdlg.c
+++ b/dlls/comdlg32/tests/itemdlg.c
@@ -27,12 +27,14 @@
 
 #define IDT_CHANGEFILETYPE 500
 #define IDT_CLOSEDIALOG    501
+#define IDT_CLOSEWRONGPOPUP 502
 
 typedef enum {
     IFDEVENT_TEST_NONE = 0,
     IFDEVENT_TEST1     = 0x1,
     IFDEVENT_TEST2     = 0x2,
-    IFDEVENT_TEST3     = 0x3
+    IFDEVENT_TEST3     = 0x3,
+    IFDEVENT_TEST4     = 0x4
 } FileDialogEventsTest;
 
 static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
@@ -193,6 +195,10 @@ static LRESULT CALLBACK test_customize_dlgproc(HWND hwnd, UINT message, WPARAM w
             br = PostMessageW(hwnd, WM_COMMAND, IDCANCEL, 0);
             ok(br, "Failed\n");
             return TRUE;
+        case IDT_CLOSEWRONGPOPUP:
+            br = PostMessageW(hwnd, WM_QUIT, 0, 0);
+            ok(br, "Failed\n");
+            return TRUE;
         }
     }
 
@@ -249,6 +255,9 @@ static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *ifac
         case IFDEVENT_TEST3:
             SetTimer(dlg_hwnd, IDT_CHANGEFILETYPE, 100, 0);
             break;
+        case IFDEVENT_TEST4:
+            SetTimer(dlg_hwnd, IDT_CLOSEWRONGPOPUP, 100, 0);
+            break;
         default:
             ok(FALSE, "Should not happen (%d)\n", This->events_test);
         }
@@ -2458,6 +2467,187 @@ static void test_overwrite(void)
     IShellItem_Release(psi_current);
 }
 
+/*test conflicts between SFGAO_FOLDER attribute and overwrite when IFileDialog set FOS_PICKFOLDERS option.*/
+static void test_fgaofolder_overwrite_conflict(void)
+{
+    static const WCHAR filename_winetest[] = {'w','i','n','e','t','e','s','t','.','o','v','w',0};
+
+    IFileDialogEventsImpl *pfdeimpl;
+    IFileDialogEvents *pfde;
+    IFileDialog *fd;
+    DWORD cookie;
+    LPWSTR filename;
+    IShellItem *psi_current;
+    WCHAR buf[MAX_PATH];
+    HRESULT hr;
+
+    GetCurrentDirectoryW(MAX_PATH, buf);
+
+    trace("current directory:%s\n",wine_dbgstr_w(buf));
+    ok(!!pSHCreateItemFromParsingName, "SHCreateItemFromParsingName is missing.\n");
+    hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psi_current);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+
+    /*Ensure that there is no file with the same name in the test directory*/
+    DeleteFileW(filename_winetest);
+
+    hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_IFileDialog, (void**)&fd);
+    ok(hr == S_OK, "got 0x%08x.\n", hr);
+
+    hr = IFileDialog_SetOptions(fd,FOS_OVERWRITEPROMPT|FOS_PICKFOLDERS );
+    if(FAILED(hr)) //hr=E_INVALIDARG
+    {
+        IFileDialog_Release(fd);
+        win_skip("Not supported on some platforms.\n");
+        return;
+    }
+    ok(hr == S_OK, "IFileDialog_SetOptions : got 0x%08x.\n", hr);
+
+    /*
+    *if FOS_PICKFOLDERS set,IFileDialog_SetFolder does work
+    *but it does not seem to switch to the corresponding
+    *directory after the dialog box is displayed.
+    */
+    hr = IFileDialog_SetFolder(fd, psi_current);
+    ok(hr == S_OK, "IFileDialog_SetFolder : got 0x%08x.\n", hr);
+
+    /*Simulate the action of the user clicking the "Save" button*/
+    pfde = IFileDialogEvents_Constructor();
+    pfdeimpl = impl_from_IFileDialogEvents(pfde);
+    pfdeimpl->set_filename = filename_winetest;
+    hr = IFileDialog_Advise(fd, pfde, &cookie);
+    ok(hr == S_OK, "IFileDialog_Advise : Got 0x%08x\n", hr);
+
+    hr = IFileDialog_Show(fd, NULL);
+    ok(hr == S_OK, "IFileDialog_Show : Got 0x%08x\n", hr);
+
+    ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
+    ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
+    hr = IFileDialog_GetFileName(fd, &filename);
+    ok(hr == S_OK, "IFileDialog_GetFileName : Got 0x%08x \n", hr);
+
+    ok(!lstrcmpW(filename, filename_winetest), "actually Got %s\n", wine_dbgstr_w(filename));
+    CoTaskMemFree(filename);
+
+    IShellItem * psi;
+    hr = IFileDialog_GetResult(fd, &psi);
+    ok(hr == S_OK, "IFileDialog_GetResult : Got 0x%08x\n", hr);
+
+    hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
+    ok(hr == S_OK, "IShellItem_GetDisplayName : Got 0x%08x \n", hr);
+    CoTaskMemFree(filename);
+
+    /*
+    *at this time,the target directory does not contain a file named filename_winetest that user set before.
+    *get the attributes of the file(named filename_winetest) that to be touch .
+    *discover the acquired file attributes has SFGAO_FOLDER flags seted.
+    *However, in fact,it should not have folder(SFGAO_FOLDER) attributes as a file.
+    */
+    SFGAOF itemattri=0;
+    hr=IShellItem_GetAttributes(psi,SFGAO_FOLDER,&itemattri);
+    ok(hr == S_OK, "IShellItem_GetAttributes : Got 0x%08x \n", hr);
+    if(hr==S_OK) trace("get attrib success 0x%08x\n",itemattri);
+    else trace("get attrib failed 0x%08x\n",itemattri);
+    IShellItem_Release(psi);
+
+    /*create file named filename_winetest*/
+    touch_file(filename_winetest);
+
+    hr = IFileDialog_Unadvise(fd, cookie);
+    ok(hr == S_OK, "got 0x%08x.\n", hr);
+
+    IFileDialog_Release(fd);
+
+    IFileDialogEvents_Release(pfde);
+
+    IShellItem_Release(psi_current);
+
+    /*at this time,file named filename_winetest already exists.
+     *the fllowing code will save filename_winetest in the same target directory as above.
+     *Should pop up an overwrite prompt box, but actually pop up a non-file prompt box.
+    */
+
+    GetCurrentDirectoryW(MAX_PATH, buf);
+
+    trace("current directory:%s\n",wine_dbgstr_w(buf));
+    ok(!!pSHCreateItemFromParsingName, "SHCreateItemFromParsingName is missing.\n");
+    hr = pSHCreateItemFromParsingName(buf, NULL, &IID_IShellItem, (void**)&psi_current);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+
+
+    hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_IFileDialog, (void**)&fd);
+    ok(hr == S_OK, "got 0x%08x.\n", hr);
+
+    hr = IFileDialog_SetOptions(fd,FOS_OVERWRITEPROMPT|FOS_PICKFOLDERS );
+    if(FAILED(hr)) //hr=E_INVALIDARG
+    {
+        IFileDialog_Release(fd);
+        win_skip("Not supported on some platforms.\n");
+        return;
+    }
+    ok(hr == S_OK, "IFileDialog_SetOptions : got 0x%08x.\n", hr);
+
+    /*
+    *if FOS_PICKFOLDERS set,IFileDialog_SetFolder does work
+    *but it does not seem to switch to the corresponding
+    *directory after the dialog box is displayed.
+    */
+    hr = IFileDialog_SetFolder(fd, psi_current);
+    ok(hr == S_OK, "IFileDialog_SetFolder : got 0x%08x.\n", hr);
+
+    pfde = IFileDialogEvents_Constructor();
+    pfdeimpl = impl_from_IFileDialogEvents(pfde);
+    pfdeimpl->set_filename = filename_winetest;
+    pfdeimpl->events_test = IFDEVENT_TEST4;
+    hr = IFileDialog_Advise(fd, pfde, &cookie);
+    ok(hr == S_OK, "IFileDialog_Advise : Got 0x%08x\n", hr);
+
+    ensure_zero_events(pfdeimpl);
+    hr = IFileDialog_Show(fd, NULL);
+    todo_wine ok(hr == S_OK, "IFileDialog_Show : Got 0x%08x\n", hr);
+
+    ok(!pfdeimpl->OnOverwrite, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
+    ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
+    if(hr != S_OK)
+    {
+        goto last;
+    }
+
+    hr = IFileDialog_GetFileName(fd, &filename);
+    ok(hr == S_OK, "IFileDialog_GetFileName : Got 0x%08x \n", hr);
+
+    ok(!lstrcmpW(filename, filename_winetest), "actually Got %s\n", wine_dbgstr_w(filename));
+    CoTaskMemFree(filename);
+
+
+    hr = IFileDialog_GetResult(fd, &psi);
+    ok(hr == S_OK, "IFileDialog_GetResult : Got 0x%08x\n", hr);
+
+    hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename);
+    ok(hr == S_OK, "IShellItem_GetDisplayName : Got 0x%08x \n", hr);
+    CoTaskMemFree(filename);
+
+    hr=IShellItem_GetAttributes(psi,SFGAO_FOLDER,&itemattri);
+    ok(hr == S_OK, "IShellItem_GetAttributes : Got 0x%08x \n", hr);
+    if(hr==S_OK) trace("get attrib success 0x%08x\n",itemattri);
+    else trace("get attrib failed 0x%08x\n",itemattri);
+    IShellItem_Release(psi);
+
+ last:
+    hr = IFileDialog_Unadvise(fd, cookie);
+    ok(hr == S_OK, "got 0x%08x.\n", hr);
+
+    IFileDialog_Release(fd);
+
+    IFileDialogEvents_Release(pfde);
+
+    IShellItem_Release(psi_current);
+
+    DeleteFileW(filename_winetest);
+}
+
 START_TEST(itemdlg)
 {
     OleInitialize(NULL);
@@ -2472,6 +2662,7 @@ START_TEST(itemdlg)
         test_customize();
         test_persistent_state();
         test_overwrite();
+        test_fgaofolder_overwrite_conflict();
     }
     else
         skip("Skipping all Item Dialog tests.\n");
-- 
2.20.1

