diff --git a/src/back/backsessionclasses.cpp b/src/back/backsessionclasses.cpp index fce5ad8..7349c19 100644 --- a/src/back/backsessionclasses.cpp +++ b/src/back/backsessionclasses.cpp @@ -1,5 +1,6 @@ #include "backsessionclasses.h" #include "backfuncs.h" + Session::Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx) { this->ep = ep; this->sessionControl = sessionControl; @@ -13,7 +14,10 @@ Session::Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx else { LPWSTR sessionDisplayName; this->sessionControl->GetDisplayName(&sessionDisplayName); - this->sessionName = std::wstring(sessionDisplayName); + if (!wcscmp(sessionDisplayName, L"")) + this->sessionName = this->fetchProcessName(pid); + else + this->sessionName = std::wstring(sessionDisplayName); CoTaskMemFree(sessionDisplayName); } } @@ -60,3 +64,86 @@ void Session::setMute(NGuid guid, bool muted) { GUID tempMsGuid = NGuidToGUID(guid); if(FAILED(sessionVolume->SetMute(muted, &tempMsGuid))) { log_wdebugcpp(std::wstring(L"SessionVolume null?")); }; } + +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 + */ + + /* Executable path retrieval */ + std::wstring exePath = L""; + + HANDLE processList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid); + if (processList == INVALID_HANDLE_VALUE) { + log_wdebugcpp(L"aye no procname."); + return exePath; + } + + MODULEENTRY32W me32w; + me32w.dwSize = sizeof(MODULEENTRY32W); + if(Module32FirstW(processList, &me32w)) { + do { + if (me32w.th32ProcessID == pid) { + exePath = std::wstring(me32w.szExePath); + break; + /* + * However, if the calling process is a 32-bit process, you must call the + * QueryFullProcessImageName function to retrieve the full path of the + * executable file for a 64-bit process. + */ + } + } while(Module32NextW(processList, &me32w)); + } + CloseHandle(processList); + + /* File description retrieval */ + struct LANGANDCODEPAGE { + WORD wLanguage; + WORD wCodePage; + } *translationArray; + + DWORD filler; + DWORD fileVersionInfoSize = GetFileVersionInfoSizeW(exePath.c_str(), &filler); + if (!fileVersionInfoSize) return exePath; + + void* fileVersionInfo = malloc(fileVersionInfoSize); + if(!GetFileVersionInfoW(exePath.c_str(),0,fileVersionInfoSize, fileVersionInfo)) + return exePath; + + UINT translationArrayLen = 0; + if (!VerQueryValueW(fileVersionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayLen)) + return exePath; + + bool match = false; + for (UINT i = 0; i < (translationArrayLen / sizeof(LANGANDCODEPAGE)); i++) { + wchar_t fileDescriptionKey[256]; + 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); + } + } + + if (!match && 1 <= (translationArrayLen / sizeof(LANGANDCODEPAGE))) { + wchar_t fileDescriptionKey[256]; + +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); + } + } + + free(fileVersionInfo); + return exePath; +} diff --git a/src/back/backsessionclasses.h b/src/back/backsessionclasses.h index 56e4cfc..369dcab 100644 --- a/src/back/backsessionclasses.h +++ b/src/back/backsessionclasses.h @@ -18,6 +18,7 @@ class Session { //uint32_t getChannelCount(); private: + std::wstring fetchProcessName(DWORD pid); std::wstring sessionName; Endpoint* ep; IAudioSessionControl2* sessionControl = nullptr; diff --git a/src/back/msinclude.h b/src/back/msinclude.h index 6709400..fc7beac 100644 --- a/src/back/msinclude.h +++ b/src/back/msinclude.h @@ -23,3 +23,4 @@ #include #include "ipolicyconfig.h" #include +#include diff --git a/src/global.h b/src/global.h index 008fbc5..1c72212 100644 --- a/src/global.h +++ b/src/global.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "debug.h"