1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) 4 * PURPOSE: Test for SHChangeNotify 5 * COPYRIGHT: Copyright 2020-2021 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 6 */ 7 8 // NOTE: This test program closes the Explorer windows before tests. 9 10 #include "shelltest.h" 11 #include "shell32_apitest_sub.h" 12 #include <time.h> 13 #include <process.h> 14 #include <versionhelpers.h> 15 16 // --- The selection of tests --- 17 #define DISABLE_THIS_TESTCASE 18 #define NO_TRIVIAL 19 //#define NO_INTERRUPT_LEVEL 20 //#define NO_SHELL_LEVEL 21 #define NEW_DELIVERY_ONLY 22 //#define RANDOM_HALF 23 #define RANDOM_QUARTER 24 25 // --- Show the elapsed time by GetTickCount() --- 26 //#define ENTRY_TICK 27 #define GROUP_TICK 28 #define TOTAL_TICK 29 30 static HWND s_hwnd = NULL; 31 static WCHAR s_szSubProgram[MAX_PATH]; 32 static HANDLE s_hThread = NULL; 33 static HANDLE s_hEvent = NULL; 34 35 static BOOL DoCreateEmptyFile(LPCWSTR pszFileName) 36 { 37 FILE *fp = _wfopen(pszFileName, L"wb"); 38 if (fp) 39 fclose(fp); 40 return fp != NULL; 41 } 42 43 struct TEST_ENTRY; 44 45 typedef BOOL (*ACTION)(const struct TEST_ENTRY *entry); 46 47 typedef struct TEST_ENTRY 48 { 49 INT line; 50 DIRTYPE iWriteDir; 51 LPCSTR pattern; 52 LPCWSTR path1; 53 LPCWSTR path2; 54 ACTION action; 55 } TEST_ENTRY; 56 57 #define TEST_FILE L"_TEST_.txt" 58 #define TEST_FILE_KAI L"_TEST_KAI_.txt" 59 #define TEST_DIR L"_TESTDIR_" 60 #define TEST_DIR_KAI L"_TESTDIR_KAI_" 61 #define MOVE_FILE(from, to) MoveFileW((from), (to)) 62 63 static BOOL DoAction1(const TEST_ENTRY *entry) 64 { 65 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 66 PathAppendW(pszPath, TEST_FILE); 67 ok(DoCreateEmptyFile(pszPath), "Line %d: DoCreateEmptyFile failed\n", entry->line); 68 return TRUE; 69 } 70 71 static BOOL DoAction2(const TEST_ENTRY *entry) 72 { 73 LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 = DoGetDir(entry->iWriteDir); 74 PathAppendW(pszPath1, TEST_FILE); 75 PathAppendW(pszPath2, TEST_FILE_KAI); 76 ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed (%ld)\n", 77 entry->line, pszPath1, pszPath2, GetLastError()); 78 return TRUE; 79 } 80 81 static BOOL DoAction3(const TEST_ENTRY *entry) 82 { 83 LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 = DoGetDir(entry->iWriteDir); 84 PathAppendW(pszPath1, TEST_FILE_KAI); 85 PathAppendW(pszPath2, TEST_FILE); 86 ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed (%ld)\n", 87 entry->line, pszPath1, pszPath2, GetLastError()); 88 return TRUE; 89 } 90 91 static BOOL DoAction4(const TEST_ENTRY *entry) 92 { 93 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 94 PathAppendW(pszPath, TEST_FILE); 95 ok(DeleteFileW(pszPath), "Line %d: DeleteFileW(%ls) failed (%ld)\n", 96 entry->line, pszPath, GetLastError()); 97 return TRUE; 98 } 99 100 static BOOL DoAction5(const TEST_ENTRY *entry) 101 { 102 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 103 PathAppendW(pszPath, TEST_DIR); 104 ok(CreateDirectoryW(pszPath, NULL), "Line %d: CreateDirectoryW(%ls) failed (%ld)\n", 105 entry->line, pszPath, GetLastError()); 106 return TRUE; 107 } 108 109 static BOOL DoAction6(const TEST_ENTRY *entry) 110 { 111 LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 = DoGetDir(entry->iWriteDir); 112 PathAppendW(pszPath1, TEST_DIR); 113 PathAppendW(pszPath2, TEST_DIR_KAI); 114 ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed (%ld)\n", 115 entry->line, pszPath1, pszPath2, GetLastError()); 116 return TRUE; 117 } 118 119 static BOOL DoAction7(const TEST_ENTRY *entry) 120 { 121 LPWSTR pszPath1 = DoGetDir(entry->iWriteDir), pszPath2 = DoGetDir(entry->iWriteDir); 122 PathAppendW(pszPath1, TEST_DIR_KAI); 123 PathAppendW(pszPath2, TEST_DIR); 124 ok(MOVE_FILE(pszPath1, pszPath2), "Line %d: MOVE_FILE(%ls, %ls) failed (%ld)\n", 125 entry->line, pszPath1, pszPath2, GetLastError()); 126 return TRUE; 127 } 128 129 static BOOL DoAction8(const TEST_ENTRY *entry) 130 { 131 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 132 PathAppendW(pszPath, TEST_DIR); 133 ok(RemoveDirectoryW(pszPath), "Line %d: RemoveDirectoryW(%ls) failed (%ld)\n", 134 entry->line, pszPath, GetLastError()); 135 return TRUE; 136 } 137 138 static BOOL DoAction9(const TEST_ENTRY *entry) 139 { 140 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 141 PathAppendW(pszPath, TEST_FILE); 142 SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL); 143 return FALSE; 144 } 145 146 static BOOL DoAction10(const TEST_ENTRY *entry) 147 { 148 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 149 PathAppendW(pszPath, TEST_FILE); 150 SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL); 151 return FALSE; 152 } 153 154 static BOOL DoAction11(const TEST_ENTRY *entry) 155 { 156 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 157 PathAppendW(pszPath, TEST_DIR); 158 SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL); 159 return FALSE; 160 } 161 162 static BOOL DoAction12(const TEST_ENTRY *entry) 163 { 164 LPWSTR pszPath = DoGetDir(entry->iWriteDir); 165 PathAppendW(pszPath, TEST_DIR); 166 SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHW | SHCNF_FLUSH, pszPath, NULL); 167 return FALSE; 168 } 169 170 #define WRITEDIR_0 DIRTYPE_DESKTOP 171 static WCHAR s_szDesktop[MAX_PATH]; 172 static WCHAR s_szTestFile0[MAX_PATH]; 173 static WCHAR s_szTestFile0Kai[MAX_PATH]; 174 static WCHAR s_szTestDir0[MAX_PATH]; 175 static WCHAR s_szTestDir0Kai[MAX_PATH]; 176 177 #define WRITEDIR_1 DIRTYPE_MYDOCUMENTS 178 static WCHAR s_szDocuments[MAX_PATH]; 179 static WCHAR s_szTestFile1[MAX_PATH]; 180 static WCHAR s_szTestFile1Kai[MAX_PATH]; 181 static WCHAR s_szTestDir1[MAX_PATH]; 182 static WCHAR s_szTestDir1Kai[MAX_PATH]; 183 184 static void DoDeleteFilesAndDirs(void) 185 { 186 DeleteFileW(TEMP_FILE); 187 DeleteFileW(s_szTestFile0); 188 DeleteFileW(s_szTestFile0Kai); 189 DeleteFileW(s_szTestFile1); 190 DeleteFileW(s_szTestFile1Kai); 191 RemoveDirectoryW(s_szTestDir0); 192 RemoveDirectoryW(s_szTestDir0Kai); 193 RemoveDirectoryW(s_szTestDir1); 194 RemoveDirectoryW(s_szTestDir1Kai); 195 } 196 197 static const TEST_ENTRY s_group_00[] = 198 { 199 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1 }, 200 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2 }, 201 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3 }, 202 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4 }, 203 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5 }, 204 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6 }, 205 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7 }, 206 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8 }, 207 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9 }, 208 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10 }, 209 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11 }, 210 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12 }, 211 212 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1 }, 213 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2 }, 214 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3 }, 215 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4 }, 216 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5 }, 217 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6 }, 218 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7 }, 219 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8 }, 220 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9 }, 221 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10 }, 222 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11 }, 223 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12 }, 224 }; 225 226 static const TEST_ENTRY s_group_01[] = 227 { 228 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1 }, 229 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2 }, 230 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3 }, 231 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4 }, 232 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5 }, 233 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6 }, 234 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7 }, 235 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8 }, 236 { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9 }, 237 { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10 }, 238 { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11 }, 239 { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12 }, 240 241 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1 }, 242 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2 }, 243 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3 }, 244 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4 }, 245 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5 }, 246 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6 }, 247 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7 }, 248 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8 }, 249 { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9 }, 250 { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10 }, 251 { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11 }, 252 { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12 }, 253 }; 254 255 static const TEST_ENTRY s_group_02[] = 256 { 257 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1 }, 258 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2 }, 259 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3 }, 260 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4 }, 261 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5 }, 262 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6 }, 263 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7 }, 264 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8 }, 265 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9 }, 266 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10 }, 267 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11 }, 268 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12 }, 269 270 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1 }, 271 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2 }, 272 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3 }, 273 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4 }, 274 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5 }, 275 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6 }, 276 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7 }, 277 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8 }, 278 { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9 }, 279 { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10 }, 280 { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11 }, 281 { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12 }, 282 }; 283 284 static const TEST_ENTRY s_group_03[] = 285 { 286 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1 }, 287 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2 }, 288 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3 }, 289 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4 }, 290 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5 }, 291 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6 }, 292 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7 }, 293 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8 }, 294 { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9 }, 295 { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10 }, 296 { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11 }, 297 { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12 }, 298 299 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1 }, 300 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2 }, 301 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3 }, 302 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4 }, 303 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5 }, 304 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6 }, 305 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7 }, 306 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8 }, 307 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9 }, 308 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10 }, 309 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11 }, 310 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12 }, 311 }; 312 313 static const TEST_ENTRY s_group_04[] = 314 { 315 { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction1 }, 316 { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0, s_szTestFile0Kai, DoAction2 }, 317 { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0Kai, s_szTestFile0, DoAction3 }, 318 { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction4 }, 319 { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction5 }, 320 { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0, s_szTestDir0Kai, DoAction6 }, 321 { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0Kai, s_szTestDir0, DoAction7 }, 322 { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction8 }, 323 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9 }, 324 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10 }, 325 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11 }, 326 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12 }, 327 328 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1 }, 329 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2 }, 330 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3 }, 331 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4 }, 332 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5 }, 333 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6 }, 334 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7 }, 335 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8 }, 336 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9 }, 337 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10 }, 338 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11 }, 339 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12 }, 340 }; 341 342 static const TEST_ENTRY s_group_05[] = 343 { 344 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1 }, 345 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2 }, 346 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3 }, 347 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4 }, 348 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5 }, 349 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6 }, 350 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7 }, 351 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8 }, 352 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9 }, 353 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10 }, 354 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11 }, 355 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12 }, 356 357 { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction1 }, 358 { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1, s_szTestFile1Kai, DoAction2 }, 359 { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1Kai, s_szTestFile1, DoAction3 }, 360 { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction4 }, 361 { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction5 }, 362 { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1, s_szTestDir1Kai, DoAction6 }, 363 { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1Kai, s_szTestDir1, DoAction7 }, 364 { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction8 }, 365 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9 }, 366 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10 }, 367 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11 }, 368 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12 }, 369 }; 370 371 static const TEST_ENTRY s_group_06[] = 372 { 373 { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction1 }, 374 { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0, s_szTestFile0Kai, DoAction2 }, 375 { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0Kai, s_szTestFile0, DoAction3 }, 376 { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction4 }, 377 { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction5 }, 378 { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0, s_szTestDir0Kai, DoAction6 }, 379 { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0Kai, s_szTestDir0, DoAction7 }, 380 { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction8 }, 381 { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9 }, 382 { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10 }, 383 { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11 }, 384 { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12 }, 385 386 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1 }, 387 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2 }, 388 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3 }, 389 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4 }, 390 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5 }, 391 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6 }, 392 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7 }, 393 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8 }, 394 { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9 }, 395 { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10 }, 396 { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11 }, 397 { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12 }, 398 }; 399 400 static const TEST_ENTRY s_group_07[] = 401 { 402 { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction1 }, 403 { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0, s_szTestFile0Kai, DoAction2 }, 404 { __LINE__, WRITEDIR_0, "1000000", s_szTestFile0Kai, s_szTestFile0, DoAction3 }, 405 { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction4 }, 406 { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction5 }, 407 { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0, s_szTestDir0Kai, DoAction6 }, 408 { __LINE__, WRITEDIR_0, "0000010", s_szTestDir0Kai, s_szTestDir0, DoAction7 }, 409 { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction8 }, 410 { __LINE__, WRITEDIR_0, "0100000", s_szTestFile0, L"", DoAction9 }, 411 { __LINE__, WRITEDIR_0, "0010000", s_szTestFile0, L"", DoAction10 }, 412 { __LINE__, WRITEDIR_0, "0001000", s_szTestDir0, L"", DoAction11 }, 413 { __LINE__, WRITEDIR_0, "0000100", s_szTestDir0, L"", DoAction12 }, 414 415 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction1 }, 416 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction2 }, 417 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction3 }, 418 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction4 }, 419 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction5 }, 420 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction6 }, 421 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction7 }, 422 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction8 }, 423 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction9 }, 424 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction10 }, 425 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction11 }, 426 { __LINE__, WRITEDIR_1, "0000000", L"", L"", DoAction12 }, 427 }; 428 429 static const TEST_ENTRY s_group_08[] = 430 { 431 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction1 }, 432 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction2 }, 433 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction3 }, 434 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction4 }, 435 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction5 }, 436 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction6 }, 437 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction7 }, 438 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction8 }, 439 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction9 }, 440 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction10 }, 441 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction11 }, 442 { __LINE__, WRITEDIR_0, "0000000", L"", L"", DoAction12 }, 443 444 { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction1 }, 445 { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1, s_szTestFile1Kai, DoAction2 }, 446 { __LINE__, WRITEDIR_1, "1000000", s_szTestFile1Kai, s_szTestFile1, DoAction3 }, 447 { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction4 }, 448 { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction5 }, 449 { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1, s_szTestDir1Kai, DoAction6 }, 450 { __LINE__, WRITEDIR_1, "0000010", s_szTestDir1Kai, s_szTestDir1, DoAction7 }, 451 { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction8 }, 452 { __LINE__, WRITEDIR_1, "0100000", s_szTestFile1, L"", DoAction9 }, 453 { __LINE__, WRITEDIR_1, "0010000", s_szTestFile1, L"", DoAction10 }, 454 { __LINE__, WRITEDIR_1, "0001000", s_szTestDir1, L"", DoAction11 }, 455 { __LINE__, WRITEDIR_1, "0000100", s_szTestDir1, L"", DoAction12 }, 456 }; 457 458 static LPCSTR PatternFromFlags(DWORD flags) 459 { 460 static CHAR s_buf[(TYPE_MAX + 1) + 1]; 461 for (INT i = 0; i < (TYPE_MAX + 1); ++i) 462 s_buf[i] = (char)('0' + !!(flags & (1 << i))); 463 464 s_buf[TYPE_MAX + 1] = 0; 465 return s_buf; 466 } 467 468 static BOOL DoGetPaths(LPWSTR pszPath1, LPWSTR pszPath2) 469 { 470 pszPath1[0] = pszPath2[0] = 0; 471 472 WCHAR szText[MAX_PATH * 2]; 473 szText[0] = 0; 474 FILE *fp = _wfopen(TEMP_FILE, L"rb"); 475 if (fp) 476 { 477 fread(szText, 1, sizeof(szText), fp); 478 fclose(fp); 479 } 480 481 LPWSTR pch = wcschr(szText, L'|'); 482 if (pch == NULL) 483 return FALSE; 484 485 *pch = 0; 486 StringCchCopyW(pszPath1, MAX_PATH, szText); 487 StringCchCopyW(pszPath2, MAX_PATH, pch + 1); 488 return TRUE; 489 } 490 491 static void DoTestEntry(INT iEntry, const TEST_ENTRY *entry, INT nSources) 492 { 493 #ifdef ENTRY_TICK 494 DWORD dwOldTick = GetTickCount(); 495 #endif 496 497 BOOL bInterrupting = FALSE; 498 if (entry->action) 499 bInterrupting = entry->action(entry); 500 501 DWORD flags; 502 LPCSTR pattern; 503 if ((nSources & SHCNRF_InterruptLevel) && bInterrupting) 504 { 505 // The event won't work at here. Manually waiting... 506 UINT cTry = ((iEntry == 0) ? 100 : 60); 507 for (UINT iTry = 0; iTry < cTry; ++iTry) 508 { 509 flags = SendMessageW(s_hwnd, WM_GET_NOTIFY_FLAGS, 0, 0); 510 pattern = PatternFromFlags(flags); 511 if (strcmp(pattern, "0000000") != 0) 512 break; 513 514 Sleep(1); 515 } 516 } 517 else 518 { 519 if (WaitForSingleObject(s_hEvent, 100) == WAIT_OBJECT_0) 520 Sleep(1); 521 522 flags = SendMessageW(s_hwnd, WM_GET_NOTIFY_FLAGS, 0, 0); 523 pattern = PatternFromFlags(flags); 524 } 525 526 SendMessageW(s_hwnd, WM_SET_PATHS, 0, 0); 527 528 WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH]; 529 szPath1[0] = szPath2[0] = 0; 530 BOOL bOK = DoGetPaths(szPath1, szPath2); 531 532 static UINT s_cCalmDown = 0; 533 534 if (pattern[TYPE_UPDATEDIR] == '1') 535 { 536 trace("Line %d: SHCNE_UPDATEDIR: Calm down (%u)...\n", entry->line, s_cCalmDown); 537 538 if (++s_cCalmDown < 3) 539 Sleep(3000); 540 541 if (entry->pattern) 542 ok(TRUE, "Line %d:\n", entry->line); 543 if (entry->path1) 544 ok(TRUE, "Line %d:\n", entry->line); 545 if (entry->path2) 546 ok(TRUE, "Line %d:\n", entry->line); 547 } 548 else 549 { 550 s_cCalmDown = 0; 551 if (entry->pattern) 552 { 553 ok(strcmp(pattern, entry->pattern) == 0, 554 "Line %d: pattern mismatch '%s', tick=0x%08lX\n", 555 entry->line, pattern, GetTickCount()); 556 } 557 if (entry->path1) 558 ok(bOK && lstrcmpiW(entry->path1, szPath1) == 0, 559 "Line %d: path1 mismatch '%S' (%d)\n", entry->line, szPath1, bOK); 560 if (entry->path2) 561 ok(bOK && lstrcmpiW(entry->path2, szPath2) == 0, 562 "Line %d: path2 mismatch '%S' (%d)\n", entry->line, szPath2, bOK); 563 } 564 565 SendMessageW(s_hwnd, WM_CLEAR_FLAGS, 0, 0); 566 ResetEvent(s_hEvent); 567 568 #ifdef ENTRY_TICK 569 DWORD dwNewTick = GetTickCount(); 570 DWORD dwTick = dwNewTick - dwOldTick; 571 trace("DoTestEntry: Line %d: tick=%lu.%lu sec\n", entry->line, 572 (dwTick / 1000), (dwTick / 100 % 10)); 573 #endif 574 } 575 576 static void DoQuitTest(BOOL bForce) 577 { 578 PostMessageW(s_hwnd, WM_COMMAND, IDOK, 0); 579 580 DoWaitForWindow(CLASSNAME, CLASSNAME, TRUE, bForce); 581 s_hwnd = NULL; 582 583 if (s_hEvent) 584 { 585 CloseHandle(s_hEvent); 586 s_hEvent = NULL; 587 } 588 589 DoDeleteFilesAndDirs(); 590 } 591 592 static void DoAbortThread(void) 593 { 594 skip("Aborting the thread...\n"); 595 if (s_hThread) 596 { 597 TerminateThread(s_hThread, -1); 598 s_hThread = NULL; 599 } 600 } 601 602 static BOOL CALLBACK HandlerRoutine(DWORD dwCtrlType) 603 { 604 switch (dwCtrlType) 605 { 606 case CTRL_C_EVENT: 607 case CTRL_BREAK_EVENT: 608 DoAbortThread(); 609 DoQuitTest(TRUE); 610 return TRUE; 611 } 612 return FALSE; 613 } 614 615 static BOOL DoInitTest(void) 616 { 617 // DIRTYPE_DESKTOP 618 LPWSTR psz = DoGetDir(DIRTYPE_DESKTOP); 619 StringCchCopyW(s_szDesktop, _countof(s_szDesktop), psz); 620 621 PathAppendW(psz, TEST_FILE); 622 StringCchCopyW(s_szTestFile0, _countof(s_szTestFile0), psz); 623 624 PathRemoveFileSpecW(psz); 625 PathAppendW(psz, TEST_FILE_KAI); 626 StringCchCopyW(s_szTestFile0Kai, _countof(s_szTestFile0Kai), psz); 627 628 PathRemoveFileSpecW(psz); 629 PathAppendW(psz, TEST_DIR); 630 StringCchCopyW(s_szTestDir0, _countof(s_szTestDir0), psz); 631 632 PathRemoveFileSpecW(psz); 633 PathAppendW(psz, TEST_DIR_KAI); 634 StringCchCopyW(s_szTestDir0Kai, _countof(s_szTestDir0Kai), psz); 635 636 // DIRTYPE_MYDOCUMENTS 637 psz = DoGetDir(DIRTYPE_MYDOCUMENTS); 638 StringCchCopyW(s_szDocuments, _countof(s_szDocuments), psz); 639 640 PathAppendW(psz, TEST_FILE); 641 StringCchCopyW(s_szTestFile1, _countof(s_szTestFile1), psz); 642 643 PathRemoveFileSpecW(psz); 644 PathAppendW(psz, TEST_FILE_KAI); 645 StringCchCopyW(s_szTestFile1Kai, _countof(s_szTestFile1Kai), psz); 646 647 PathRemoveFileSpecW(psz); 648 PathAppendW(psz, TEST_DIR); 649 StringCchCopyW(s_szTestDir1, _countof(s_szTestDir1), psz); 650 651 PathRemoveFileSpecW(psz); 652 PathAppendW(psz, TEST_DIR_KAI); 653 StringCchCopyW(s_szTestDir1Kai, _countof(s_szTestDir1Kai), psz); 654 655 // prepare for files and dirs 656 DoDeleteFilesAndDirs(); 657 DoCreateEmptyFile(TEMP_FILE); 658 659 // Ctrl+C 660 SetConsoleCtrlHandler(HandlerRoutine, TRUE); 661 662 // close Explorer windows 663 trace("Closing Explorer windows...\n"); 664 DoWaitForWindow(L"CabinetWClass", NULL, TRUE, TRUE); 665 666 // close the CLASSNAME windows 667 return DoWaitForWindow(CLASSNAME, CLASSNAME, TRUE, TRUE) == NULL; 668 } 669 670 static BOOL 671 GetSubProgramPath(void) 672 { 673 GetModuleFileNameW(NULL, s_szSubProgram, _countof(s_szSubProgram)); 674 PathRemoveFileSpecW(s_szSubProgram); 675 PathAppendW(s_szSubProgram, L"shell32_apitest_sub.exe"); 676 677 if (!PathFileExistsW(s_szSubProgram)) 678 { 679 PathRemoveFileSpecW(s_szSubProgram); 680 PathAppendW(s_szSubProgram, L"testdata\\shell32_apitest_sub.exe"); 681 682 if (!PathFileExistsW(s_szSubProgram)) 683 return FALSE; 684 } 685 686 return TRUE; 687 } 688 689 #define SRC_00 0 690 #define SRC_01 SHCNRF_ShellLevel 691 #define SRC_02 (SHCNRF_NewDelivery) 692 #define SRC_03 (SHCNRF_NewDelivery | SHCNRF_ShellLevel) 693 #define SRC_04 SHCNRF_InterruptLevel 694 #define SRC_05 (SHCNRF_InterruptLevel | SHCNRF_ShellLevel) 695 #define SRC_06 (SHCNRF_InterruptLevel | SHCNRF_NewDelivery) 696 #define SRC_07 (SHCNRF_InterruptLevel | SHCNRF_NewDelivery | SHCNRF_ShellLevel) 697 #define SRC_08 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel) 698 #define SRC_09 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel | SHCNRF_ShellLevel) 699 #define SRC_10 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel | SHCNRF_NewDelivery) 700 #define SRC_11 (SHCNRF_RecursiveInterrupt | SHCNRF_InterruptLevel | SHCNRF_NewDelivery | SHCNRF_ShellLevel) 701 702 #define WATCHDIR_0 DIRTYPE_NULL 703 #define WATCHDIR_1 DIRTYPE_DESKTOP 704 #define WATCHDIR_2 DIRTYPE_MYCOMPUTER 705 #define WATCHDIR_3 DIRTYPE_MYDOCUMENTS 706 707 static void 708 DoTestGroup(INT line, UINT cEntries, const TEST_ENTRY *pEntries, BOOL fRecursive, 709 INT nSources, DIRTYPE iWatchDir) 710 { 711 #ifdef NO_INTERRUPT_LEVEL 712 if (nSources & SHCNRF_InterruptLevel) 713 return; 714 #endif 715 #ifdef NO_SHELL_LEVEL 716 if (nSources & SHCNRF_ShellLevel) 717 return; 718 #endif 719 #ifdef NEW_DELIVERY_ONLY 720 if (!(nSources & SHCNRF_NewDelivery)) 721 return; 722 #endif 723 #ifdef GROUP_TICK 724 DWORD dwOldTick = GetTickCount(); 725 #endif 726 #ifdef RANDOM_QUARTER 727 if ((rand() & 3) == 0) 728 return; 729 #elif defined(RANDOM_HALF) 730 if (rand() & 1) 731 return; 732 #endif 733 734 trace("DoTestGroup: Line %d: fRecursive:%u, iWatchDir:%u, nSources:0x%X\n", 735 line, fRecursive, iWatchDir, nSources); 736 737 if (s_hEvent) 738 { 739 CloseHandle(s_hEvent); 740 s_hEvent = NULL; 741 } 742 s_hEvent = CreateEventW(NULL, TRUE, FALSE, EVENT_NAME); 743 744 WCHAR szParams[64]; 745 StringCchPrintfW(szParams, _countof(szParams), L"%u,%u,%u", fRecursive, iWatchDir, nSources); 746 747 HINSTANCE hinst = ShellExecuteW(NULL, NULL, s_szSubProgram, szParams, NULL, SW_SHOWNORMAL); 748 if ((INT_PTR)hinst <= 32) 749 { 750 skip("Unable to run shell32_apitest_sub.exe.\n"); 751 return; 752 } 753 754 s_hwnd = DoWaitForWindow(CLASSNAME, CLASSNAME, FALSE, FALSE); 755 if (!s_hwnd) 756 { 757 skip("Unable to find window.\n"); 758 return; 759 } 760 761 for (UINT i = 0; i < cEntries; ++i) 762 { 763 if (!IsWindow(s_hwnd)) 764 { 765 DoAbortThread(); 766 DoQuitTest(TRUE); 767 break; 768 } 769 770 DoTestEntry(i, &pEntries[i], nSources); 771 } 772 773 DoQuitTest(FALSE); 774 775 #ifdef GROUP_TICK 776 DWORD dwNewTick = GetTickCount(); 777 DWORD dwTick = dwNewTick - dwOldTick; 778 trace("DoTestGroup: Line %d: %lu.%lu sec\n", line, (dwTick / 1000), (dwTick / 100 % 10)); 779 #endif 780 } 781 782 static unsigned __stdcall TestThreadProc(void *) 783 { 784 srand(time(NULL)); 785 #ifdef RANDOM_QUARTER 786 skip("RANDOM_QUARTER\n"); 787 #elif defined(RANDOM_HALF) 788 skip("RANDOM_HALF\n"); 789 #endif 790 791 // fRecursive == FALSE. 792 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_0); 793 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, FALSE, SRC_01, WATCHDIR_0); 794 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_0); 795 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, FALSE, SRC_03, WATCHDIR_0); 796 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_04, WATCHDIR_0); 797 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_05, WATCHDIR_0); 798 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_06, WATCHDIR_0); 799 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_07, WATCHDIR_0); 800 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_08, WATCHDIR_0); 801 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_09, WATCHDIR_0); 802 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_10, WATCHDIR_0); 803 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, FALSE, SRC_11, WATCHDIR_0); 804 805 BOOL bTarget = IsWindowsXPOrGreater() && !IsWindowsVistaOrGreater(); 806 807 #define SWITCH(x, y) (bTarget ? (x) : (y)) 808 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_1); 809 DoTestGroup(__LINE__, _countof(s_group_03), s_group_03, FALSE, SRC_01, WATCHDIR_1); 810 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_1); 811 DoTestGroup(__LINE__, _countof(s_group_03), s_group_03, FALSE, SRC_03, WATCHDIR_1); 812 DoTestGroup(__LINE__, SWITCH(_countof(s_group_00), _countof(s_group_04)), SWITCH(s_group_00, s_group_04), FALSE, SRC_04, WATCHDIR_1); 813 DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_05, WATCHDIR_1); 814 DoTestGroup(__LINE__, SWITCH(_countof(s_group_00), _countof(s_group_04)), SWITCH(s_group_00, s_group_04), FALSE, SRC_06, WATCHDIR_1); 815 DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_07, WATCHDIR_1); 816 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, FALSE, SRC_08, WATCHDIR_1); 817 DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_09, WATCHDIR_1); 818 DoTestGroup(__LINE__, SWITCH(_countof(s_group_00), _countof(s_group_04)), SWITCH(s_group_00, s_group_04), FALSE, SRC_06, WATCHDIR_1); 819 DoTestGroup(__LINE__, _countof(s_group_07), s_group_07, FALSE, SRC_11, WATCHDIR_1); 820 #undef SWITCH 821 822 #ifndef NO_TRIVIAL 823 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_2); 824 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_01, WATCHDIR_2); 825 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_2); 826 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_03, WATCHDIR_2); 827 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_04, WATCHDIR_2); 828 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_05, WATCHDIR_2); 829 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_06, WATCHDIR_2); 830 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_07, WATCHDIR_2); 831 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_08, WATCHDIR_2); 832 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_09, WATCHDIR_2); 833 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_10, WATCHDIR_2); 834 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_11, WATCHDIR_2); 835 #endif 836 837 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_00, WATCHDIR_3); 838 DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, FALSE, SRC_01, WATCHDIR_3); 839 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, FALSE, SRC_02, WATCHDIR_3); 840 DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, FALSE, SRC_03, WATCHDIR_3); 841 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_04, WATCHDIR_3); 842 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_05, WATCHDIR_3); 843 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_06, WATCHDIR_3); 844 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_07, WATCHDIR_3); 845 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_08, WATCHDIR_3); 846 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_09, WATCHDIR_3); 847 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, FALSE, SRC_10, WATCHDIR_3); 848 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, FALSE, SRC_11, WATCHDIR_3); 849 850 // fRecursive == TRUE. 851 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_0); 852 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_01, WATCHDIR_0); 853 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_0); 854 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_03, WATCHDIR_0); 855 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_04, WATCHDIR_0); 856 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_05, WATCHDIR_0); 857 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_06, WATCHDIR_0); 858 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_07, WATCHDIR_0); 859 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_08, WATCHDIR_0); 860 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_09, WATCHDIR_0); 861 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_10, WATCHDIR_0); 862 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_11, WATCHDIR_0); 863 864 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_1); 865 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_01, WATCHDIR_1); 866 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_1); 867 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_03, WATCHDIR_1); 868 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_04, WATCHDIR_1); 869 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_05, WATCHDIR_1); 870 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_06, WATCHDIR_1); 871 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_07, WATCHDIR_1); 872 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_08, WATCHDIR_1); 873 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_09, WATCHDIR_1); 874 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_10, WATCHDIR_1); 875 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_11, WATCHDIR_1); 876 877 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_2); 878 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_01, WATCHDIR_2); 879 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_2); 880 DoTestGroup(__LINE__, _countof(s_group_01), s_group_01, TRUE, SRC_03, WATCHDIR_2); 881 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_04, WATCHDIR_2); 882 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_05, WATCHDIR_2); 883 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_06, WATCHDIR_2); 884 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_07, WATCHDIR_2); 885 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_08, WATCHDIR_2); 886 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_09, WATCHDIR_2); 887 DoTestGroup(__LINE__, _countof(s_group_04), s_group_04, TRUE, SRC_10, WATCHDIR_2); 888 DoTestGroup(__LINE__, _countof(s_group_06), s_group_06, TRUE, SRC_11, WATCHDIR_2); 889 890 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_00, WATCHDIR_3); 891 DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, TRUE, SRC_01, WATCHDIR_3); 892 DoTestGroup(__LINE__, _countof(s_group_00), s_group_00, TRUE, SRC_02, WATCHDIR_3); 893 DoTestGroup(__LINE__, _countof(s_group_02), s_group_02, TRUE, SRC_03, WATCHDIR_3); 894 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_04, WATCHDIR_3); 895 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_05, WATCHDIR_3); 896 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_06, WATCHDIR_3); 897 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_07, WATCHDIR_3); 898 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_08, WATCHDIR_3); 899 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_09, WATCHDIR_3); 900 DoTestGroup(__LINE__, _countof(s_group_05), s_group_05, TRUE, SRC_10, WATCHDIR_3); 901 DoTestGroup(__LINE__, _countof(s_group_08), s_group_08, TRUE, SRC_11, WATCHDIR_3); 902 903 return 0; 904 } 905 906 START_TEST(SHChangeNotify) 907 { 908 #ifdef TOTAL_TICK 909 DWORD dwOldTick = GetTickCount(); 910 #endif 911 #ifdef DISABLE_THIS_TESTCASE 912 skip("This testcase is disabled by DISABLE_THIS_TESTCASE macro.\n"); 913 return; 914 #endif 915 916 trace("Please don't operate your PC while testing...\n"); 917 918 if (!GetSubProgramPath()) 919 { 920 skip("shell32_apitest_sub.exe not found\n"); 921 return; 922 } 923 924 if (!DoInitTest()) 925 { 926 skip("Unable to initialize.\n"); 927 DoQuitTest(TRUE); 928 return; 929 } 930 931 s_hThread = (HANDLE)_beginthreadex(NULL, 0, TestThreadProc, NULL, 0, NULL); 932 WaitForSingleObject(s_hThread, INFINITE); 933 CloseHandle(s_hThread); 934 935 #ifdef TOTAL_TICK 936 DWORD dwNewTick = GetTickCount(); 937 DWORD dwTick = dwNewTick - dwOldTick; 938 trace("SHChangeNotify: Total %lu.%lu sec\n", (dwTick / 1000), (dwTick / 100 % 10)); 939 #endif 940 941 DoWaitForWindow(CLASSNAME, CLASSNAME, TRUE, TRUE); 942 Sleep(100); 943 } 944