6 #include <QCoreApplication>
13 # include <tlhelp32.h>
21 namespace PrivateWindows
23 struct LanguageCodePage
29 QString languageToIsoCode(LanguageCodePage codePage)
31 const LCID locale = codePage.wLanguage;
32 const int nchars = GetLocaleInfo(locale, LOCALE_SISO639LANGNAME,
nullptr, 0);
33 std::vector<wchar_t> language(
static_cast<size_t>(nchars));
34 GetLocaleInfo(locale, LOCALE_SISO639LANGNAME, language.data(), nchars);
35 const QString iso = QString::fromWCharArray(language.data(), nchars);
39 QString queryStringFileInfo(BYTE *pbVersionInfo, LanguageCodePage codePage,
const QString &stringName)
41 constexpr
int fieldWidth = 4;
42 constexpr
int base = 16;
43 QString subBlockNameBuffer = QStringLiteral(
"\\StringFileInfo\\%1%2\\%3")
44 .arg(codePage.wLanguage, fieldWidth, base, QLatin1Char(
'0'))
45 .arg(codePage.wCodePage, fieldWidth, base, QLatin1Char(
'0'))
48 wchar_t *szQueryString =
nullptr;
49 VerQueryValue(pbVersionInfo, subBlockNameBuffer.toStdWString().c_str(),
50 reinterpret_cast<LPVOID *
>(&szQueryString), &dwBytes);
51 const QString queryString = QString::fromWCharArray(szQueryString, dwBytes);
60 const QFile dllQFile(dllFile);
61 if (!dllQFile.exists())
63 result.errorMsg = QStringLiteral(
"No file '%1'").arg(dllFile);
66 const QString dll(QDir::toNativeSeparators(dllFile));
69 const std::wstring dllStr(dll.toStdWString());
72 UINT puLenFileInfo = 0;
73 const TCHAR *pszFilePath = dllStr.c_str();
74 VS_FIXEDFILEINFO *pFileInfo =
nullptr;
77 dwSize = GetFileVersionInfoSize(pszFilePath,
nullptr);
80 result.errorMsg = QStringLiteral(
"Error in GetFileVersionInfoSize: %1\n").arg(GetLastError());
84 std::vector<BYTE> pbVersionInfo(dwSize);
85 if (!GetFileVersionInfo(pszFilePath, 0, dwSize, pbVersionInfo.data()))
87 result.errorMsg = QStringLiteral(
"Error in GetFileVersionInfo: %1\n").arg(GetLastError());
92 if (!VerQueryValue(pbVersionInfo.data(), TEXT(
"\\"),
reinterpret_cast<LPVOID *
>(&pFileInfo), &puLenFileInfo))
94 result.errorMsg = QStringLiteral(
"Error in VerQueryValue: %1\n").arg(GetLastError());
100 result.fileVersion = QStringLiteral(
"%1.%2.%3.%4")
101 .arg((pFileInfo->dwFileVersionMS >> 16) & 0xffff)
102 .arg((pFileInfo->dwFileVersionMS >> 0) & 0xffff)
103 .arg((pFileInfo->dwFileVersionLS >> 16) & 0xffff)
104 .arg((pFileInfo->dwFileVersionLS >> 0) & 0xffff);
108 result.productVersion = QStringLiteral(
"%1.%2.%3.%4")
109 .arg((pFileInfo->dwProductVersionMS >> 16) & 0xffff)
110 .arg((pFileInfo->dwProductVersionMS >> 0) & 0xffff)
111 .arg((pFileInfo->dwProductVersionLS >> 16) & 0xffff)
112 .arg((pFileInfo->dwProductVersionLS >> 0) & 0xffff);
114 PrivateWindows::LanguageCodePage *lpTranslate;
117 VerQueryValue(pbVersionInfo.data(), TEXT(
"\\VarFileInfo\\Translation"),
118 reinterpret_cast<LPVOID *
>(&lpTranslate), &puLenFileInfo);
122 for (UINT i = 0; i < (puLenFileInfo /
sizeof(
struct PrivateWindows::LanguageCodePage)); i++)
125 const PrivateWindows::LanguageCodePage cp = lpTranslate[i];
126 result.iso = PrivateWindows::languageToIsoCode(cp);
127 result.fileDescription =
128 PrivateWindows::queryStringFileInfo(pbVersionInfo.data(), cp, QStringLiteral(
"FileDescription"));
130 PrivateWindows::queryStringFileInfo(pbVersionInfo.data(), cp, QStringLiteral(
"ProductName"));
131 result.productVersionName =
132 PrivateWindows::queryStringFileInfo(pbVersionInfo.data(), cp, QStringLiteral(
"ProductVersion"));
133 result.originalFilename =
134 PrivateWindows::queryStringFileInfo(pbVersionInfo.data(), cp, QStringLiteral(
"OriginalFilename"));
135 result.fullFilename = dllQFile.fileName();
147 QList<CWinDllUtils::ProcessModule> results;
149 const DWORD dwPID =
static_cast<DWORD>(processId < 0 ? QCoreApplication::applicationPid() : processId);
150 HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
154 hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
155 if (hModuleSnap == INVALID_HANDLE_VALUE)
162 me32.dwSize =
sizeof(MODULEENTRY32);
166 if (!Module32First(hModuleSnap, &me32))
169 CloseHandle(hModuleSnap);
177 pm.moduleName = QString::fromWCharArray(
static_cast<const wchar_t *
>(&me32.szModule[0]));
178 if (nameFilter.isEmpty() || pm.moduleName.contains(nameFilter, Qt::CaseInsensitive))
180 pm.executable = QString::fromWCharArray(
static_cast<const wchar_t *
>(&me32.szExePath[0]));
181 pm.processId =
static_cast<qint64
>(me32.th32ProcessID);
183 if (!nameFilter.isEmpty()) {
break; }
186 while (Module32Next(hModuleSnap, &me32));
188 CloseHandle(hModuleSnap);
198 result.
errorMsg = QString(
"Only works on Windows");
205 Q_UNUSED(nameFilter);
206 static const QList<CWinDllUtils::ProcessModule> results;
static DLLInfo getDllInfo(const QString &dllFile)
Get DDL.
static QList< ProcessModule > getModules(qint64 processId=-1, const QString &nameFilter={})
Process modules per id.
Free functions in swift::misc.
unsigned long DWORD
Fake Windows DWORD.
QString errorMsg
error message if any