| 644 | } |
| 645 | |
| 646 | std::optional<QString> getAssocString(const QFileInfo& file, ASSOCSTR astr) |
| 647 | { |
| 648 | const auto ext = L"." + file.suffix().toStdWString(); |
| 649 | |
| 650 | // getting buffer size |
| 651 | DWORD bufferSize = 0; |
| 652 | auto r = AssocQueryStringW(ASSOCF_INIT_IGNOREUNKNOWN, astr, ext.c_str(), L"open", |
| 653 | nullptr, &bufferSize); |
| 654 | |
| 655 | // returns S_FALSE when giving back the buffer size, so that's actually the |
| 656 | // expected return value |
| 657 | |
| 658 | if (r != S_FALSE || bufferSize == 0) { |
| 659 | if (r == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION)) { |
| 660 | log::error("file '{}' has no associated executable", file.absoluteFilePath()); |
| 661 | } else { |
| 662 | log::error("can't get buffer size for AssocQueryStringW(), {}", |
| 663 | formatSystemMessage(r)); |
| 664 | } |
| 665 | return {}; |
| 666 | } |
| 667 | |
| 668 | // getting string |
| 669 | auto buffer = std::make_unique<wchar_t[]>(bufferSize + 1); |
| 670 | std::fill(buffer.get(), buffer.get() + bufferSize + 1, 0); |
| 671 | |
| 672 | r = AssocQueryStringW(ASSOCF_INIT_IGNOREUNKNOWN, astr, ext.c_str(), L"open", |
| 673 | buffer.get(), &bufferSize); |
| 674 | |
| 675 | if (FAILED(r)) { |
| 676 | log::error("failed to get exe associated with '{}', {}", file.suffix(), |
| 677 | formatSystemMessage(r)); |
| 678 | |
| 679 | return {}; |
| 680 | } |
| 681 | |
| 682 | // buffer size includes the null terminator |
| 683 | return QString::fromWCharArray(buffer.get(), bufferSize - 1); |
| 684 | } |
| 685 | |
| 686 | QString formatCommandLine(const QFileInfo& targetInfo, const QString& cmd) |
| 687 | { |