1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) 4 * PURPOSE: Test for fc.exe 5 * COPYRIGHT: Copyright 2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8 #include "precomp.h" 9 #include <stdlib.h> 10 #include <stdio.h> 11 #include <string.h> 12 #include <shlwapi.h> 13 14 typedef struct TEST_ENTRY 15 { 16 INT lineno; 17 INT ret; 18 LPCSTR cmdline; 19 LPCSTR file1_data; 20 LPCSTR file2_data; 21 INT file1_size; // -1 for zero-terminated 22 INT file2_size; // -1 for zero-terminated 23 LPCSTR output; 24 } TEST_ENTRY; 25 26 #define FILE1 "fc-test1.txt" 27 #define FILE2 "fc-test2.txt" 28 #define FILES " " FILE1 " " FILE2 29 #define COMPARING "Comparing files fc-test1.txt and FC-TEST2.TXT\n" 30 #define NO_DIFF "FC: no differences encountered\n" 31 #define RESYNC_FAILED "Resync Failed. Files are too different.\n" 32 33 static const TEST_ENTRY s_entries[] = 34 { 35 /* binary comparison */ 36 { 37 __LINE__, 0, "fc /B" FILES, "", "", -1, -1, COMPARING 38 NO_DIFF 39 }, 40 { 41 __LINE__, 1, "fc /B" FILES, "A", "B", -1, -1, COMPARING 42 "00000000: 41 42\n" 43 }, 44 { 45 __LINE__, 1, "fc /B" FILES, "B", "A", -1, -1, COMPARING 46 "00000000: 42 41\n" 47 }, 48 { 49 __LINE__, 0, "fc /B" FILES, "AB", "AB", -1, -1, COMPARING 50 NO_DIFF 51 }, 52 { 53 __LINE__, 1, "fc /B" FILES, "AB", "BA", -1, -1, COMPARING 54 "00000000: 41 42\n" 55 "00000001: 42 41\n" 56 }, 57 { 58 __LINE__, 0, "fc /B" FILES, "ABC", "ABC", -1, -1, COMPARING 59 NO_DIFF 60 }, 61 { 62 __LINE__, 1, "fc /B" FILES, "ABC", "ABCD", -1, -1, COMPARING 63 "FC: FC-TEST2.TXT longer than fc-test1.txt\n\n" 64 }, 65 { 66 __LINE__, 1, "fc /B" FILES, "ABC", "ABDD", -1, -1, COMPARING 67 "00000002: 43 44\n" 68 "FC: FC-TEST2.TXT longer than fc-test1.txt\n" 69 }, 70 { 71 __LINE__, 1, "fc /B /C" FILES, "ABC", "abc", -1, -1, COMPARING 72 "00000000: 41 61\n" 73 "00000001: 42 62\n" 74 "00000002: 43 63\n" 75 }, 76 /* text comparison */ 77 { 78 __LINE__, 0, "fc" FILES, "", "", -1, -1, COMPARING 79 NO_DIFF 80 }, 81 { 82 __LINE__, 1, "fc" FILES, "A", "B", -1, -1, COMPARING 83 "***** fc-test1.txt\nA\n" 84 "***** FC-TEST2.TXT\nB\n" 85 "*****\n\n" 86 }, 87 { 88 __LINE__, 1, "fc" FILES, "B", "A", -1, -1, COMPARING 89 "***** fc-test1.txt\nB\n" 90 "***** FC-TEST2.TXT\nA\n" 91 "*****\n\n" 92 }, 93 { 94 __LINE__, 0, "fc" FILES, "AB", "AB", -1, -1, COMPARING 95 NO_DIFF 96 }, 97 { 98 __LINE__, 1, "fc" FILES, "AB", "BA", -1, -1, COMPARING 99 "***** fc-test1.txt\nAB\n" 100 "***** FC-TEST2.TXT\nBA\n" 101 "*****\n\n" 102 }, 103 { 104 __LINE__, 0, "fc" FILES, "ABC", "ABC", -1, -1, COMPARING 105 NO_DIFF 106 }, 107 { 108 __LINE__, 0, "fc /C" FILES, "ABC", "abc", -1, -1, COMPARING 109 NO_DIFF 110 }, 111 { 112 __LINE__, 1, "fc" FILES, "A\nB\nC\nD\nE\n", "A\nB\nB\nD\nE\n", -1, -1, COMPARING 113 "***** fc-test1.txt\nB\nC\nD\n" 114 "***** FC-TEST2.TXT\nB\nB\nD\n" 115 "*****\n\n" 116 }, 117 /* Test /A */ 118 { 119 __LINE__, 1, "fc /A" FILES, "A\nB\nC\nD\nE\n", "B\nB\nC\nD\nE\n", -1, -1, COMPARING 120 "***** fc-test1.txt\nA\nB\n" 121 "***** FC-TEST2.TXT\nB\nB\n" 122 "*****\n\n" 123 }, 124 { 125 __LINE__, 1, "fc /A" FILES, "A\nB\nC\nD\nE\n", "C\nC\nC\nD\nE\n", -1, -1, COMPARING 126 "***** fc-test1.txt\nA\nB\nC\n" 127 "***** FC-TEST2.TXT\nC\nC\nC\n" 128 "*****\n\n" 129 }, 130 { 131 __LINE__, 1, "fc /A" FILES, "A\nB\nC\nD\nE\n", "A\nC\nC\nD\nE\n", -1, -1, COMPARING 132 "***** fc-test1.txt\nA\nB\nC\n" 133 "***** FC-TEST2.TXT\nA\nC\nC\n" 134 "*****\n\n" 135 }, 136 { 137 __LINE__, 1, "fc /A" FILES, "A\nB\nC\nD\nE\n", "A\nC\nC\nC\nE\n", -1, -1, COMPARING 138 "***** fc-test1.txt\nA\n...\nE\n" 139 "***** FC-TEST2.TXT\nA\n...\nE\n" 140 "*****\n\n" 141 }, 142 { 143 __LINE__, 1, "fc /A" FILES, "A\nB\nC\nD\nE\n", "A\nB\nC\nD\nF\n", -1, -1, COMPARING 144 "***** fc-test1.txt\nD\nE\n" 145 "***** FC-TEST2.TXT\nD\nF\n" 146 "*****\n\n" 147 }, 148 { 149 __LINE__, 1, "fc /A" FILES, "A\nB\nC\nD\nE\n", "A\nB\nC\nF\nF\n", -1, -1, COMPARING 150 "***** fc-test1.txt\nC\nD\nE\n" 151 "***** FC-TEST2.TXT\nC\nF\nF\n" 152 "*****\n\n" 153 }, 154 { 155 __LINE__, 1, "fc /A" FILES, "A\nB\nC\nD\nE\n", "A\nB\nF\nF\nF\n", -1, -1, COMPARING 156 "***** fc-test1.txt\nB\n...\nE\n" 157 "***** FC-TEST2.TXT\nB\n...\nF\n" 158 "*****\n\n" 159 }, 160 { 161 __LINE__, 1, "fc /A" FILES, "A\nC\nE\nF\nE\n", "A\nB\nC\nD\nE\n", -1, -1, COMPARING 162 "***** fc-test1.txt\nA\nC\nE\n" 163 "***** FC-TEST2.TXT\nA\n...\nE\n" 164 "*****\n\n" 165 "***** fc-test1.txt\nF\nE\n" 166 "***** FC-TEST2.TXT\n" 167 "*****\n\n" 168 }, 169 /* Test /N /A */ 170 { 171 __LINE__, 1, "fc /N /A" FILES, "A\nB\nC\nD\nE\n", "A\nB\nB\nD\nE\n", -1, -1, COMPARING 172 "***** fc-test1.txt\n 2: B\n 3: C\n 4: D\n" 173 "***** FC-TEST2.TXT\n 2: B\n 3: B\n 4: D\n" 174 "*****\n\n" 175 }, 176 { 177 __LINE__, 1, "fc /N /A" FILES, "A\nC\nC\nD\nE\n", "A\nB\nC\nD\nE\n", -1, -1, COMPARING 178 "***** fc-test1.txt\n 1: A\n 2: C\n 3: C\n" 179 "***** FC-TEST2.TXT\n 1: A\n 2: B\n 3: C\n" 180 "*****\n\n" 181 }, 182 { 183 __LINE__, 1, "fc /N /A" FILES, "A\nC\nC\nC\nE\n", "A\nB\nC\nD\nE\n", -1, -1, COMPARING 184 "***** fc-test1.txt\n 1: A\n...\n 5: E\n" 185 "***** FC-TEST2.TXT\n 1: A\n...\n 5: E\n" 186 "*****\n\n" 187 }, 188 { 189 __LINE__, 1, "fc /N /A" FILES, "A\nC\nE\nF\nC\n", "A\nB\nC\nD\nE\n", -1, -1, COMPARING 190 "***** fc-test1.txt\n 1: A\n...\n 5: C\n" 191 "***** FC-TEST2.TXT\n 1: A\n 2: B\n 3: C\n" 192 "*****\n\n" 193 "***** fc-test1.txt\n" 194 "***** FC-TEST2.TXT\n 4: D\n 5: E\n" 195 "*****\n\n" 196 }, 197 { 198 __LINE__, 1, "fc /N /A" FILES, "A\nC\nE\nF\nE\n", "A\nB\nC\nD\nE\n", -1, -1, COMPARING 199 "***** fc-test1.txt\n 1: A\n 2: C\n 3: E\n" 200 "***** FC-TEST2.TXT\n 1: A\n...\n 5: E\n" 201 "*****\n\n" 202 "***** fc-test1.txt\n 4: F\n 5: E\n" 203 "***** FC-TEST2.TXT\n" 204 "*****\n\n" 205 }, 206 /* Test tab expansion */ 207 { 208 __LINE__, 0, "fc" FILES, "A\n\tB\nC", "A\n B\nC", -1, -1, COMPARING 209 NO_DIFF 210 }, 211 { 212 __LINE__, 0, "fc" FILES, "A\n \tB\nC", "A\n B\nC", -1, -1, COMPARING 213 NO_DIFF 214 }, 215 /* Test /T */ 216 { 217 __LINE__, 1, "fc /T" FILES, "A\n\tB\nC", "A\n B\nC", -1, -1, COMPARING 218 "***** fc-test1.txt\nA\n\tB\nC\n" 219 "***** FC-TEST2.TXT\nA\n B\nC\n" 220 "*****\n\n" 221 }, 222 { 223 __LINE__, 1, "fc /T" FILES, "A\n \tB\nC", "A\n B\nC", -1, -1, COMPARING 224 "***** fc-test1.txt\nA\n \tB\nC\n" 225 "***** FC-TEST2.TXT\nA\n B\nC\n" 226 "*****\n\n" 227 }, 228 /* Test /W */ 229 { 230 __LINE__, 0, "fc /W" FILES, "A\n \tB\nC", "A\n B\nC", -1, -1, COMPARING 231 NO_DIFF 232 }, 233 { 234 __LINE__, 0, "fc /W" FILES, "\tA \nB\n", "A\nB\n", -1, -1, COMPARING 235 NO_DIFF 236 }, 237 { 238 __LINE__, 1, "fc /W" FILES, " A \nB\n", "AB\nB\n", -1, -1, COMPARING 239 "***** fc-test1.txt\n A \nB\n" 240 "***** FC-TEST2.TXT\nAB\nB\n" 241 "*****\n\n" 242 }, 243 /* TEST /W /T */ 244 { 245 __LINE__, 0, "fc /W /T" FILES, "A\n \tB\nC", "A\n B\nC", -1, -1, COMPARING 246 NO_DIFF 247 }, 248 { 249 __LINE__, 0, "fc /W /T" FILES, "A\n \tB\nC", "A\n B\nC", -1, -1, COMPARING 250 NO_DIFF 251 }, 252 { 253 __LINE__, 1, "fc /W /T" FILES, "\tA \nB\n", "AB\nB\n", -1, -1, COMPARING 254 "***** fc-test1.txt\n\tA \nB\n" 255 "***** FC-TEST2.TXT\nAB\nB\n" 256 "*****\n\n" 257 }, 258 /* Test /N */ 259 { 260 __LINE__, 1, "fc /N" FILES, "A\nB\nC\nD\nE\n", "A\nB\nC\nE\nE\n", -1, -1, COMPARING 261 "***** fc-test1.txt\n 3: C\n 4: D\n 5: E\n" 262 "***** FC-TEST2.TXT\n 3: C\n 4: E\n" 263 "*****\n\n" 264 "***** fc-test1.txt\n" 265 "***** FC-TEST2.TXT\n 5: E\n" 266 "*****\n\n" 267 }, 268 /* Test NUL */ 269 { 270 __LINE__, 1, "fc" FILES, "ABC\000DE", "ABC\000\000\000", 6, 6, COMPARING 271 "***** fc-test1.txt\nABC\nDE\n" 272 "***** FC-TEST2.TXT\nABC\n\n\n" 273 "*****\n\n" 274 }, 275 { 276 __LINE__, 1, "fc" FILES, "ABC\000DE", "ABC\n\000\000", 6, 6, COMPARING 277 "***** fc-test1.txt\nABC\nDE\n" 278 "***** FC-TEST2.TXT\nABC\n\n\n" 279 "*****\n\n" 280 }, 281 { 282 __LINE__, 0, "fc" FILES, "ABC\000DE", "ABC\nDE", 6, 6, COMPARING 283 NO_DIFF 284 }, 285 /* Test CR ('\r') */ 286 { 287 __LINE__, 0, "fc" FILES, "ABC\nABC", "ABC\r\nABC", -1, -1, COMPARING 288 NO_DIFF 289 }, 290 { 291 __LINE__, 1, "fc" FILES, "ABC\nABC", "ABC\r\r\nABC", -1, -1, COMPARING 292 "***** fc-test1.txt\nABC\nABC\n" 293 "***** FC-TEST2.TXT\nABC\nABC\n" 294 "*****\n\n" 295 }, 296 /* Test '\n' at EOF */ 297 { 298 __LINE__, 0, "fc" FILES, "ABC", "ABC\n", -1, -1, COMPARING 299 NO_DIFF 300 }, 301 /* Test /U */ 302 { 303 /* L"AB" */ 304 __LINE__, 0, "fc /U" FILES, "A\000B\000", "A\000B\000", 4, 4, COMPARING 305 NO_DIFF 306 }, 307 { 308 __LINE__, 1, "fc /U" FILES, "A\000B\000", "A\000C\000", 4, 4, COMPARING 309 "***** fc-test1.txt\nAB\n" 310 "***** FC-TEST2.TXT\nAC\n" 311 "*****\n\n" 312 }, 313 /* Test /LB2 */ 314 { 315 __LINE__, 1, "fc /LB2" FILES, "A\nB\nC\nD\nE\n", "B\nB\nC\nD\nE\n", -1, -1, COMPARING 316 "***** fc-test1.txt\nA\nB\n" 317 "***** FC-TEST2.TXT\nB\nB\n" 318 "*****\n\n" 319 }, 320 { 321 __LINE__, 1, "fc /LB2" FILES, "A\nB\nC\nD\nE\n", "C\nC\nC\nD\nE\n", -1, -1, COMPARING 322 RESYNC_FAILED 323 "***** fc-test1.txt\nA\nB\n" 324 "***** FC-TEST2.TXT\nC\nC\n" 325 "*****\n\n" 326 }, 327 { 328 __LINE__, 1, "fc /LB2" FILES, "A\nB\nC\nD\nE\n", "D\nD\nD\nD\nE\n", -1, -1, COMPARING 329 RESYNC_FAILED 330 "***** fc-test1.txt\nA\nB\n" 331 "***** FC-TEST2.TXT\nD\nD\n" 332 "*****\n\n" 333 }, 334 { 335 __LINE__, 1, "fc /LB2" FILES, "A\nB\nC\nD\nE\n", "A\nC\nC\nD\nE\n", -1, -1, COMPARING 336 RESYNC_FAILED 337 "***** fc-test1.txt\nA\nB\n" 338 "***** FC-TEST2.TXT\nA\nC\n" 339 "*****\n\n" 340 }, 341 /* Test /LB3 */ 342 { 343 __LINE__, 1, "fc /LB3" FILES, "A\nB\nC\nD\nE\n", "C\nC\nC\nD\nE\n", -1, -1, COMPARING 344 "***** fc-test1.txt\nA\nB\nC\n" 345 "***** FC-TEST2.TXT\nC\nC\n" 346 "*****\n\n" 347 "***** fc-test1.txt\nC\nD\n" 348 "***** FC-TEST2.TXT\nC\nC\nD\n" 349 "*****\n\n" 350 }, 351 { 352 __LINE__, 1, "fc /LB3" FILES, "A\nB\nC\nD\nE\n", "D\nD\nD\nD\nE\n", -1, -1, COMPARING 353 RESYNC_FAILED 354 "***** fc-test1.txt\nA\nB\nC\n" 355 "***** FC-TEST2.TXT\nD\nD\nD\n" 356 "*****\n\n" 357 }, 358 /* Test /N /LB2 */ 359 { 360 __LINE__, 1, "fc /N /LB2" FILES, "A\nB\nC\nD\nE\n", "A\nB\nC\nE\nE\n", -1, -1, COMPARING 361 RESYNC_FAILED 362 "***** fc-test1.txt\n 3: C\n 4: D\n" 363 "***** FC-TEST2.TXT\n 3: C\n 4: E\n" 364 "*****\n\n" 365 }, 366 /* Test /1 */ 367 { 368 __LINE__, 1, "fc /1" FILES, "A\nB\nC\nD\nE\n", "A\nB\nC\nE\nE\n", -1, -1, COMPARING 369 "***** fc-test1.txt\nC\nD\nE\n" 370 "***** FC-TEST2.TXT\nC\nE\n" 371 "*****\n\n" 372 }, 373 { 374 __LINE__, 1, "fc /1" FILES, "A\nB\nC\nD\nE\n", "A\nB\nX\nX\nE\n", -1, -1, COMPARING 375 "***** fc-test1.txt\nB\nC\nD\nE\n" 376 "***** FC-TEST2.TXT\nB\nX\nX\nE\n" 377 "*****\n\n" 378 }, 379 { 380 __LINE__, 1, "fc /1" FILES, "A\nB\nC\nD\nE\nF\n", "A\nB\nX\nD\nX\nF", -1, -1, COMPARING 381 "***** fc-test1.txt\nB\nC\nD\n" 382 "***** FC-TEST2.TXT\nB\nX\nD\n" 383 "*****\n\n" 384 "***** fc-test1.txt\nD\nE\nF\n" 385 "***** FC-TEST2.TXT\nD\nX\nF\n" 386 "*****\n\n" 387 }, 388 /* Test /3 */ 389 { 390 __LINE__, 1, "fc /3" FILES, "A\nB\nC\nD\nE\n", "A\nB\nC\nE\nE\n", -1, -1, COMPARING 391 "***** fc-test1.txt\nC\nD\nE\n" 392 "***** FC-TEST2.TXT\nC\nE\n" 393 "*****\n\n" 394 }, 395 { 396 __LINE__, 1, "fc /3" FILES, "A\nB\nC\nD\nE\n", "A\nB\nX\nX\nE\n", -1, -1, COMPARING 397 "***** fc-test1.txt\nB\nC\nD\nE\n" 398 "***** FC-TEST2.TXT\nB\nX\nX\nE\n" 399 "*****\n\n" 400 }, 401 { 402 __LINE__, 1, "fc /3" FILES, "A\nB\nC\nD\nE\nF\n", "A\nB\nX\nD\nX\nF", -1, -1, COMPARING 403 "***** fc-test1.txt\nB\nC\nD\nE\nF\n" 404 "***** FC-TEST2.TXT\nB\nX\nD\nX\nF\n" 405 "*****\n\n" 406 }, 407 }; 408 409 BOOL DoDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit) 410 { 411 HANDLE hProcess = GetCurrentProcess(); 412 return DuplicateHandle(hProcess, hFile, hProcess, phFile, 0, 413 bInherit, DUPLICATE_SAME_ACCESS); 414 } 415 416 static BOOL 417 PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite, PHANDLE phOutputRead, 418 PHANDLE phErrorRead) 419 { 420 SECURITY_ATTRIBUTES sa; 421 HANDLE hInputRead = NULL, hInputWriteTmp = NULL; 422 HANDLE hOutputReadTmp = NULL, hOutputWrite = NULL; 423 HANDLE hErrorReadTmp = NULL, hErrorWrite = NULL; 424 425 sa.nLength = sizeof(sa); 426 sa.lpSecurityDescriptor = NULL; 427 sa.bInheritHandle = TRUE; 428 429 if (phInputWrite) 430 { 431 if (CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0)) 432 { 433 if (!DoDuplicateHandle(hInputWriteTmp, phInputWrite, FALSE)) 434 return FALSE; 435 CloseHandle(hInputWriteTmp); 436 } 437 else 438 goto failure; 439 } 440 441 if (phOutputRead) 442 { 443 if (CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0)) 444 { 445 if (!DoDuplicateHandle(hOutputReadTmp, phOutputRead, FALSE)) 446 return FALSE; 447 CloseHandle(hOutputReadTmp); 448 } 449 else 450 goto failure; 451 } 452 453 if (phOutputRead && phOutputRead == phErrorRead) 454 { 455 if (!DoDuplicateHandle(hOutputWrite, &hErrorWrite, TRUE)) 456 return FALSE; 457 } 458 else if (phErrorRead) 459 { 460 if (CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0)) 461 { 462 if (!DoDuplicateHandle(hErrorReadTmp, phErrorRead, FALSE)) 463 return FALSE; 464 CloseHandle(hErrorReadTmp); 465 } 466 else 467 goto failure; 468 } 469 470 if (phInputWrite) 471 { 472 psi->hStdInput = hInputRead; 473 psi->dwFlags |= STARTF_USESTDHANDLES; 474 } 475 if (phOutputRead) 476 { 477 psi->hStdOutput = hOutputWrite; 478 psi->dwFlags |= STARTF_USESTDHANDLES; 479 } 480 if (phErrorRead) 481 { 482 psi->hStdOutput = hErrorWrite; 483 psi->dwFlags |= STARTF_USESTDHANDLES; 484 } 485 return TRUE; 486 487 failure: 488 CloseHandle(hInputRead); 489 CloseHandle(hInputWriteTmp); 490 CloseHandle(hOutputReadTmp); 491 CloseHandle(hOutputWrite); 492 CloseHandle(hErrorReadTmp); 493 CloseHandle(hErrorWrite); 494 return FALSE; 495 } 496 497 static void ConvertOutput(LPSTR psz) 498 { 499 LPSTR pch1, pch2; 500 pch1 = pch2 = psz; 501 while (*pch1) 502 { 503 if (*pch1 != '\r') 504 { 505 *pch2++ = *pch1; 506 } 507 ++pch1; 508 } 509 *pch2 = 0; 510 } 511 512 static void DoTestEntry(const TEST_ENTRY* pEntry) 513 { 514 FILE *fp; 515 STARTUPINFOA si = { sizeof(si) }; 516 PROCESS_INFORMATION pi; 517 INT file1_size, file2_size; 518 HANDLE hOutputRead; 519 DWORD cbAvail, cbRead; 520 CHAR szOutput[1024]; 521 BOOL ret; 522 DWORD dwExitCode; 523 LPSTR psz; 524 525 file1_size = pEntry->file1_size; 526 file2_size = pEntry->file2_size; 527 if (file1_size == -1) 528 file1_size = strlen(pEntry->file1_data); 529 if (file2_size == -1) 530 file2_size = strlen(pEntry->file2_data); 531 532 fp = fopen(FILE1, "wb"); 533 fwrite(pEntry->file1_data, file1_size, 1, fp); 534 fclose(fp); 535 536 fp = fopen(FILE2, "wb"); 537 fwrite(pEntry->file2_data, file2_size, 1, fp); 538 fclose(fp); 539 540 ok(PathFileExistsA(FILE1), "Line %d: PathFileExistsA(FILE1) failed\n", pEntry->lineno); 541 ok(PathFileExistsA(FILE2), "Line %d: PathFileExistsA(FILE2) failed\n", pEntry->lineno); 542 543 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 544 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 545 si.hStdError = GetStdHandle(STD_ERROR_HANDLE); 546 547 PrepareForRedirect(&si, NULL, &hOutputRead, &hOutputRead); 548 549 psz = _strdup(pEntry->cmdline); 550 ret = CreateProcessA(NULL, psz, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); 551 free(psz); 552 553 ok(ret, "Line %d: CreateProcessA failed\n", pEntry->lineno); 554 555 #define TIMEOUT (10 * 1000) 556 WaitForSingleObject(pi.hProcess, TIMEOUT); 557 558 ZeroMemory(szOutput, sizeof(szOutput)); 559 if (PeekNamedPipe(hOutputRead, NULL, 0, NULL, &cbAvail, NULL)) 560 { 561 if (cbAvail > 0) 562 { 563 if (cbAvail > sizeof(szOutput)) 564 cbAvail = sizeof(szOutput) - 1; 565 566 ReadFile(hOutputRead, szOutput, cbAvail, &cbRead, NULL); 567 } 568 } 569 ConvertOutput(szOutput); 570 571 GetExitCodeProcess(pi.hProcess, &dwExitCode); 572 ok(dwExitCode == pEntry->ret, "Line %d: dwExitCode was 0x%lx\n", pEntry->lineno, dwExitCode); 573 574 if (StrCmpNIA(pEntry->output, szOutput, strlen(pEntry->output)) != 0) 575 { 576 ok(FALSE, "Line %d: Output was wrong\n", pEntry->lineno); 577 printf("---FROM HERE\n"); 578 printf("%s\n", szOutput); 579 printf("---UP TO HERE\n"); 580 } 581 else 582 { 583 ok_int(TRUE, TRUE); 584 } 585 586 CloseHandle(pi.hProcess); 587 CloseHandle(pi.hThread); 588 589 CloseHandle(hOutputRead); 590 if (si.hStdInput != GetStdHandle(STD_INPUT_HANDLE)) 591 CloseHandle(si.hStdInput); 592 if (si.hStdOutput != GetStdHandle(STD_OUTPUT_HANDLE)) 593 CloseHandle(si.hStdOutput); 594 if (si.hStdError != GetStdHandle(STD_ERROR_HANDLE)) 595 CloseHandle(si.hStdError); 596 597 DeleteFileA(FILE1); 598 DeleteFileA(FILE2); 599 } 600 601 #define ENGLISH_CP 437 /* English codepage */ 602 603 START_TEST(fc) 604 { 605 UINT i; 606 UINT uOldCP = GetConsoleCP(), uOldOutputCP = GetConsoleOutputCP(); 607 SetConsoleCP(ENGLISH_CP); 608 SetConsoleOutputCP(ENGLISH_CP); 609 610 for (i = 0; i < _countof(s_entries); ++i) 611 { 612 DoTestEntry(&s_entries[i]); 613 } 614 615 SetConsoleCP(uOldCP); 616 SetConsoleOutputCP(uOldOutputCP); 617 } 618