[PATCH v11 1/3] shell32/tests: Add tests for FolderItems_Item and FolderItems_get_Count.

Alex Henrie alexhenrie24 at gmail.com
Tue Sep 6 00:40:29 CDT 2016


Cc: Sebastian Lackner <sebastian at fds-team.de>

v11:
- removed the tests for variant types other than VT_EMPTY, VT_I2, VT_I4,
  VT_BSTR, and VT_ERROR
- added tests to prove that you can still get the item objects using
  numeric indices even after deleting the files, but not using string
  indices, and not if the folder itself is deleted
- unrolled the inner loop and removed the state machine

Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
---
 dlls/shell32/tests/Makefile.in     |   2 +-
 dlls/shell32/tests/shelldispatch.c | 310 +++++++++++++++++++++++++++++++++++--
 2 files changed, 299 insertions(+), 13 deletions(-)

diff --git a/dlls/shell32/tests/Makefile.in b/dlls/shell32/tests/Makefile.in
index cfe0c50..ef95b52 100644
--- a/dlls/shell32/tests/Makefile.in
+++ b/dlls/shell32/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = shell32.dll
-IMPORTS   = shell32 ole32 oleaut32 user32 advapi32
+IMPORTS   = shell32 ole32 oleaut32 user32 advapi32 shlwapi
 
 C_SRCS = \
 	appbar.c \
diff --git a/dlls/shell32/tests/shelldispatch.c b/dlls/shell32/tests/shelldispatch.c
index 9a47c67..8e83b36 100644
--- a/dlls/shell32/tests/shelldispatch.c
+++ b/dlls/shell32/tests/shelldispatch.c
@@ -310,19 +310,45 @@ static void test_namespace(void)
 
 static void test_items(void)
 {
-    WCHAR wstr[MAX_PATH], orig_dir[MAX_PATH];
+    static const struct
+    {
+        char name[32];
+        enum
+        {
+            DIRECTORY,
+            SHORTCUT,
+            EMPTY,
+            RANDOM,
+        }
+        type;
+    }
+    file_defs[] =
+    {
+        { "00-Myfolder",        DIRECTORY },
+        { "01-empty.lnk",       EMPTY     },
+        { "02-shortcut.lnk",    SHORTCUT  },
+        { "03-empty.bin",       EMPTY     },
+        { "04-random.bin",      RANDOM    },
+    };
+    WCHAR wstr[MAX_PATH], wstr2[MAX_PATH], cur_dir[MAX_PATH], orig_dir[MAX_PATH];
     HRESULT r;
     IShellDispatch *sd = NULL;
     Folder *folder = NULL;
     FolderItems *items = NULL;
     FolderItems2 *items2 = NULL;
     FolderItems3 *items3 = NULL;
-    FolderItem *item = (FolderItem*)0xdeadbeef;
+    FolderItem *item = (FolderItem*)0xdeadbeef, *item2;
     IDispatch *disp = NULL;
     IUnknown *unk = NULL;
     FolderItemVerbs *verbs = (FolderItemVerbs*)0xdeadbeef;
-    VARIANT var;
+    VARIANT var, int_index, str_index;
     LONG lcount = -1;
+    HANDLE file;
+    DWORD dwcount;
+    IPersistFile *shortcut;
+    BSTR bstr;
+    char buf[512];
+    int i, j;
 
     r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&sd);
     ok(SUCCEEDED(r), "CoCreateInstance failed: %08x\n", r);
@@ -331,7 +357,7 @@ static void test_items(void)
     GetTempPathW(MAX_PATH, wstr);
     GetCurrentDirectoryW(MAX_PATH, orig_dir);
     SetCurrentDirectoryW(wstr);
-    CreateDirectoryW(winetestW, NULL);
+    ok(CreateDirectoryW(winetestW, NULL), "CreateDirectory failed: %08x\n", GetLastError());
     GetFullPathNameW(winetestW, MAX_PATH, wstr, NULL);
     V_VT(&var) = VT_BSTR;
     V_BSTR(&var) = SysAllocString(wstr);
@@ -341,17 +367,12 @@ static void test_items(void)
     SysFreeString(V_BSTR(&var));
     IShellDispatch_Release(sd);
     SetCurrentDirectoryW(winetestW);
+    GetCurrentDirectoryW(MAX_PATH, wstr);
+    GetLongPathNameW(wstr, cur_dir, MAX_PATH);
 
     r = Folder_Items(folder, &items);
     ok(r == S_OK, "Folder::Items failed: %08x\n", r);
     ok(!!items, "items is null\n");
-    r = FolderItems_QueryInterface(items, &IID_FolderItems2, (void**)&items2);
-    ok(r == S_OK || broken(E_NOINTERFACE) /* xp and later */, "FolderItems::QueryInterface failed: %08x\n", r);
-    ok(!!items2 || broken(!items2) /* xp and later */, "items2 is null\n");
-    r = FolderItems_QueryInterface(items, &IID_FolderItems3, (void**)&items3);
-    ok(r == S_OK, "FolderItems::QueryInterface failed: %08x\n", r);
-    ok(!!items3, "items3 is null\n");
-    Folder_Release(folder);
 
     if (0) /* crashes on all versions of Windows */
         r = FolderItems_get_Count(items, NULL);
@@ -373,6 +394,245 @@ todo_wine
     ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
     ok(!item, "item is not null\n");
 
+    for (i = 0; i < sizeof(file_defs)/sizeof(file_defs[0]); i++)
+    {
+        switch (file_defs[i].type)
+        {
+            case DIRECTORY:
+                r = CreateDirectoryA(file_defs[i].name, NULL);
+                ok(r, "CreateDirectory failed: %08x\n", GetLastError());
+                PathCombineA(buf, file_defs[i].name, "foo.txt");
+                file = CreateFileA(buf, 0, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+                ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %08x\n", GetLastError());
+                CloseHandle(file);
+                break;
+
+            case SHORTCUT:
+                CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IPersistFile, (void**)&shortcut);
+                MultiByteToWideChar(CP_ACP, 0, file_defs[i].name, -1, wstr, sizeof(wstr)/sizeof(WCHAR));
+                r = IPersistFile_Save(shortcut, wstr, FALSE);
+                ok(SUCCEEDED(r), "IPersistFile_Save failed: %08x\n", r);
+                IPersistFile_Release(shortcut);
+                break;
+
+            case EMPTY:
+                file = CreateFileA(file_defs[i].name, 0, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+                ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %08x\n", GetLastError());
+                CloseHandle(file);
+                break;
+
+            case RANDOM:
+                file = CreateFileA(file_defs[i].name, GENERIC_WRITE, 0, NULL,
+                                   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+                ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %08x\n", GetLastError());
+                for (j = 0; j < sizeof(buf); j++)
+                    buf[j] = rand() % 256;
+                r = WriteFile(file, buf, sizeof(buf), &dwcount, NULL);
+                ok(r, "WriteFile failed: %08x\n", GetLastError());
+                CloseHandle(file);
+                break;
+        }
+    }
+
+    lcount = -1;
+    r = FolderItems_get_Count(items, &lcount);
+todo_wine
+    ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
+todo_wine
+    ok(!lcount, "expected 0 files, got %d\n", lcount);
+
+    MultiByteToWideChar(CP_ACP, 0, file_defs[0].name, -1, wstr, MAX_PATH);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(wstr);
+    item = (FolderItem*)0xdeadbeef;
+    r = FolderItems_Item(items, var, &item);
+todo_wine
+    ok(r == S_OK, "FolderItems::Item failed: %08x\n", r);
+todo_wine
+    ok(!!item, "item is null\n");
+    VariantClear(&var);
+
+    FolderItems_Release(items);
+    items = NULL;
+    r = Folder_Items(folder, &items);
+    ok(r == S_OK, "Folder::Items failed: %08x\n", r);
+    ok(!!items, "items is null\n");
+    r = FolderItems_QueryInterface(items, &IID_FolderItems2, (void**)&items2);
+    ok(r == S_OK || broken(E_NOINTERFACE) /* xp and later */, "FolderItems::QueryInterface failed: %08x\n", r);
+    if (r == S_OK) ok(!!items2, "items2 is null\n");
+    r = FolderItems_QueryInterface(items, &IID_FolderItems3, (void**)&items3);
+    ok(r == S_OK, "FolderItems::QueryInterface failed: %08x\n", r);
+    ok(!!items3, "items3 is null\n");
+    Folder_Release(folder);
+
+    lcount = -1;
+    r = FolderItems_get_Count(items, &lcount);
+todo_wine
+    ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
+todo_wine
+    ok(lcount == sizeof(file_defs)/sizeof(file_defs[0]),
+       "expected %d files, got %d\n", sizeof(file_defs)/sizeof(file_defs[0]), lcount);
+
+    V_VT(&var) = VT_EMPTY;
+    item = (FolderItem*)0xdeadbeef;
+    r = FolderItems_Item(items, var, &item);
+    ok(r == E_NOTIMPL, "expected E_NOTIMPL, got %08x\n", r);
+    ok(!item, "item is not null\n");
+
+    V_VT(&var) = VT_I2;
+    V_I2(&var) = 0;
+    item = NULL;
+    r = FolderItems_Item(items, var, &item);
+todo_wine
+    ok(r == S_OK, "FolderItems::Item failed: %08x\n", r);
+todo_wine
+    ok(!!item, "item is null\n");
+
+    V_VT(&var) = VT_I4;
+    V_I4(&var) = 0;
+    item = NULL;
+    r = FolderItems_Item(items, var, &item);
+todo_wine
+    ok(r == S_OK, "FolderItems::Item failed: %08x\n", r);
+todo_wine
+    ok(!!item, "item is null\n");
+
+    V_I4(&var) = -1;
+    item = (FolderItem*)0xdeadbeef;
+    r = FolderItems_Item(items, var, &item);
+todo_wine
+    ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
+    ok(!item, "item is not null\n");
+
+    for (i = -10; i < 10; i++)
+    {
+        V_VT(&var) = VT_ERROR;
+        V_ERROR(&var) = i;
+        item = NULL;
+        r = FolderItems_Item(items, var, &item);
+todo_wine
+        ok(r == S_OK, "expected S_OK, got %08x\n", r);
+todo_wine
+        ok(!!item, "item is null\n");
+        if (!item) continue;
+
+        bstr = NULL;
+        r = FolderItem_get_Path(item, &bstr);
+        ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
+        ok(!!bstr, "bstr is null\n");
+        ok(!lstrcmpW(bstr, cur_dir),
+           "expected %s, got %s\n", wine_dbgstr_w(cur_dir), wine_dbgstr_w(bstr));
+
+        SysFreeString(bstr);
+        FolderItem_Release(item);
+    }
+
+    for (i = 0; i < sizeof(file_defs)/sizeof(file_defs[0]); i++)
+    {
+        MultiByteToWideChar(CP_ACP, 0, file_defs[i].name, -1, wstr, MAX_PATH);
+
+        V_VT(&int_index) = VT_I4;
+        V_I4(&int_index) = i;
+
+        V_VT(&str_index) = VT_BSTR;
+        V_BSTR(&str_index) = SysAllocString(wstr);
+
+        item = NULL;
+        r = FolderItems_Item(items, int_index, &item);
+todo_wine
+        ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
+todo_wine
+        ok(!!item, "file_defs[%d]: item is null\n", i);
+        if (!item) goto cleanup;
+
+        item2 = NULL;
+        r = FolderItems_Item(items, int_index, &item2);
+        ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
+        ok(item2 != item, "file_defs[%d]: item and item2 are the same\n", i);
+        FolderItem_Release(item2);
+
+        bstr = NULL;
+        r = FolderItem_get_Path(item, &bstr);
+        ok(r == S_OK, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i, r);
+        ok(!!bstr, "file_defs[%d]: bstr is null\n", i);
+        PathCombineW(wstr2, cur_dir, wstr);
+        ok(!lstrcmpW(bstr, wstr2),
+           "file_defs[%d]: expected %s, got %s\n", i, wine_dbgstr_w(wstr2), wine_dbgstr_w(bstr));
+        SysFreeString(bstr);
+
+        item = NULL;
+        r = FolderItems_Item(items, str_index, &item);
+        ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
+        ok(!!item, "file_defs[%d]: item is null\n", i);
+
+        bstr = NULL;
+        r = FolderItem_get_Path(item, &bstr);
+        ok(r == S_OK, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i, r);
+        ok(!!bstr, "file_defs[%d]: bstr is null\n", i);
+        PathCombineW(wstr2, cur_dir, wstr);
+        ok(!lstrcmpW(bstr, wstr2),
+           "file_defs[%d]: expected %s, got %s\n", i, wine_dbgstr_w(wstr2), wine_dbgstr_w(bstr));
+        SysFreeString(bstr);
+
+        FolderItem_Release(item);
+
+cleanup:
+        if (file_defs[i].type == DIRECTORY)
+        {
+            PathCombineA(buf, file_defs[i].name, "foo.txt");
+            MultiByteToWideChar(CP_ACP, 0, buf, -1, wstr2, MAX_PATH);
+            V_VT(&var) = VT_BSTR;
+            V_BSTR(&var) = SysAllocString(wstr2);
+            item2 = NULL;
+            r = FolderItems_Item(items, var, &item2);
+todo_wine
+            ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
+todo_wine
+            ok(!!item2, "file_defs[%d]: item is null\n", i);
+            if (item2) FolderItem_Release(item2);
+            VariantClear(&var);
+
+            ok(DeleteFileA(buf), "file_defs[%d]: DeleteFile failed: %08x\n", i, GetLastError());
+            ok(RemoveDirectoryW(wstr), "file_defs[%d]: RemoveDirectory failed: %08x\n", i, GetLastError());
+        }
+        else
+        {
+            ok(DeleteFileW(wstr), "file_defs[%d]: DeleteFile failed: %08x\n", i, GetLastError());
+        }
+        if (!item) continue;
+
+        item = NULL;
+        r = FolderItems_Item(items, int_index, &item);
+        ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
+        ok(!!item, "file_defs[%d]: item is null\n", i);
+
+        bstr = NULL;
+        r = FolderItem_get_Path(item, &bstr);
+        ok(r == S_OK, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i, r);
+        ok(!!bstr, "file_defs[%d]: bstr is null\n", i);
+        PathCombineW(wstr2, cur_dir, wstr);
+        ok(!lstrcmpW(bstr, wstr2),
+           "file_defs[%d]: expected %s, got %s\n", i, wine_dbgstr_w(wstr2), wine_dbgstr_w(bstr));
+        SysFreeString(bstr);
+
+        FolderItem_Release(item);
+
+        item = (FolderItem*)0xdeadbeef;
+        r = FolderItems_Item(items, str_index, &item);
+        ok(r == S_FALSE, "file_defs[%d]: expected S_FALSE, got %08x\n", i, r);
+        ok(!item, "file_defs[%d]: item is not null\n", i);
+
+        VariantClear(&str_index);
+    }
+
+    V_VT(&var) = VT_I4;
+    V_I4(&var) = sizeof(file_defs)/sizeof(file_defs[0]);
+    item = (FolderItem*)0xdeadbeef;
+    r = FolderItems_Item(items, var, &item);
+todo_wine
+    ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
+    ok(!item, "item is not null\n");
+
     if (0) /* crashes on xp */
     {
         r = FolderItems_get_Application(items, NULL);
@@ -430,9 +690,35 @@ todo_wine
 
     GetTempPathW(MAX_PATH, wstr);
     SetCurrentDirectoryW(wstr);
-    RemoveDirectoryW(winetestW);
+    ok(RemoveDirectoryW(winetestW), "RemoveDirectory failed: %08x\n", GetLastError());
     SetCurrentDirectoryW(orig_dir);
 
+    lcount = -1;
+    r = FolderItems_get_Count(items, &lcount);
+todo_wine
+    ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
+todo_wine
+    ok(!lcount, "expected 0 files, got %d\n", lcount);
+
+    item = NULL;
+    V_VT(&var) = VT_I4;
+    V_I4(&var) = 0;
+    item = (FolderItem*)0xdeadbeef;
+    r = FolderItems_Item(items, var, &item);
+todo_wine
+    ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
+    ok(!item, "item is not null\n");
+
+    MultiByteToWideChar(CP_ACP, 0, file_defs[0].name, -1, wstr, MAX_PATH);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(wstr);
+    item = (FolderItem*)0xdeadbeef;
+    r = FolderItems_Item(items, var, &item);
+todo_wine
+    ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
+    ok(!item, "item is not null\n");
+    VariantClear(&var);
+
     FolderItems_Release(items);
     if (items2) FolderItems2_Release(items2);
     if (items3) FolderItems3_Release(items3);
-- 
2.9.3




More information about the wine-patches mailing list