Og & wip: names
This commit is contained in:
parent
544da49e32
commit
42b30b1bf8
5 changed files with 227 additions and 28 deletions
|
|
@ -1,4 +1,4 @@
|
|||
QMAKE_CXXFLAGS += --target=x86_64-w64-mingw32 -g -gcodeview
|
||||
QMAKE_CXXFLAGS += --target=x86_64-w64-mingw32 -g -gcodeview -Og
|
||||
QMAKE_LFLAGS += --target=x86_64-w64-mingw32 -g -Wl,-pdb= -v
|
||||
LIBS += -LC:/capybara/libclang/x86_64-w64-mingw32/lib -lWinmm -lodbc32 -lodbccp32 -luuid -loleaut32 -lole32 -lshell32 -ladvapi32 -lcomdlg32 -lwinspool -lgdi32 -luser32 -lkernel32 -lpropsys -static -stdlib=libc++ -lunwind
|
||||
#"kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" -luuid -loleaut32 -lole32 -lshell32 -ladvapi32 -lcomdlg32 -lwinspool -lgdi32 -luser32 -lkernel32
|
||||
|
|
|
|||
|
|
@ -126,9 +126,12 @@ Session::Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx
|
|||
else {
|
||||
LPWSTR sessionDisplayName;
|
||||
this->sessionControl->GetDisplayName(&sessionDisplayName);
|
||||
if (!wcscmp(sessionDisplayName, L""))
|
||||
this->sessionName = this->fetchProcessName(pid);
|
||||
else
|
||||
if (!wcscmp(sessionDisplayName, L"")) {
|
||||
std::wstring exePath;
|
||||
if (getExePath(pid, &exePath))
|
||||
fetchName(exePath, pid);
|
||||
else this->sessionName = std::wstring(LSTRING_UNNAMED_SESSION);
|
||||
} else
|
||||
this->sessionName = std::wstring(sessionDisplayName);
|
||||
CoTaskMemFree(sessionDisplayName);
|
||||
}
|
||||
|
|
@ -192,7 +195,7 @@ void Session::setMute(NGuid guid, bool muted) {
|
|||
if(FAILED(sessionVolume->SetMute(muted, &tempMsGuid))) { log_wdebugcpp(std::wstring(L"SessionVolume null?")); };
|
||||
}
|
||||
|
||||
std::wstring Session::fetchProcessName(DWORD pid) {
|
||||
bool Session::getExePath(DWORD pid, std::wstring *exePath) {
|
||||
/*
|
||||
* https://learn.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot
|
||||
* https://stackoverflow.com/questions/11843368/how-to-get-process-description
|
||||
|
|
@ -200,14 +203,12 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
* 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;
|
||||
//std::wstring msixName;
|
||||
|
||||
HANDLE processList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
|
||||
if (processList == INVALID_HANDLE_VALUE) {
|
||||
log_wdebugcpp(L"aye no procname.");
|
||||
return exePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
MODULEENTRY32W me32w;
|
||||
|
|
@ -215,7 +216,7 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
if(Module32FirstW(processList, &me32w)) {
|
||||
do {
|
||||
if (me32w.th32ProcessID == pid) {
|
||||
exePath = std::wstring(me32w.szExePath);
|
||||
*exePath = std::wstring(me32w.szExePath);
|
||||
break;
|
||||
/*
|
||||
* However, if the calling process is a 32-bit process, you must call the
|
||||
|
|
@ -226,7 +227,10 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
} while(Module32NextW(processList, &me32w));
|
||||
}
|
||||
CloseHandle(processList);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Session::fetchNameViaFD(std::wstring exePath, DWORD pid, std::wstring *sessionName) {
|
||||
/* File description retrieval: size and available lang-codepages */
|
||||
struct LANGANDCODEPAGE {
|
||||
WORD wLanguage;
|
||||
|
|
@ -236,16 +240,16 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
DWORD filler;
|
||||
DWORD fileVersionInfoSize = GetFileVersionInfoSizeExW
|
||||
(FILE_VER_GET_LOCALISED | FILE_VER_GET_NEUTRAL, exePath.c_str(), &filler);
|
||||
if (!fileVersionInfoSize) return exePath;
|
||||
if (!fileVersionInfoSize) return false;
|
||||
|
||||
void* fileVersionInfo = malloc(fileVersionInfoSize);
|
||||
if(!GetFileVersionInfoExW(FILE_VER_GET_LOCALISED | FILE_VER_GET_NEUTRAL,
|
||||
exePath.c_str(),0,fileVersionInfoSize, fileVersionInfo))
|
||||
return exePath;
|
||||
return false;
|
||||
|
||||
UINT translationArrayLen = 0;
|
||||
if (!VerQueryValueW(fileVersionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayLen))
|
||||
return exePath;
|
||||
return false;
|
||||
|
||||
//File descriptor parsing
|
||||
//TODO: https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getuserpreferreduilanguages
|
||||
|
|
@ -254,7 +258,7 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
* sysem is put in place, I'll come finish this up.
|
||||
*/
|
||||
uint64_t availableLangs = (translationArrayLen / sizeof(LANGANDCODEPAGE));
|
||||
if (!availableLangs) return exePath;
|
||||
if (!availableLangs) { free(fileVersionInfo); return false; }
|
||||
|
||||
int8_t syslangIdx = -1;
|
||||
wchar_t metadataStringKey[256];
|
||||
|
|
@ -275,19 +279,30 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
translationArray[(syslangIdx < 0 ? 0 : syslangIdx)].wCodePage);
|
||||
if (VerQueryValueW(fileVersionInfo, metadataStringKey, (LPVOID*)&metadataString, &metadataStringSize)
|
||||
&& metadataString[0] != '\0') {
|
||||
return std::wstring(metadataString);
|
||||
free(fileVersionInfo);
|
||||
*sessionName = std::wstring(metadataString);
|
||||
return true;
|
||||
}
|
||||
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);
|
||||
free(fileVersionInfo);
|
||||
*sessionName = std::wstring(metadataString);
|
||||
return true;
|
||||
}
|
||||
|
||||
//MSIX?
|
||||
if(fileVersionInfo)
|
||||
free(fileVersionInfo);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Session::fetchNameViaMSIX(std::wstring exePath, DWORD pid, std::wstring *sessionName) {
|
||||
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
||||
if(!process) return exePath;
|
||||
if(!process) return false;
|
||||
|
||||
//constant missing in mingw64. TB removed when I upgrade to a mingw64 ver that has it
|
||||
#define APPLICATION_USER_MODEL_ID_MAX_LENGTH 130
|
||||
|
|
@ -295,7 +310,7 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
PWSTR userModelId = (PWSTR)malloc(length * sizeof(wchar_t));
|
||||
if(GetApplicationUserModelId(process, &length, userModelId) != ERROR_SUCCESS) {
|
||||
CloseHandle(process);
|
||||
return exePath;
|
||||
return false;
|
||||
}
|
||||
CloseHandle(process);
|
||||
|
||||
|
|
@ -323,17 +338,190 @@ std::wstring Session::fetchProcessName(DWORD pid) {
|
|||
LPWSTR humanName = nullptr;
|
||||
si->GetDisplayName(SIGDN_NORMALDISPLAY, &humanName);
|
||||
if(humanName && humanName[0] != '\0') {
|
||||
msixName = std::wstring(humanName);
|
||||
*sessionName = std::wstring(humanName);
|
||||
CoTaskMemFree(humanName);
|
||||
}
|
||||
if(si) si->Release();
|
||||
|
||||
if (msixName.length() > 0)
|
||||
return msixName;
|
||||
else return exePath;
|
||||
//free(fileVersionInfo);
|
||||
if (sessionName->length() > 0)
|
||||
return true;
|
||||
else return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
BOOL test(HWND hwnd, LPARAM lParam) {
|
||||
int length = GetWindowTextLength(hwnd);
|
||||
wchar_t* buffer = new wchar_t[length + 1];
|
||||
GetWindowTextW(hwnd, buffer, length + 1);
|
||||
std::wstring windowTitle(buffer);
|
||||
delete[] buffer;
|
||||
|
||||
// List visible windows with a non-empty title
|
||||
if (IsWindowVisible(hwnd) && length != 0) {
|
||||
//std::wcout << hwnd << ": " << windowTitle << std::endl;
|
||||
log_wdebugcpp(windowTitle);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
* auto pParams = (DWORD)(lParam);
|
||||
*
|
||||
* DWORD processId;
|
||||
* if (GetWindowThreadProcessId(hwnd, &processId) && processId == pParams) {
|
||||
* // Stop enumerating
|
||||
* //SetLastError(-1);
|
||||
* //pParams->first = hwnd;
|
||||
* //return FALSE;
|
||||
* }
|
||||
*
|
||||
* // Continue enumerating
|
||||
* return TRUE;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
bool Session::fetchNameViaWindowName(std::wstring exePath, DWORD pid, std::wstring *sessionName) {
|
||||
std::pair<HWND, DWORD> params = { 0, pid };
|
||||
|
||||
BOOL result = EnumWindows(test, NULL);
|
||||
|
||||
/*
|
||||
* if (!params.first) goto msix;
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* if (!result && GetLastError() == -1 && params.first) {
|
||||
* return params.first;
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
||||
void Session::fetchName(std::wstring exePath, DWORD pid) {
|
||||
if(fetchNameViaWindowName(exePath, pid, &this->sessionName))
|
||||
return;
|
||||
else if(fetchNameViaMSIX(exePath, pid, &this->sessionName))
|
||||
return;
|
||||
else if(!fetchNameViaFD(exePath, pid, &this->sessionName))
|
||||
this->sessionName = exePath;
|
||||
|
||||
/*
|
||||
* std::thread ttest(&Session::fetchNameViaWindowName, this, exePath, pid, &this->sessionName);
|
||||
* ttest.join();
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* std::wstring Session::fetchProcessName(DWORD pid) {
|
||||
* /\* 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.");
|
||||
* 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);
|
||||
*
|
||||
*
|
||||
* //No FD info available. Window name?
|
||||
* nofdinfo:
|
||||
* if(fileVersionInfo)
|
||||
* free(fileVersionInfo);
|
||||
*
|
||||
* std::pair<HWND, DWORD> params = { 0, pid };
|
||||
* BOOL result = EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
|
||||
* auto pParams = (std::pair<HWND, DWORD>*)(lParam);
|
||||
*
|
||||
* DWORD processId;
|
||||
* if (GetWindowThreadProcessId(hwnd, &processId) && processId == pParams->second) {
|
||||
* // Stop enumerating
|
||||
* SetLastError(-1);
|
||||
* pParams->first = hwnd;
|
||||
* return FALSE;
|
||||
* }
|
||||
*
|
||||
* // Continue enumerating
|
||||
* return TRUE;
|
||||
* }, (LPARAM)¶ms);
|
||||
*
|
||||
* if (!params.first) goto msix;
|
||||
*
|
||||
*
|
||||
* /\*
|
||||
* * if (!result && GetLastError() == -1 && params.first) {
|
||||
* * return params.first;
|
||||
* * }
|
||||
* *\/
|
||||
*
|
||||
* //No window info. MSIX?
|
||||
* HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
||||
* if(!process) 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;
|
||||
* }
|
||||
*/
|
||||
|
||||
//todo: conflicting names. change callback name
|
||||
void Session::setState(SessionState state) {
|
||||
sessionState = state;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "global.h"
|
||||
#include "contclasses.h"
|
||||
|
||||
#include <thread>
|
||||
class Endpoint;
|
||||
|
||||
class SessionStateCallback : public IAudioSessionEvents {
|
||||
|
|
@ -47,7 +48,12 @@ class Session {
|
|||
//uint32_t getChannelCount();
|
||||
|
||||
private:
|
||||
std::wstring fetchProcessName(DWORD pid);
|
||||
bool getExePath(DWORD pid, /*out*/ std::wstring *exePath);
|
||||
void fetchName(std::wstring exePath, DWORD pid);
|
||||
bool fetchNameViaFD(std::wstring exePath, DWORD pid, /*out*/ std::wstring *sessionName);
|
||||
bool fetchNameViaMSIX(std::wstring exePath, DWORD pid, /*out*/ std::wstring *sessionName);
|
||||
bool fetchNameViaWindowName(std::wstring exePath, DWORD pid, /*out*/ std::wstring *sessionName);
|
||||
/* std::wstring fetchProcessName(DWORD pid); */
|
||||
std::wstring sessionName;
|
||||
SessionState sessionState;
|
||||
Endpoint* ep;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#define STRING_CP "Open Control Panel"
|
||||
#define STRING_ABOUT "About"
|
||||
#define STRING_STARTUP "Run at startup"
|
||||
|
||||
#define LSTRING_UNNAMED_SESSION L"Unnamed session"
|
||||
//INIT BACK
|
||||
|
||||
enum AudioChannel {
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent)
|
|||
|
||||
muteButton = new QCheckBox(this);
|
||||
mainLabel = new QLabel(QString::fromStdWString(sh->getName()), this);
|
||||
mainLabel->setToolTip(QString::fromStdWString(sh->getName()));
|
||||
mainSlider = new MeterSlider(Qt::Horizontal, this);
|
||||
|
||||
//mainLabel->setMaximumWidth(150 /*1/16ish 1080p*/);
|
||||
|
|
@ -368,8 +369,10 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent)
|
|||
connect(volumePoller, &QTimer::timeout, [this, sh](){
|
||||
//if (memcmp(osh->callbackInfo[idx]->caller, osh->getGuid(), sizeof(NGuid)) == 0) return; CHECK IF THIS PROGRAM GENERATED THE FUNSIES IS NO LONGER IN USE FOR NOW.
|
||||
//todo: global + constexpr + ratio
|
||||
if (sh->getVolumeInfo()->isNameChanged)
|
||||
if (sh->getVolumeInfo()->isNameChanged) {
|
||||
mainLabel->setText(QString::fromStdWString(sh->getName()));
|
||||
mainLabel->setToolTip(QString::fromStdWString(sh->getName()));
|
||||
}
|
||||
const float roundingFactor = 0.005;
|
||||
mainSlider->blockSignals(true);
|
||||
muteButton->blockSignals(true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue