https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7e9cf359675f0ab4c71dd…
commit 7e9cf359675f0ab4c71dd459fea955d509cf4449
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Dec 27 09:45:44 2021 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Dec 27 09:45:44 2021 +0900
[SHELL32_APITEST] Strengthen SHChangeNotify testcase more and more (#4174)
CORE-13950
---
.../rostests/apitests/shell32/SHChangeNotify.cpp | 1035 +++++++++++++++-----
modules/rostests/apitests/shell32/SHChangeNotify.h | 79 +-
.../apitests/shell32/shell32_apitest_sub.cpp | 162 +--
3 files changed, 916 insertions(+), 360 deletions(-)
diff --git a/modules/rostests/apitests/shell32/SHChangeNotify.cpp
b/modules/rostests/apitests/shell32/SHChangeNotify.cpp
index 377b9ce1cec..50481848357 100644
--- a/modules/rostests/apitests/shell32/SHChangeNotify.cpp
+++ b/modules/rostests/apitests/shell32/SHChangeNotify.cpp
@@ -2,213 +2,502 @@
* PROJECT: ReactOS api tests
* LICENSE: LGPL-2.0-or-later (
https://spdx.org/licenses/LGPL-2.0-or-later)
* PURPOSE: Test for SHChangeNotify
- * COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
+ * COPYRIGHT: Copyright 2020-2021 Katayama Hirofumi MZ
(katayama.hirofumi.mz(a)gmail.com)
*/
-// NOTE: This test program closes the Explorer cabinets before tests.
+// NOTE: This test program closes the Explorer windows before tests.
#include "shelltest.h"
-#include <shlwapi.h>
-#include <stdio.h>
#include "SHChangeNotify.h"
-
-#define DONT_SEND 0x24242424
+#include <time.h>
+#include <process.h>
+#include <versionhelpers.h>
+
+// --- The selection of tests ---
+//#define DISABLE_THIS_TESTCASE
+#define NO_TRIVIAL
+//#define NO_INTERRUPT_LEVEL
+//#define NO_SHELL_LEVEL
+#define NEW_DELIVERY_ONLY
+//#define RANDOM_HALF
+#define RANDOM_QUARTER
+
+// --- Show the elapsed time by GetTickCount() ---
+//#define ENTRY_TICK
+#define GROUP_TICK
+#define TOTAL_TICK
static HWND s_hwnd = NULL;
-static const WCHAR s_szName[] = L"SHChangeNotify testcase";
static WCHAR s_szSubProgram[MAX_PATH];
+static HANDLE s_hThread = NULL;
+static HANDLE s_hEvent = NULL;
+
+static HWND DoWaitForWindow(LPCWSTR clsname, LPCWSTR text, BOOL bClosing, BOOL bForce)
+{
+ HWND hwnd = NULL;
+ for (INT i = 0; i < 50; ++i)
+ {
+ hwnd = FindWindowW(clsname, text);
+ if (bClosing)
+ {
+ if (!hwnd)
+ break;
+
+ if (bForce)
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ }
+ else
+ {
+ if (hwnd)
+ break;
+ }
+
+ Sleep(1);
+ }
+ return hwnd;
+}
+
+static BOOL DoCreateEmptyFile(LPCWSTR pszFileName)
+{
+ FILE *fp = _wfopen(pszFileName, L"wb");
+ if (fp)
+ fclose(fp);
+ return fp != NULL;
+}
-typedef void (*ACTION)(void);
+struct TEST_ENTRY;
+
+typedef BOOL (*ACTION)(const struct TEST_ENTRY *entry);
typedef struct TEST_ENTRY
{
INT line;
- DWORD event;
- LPCVOID item1;
- LPCVOID item2;
+ DIRTYPE iWriteDir;
LPCSTR pattern;
- ACTION action;
LPCWSTR path1;
LPCWSTR path2;
+ ACTION action;
} TEST_ENTRY;
-static BOOL
-DoCreateEmptyFile(LPCWSTR pszFileName)
+#define TEST_FILE L"_TEST_.txt"
+#define TEST_FILE_KAI L"_TEST_KAI_.txt"
+#define TEST_DIR L"_TESTDIR_"
+#define TEST_DIR_KAI L"_TESTDIR_KAI_"
+#define MOVE_FILE(from, to) MoveFileW((from), (to))
+
+static BOOL DoAction1(const TEST_ENTRY *entry)
{
- FILE *fp = _wfopen(pszFileName, L"wb");
- fclose(fp);
- return fp != NULL;
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_FILE);
+ ok(DoCreateEmptyFile(pszPath), "Line %d: DoCreateEmptyFile failed\n",
entry->line);
+ return TRUE;
}
-static void
-DoAction1(void)
+static BOOL DoAction2(const TEST_ENTRY *entry)
{
- ok_int(CreateDirectoryW(s_dir2, NULL), TRUE);
+ LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 =
DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath1, TEST_FILE);
+ PathAppendW(pszPath2, TEST_FILE_KAI);
+ ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed
(%ld)\n",
+ entry->line, pszPath1, pszPath2, GetLastError());
+ return TRUE;
}
-static void
-DoAction2(void)
+static BOOL DoAction3(const TEST_ENTRY *entry)
{
- ok_int(RemoveDirectoryW(s_dir2), TRUE);
+ LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 =
DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath1, TEST_FILE_KAI);
+ PathAppendW(pszPath2, TEST_FILE);
+ ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed
(%ld)\n",
+ entry->line, pszPath1, pszPath2, GetLastError());
+ return TRUE;
}
-static void
-DoAction3(void)
+static BOOL DoAction4(const TEST_ENTRY *entry)
{
- ok_int(MoveFileExW(s_dir2, s_dir3, MOVEFILE_COPY_ALLOWED |
MOVEFILE_REPLACE_EXISTING), TRUE);
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_FILE);
+ ok(DeleteFileW(pszPath), "Line %d: DeleteFileW(%ls) failed (%ld)\n",
+ entry->line, pszPath, GetLastError());
+ return TRUE;
}
-static void
-DoAction4(void)
+static BOOL DoAction5(const TEST_ENTRY *entry)
{
- ok_int(DoCreateEmptyFile(s_file1), TRUE);
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_DIR);
+ ok(CreateDirectoryW(pszPath, NULL), "Line %d: CreateDirectoryW(%ls) failed
(%ld)\n",
+ entry->line, pszPath, GetLastError());
+ return TRUE;
}
-static void
-DoAction5(void)
+static BOOL DoAction6(const TEST_ENTRY *entry)
{
- ok_int(MoveFileExW(s_file1, s_file2, MOVEFILE_COPY_ALLOWED |
MOVEFILE_REPLACE_EXISTING), TRUE);
+ LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 =
DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath1, TEST_DIR);
+ PathAppendW(pszPath2, TEST_DIR_KAI);
+ ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed
(%ld)\n",
+ entry->line, pszPath1, pszPath2, GetLastError());
+ return TRUE;
}
-static void
-DoAction6(void)
+static BOOL DoAction7(const TEST_ENTRY *entry)
{
- ok_int(DeleteFileW(s_file2), TRUE);
+ LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 =
DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath1, TEST_DIR_KAI);
+ PathAppendW(pszPath2, TEST_DIR);
+ ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed
(%ld)\n",
+ entry->line, pszPath1, pszPath2, GetLastError());
+ return TRUE;
}
-static void
-DoAction7(void)
+static BOOL DoAction8(const TEST_ENTRY *entry)
{
- DeleteFileW(s_file1);
- DeleteFileW(s_file2);
- ok_int(RemoveDirectoryW(s_dir3), TRUE);
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_DIR);
+ ok(RemoveDirectoryW(pszPath), "Line %d: RemoveDirectoryW(%ls) failed
(%ld)\n",
+ entry->line, pszPath, GetLastError());
+ return TRUE;
}
-static void
-DoAction8(void)
+static BOOL DoAction9(const TEST_ENTRY *entry)
+{
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_FILE);
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL);
+ return FALSE;
+}
+
+static BOOL DoAction10(const TEST_ENTRY *entry)
{
- BOOL ret = RemoveDirectoryW(s_dir1);
- ok(ret, "RemoveDirectoryW failed. GetLastError() == %ld\n",
GetLastError());
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_FILE);
+ SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL);
+ return FALSE;
}
-static const TEST_ENTRY s_TestEntriesMode0[] =
-{
- {__LINE__, SHCNE_MKDIR, s_dir2, NULL, NULL, DoAction1, NULL, NULL},
- {__LINE__, SHCNE_RMDIR, s_dir2, NULL, "00001000", NULL, s_dir2,
L""},
- {__LINE__, SHCNE_RMDIR, s_dir2, NULL, "00001000", DoAction2, s_dir2,
L""},
- {__LINE__, SHCNE_MKDIR, s_dir2, NULL, "00010000", DoAction1, s_dir2,
L""},
- {__LINE__, SHCNE_RENAMEFOLDER, s_dir2, s_dir3, "00000001", NULL, s_dir2,
s_dir3},
- {__LINE__, SHCNE_RENAMEFOLDER, s_dir2, s_dir3, "00000001", DoAction3,
s_dir2, s_dir3},
- {__LINE__, SHCNE_CREATE, s_file1, NULL, "01000000", NULL, s_file1,
L""},
- {__LINE__, SHCNE_CREATE, s_file1, s_file2, "01000000", NULL, s_file1,
s_file2},
- {__LINE__, SHCNE_CREATE, s_file1, NULL, "01000000", DoAction4, s_file1,
L""},
- {__LINE__, SHCNE_RENAMEITEM, s_file1, s_file2, "10000000", NULL, s_file1,
s_file2},
- {__LINE__, SHCNE_RENAMEITEM, s_file1, s_file2, "10000000", DoAction5,
s_file1, s_file2},
- {__LINE__, SHCNE_RENAMEITEM, s_file1, s_file2, "10000000", NULL, s_file1,
s_file2},
- {__LINE__, SHCNE_UPDATEITEM, s_file1, NULL, "00000010", NULL, s_file1,
L""},
- {__LINE__, SHCNE_UPDATEITEM, s_file2, NULL, "00000010", NULL, s_file2,
L""},
- {__LINE__, SHCNE_DELETE, s_file1, NULL, "00100000", NULL, s_file1,
L""},
- {__LINE__, SHCNE_DELETE, s_file2, NULL, "00100000", NULL, s_file2,
L""},
- {__LINE__, SHCNE_DELETE, s_file2, NULL, "00100000", DoAction6, s_file2,
L""},
- {__LINE__, SHCNE_DELETE, s_file2, NULL, "00100000", NULL, s_file2,
L""},
- {__LINE__, SHCNE_DELETE, s_file1, NULL, "00100000", NULL, s_file1,
L""},
- {__LINE__, SHCNE_RMDIR, s_dir2, NULL, "00001000", NULL, s_dir2,
L""},
- {__LINE__, SHCNE_RMDIR, s_dir3, NULL, "00001000", DoAction7, s_dir3,
L""},
- {__LINE__, SHCNE_RMDIR, s_dir1, NULL, "00001000", NULL, s_dir1,
L""},
- {__LINE__, SHCNE_RMDIR, s_dir1, NULL, "00001000", DoAction8, s_dir1,
L""},
+static BOOL DoAction11(const TEST_ENTRY *entry)
+{
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_DIR);
+ SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL);
+ return FALSE;
+}
+
+static BOOL DoAction12(const TEST_ENTRY *entry)
+{
+ LPWSTR pszPath = DoGetDir(entry->iWriteDir);
+ PathAppendW(pszPath, TEST_DIR);
+ SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL);
+ return FALSE;
+}
+
+#define WRITEDIR_0 DIRTYPE_DESKTOP
+static WCHAR s_szDesktop[MAX_PATH];
+static WCHAR s_szTestFile0[MAX_PATH];
+static WCHAR s_szTestFile0Kai[MAX_PATH];
+static WCHAR s_szTestDir0[MAX_PATH];
+static WCHAR s_szTestDir0Kai[MAX_PATH];
+
+#define WRITEDIR_1 DIRTYPE_MYDOCUMENTS
+static WCHAR s_szDocuments[MAX_PATH];
+static WCHAR s_szTestFile1[MAX_PATH];
+static WCHAR s_szTestFile1Kai[MAX_PATH];
+static WCHAR s_szTestDir1[MAX_PATH];
+static WCHAR s_szTestDir1Kai[MAX_PATH];
+
+static void DoDeleteFilesAndDirs(void)
+{
+ DeleteFileW(TEMP_FILE);
+ DeleteFileW(s_szTestFile0);
+ DeleteFileW(s_szTestFile0Kai);
+ DeleteFileW(s_szTestFile1);
+ DeleteFileW(s_szTestFile1Kai);
+ RemoveDirectoryW(s_szTestDir0);
+ RemoveDirectoryW(s_szTestDir0Kai);
+ RemoveDirectoryW(s_szTestDir1);
+ RemoveDirectoryW(s_szTestDir1Kai);
+}
+
+static const TEST_ENTRY s_group_00[] =
+{
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12
},
};
-#define s_TestEntriesMode1 s_TestEntriesMode0
-#define s_TestEntriesMode2 s_TestEntriesMode0
-
-static const TEST_ENTRY s_TestEntriesMode3[] =
-{
- {__LINE__, DONT_SEND, s_dir2, NULL, NULL, DoAction1, NULL, NULL},
- {__LINE__, DONT_SEND, s_dir2, NULL, "00001000", DoAction2, s_dir2,
L""},
- {__LINE__, DONT_SEND, s_dir2, NULL, "00010000", DoAction1, s_dir2,
L""},
- {__LINE__, DONT_SEND, s_dir2, s_dir3, "00000001", DoAction3, s_dir2,
s_dir3},
- {__LINE__, DONT_SEND, s_file1, NULL, "01000000", DoAction4, s_file1,
L""},
- {__LINE__, DONT_SEND, s_file1, s_file2, "10000000", DoAction5, s_file1,
s_file2},
- {__LINE__, DONT_SEND, s_file2, NULL, "00100000", DoAction6, s_file2,
L""},
- {__LINE__, DONT_SEND, s_dir3, NULL, "00001000", DoAction7, s_dir3,
L""},
- {__LINE__, SHCNE_MKDIR, s_dir2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_MKDIR, s_dir2, NULL, "00000000", NULL,
NULL, NULL},
+static const TEST_ENTRY s_group_01[] =
+{
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12
},
};
-static const TEST_ENTRY s_TestEntriesMode4[] =
-{
- {__LINE__, DONT_SEND, s_dir2, NULL, NULL, DoAction1, NULL, NULL},
- {__LINE__, DONT_SEND, s_dir2, NULL, "00001000", DoAction2, s_dir2,
L""},
- {__LINE__, DONT_SEND, s_dir2, NULL, "00010000", DoAction1, s_dir2,
L""},
- {__LINE__, DONT_SEND, s_dir2, s_dir3, "00000001", DoAction3, s_dir2,
s_dir3},
- {__LINE__, DONT_SEND, s_file1, NULL, "01000000", DoAction4, s_file1,
L""},
- {__LINE__, DONT_SEND, s_file1, s_file2, "10000000", DoAction5, s_file1,
s_file2},
- {__LINE__, DONT_SEND, s_file2, NULL, "00100000", DoAction6, s_file2,
L""},
- {__LINE__, DONT_SEND, s_dir3, NULL, "00001000", DoAction7, s_dir3,
L""},
- {__LINE__, SHCNE_MKDIR, s_dir2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_MKDIR, s_dir2, NULL, "00000000", NULL,
NULL, NULL},
+static const TEST_ENTRY s_group_02[] =
+{
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12
},
};
-static const TEST_ENTRY s_TestEntriesMode5[] =
-{
- {__LINE__, SHCNE_MKDIR, s_dir2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_RMDIR, s_dir2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_MKDIR, s_dir2, NULL, "00000000", DoAction1, NULL, NULL},
- {__LINE__, SHCNE_RMDIR, s_dir2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_RMDIR, s_dir2, NULL, "00000000", DoAction2, NULL, NULL},
- {__LINE__, SHCNE_MKDIR, s_dir2, NULL, "00000000", DoAction1, NULL, NULL},
- {__LINE__, SHCNE_RENAMEFOLDER, s_dir2, s_dir3, "00000000", NULL, NULL,
NULL},
- {__LINE__, SHCNE_RENAMEFOLDER, s_dir2, s_dir3, "00000000", DoAction3, NULL,
NULL},
- {__LINE__, SHCNE_CREATE, s_file1, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_CREATE, s_file1, s_file2, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_CREATE, s_file1, NULL, "00000000", DoAction4, NULL,
NULL},
- {__LINE__, SHCNE_RENAMEITEM, s_file1, s_file2, "00000000", NULL, NULL,
NULL},
- {__LINE__, SHCNE_RENAMEITEM, s_file1, s_file2, "00000000", DoAction5, NULL,
NULL},
- {__LINE__, SHCNE_RENAMEITEM, s_file1, s_file2, "00000000", NULL, NULL,
NULL},
- {__LINE__, SHCNE_UPDATEITEM, s_file1, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_UPDATEITEM, s_file2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_UPDATEITEM, s_file1, s_file2, "00000000", NULL, NULL,
NULL},
- {__LINE__, SHCNE_UPDATEITEM, s_file2, s_file1, "00000000", NULL, NULL,
NULL},
- {__LINE__, SHCNE_DELETE, s_file1, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_DELETE, s_file2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_DELETE, s_file2, s_file1, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_DELETE, s_file1, s_file2, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_DELETE, s_file2, NULL, "00000000", DoAction6, NULL,
NULL},
- {__LINE__, SHCNE_DELETE, s_file2, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_DELETE, s_file1, NULL, "00000000", NULL, NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir1, NULL, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir2, NULL, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir3, NULL, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir1, s_dir2, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir1, s_dir3, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir2, s_dir1, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir2, s_dir3, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir3, NULL, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir3, NULL, "00000000",
DoAction7, NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir1, NULL, "00000000", NULL,
NULL, NULL},
- {__LINE__, SHCNE_INTERRUPT | SHCNE_RMDIR, s_dir1, NULL, "00000000",
DoAction8, NULL, NULL},
+static const TEST_ENTRY s_group_03[] =
+{
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12
},
};
-LPCSTR PatternFromFlags(DWORD flags)
+static const TEST_ENTRY s_group_04[] =
{
- static char s_buf[TYPE_RENAMEFOLDER + 1 + 1];
- DWORD i;
- for (i = 0; i <= TYPE_RENAMEFOLDER; ++i)
- {
+ { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0, s_szTestFile0Kai,
DoAction2 },
+ { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0Kai, s_szTestFile0,
DoAction3 },
+ { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0, s_szTestDir0Kai, DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0Kai, s_szTestDir0, DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12
},
+};
+
+static const TEST_ENTRY s_group_05[] =
+{
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1, s_szTestFile1Kai,
DoAction2 },
+ { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1Kai, s_szTestFile1,
DoAction3 },
+ { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1, s_szTestDir1Kai, DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1Kai, s_szTestDir1, DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12
},
+};
+
+static const TEST_ENTRY s_group_06[] =
+{
+ { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0, s_szTestFile0Kai,
DoAction2 },
+ { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0Kai, s_szTestFile0,
DoAction3 },
+ { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0, s_szTestDir0Kai, DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0Kai, s_szTestDir0, DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12
},
+};
+
+static const TEST_ENTRY s_group_07[] =
+{
+ { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0, s_szTestFile0Kai,
DoAction2 },
+ { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0Kai, s_szTestFile0,
DoAction3 },
+ { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0, s_szTestDir0Kai, DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0Kai, s_szTestDir0, DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12
},
+};
+
+static const TEST_ENTRY s_group_08[] =
+{
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11
},
+ { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12
},
+
+ { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction1
},
+ { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1, s_szTestFile1Kai,
DoAction2 },
+ { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1Kai, s_szTestFile1,
DoAction3 },
+ { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction4
},
+ { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction5
},
+ { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1, s_szTestDir1Kai, DoAction6
},
+ { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1Kai, s_szTestDir1, DoAction7
},
+ { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction8
},
+ { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9
},
+ { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10
},
+ { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11
},
+ { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12
},
+};
+
+static LPCSTR PatternFromFlags(DWORD flags)
+{
+ static CHAR s_buf[(TYPE_MAX + 1) + 1];
+ for (INT i = 0; i < (TYPE_MAX + 1); ++i)
s_buf[i] = (char)('0' + !!(flags & (1 << i)));
- }
- s_buf[i] = 0;
+
+ s_buf[TYPE_MAX + 1] = 0;
return s_buf;
}
-static BOOL
-DoGetPaths(LPWSTR pszPath1, LPWSTR pszPath2)
+static BOOL DoGetPaths(LPWSTR pszPath1, LPWSTR pszPath2)
{
pszPath1[0] = pszPath2[0] = 0;
WCHAR szText[MAX_PATH * 2];
szText[0] = 0;
- if (FILE *fp = fopen(TEMP_FILE, "rb"))
+ FILE *fp = _wfopen(TEMP_FILE, L"rb");
+ if (fp)
{
fread(szText, 1, sizeof(szText), fp);
fclose(fp);
@@ -219,56 +508,77 @@ DoGetPaths(LPWSTR pszPath1, LPWSTR pszPath2)
return FALSE;
*pch = 0;
- lstrcpynW(pszPath1, szText, MAX_PATH);
- lstrcpynW(pszPath2, pch + 1, MAX_PATH);
+ StringCchCopyW(pszPath1, MAX_PATH, szText);
+ StringCchCopyW(pszPath2, MAX_PATH, pch + 1);
return TRUE;
}
-static void
-DoTestEntry(const TEST_ENTRY *entry)
+static void DoTestEntry(INT iEntry, const TEST_ENTRY *entry, INT nSources)
{
+#ifdef ENTRY_TICK
+ DWORD dwOldTick = GetTickCount();
+#endif
+
+ BOOL bInterrupting = FALSE;
if (entry->action)
- {
- (*entry->action)();
- }
+ bInterrupting = entry->action(entry);
- if (entry->event != DONT_SEND)
+ DWORD flags;
+ LPCSTR pattern;
+ if ((nSources & SHCNRF_InterruptLevel) && bInterrupting)
{
- SHChangeNotify(entry->event, SHCNF_PATHW | SHCNF_FLUSH, entry->item1,
entry->item2);
+ // The event won't work at here. Manually waiting...
+ UINT cTry = ((iEntry == 0) ? 100 : 60);
+ for (UINT iTry = 0; iTry < cTry; ++iTry)
+ {
+ flags = SendMessageW(s_hwnd, WM_GET_NOTIFY_FLAGS, 0, 0);
+ pattern = PatternFromFlags(flags);
+ if (strcmp(pattern, "0000000") != 0)
+ break;
+
+ Sleep(1);
+ }
}
else
{
- SHChangeNotify(0, SHCNF_FLUSH, NULL, NULL);
- }
+ if (WaitForSingleObject(s_hEvent, 100) == WAIT_OBJECT_0)
+ Sleep(1);
- DWORD flags = SendMessageW(s_hwnd, WM_GET_NOTIFY_FLAGS, 0, 0);
- LPCSTR pattern = PatternFromFlags(flags);
-
- if (entry->pattern)
- {
- ok(lstrcmpA(pattern, entry->pattern) == 0 ||
- lstrcmpA(pattern, "00000100") == 0, // SHCNE_UPDATEDIR
- "Line %d: pattern mismatch '%s'\n", entry->line,
pattern);
+ flags = SendMessageW(s_hwnd, WM_GET_NOTIFY_FLAGS, 0, 0);
+ pattern = PatternFromFlags(flags);
}
SendMessageW(s_hwnd, WM_SET_PATHS, 0, 0);
- Sleep(50);
WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
szPath1[0] = szPath2[0] = 0;
BOOL bOK = DoGetPaths(szPath1, szPath2);
- if (lstrcmpA(pattern, "00000100") == 0) // SHCNE_UPDATEDIR
+ static UINT s_cCalmDown = 0;
+
+ if (pattern[TYPE_UPDATEDIR] == '1')
{
+ trace("Line %d: SHCNE_UPDATEDIR: Calm down (%u)...\n", entry->line,
s_cCalmDown);
+
+ if (++s_cCalmDown < 3)
+ Sleep(3000);
+
+ if (entry->pattern)
+ ok(TRUE, "Line %d:\n", entry->line);
if (entry->path1)
- ok(bOK && lstrcmpiW(s_dir1, szPath1) == 0,
- "Line %d: path1 mismatch '%S' (%d)\n", entry->line,
szPath1, bOK);
+ ok(TRUE, "Line %d:\n", entry->line);
if (entry->path2)
- ok(bOK && lstrcmpiW(L"", szPath2) == 0,
- "Line %d: path2 mismatch '%S' (%d)\n", entry->line,
szPath2, bOK);
+ ok(TRUE, "Line %d:\n", entry->line);
}
else
{
+ s_cCalmDown = 0;
+ if (entry->pattern)
+ {
+ ok(strcmp(pattern, entry->pattern) == 0,
+ "Line %d: pattern mismatch '%s', tick=0x%08lX\n",
+ entry->line, pattern, GetTickCount());
+ }
if (entry->path1)
ok(bOK && lstrcmpiW(entry->path1, szPath1) == 0,
"Line %d: path1 mismatch '%S' (%d)\n", entry->line,
szPath1, bOK);
@@ -278,43 +588,108 @@ DoTestEntry(const TEST_ENTRY *entry)
}
SendMessageW(s_hwnd, WM_CLEAR_FLAGS, 0, 0);
+ ResetEvent(s_hEvent);
+
+#ifdef ENTRY_TICK
+ DWORD dwNewTick = GetTickCount();
+ DWORD dwTick = dwNewTick - dwOldTick;
+ trace("DoTestEntry: Line %d: tick=%lu.%lu sec\n", entry->line,
+ (dwTick / 1000), (dwTick / 100 % 10));
+#endif
}
-static BOOL
-DoInit(void)
+static void DoQuitTest(BOOL bForce)
{
- DoInitPaths();
+ PostMessageW(s_hwnd, WM_COMMAND, IDOK, 0);
- CreateDirectoryW(s_dir1, NULL);
+ DoWaitForWindow(CLASSNAME, CLASSNAME, TRUE, bForce);
+ s_hwnd = NULL;
- // close Explorer before tests
- INT i, nCount = 50;
- for (i = 0; i < nCount; ++i)
+ if (s_hEvent)
{
- HWND hwnd = FindWindowW(L"CabinetWClass", NULL);
- if (hwnd == NULL)
- break;
+ CloseHandle(s_hEvent);
+ s_hEvent = NULL;
+ }
- PostMessage(hwnd, WM_CLOSE, 0, 0);
- Sleep(100);
+ DoDeleteFilesAndDirs();
+}
+
+static void DoAbortThread(void)
+{
+ skip("Aborting the thread...\n");
+ if (s_hThread)
+ {
+ TerminateThread(s_hThread, -1);
+ s_hThread = NULL;
}
- if (i == nCount)
- skip("Unable to close Explorer cabinet\n");
+}
- return PathIsDirectoryW(s_dir1);
+static BOOL CALLBACK HandlerRoutine(DWORD dwCtrlType)
+{
+ switch (dwCtrlType)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ DoAbortThread();
+ DoQuitTest(TRUE);
+ return TRUE;
+ }
+ return FALSE;
}
-static void
-DoEnd(HWND hwnd)
+static BOOL DoInitTest(void)
{
- DeleteFileW(s_file1);
- DeleteFileW(s_file2);
- RemoveDirectoryW(s_dir3);
- RemoveDirectoryW(s_dir2);
- RemoveDirectoryW(s_dir1);
- DeleteFileA(TEMP_FILE);
+ // DIRTYPE_DESKTOP
+ LPWSTR psz = DoGetDir(DIRTYPE_DESKTOP);
+ StringCchCopyW(s_szDesktop, _countof(s_szDesktop), psz);
+
+ PathAppendW(psz, TEST_FILE);
+ StringCchCopyW(s_szTestFile0, _countof(s_szTestFile0), psz);
+
+ PathRemoveFileSpecW(psz);
+ PathAppendW(psz, TEST_FILE_KAI);
+ StringCchCopyW(s_szTestFile0Kai, _countof(s_szTestFile0Kai), psz);
+
+ PathRemoveFileSpecW(psz);
+ PathAppendW(psz, TEST_DIR);
+ StringCchCopyW(s_szTestDir0, _countof(s_szTestDir0), psz);
+
+ PathRemoveFileSpecW(psz);
+ PathAppendW(psz, TEST_DIR_KAI);
+ StringCchCopyW(s_szTestDir0Kai, _countof(s_szTestDir0Kai), psz);
+
+ // DIRTYPE_MYDOCUMENTS
+ psz = DoGetDir(DIRTYPE_MYDOCUMENTS);
+ StringCchCopyW(s_szDocuments, _countof(s_szDocuments), psz);
+
+ PathAppendW(psz, TEST_FILE);
+ StringCchCopyW(s_szTestFile1, _countof(s_szTestFile1), psz);
+
+ PathRemoveFileSpecW(psz);
+ PathAppendW(psz, TEST_FILE_KAI);
+ StringCchCopyW(s_szTestFile1Kai, _countof(s_szTestFile1Kai), psz);
+
+ PathRemoveFileSpecW(psz);
+ PathAppendW(psz, TEST_DIR);
+ StringCchCopyW(s_szTestDir1, _countof(s_szTestDir1), psz);
+
+ PathRemoveFileSpecW(psz);
+ PathAppendW(psz, TEST_DIR_KAI);
+ StringCchCopyW(s_szTestDir1Kai, _countof(s_szTestDir1Kai), psz);
+
+ // prepare for files and dirs
+ DoDeleteFilesAndDirs();
+ DoCreateEmptyFile(TEMP_FILE);
- SendMessageW(s_hwnd, WM_COMMAND, IDOK, 0);
+ // Ctrl+C
+ SetConsoleCtrlHandler(HandlerRoutine, TRUE);
+
+ // close Explorer windows
+ trace("Closing Explorer windows...\n");
+ DoWaitForWindow(L"CabinetWClass", NULL, TRUE, TRUE);
+
+ // close the CLASSNAME windows
+ return DoWaitForWindow(CLASSNAME, CLASSNAME, TRUE, TRUE) == NULL;
}
static BOOL
@@ -330,28 +705,69 @@ GetSubProgramPath(void)
PathAppendW(s_szSubProgram, L"testdata\\shell32_apitest_sub.exe");
if (!PathFileExistsW(s_szSubProgram))
- {
return FALSE;
- }
}
return TRUE;
}
+#define SRC_00 0
+#define SRC_01 SHCNRF_ShellLevel
+#define SRC_02 (SHCNRF_NewDelivery)
+#define SRC_03 (SHCNRF_NewDelivery | SHCNRF_ShellLevel)
+#define SRC_04 SHCNRF_InterruptLevel
+#define SRC_05 (SHCNRF_InterruptLevel | SHCNRF_ShellLevel)
+#define SRC_06 (SHCNRF_InterruptLevel | SHCNRF_NewDelivery)
+#define SRC_07 (SHCNRF_InterruptLevel | SHCNRF_NewDelivery | SHCNRF_ShellLevel)
+#define SRC_08 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel)
+#define SRC_09 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel | SHCNRF_ShellLevel)
+#define SRC_10 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel | SHCNRF_NewDelivery)
+#define SRC_11 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel | SHCNRF_NewDelivery |
SHCNRF_ShellLevel)
+
+#define WATCHDIR_0 DIRTYPE_NULL
+#define WATCHDIR_1 DIRTYPE_DESKTOP
+#define WATCHDIR_2 DIRTYPE_MYCOMPUTER
+#define WATCHDIR_3 DIRTYPE_MYDOCUMENTS
+
static void
-JustDoIt(INT nMode)
+DoTestGroup(INT line, UINT cEntries, const TEST_ENTRY *pEntries, BOOL fRecursive,
+ INT nSources, DIRTYPE iWatchDir)
{
- trace("nMode: %d\n", nMode);
- SHChangeNotify(0, SHCNF_FLUSH, NULL, NULL);
+#ifdef NO_INTERRUPT_LEVEL
+ if (nSources & SHCNRF_InterruptLevel)
+ return;
+#endif
+#ifdef NO_SHELL_LEVEL
+ if (nSources & SHCNRF_ShellLevel)
+ return;
+#endif
+#ifdef NEW_DELIVERY_ONLY
+ if (!(nSources & SHCNRF_NewDelivery))
+ return;
+#endif
+#ifdef GROUP_TICK
+ DWORD dwOldTick = GetTickCount();
+#endif
+#ifdef RANDOM_QUARTER
+ if ((rand() & 3) == 0)
+ return;
+#elif defined(RANDOM_HALF)
+ if (rand() & 1)
+ return;
+#endif
- if (!DoInit())
+ trace("DoTestGroup: Line %d: fRecursive:%u, iWatchDir:%u,
nSources:0x%X\n",
+ line, fRecursive, iWatchDir, nSources);
+
+ if (s_hEvent)
{
- skip("Unable to initialize.\n");
- return;
+ CloseHandle(s_hEvent);
+ s_hEvent = NULL;
}
+ s_hEvent = CreateEventW(NULL, TRUE, FALSE, EVENT_NAME);
- WCHAR szParams[8];
- wsprintfW(szParams, L"%u", nMode);
+ WCHAR szParams[64];
+ StringCchPrintfW(szParams, _countof(szParams), L"%u,%u,%u", fRecursive,
iWatchDir, nSources);
HINSTANCE hinst = ShellExecuteW(NULL, NULL, s_szSubProgram, szParams, NULL,
SW_SHOWNORMAL);
if ((INT_PTR)hinst <= 32)
@@ -360,74 +776,189 @@ JustDoIt(INT nMode)
return;
}
- for (int i = 0; i < 15; ++i)
- {
- s_hwnd = FindWindowW(s_szName, s_szName);
- if (s_hwnd)
- break;
-
- Sleep(50);
- }
-
+ s_hwnd = DoWaitForWindow(CLASSNAME, CLASSNAME, FALSE, FALSE);
if (!s_hwnd)
{
skip("Unable to find window.\n");
return;
}
- switch (nMode)
+ for (UINT i = 0; i < cEntries; ++i)
{
- case 0:
- case 1:
- case 2:
- for (size_t i = 0; i < _countof(s_TestEntriesMode0); ++i)
- {
- DoTestEntry(&s_TestEntriesMode0[i]);
- }
- break;
- case 3:
- for (size_t i = 0; i < _countof(s_TestEntriesMode3); ++i)
- {
- DoTestEntry(&s_TestEntriesMode3[i]);
- }
- break;
- case 4:
- for (size_t i = 0; i < _countof(s_TestEntriesMode4); ++i)
- {
- DoTestEntry(&s_TestEntriesMode4[i]);
- }
- break;
- case 5:
- for (size_t i = 0; i < _countof(s_TestEntriesMode5); ++i)
- {
- DoTestEntry(&s_TestEntriesMode5[i]);
- }
+ if (!IsWindow(s_hwnd))
+ {
+ DoAbortThread();
+ DoQuitTest(TRUE);
break;
+ }
+
+ DoTestEntry(i, &pEntries[i], nSources);
}
- DoEnd(s_hwnd);
+ DoQuitTest(FALSE);
- for (int i = 0; i < 15; ++i)
- {
- s_hwnd = FindWindowW(s_szName, s_szName);
- if (!s_hwnd)
- break;
+#ifdef GROUP_TICK
+ DWORD dwNewTick = GetTickCount();
+ DWORD dwTick = dwNewTick - dwOldTick;
+ trace("DoTestGroup: Line %d: %lu.%lu sec\n", line, (dwTick / 1000), (dwTick
/ 100 % 10));
+#endif
+}
- Sleep(50);
- }
+static unsigned __stdcall TestThreadProc(void *)
+{
+ srand(time(NULL));
+#ifdef RANDOM_QUARTER
+ skip("RANDOM_QUARTER\n");
+#elif defined(RANDOM_HALF)
+ skip("RANDOM_HALF\n");
+#endif
+
+ // fRecursive == FALSE.
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, FALSE, SRC_01, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, FALSE, SRC_03, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_04, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_05, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_06, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_07, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_08, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_09, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_10, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_11, WATCHDIR_0);
+
+ BOOL bTarget = IsWindowsXPOrGreater() && !IsWindowsVistaOrGreater();
+
+#define SWITCH(x, y) (bTarget ? (x) : (y))
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_03), s_group_03, FALSE, SRC_01, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_03), s_group_03, FALSE, SRC_03, WATCHDIR_1);
+ DoTestGroup(__LINE__, SWITCH(_countof(s_group_00), _countof(s_group_04)),
SWITCH(s_group_00, s_group_04), FALSE, SRC_04, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_05, WATCHDIR_1);
+ DoTestGroup(__LINE__, SWITCH(_countof(s_group_00), _countof(s_group_04)),
SWITCH(s_group_00, s_group_04), FALSE, SRC_06, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_07, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_08, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_09, WATCHDIR_1);
+ DoTestGroup(__LINE__, SWITCH(_countof(s_group_00), _countof(s_group_04)),
SWITCH(s_group_00, s_group_04), FALSE, SRC_06, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_11, WATCHDIR_1);
+#undef SWITCH
+
+#ifndef NO_TRIVIAL
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_01, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_03, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_04, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_05, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_06, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_07, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_08, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_09, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_10, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_11, WATCHDIR_2);
+#endif
+
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, FALSE, SRC_01, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, FALSE, SRC_03, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_04, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_05, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_06, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_07, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_08, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_09, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_10, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_11, WATCHDIR_3);
+
+ // fRecursive == TRUE.
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_01, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_03, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_04, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_05, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_06, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_07, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_08, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_09, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_10, WATCHDIR_0);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_11, WATCHDIR_0);
+
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_01, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_03, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_04, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_05, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_06, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_07, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_08, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_09, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_10, WATCHDIR_1);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_11, WATCHDIR_1);
+
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_01, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_03, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_04, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_05, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_06, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_07, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_08, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_09, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_10, WATCHDIR_2);
+ DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_11, WATCHDIR_2);
+
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, TRUE, SRC_01, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, TRUE, SRC_03, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_04, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_05, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_06, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_07, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_08, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_09, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_10, WATCHDIR_3);
+ DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_11, WATCHDIR_3);
+
+ return 0;
}
START_TEST(SHChangeNotify)
{
+#ifdef DISABLE_THIS_TESTCASE
+ skip("This testcase is disabled by DISABLE_THIS_TESTCASE macro.\n");
+#endif
+#ifdef TOTAL_TICK
+ DWORD dwOldTick = GetTickCount();
+#endif
+
+ trace("Please don't operate your PC while testing...\n");
+
if (!GetSubProgramPath())
{
skip("shell32_apitest_sub.exe not found\n");
+ return;
}
- JustDoIt(0);
- JustDoIt(1);
- JustDoIt(2);
- JustDoIt(3);
- JustDoIt(4);
- JustDoIt(5);
+ if (!DoInitTest())
+ {
+ skip("Unable to initialize.\n");
+ DoQuitTest(TRUE);
+ return;
+ }
+
+ s_hThread = (HANDLE)_beginthreadex(NULL, 0, TestThreadProc, NULL, 0, NULL);
+ WaitForSingleObject(s_hThread, INFINITE);
+ CloseHandle(s_hThread);
+
+#ifdef TOTAL_TICK
+ DWORD dwNewTick = GetTickCount();
+ DWORD dwTick = dwNewTick - dwOldTick;
+ trace("SHChangeNotify: Total %lu.%lu sec\n", (dwTick / 1000), (dwTick / 100
% 10));
+#endif
}
diff --git a/modules/rostests/apitests/shell32/SHChangeNotify.h
b/modules/rostests/apitests/shell32/SHChangeNotify.h
index 71389513eb2..e20b6b7a74c 100644
--- a/modules/rostests/apitests/shell32/SHChangeNotify.h
+++ b/modules/rostests/apitests/shell32/SHChangeNotify.h
@@ -1,6 +1,18 @@
#pragma once
-#define TEMP_FILE "shell-notify-temporary.txt"
+#include <shlwapi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <strsafe.h>
+
+#define TEMP_FILE L"shell-notify-temporary.txt"
+#define CLASSNAME L"SHChangeNotify testcase window"
+#define EVENT_NAME L"SHChangeNotify testcase event"
+
+#define WM_SHELL_NOTIFY (WM_USER + 100)
+#define WM_GET_NOTIFY_FLAGS (WM_USER + 101)
+#define WM_CLEAR_FLAGS (WM_USER + 102)
+#define WM_SET_PATHS (WM_USER + 103)
typedef enum TYPE
{
@@ -9,40 +21,53 @@ typedef enum TYPE
TYPE_DELETE,
TYPE_MKDIR,
TYPE_RMDIR,
+ TYPE_RENAMEFOLDER,
TYPE_UPDATEDIR,
- TYPE_UPDATEITEM,
- TYPE_RENAMEFOLDER
+ TYPE_MAX = TYPE_UPDATEDIR
} TYPE;
-#define WM_SHELL_NOTIFY (WM_USER + 100)
-#define WM_GET_NOTIFY_FLAGS (WM_USER + 101)
-#define WM_CLEAR_FLAGS (WM_USER + 102)
-#define WM_SET_PATHS (WM_USER + 103)
-
-static WCHAR s_dir1[MAX_PATH]; // "%TEMP%\\WatchDir1"
-static WCHAR s_dir2[MAX_PATH]; // "%TEMP%\\WatchDir1\\Dir2"
-static WCHAR s_dir3[MAX_PATH]; // "%TEMP%\\WatchDir1\\Dir3"
-static WCHAR s_file1[MAX_PATH]; // "%TEMP%\\WatchDir1\\File1.txt"
-static WCHAR s_file2[MAX_PATH]; // "%TEMP%\\WatchDir1\\File2.txt"
+typedef enum DIRTYPE
+{
+ DIRTYPE_NULL = 0,
+ DIRTYPE_DESKTOP,
+ DIRTYPE_MYCOMPUTER,
+ DIRTYPE_MYDOCUMENTS
+} DIRTYPE;
-inline void DoInitPaths(void)
+inline LPITEMIDLIST DoGetPidl(DIRTYPE iDir)
{
- WCHAR szTemp[MAX_PATH], szPath[MAX_PATH];
- GetTempPathW(_countof(szTemp), szTemp);
- GetLongPathNameW(szTemp, szPath, _countof(szPath));
+ LPITEMIDLIST ret = NULL;
+
+ switch (iDir)
+ {
+ case DIRTYPE_NULL:
+ break;
- lstrcpyW(s_dir1, szPath);
- PathAppendW(s_dir1, L"WatchDir1");
+ case DIRTYPE_DESKTOP:
+ SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &ret);
+ break;
- lstrcpyW(s_dir2, s_dir1);
- PathAppendW(s_dir2, L"Dir2");
+ case DIRTYPE_MYCOMPUTER:
+ SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &ret);
+ break;
- lstrcpyW(s_dir3, s_dir1);
- PathAppendW(s_dir3, L"Dir3");
+ case DIRTYPE_MYDOCUMENTS:
+ SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &ret);
+ break;
+ }
- lstrcpyW(s_file1, s_dir1);
- PathAppendW(s_file1, L"File1.txt");
+ return ret;
+}
- lstrcpyW(s_file2, s_dir1);
- PathAppendW(s_file2, L"File2.txt");
+inline LPWSTR DoGetDir(DIRTYPE iDir)
+{
+ static size_t s_index = 0;
+ static WCHAR s_pathes[3][MAX_PATH];
+ LPWSTR psz = s_pathes[s_index];
+ LPITEMIDLIST pidl = DoGetPidl(iDir);
+ psz[0] = 0;
+ SHGetPathFromIDListW(pidl, psz);
+ CoTaskMemFree(pidl);
+ s_index = (s_index + 1) % _countof(s_pathes);
+ return psz;
}
diff --git a/modules/rostests/apitests/shell32/shell32_apitest_sub.cpp
b/modules/rostests/apitests/shell32/shell32_apitest_sub.cpp
index 127ecaf687f..1b90c7ae39a 100644
--- a/modules/rostests/apitests/shell32/shell32_apitest_sub.cpp
+++ b/modules/rostests/apitests/shell32/shell32_apitest_sub.cpp
@@ -6,72 +6,28 @@
*/
#include "shelltest.h"
-#include <shlwapi.h>
-#include <stdio.h>
#include "SHChangeNotify.h"
static HWND s_hwnd = NULL;
-static const WCHAR s_szName[] = L"SHChangeNotify testcase";
-static INT s_nMode;
-
-static BYTE s_counters[TYPE_RENAMEFOLDER + 1];
static UINT s_uRegID = 0;
-
-static WCHAR s_path1[MAX_PATH], s_path2[MAX_PATH];
-
+static BOOL s_fRecursive = FALSE;
+static DIRTYPE s_iWatchDir = DIRTYPE_NULL;
+static INT s_nSources = 0;
static LPITEMIDLIST s_pidl = NULL;
-static SHChangeNotifyEntry s_entry;
+static WCHAR s_path1[MAX_PATH], s_path2[MAX_PATH];
+static BYTE s_counters[TYPE_MAX + 1];
+static HANDLE s_hEvent = NULL;
static BOOL
OnCreate(HWND hwnd)
{
s_hwnd = hwnd;
+ s_pidl = DoGetPidl(s_iWatchDir);
- DoInitPaths();
-
- s_pidl = ILCreateFromPathW(s_dir1);
- s_entry.pidl = s_pidl;
-
- INT nSources;
- switch (s_nMode)
- {
- case 0:
- s_entry.fRecursive = TRUE;
- nSources = SHCNRF_ShellLevel;
- break;
-
- case 1:
- s_entry.fRecursive = TRUE;
- nSources = SHCNRF_ShellLevel | SHCNRF_InterruptLevel;
- break;
-
- case 2:
- s_entry.fRecursive = FALSE;
- nSources = SHCNRF_ShellLevel | SHCNRF_NewDelivery;
- break;
-
- case 3:
- s_entry.fRecursive = TRUE;
- nSources = SHCNRF_InterruptLevel | SHCNRF_RecursiveInterrupt |
SHCNRF_NewDelivery;
- break;
-
- case 4:
- s_entry.fRecursive = FALSE;
- nSources = SHCNRF_InterruptLevel | SHCNRF_NewDelivery;
- break;
-
- case 5:
- s_entry.fRecursive = TRUE;
- nSources = SHCNRF_InterruptLevel | SHCNRF_RecursiveInterrupt |
SHCNRF_NewDelivery;
- s_entry.pidl = NULL;
- break;
-
- default:
- return FALSE;
- }
- LONG fEvents = SHCNE_ALLEVENTS;
- s_uRegID = SHChangeNotifyRegister(hwnd, nSources, fEvents, WM_SHELL_NOTIFY,
- 1, &s_entry);
+ SHChangeNotifyEntry entry;
+ entry.pidl = s_pidl;
+ entry.fRecursive = s_fRecursive;
+ s_uRegID = SHChangeNotifyRegister(hwnd, s_nSources, SHCNE_ALLEVENTS, WM_SHELL_NOTIFY,
1, &entry);
return s_uRegID != 0;
}
@@ -100,35 +56,54 @@ OnDestroy(HWND hwnd)
s_hwnd = NULL;
}
-static void
-DoShellNotify(HWND hwnd, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2, LONG lEvent)
+static BOOL DoPathes(PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
{
- if (pidl1)
- SHGetPathFromIDListW(pidl1, s_path1);
- else
- s_path1[0] = 0;
+ WCHAR path[MAX_PATH];
+ if (!SHGetPathFromIDListW(pidl1, path))
+ {
+ s_path1[0] = s_path2[0] = 0;
+ return FALSE;
+ }
- if (pidl2)
- SHGetPathFromIDListW(pidl2, s_path2);
- else
+ if (wcsstr(path, L"Recent") != NULL)
+ return FALSE;
+
+ StringCchCopyW(s_path1, _countof(s_path1), path);
+
+ if (!SHGetPathFromIDListW(pidl2, s_path2))
s_path2[0] = 0;
+ return TRUE;
+}
+
+static VOID DoPathesAndFlags(UINT type, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
+{
+ if (DoPathes(pidl1, pidl2))
+ {
+ s_counters[type] = 1;
+ SetEvent(s_hEvent);
+ }
+}
+
+static void
+DoShellNotify(HWND hwnd, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2, LONG lEvent)
+{
switch (lEvent)
{
case SHCNE_RENAMEITEM:
- s_counters[TYPE_RENAMEITEM] = 1;
+ DoPathesAndFlags(TYPE_RENAMEITEM, pidl1, pidl2);
break;
case SHCNE_CREATE:
- s_counters[TYPE_CREATE] = 1;
+ DoPathesAndFlags(TYPE_CREATE, pidl1, pidl2);
break;
case SHCNE_DELETE:
- s_counters[TYPE_DELETE] = 1;
+ DoPathesAndFlags(TYPE_DELETE, pidl1, pidl2);
break;
case SHCNE_MKDIR:
- s_counters[TYPE_MKDIR] = 1;
+ DoPathesAndFlags(TYPE_MKDIR, pidl1, pidl2);
break;
case SHCNE_RMDIR:
- s_counters[TYPE_RMDIR] = 1;
+ DoPathesAndFlags(TYPE_RMDIR, pidl1, pidl2);
break;
case SHCNE_MEDIAINSERTED:
break;
@@ -145,10 +120,9 @@ DoShellNotify(HWND hwnd, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE
pidl2, LONG lE
case SHCNE_ATTRIBUTES:
break;
case SHCNE_UPDATEDIR:
- s_counters[TYPE_UPDATEDIR] = 1;
+ DoPathesAndFlags(TYPE_UPDATEDIR, pidl1, pidl2);
break;
case SHCNE_UPDATEITEM:
- s_counters[TYPE_UPDATEITEM] = 1;
break;
case SHCNE_SERVERDISCONNECT:
break;
@@ -157,7 +131,7 @@ DoShellNotify(HWND hwnd, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE
pidl2, LONG lE
case SHCNE_DRIVEADDGUI:
break;
case SHCNE_RENAMEFOLDER:
- s_counters[TYPE_RENAMEFOLDER] = 1;
+ DoPathesAndFlags(TYPE_RENAMEFOLDER, pidl1, pidl2);
break;
case SHCNE_FREESPACE:
break;
@@ -208,13 +182,14 @@ static void
DoSetPaths(HWND hwnd)
{
WCHAR szText[MAX_PATH * 2];
- lstrcpyW(szText, s_path1);
- lstrcatW(szText, L"|");
- lstrcatW(szText, s_path2);
+ StringCchCopyW(szText, _countof(szText), s_path1);
+ StringCchCatW(szText, _countof(szText), L"|");
+ StringCchCatW(szText, _countof(szText), s_path2);
- if (FILE *fp = fopen(TEMP_FILE, "wb"))
+ FILE *fp = _wfopen(TEMP_FILE, L"wb");
+ if (fp)
{
- fwrite(szText, (lstrlenW(szText) + 1) * sizeof(WCHAR), 1, fp);
+ fwrite(szText, (wcslen(szText) + 1) * sizeof(WCHAR), 1, fp);
fflush(fp);
fclose(fp);
}
@@ -244,6 +219,7 @@ WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_CLEAR_FLAGS:
ZeroMemory(&s_counters, sizeof(s_counters));
+ s_path1[0] = s_path2[0] = 0;
break;
case WM_SET_PATHS:
@@ -256,6 +232,25 @@ WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0;
}
+static BOOL ParseCommandLine(LPWSTR lpCmdLine)
+{
+ LPWSTR pch = lpCmdLine; // fRecursive,iWatchDir,nSources
+ s_fRecursive = !!wcstoul(pch, NULL, 0);
+ pch = wcschr(pch, L',');
+ if (!pch)
+ return FALSE;
+ ++pch;
+
+ s_iWatchDir = (DIRTYPE)wcstoul(pch, NULL, 0);
+ pch = wcschr(pch, L',');
+ if (!pch)
+ return FALSE;
+ ++pch;
+
+ s_nSources = wcstoul(pch, NULL, 0);
+ return TRUE;
+}
+
INT APIENTRY
wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
@@ -265,7 +260,10 @@ wWinMain(HINSTANCE hInstance,
if (lstrcmpiW(lpCmdLine, L"") == 0 || lstrcmpiW(lpCmdLine,
L"TEST") == 0)
return 0;
- s_nMode = _wtoi(lpCmdLine);
+ if (!ParseCommandLine(lpCmdLine))
+ return -1;
+
+ s_hEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, EVENT_NAME);
WNDCLASSW wc;
ZeroMemory(&wc, sizeof(wc));
@@ -274,12 +272,12 @@ wWinMain(HINSTANCE hInstance,
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
- wc.lpszClassName = s_szName;
+ wc.lpszClassName = CLASSNAME;
if (!RegisterClassW(&wc))
return -1;
- HWND hwnd = CreateWindowW(s_szName, s_szName, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
+ HWND hwnd = CreateWindowW(CLASSNAME, CLASSNAME, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, 400, 100,
NULL, NULL, GetModuleHandleW(NULL), NULL);
if (!hwnd)
return -1;
@@ -294,5 +292,7 @@ wWinMain(HINSTANCE hInstance,
DispatchMessageW(&msg);
}
+ CloseHandle(s_hEvent);
+
return 0;
}