| 593 | } |
| 594 | |
| 595 | bool GetFilePathFromSpaceDelimitedString(const wchar_t* commandLine, CEStr& szExe, const wchar_t*& rsArguments) |
| 596 | { |
| 597 | szExe.Clear(); |
| 598 | rsArguments = nullptr; |
| 599 | |
| 600 | // 17.10.2010 - support executable file path without parameters, but with spaces in its path |
| 601 | // 22.11.2015 - or some weirdness, like `C:\Program Files\CodeBlocks/cb_console_runner.exe "C:\sources\app.exe"` |
| 602 | |
| 603 | if (!commandLine) |
| 604 | return false; |
| 605 | |
| 606 | bool result = false; |
| 607 | const auto* command = commandLine; |
| 608 | // Skip quotation marks for now, we process here commands like |
| 609 | // `"C:\Program Files\Far\far.exe /p:path /some-switch"` |
| 610 | // `"C:\arc\7z.exe a test.7z *.*"` |
| 611 | size_t wasQuoted = 0; |
| 612 | while (*command == L'"') |
| 613 | { |
| 614 | ++command; ++wasQuoted; |
| 615 | } |
| 616 | |
| 617 | // Empty string - nothing to do |
| 618 | if (!*command) |
| 619 | return false; |
| 620 | |
| 621 | const auto* validEnd = wcspbrk(command, ILLEGAL_CHARACTERS); |
| 622 | if (!validEnd) |
| 623 | validEnd = command + wcslen(command); |
| 624 | |
| 625 | const wchar_t breakChars[] = L" \"\t\r\n"; |
| 626 | LPCWSTR nextBreak = wcspbrk(command, breakChars); |
| 627 | if (!nextBreak) |
| 628 | nextBreak = validEnd; |
| 629 | |
| 630 | CEStr szTemp; |
| 631 | uint64_t nTempSize; |
| 632 | bool repeat = true; // at least once, even if *nextBreak == 0 |
| 633 | while (repeat) |
| 634 | { |
| 635 | // ReSharper disable once CppAssignedValueIsNeverUsed |
| 636 | repeat = false; |
| 637 | _ASSERTE(nextBreak > command); |
| 638 | if (*nextBreak == L'"') |
| 639 | { |
| 640 | // If we reached the '"' - we don't care about this string, |
| 641 | // reason is that executable is already properly quoted. |
| 642 | // Or the string is completely malformed. |
| 643 | break; |
| 644 | } |
| 645 | |
| 646 | _ASSERTE(command && *command != L'"'); |
| 647 | szTemp.Set(command, (nextBreak - command)); |
| 648 | _ASSERTE(szTemp[(nextBreak - command)] == 0); |
| 649 | |
| 650 | // one of cmd internal commands? |
| 651 | if (!szTemp.IsEmpty() && !IsFilePath(szTemp, true) && !wcspbrk(szTemp.c_str(), L":\\/") |
| 652 | && !wcspbrk(szTemp.c_str(), ILLEGAL_CHARACTERS) && !wcspbrk(szTemp.c_str(), SPECIAL_CMD_CHARACTERS) |