-
Notifications
You must be signed in to change notification settings - Fork 2
/
ObsUtils.cpp
161 lines (144 loc) · 5.16 KB
/
ObsUtils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <QtCore/QDebug>
#include "ObsUtils.hpp"
#ifdef Q_OS_OSX
#include "ObsUtilsOSX.hpp"
#endif
namespace ObsUtils
{
QString getOpenApp(QHash<QString, QString> &appsToWatch)
{
QSet<QString> appsOpen;
#ifdef Q_OS_WIN
EnumWindows(EnumWindowsProcOpenApps, reinterpret_cast<LPARAM>(&appsOpen));
#endif
#ifdef Q_OS_OSX
ObsUtilsOSX::setOpenApps(appsOpen);
#endif
auto end = appsToWatch.cend();
for (auto it = appsToWatch.cbegin(); it != end; ++it)
{
if (appsOpen.contains(it.key()))
{
return it.value();
}
}
return "";
}
QString getFilteredNameFromAppPath(const QString &appPath) {
QString appName = getNameFromAppPath(appPath);
appName.replace("|", "");
appName.replace(":", "");
appName.replace("<", "");
appName.replace(">", "");
appName.replace("?", "");
appName.replace("*", "");
appName.replace("\"", "");
return appName;
}
QString getNameFromAppPath(const QString &appPath) {
#ifdef Q_OS_WIN
const char *exe = appPath.toStdString().c_str();
DWORD dwHandle;
DWORD dwLen = GetFileVersionInfoSizeA(exe, &dwHandle);
if (dwLen != 0)
{
std::vector<unsigned char> data(dwLen);
if (GetFileVersionInfoA(exe, dwHandle, dwLen, &data[0]))
{
// catch default information
VS_FIXEDFILEINFO fileInfo;
LPVOID lpInfo;
UINT unInfoLen;
if (VerQueryValueA(&data[0], "\\", &lpInfo, &unInfoLen))
{
memcpy(&fileInfo, lpInfo, unInfoLen);
}
// find best matching language and codepage
VerQueryValueA(&data[0], "\\VarFileInfo\\Translation", &lpInfo, &unInfoLen);
DWORD dwLangCode = 0;
if (!GetTranslationId(lpInfo, unInfoLen, GetUserDefaultLangID(), dwLangCode, FALSE))
{
if (!GetTranslationId(lpInfo, unInfoLen, GetUserDefaultLangID(), dwLangCode, TRUE))
{
if (!GetTranslationId(lpInfo, unInfoLen, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), dwLangCode, TRUE))
{
if (!GetTranslationId(lpInfo, unInfoLen, MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL), dwLangCode, TRUE))
// use the first one we can get
dwLangCode = *((DWORD*)lpInfo);
}
}
}
CHAR buffer[1024];
std::sprintf(buffer, "\\StringFileInfo\\%04X%04X\\FileDescription", dwLangCode & 0x0000FFFF, (dwLangCode & 0xFFFF0000) >> 16);
if (VerQueryValueA(&data[0], buffer, &lpInfo, &unInfoLen))
{
return QString((char*)lpInfo);
}
else
{
std::sprintf(buffer, "\\StringFileInfo\\%04X%04X\\ProductName", dwLangCode & 0x0000FFFF, (dwLangCode & 0xFFFF0000) >> 16);
if (VerQueryValueA(&data[0], buffer, &lpInfo, &unInfoLen))
{
return QString((char*)lpInfo);
}
}
}
}
QString appFile = appPath.mid(appPath.lastIndexOf("\\") + 1);
#else
QString appFile = appPath.mid(appPath.lastIndexOf("/") + 1);
#endif
if (appFile.endsWith(".exe") || appFile.endsWith(".app"))
{
return appFile.chopped(4);
}
else
{
return appFile;
}
}
#ifdef Q_OS_WIN
BOOL GetTranslationId(LPVOID lpData, UINT unBlockSize, WORD wLangId, DWORD &dwId, BOOL bPrimaryEnough/*= FALSE*/)
{
LPWORD lpwData;
for (lpwData = (LPWORD)lpData; (LPBYTE)lpwData < ((LPBYTE)lpData) + unBlockSize; lpwData += 2)
{
if (*lpwData == wLangId)
{
dwId = *((DWORD*)lpwData);
return TRUE;
}
}
if (!bPrimaryEnough)
return FALSE;
for (lpwData = (LPWORD)lpData; (LPBYTE)lpwData < ((LPBYTE)lpData) + unBlockSize; lpwData += 2)
{
if (((*lpwData) & 0x00FF) == (wLangId & 0x00FF))
{
dwId = *((DWORD*)lpwData);
return TRUE;
}
}
return FALSE;
}
BOOL CALLBACK EnumWindowsProcOpenApps(HWND hwnd, LPARAM lParam)
{
if ((!IsWindowVisible(hwnd) && !IsIconic(hwnd)))
return TRUE;
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess == 0)
return TRUE;
DWORD exe_size = 1024;
CHAR exe[1024];
QueryFullProcessImageNameA(hProcess, 0, exe, &exe_size);
QSet<QString>& appsOpen =
*reinterpret_cast<QSet<QString>*>(lParam);
QString filename(&exe[0]);
appsOpen.insert(filename.mid(filename.lastIndexOf("\\") + 1));
CloseHandle(hProcess);
return TRUE;
}
#endif
}