From 544da49e32f98e3f76d673d1e72540a02a0481c5 Mon Sep 17 00:00:00 2001 From: Hane Date: Thu, 6 Jun 2024 20:08:36 +0200 Subject: [PATCH] test: fixed unnamed sessions #6 --- src/back/backlasses.cpp | 2 +- src/back/backsessionclasses.cpp | 113 ++++++++++++++++++++++++-------- src/back/msinclude.h | 2 + src/qt/qtclasses.cpp | 2 +- src/qt/qtcommon.h | 2 +- 5 files changed, 91 insertions(+), 30 deletions(-) diff --git a/src/back/backlasses.cpp b/src/back/backlasses.cpp index bfc0e83..60e6a93 100644 --- a/src/back/backlasses.cpp +++ b/src/back/backlasses.cpp @@ -475,7 +475,7 @@ void Endpoint::setFlow() { if(FAILED(this->endpoint->QueryInterface(__uuidof(IMMEndpoint), (void**)&flowGetter))) { log_debugcpp("no flow..."); } EDataFlow MSflow; - HRESULT vafllar = flowGetter->GetDataFlow(&MSflow); + flowGetter->GetDataFlow(&MSflow); this->flow = (MSflow == EDataFlow::eRender ? Flows::FLOW_PLAYBACK : Flows::FLOW_CAPTURE); log_debugcpp("Endpoint flow: " + std::to_string(flow)); flowGetter->Release(); diff --git a/src/back/backsessionclasses.cpp b/src/back/backsessionclasses.cpp index 80eeac8..ba0eaa6 100644 --- a/src/back/backsessionclasses.cpp +++ b/src/back/backsessionclasses.cpp @@ -196,11 +196,14 @@ std::wstring Session::fetchProcessName(DWORD pid) { /* * https://learn.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot * https://stackoverflow.com/questions/11843368/how-to-get-process-description + * https://notes.indezine.com/2018/05/microsoft-locale-ids.html#:~:text=Wait%2C%201033%20is%20the%20decimal,ID%20for%20English%20%E2%80%93%20United%20States. + * https://stackoverflow.com/questions/64321036/c-win32-getting-app-name-using-pid-and-executable-path */ /* Executable path retrieval */ std::wstring exePath = L""; - + std::wstring msixName; + HANDLE processList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid); if (processList == INVALID_HANDLE_VALUE) { log_wdebugcpp(L"aye no procname."); @@ -224,55 +227,111 @@ std::wstring Session::fetchProcessName(DWORD pid) { } CloseHandle(processList); - /* File description retrieval */ + /* File description retrieval: size and available lang-codepages */ struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *translationArray; DWORD filler; - DWORD fileVersionInfoSize = GetFileVersionInfoSizeW(exePath.c_str(), &filler); + DWORD fileVersionInfoSize = GetFileVersionInfoSizeExW + (FILE_VER_GET_LOCALISED | FILE_VER_GET_NEUTRAL, exePath.c_str(), &filler); if (!fileVersionInfoSize) return exePath; void* fileVersionInfo = malloc(fileVersionInfoSize); - if(!GetFileVersionInfoW(exePath.c_str(),0,fileVersionInfoSize, fileVersionInfo)) + if(!GetFileVersionInfoExW(FILE_VER_GET_LOCALISED | FILE_VER_GET_NEUTRAL, + exePath.c_str(),0,fileVersionInfoSize, fileVersionInfo)) return exePath; UINT translationArrayLen = 0; if (!VerQueryValueW(fileVersionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayLen)) return exePath; + + //File descriptor parsing + //TODO: https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getuserpreferreduilanguages + /* It is possible to retrieve user languages and try to use one of those before falling back to whatever + * is available. Also possible to hardcode en-US or any other lang-codepage combo. When an actual translation + * sysem is put in place, I'll come finish this up. + */ + uint64_t availableLangs = (translationArrayLen / sizeof(LANGANDCODEPAGE)); + if (!availableLangs) return exePath; - bool match = false; - for (UINT i = 0; i < (translationArrayLen / sizeof(LANGANDCODEPAGE)); i++) { - wchar_t fileDescriptionKey[256]; + int8_t syslangIdx = -1; + wchar_t metadataStringKey[256]; + wchar_t* metadataString = NULL; + //std::wstring name; + for (UINT i = 0; i < availableLangs; i++) { LANGID defaultUILanguage = GetUserDefaultUILanguage(); if (defaultUILanguage != translationArray[i].wLanguage) continue; - match = true; - wchar_t* fileDescription = NULL; - UINT fileDescriptionSize = 0; - swprintf(fileDescriptionKey, L"\\StringFileInfo\\%04x%04x\\FileDescription", - translationArray[i].wLanguage, translationArray[i].wCodePage); - if (VerQueryValueW(fileVersionInfo, fileDescriptionKey, (LPVOID*)&fileDescription, &fileDescriptionSize)) { - exePath = std::wstring(fileDescription); - } + syslangIdx = i; + break; } - if (!match && 1 <= (translationArrayLen / sizeof(LANGANDCODEPAGE))) { - wchar_t fileDescriptionKey[256]; + UINT metadataStringSize = 0; + swprintf(metadataStringKey, L"\\StringFileInfo\\%04x%04x\\FileDescription", + translationArray[(syslangIdx < 0 ? 0 : syslangIdx)].wLanguage, + translationArray[(syslangIdx < 0 ? 0 : syslangIdx)].wCodePage); + if (VerQueryValueW(fileVersionInfo, metadataStringKey, (LPVOID*)&metadataString, &metadataStringSize) + && metadataString[0] != '\0') { + return std::wstring(metadataString); + } + swprintf(metadataStringKey, L"\\StringFileInfo\\%04x%04x\\ProductName", + translationArray[(syslangIdx < 0 ? 0 : syslangIdx)].wLanguage, + translationArray[(syslangIdx < 0 ? 0 : syslangIdx)].wCodePage); + if (VerQueryValueW(fileVersionInfo, metadataStringKey, (LPVOID*)&metadataString, &metadataStringSize) + && metadataString[0] != '\0') { + return std::wstring(metadataString); + } -wchar_t* fileDescription = NULL; - UINT fileDescriptionSize = 0; - swprintf(fileDescriptionKey, L"\\StringFileInfo\\%04x%04x\\FileDescription", - translationArray[0].wLanguage, translationArray[0].wCodePage); - if (VerQueryValueW(fileVersionInfo, fileDescriptionKey, (LPVOID*)&fileDescription, &fileDescriptionSize)) { - exePath = std::wstring(fileDescription); - } - } + //MSIX? + HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid); + if(!process) return exePath; - free(fileVersionInfo); - return exePath; + //constant missing in mingw64. TB removed when I upgrade to a mingw64 ver that has it + #define APPLICATION_USER_MODEL_ID_MAX_LENGTH 130 + uint32_t length = APPLICATION_USER_MODEL_ID_MAX_LENGTH; + PWSTR userModelId = (PWSTR)malloc(length * sizeof(wchar_t)); + if(GetApplicationUserModelId(process, &length, userModelId) != ERROR_SUCCESS) { + CloseHandle(process); + return exePath; + } + CloseHandle(process); + + static constexpr wchar_t* prefix = L"shell:appsfolder\\"; + uint32_t prefixLen = wcslen(prefix); + uint32_t userModelIdLen = wcslen(userModelId); + wchar_t* fullName; + fullName = (prefixLen + userModelIdLen < length) + ? (wchar_t*)malloc(length * sizeof(wchar_t)) + : (wchar_t*)malloc((length * 2) * sizeof(wchar_t)); + for (int32_t i = prefixLen - 1; i >= 0; i--) { + fullName[i] = prefix[i]; + } + for (uint32_t i = 0; i < userModelIdLen + 1; i++) { + fullName[prefixLen + i] = userModelId[i]; + } + + IShellItem* si; + HRESULT hr = SHCreateItemFromParsingName(fullName, + nullptr, + IID_IShellItem, + (void**)&si + ); + free(fullName); + LPWSTR humanName = nullptr; + si->GetDisplayName(SIGDN_NORMALDISPLAY, &humanName); + if(humanName && humanName[0] != '\0') { + msixName = std::wstring(humanName); + CoTaskMemFree(humanName); + } + if(si) si->Release(); + + if (msixName.length() > 0) + return msixName; + else return exePath; + //free(fileVersionInfo); } //todo: conflicting names. change callback name diff --git a/src/back/msinclude.h b/src/back/msinclude.h index 16216f6..6f21ae1 100644 --- a/src/back/msinclude.h +++ b/src/back/msinclude.h @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include #include diff --git a/src/qt/qtclasses.cpp b/src/qt/qtclasses.cpp index d6b4c48..48b248c 100644 --- a/src/qt/qtclasses.cpp +++ b/src/qt/qtclasses.cpp @@ -263,7 +263,7 @@ void MainWindow::compose() { log_to_file("dpr: %f \n", dpr); for (auto *epw : ews) { if (!epw) continue; - epw->calculateSize(windowWidth * dpr,screenHeight * screen->devicePixelRatio()); + epw->calculateSize(windowWidth, screenHeight); log_debugcpp("epw loop"); log_debugcpp("epw roles: " + print_as_binary((epw->getEndpointHandler()->getRoles()))); //std::bitset content = diff --git a/src/qt/qtcommon.h b/src/qt/qtcommon.h index dc2797b..414e236 100644 --- a/src/qt/qtcommon.h +++ b/src/qt/qtcommon.h @@ -86,7 +86,7 @@ namespace StylingHelper { #endif } - static inline qreal calculateDpi(const QScreen screen) { + static inline qreal calculateDpi() { return QFontMetrics(QApplication::font()).fontDpi(); }