/* * (C) 2011-2013 see Authors.txt * * This file is part of MPC-HC. * * MPC-HC is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * MPC-HC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "stdafx.h" #include #include "WinAPIUtils.h" #include "SysVersion.h" bool SetPrivilege(LPCTSTR privilege, bool bEnable) { HANDLE hToken; TOKEN_PRIVILEGES tkp; SetThreadExecutionState(ES_CONTINUOUS); // Get a token for this process. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return false; } // Get the LUID for the privilege. LookupPrivilegeValue(nullptr, privilege, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; // Set the privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)nullptr, 0); return (GetLastError() == ERROR_SUCCESS); } CString GetHiveName(HKEY hive) { switch ((ULONG_PTR)hive) { case (ULONG_PTR)HKEY_CLASSES_ROOT: return _T("HKEY_CLASSES_ROOT"); case (ULONG_PTR)HKEY_CURRENT_USER: return _T("HKEY_CURRENT_USER"); case (ULONG_PTR)HKEY_LOCAL_MACHINE: return _T("HKEY_LOCAL_MACHINE"); case (ULONG_PTR)HKEY_USERS: return _T("HKEY_USERS"); case (ULONG_PTR)HKEY_PERFORMANCE_DATA: return _T("HKEY_PERFORMANCE_DATA"); case (ULONG_PTR)HKEY_CURRENT_CONFIG: return _T("HKEY_CURRENT_CONFIG"); case (ULONG_PTR)HKEY_DYN_DATA: return _T("HKEY_DYN_DATA"); case (ULONG_PTR)HKEY_PERFORMANCE_TEXT: return _T("HKEY_PERFORMANCE_TEXT"); case (ULONG_PTR)HKEY_PERFORMANCE_NLSTEXT: return _T("HKEY_PERFORMANCE_NLSTEXT"); default: return _T(""); } } bool ExportRegistryKey(CStdioFile& file, HKEY hKeyRoot, CString keyName) { // Registry functions don't set GetLastError(), so it needs to be set explicitly LSTATUS errorCode = ERROR_SUCCESS; HKEY hKey = nullptr; errorCode = RegOpenKeyEx(hKeyRoot, keyName, 0, KEY_READ, &hKey); if (errorCode != ERROR_SUCCESS) { SetLastError(errorCode); return false; } DWORD subKeysCount = 0, maxSubKeyLen = 0; DWORD valuesCount = 0, maxValueNameLen = 0, maxValueDataLen = 0; errorCode = RegQueryInfoKey(hKey, nullptr, nullptr, nullptr, &subKeysCount, &maxSubKeyLen, nullptr, &valuesCount, &maxValueNameLen, &maxValueDataLen, nullptr, nullptr); if (errorCode != ERROR_SUCCESS) { SetLastError(errorCode); return false; } maxSubKeyLen += 1; maxValueNameLen += 1; CString buffer; buffer.Format(_T("[%s\\%s]\n"), GetHiveName(hKeyRoot), keyName); file.WriteString(buffer); CString valueName; DWORD valueNameLen, valueDataLen, type; BYTE* data = DEBUG_NEW BYTE[maxValueDataLen]; for (DWORD indexValue = 0; indexValue < valuesCount; indexValue++) { valueNameLen = maxValueNameLen; valueDataLen = maxValueDataLen; errorCode = RegEnumValue(hKey, indexValue, valueName.GetBuffer(maxValueNameLen), &valueNameLen, nullptr, &type, data, &valueDataLen); if (errorCode != ERROR_SUCCESS) { SetLastError(errorCode); return false; } switch (type) { case REG_SZ: { CString str((TCHAR*)data); str.Replace(_T("\\"), _T("\\\\")); str.Replace(_T("\""), _T("\\\"")); buffer.Format(_T("\"%s\"=\"%s\"\n"), valueName, str); file.WriteString(buffer); } break; case REG_BINARY: buffer.Format(_T("\"%s\"=hex:%02x"), valueName, data[0]); file.WriteString(buffer); for (DWORD i = 1; i < valueDataLen; i++) { buffer.Format(_T(",%02x"), data[i]); file.WriteString(buffer); } file.WriteString(_T("\n")); break; case REG_DWORD: buffer.Format(_T("\"%s\"=dword:%08x\n"), valueName, *((DWORD*)data)); file.WriteString(buffer); break; default: { CString msg; msg.Format(_T("The value \"%s\\%s\\%s\" has an unsupported type and has been ignored.\nPlease report this error to the developers."), GetHiveName(hKeyRoot), keyName, valueName); AfxMessageBox(msg, MB_ICONERROR | MB_OK); } delete [] data; return false; } } delete [] data; file.WriteString(_T("\n")); CString subKeyName; DWORD subKeyLen; for (DWORD indexSubKey = 0; indexSubKey < subKeysCount; indexSubKey++) { subKeyLen = maxSubKeyLen; errorCode = RegEnumKeyEx(hKey, indexSubKey, subKeyName.GetBuffer(maxSubKeyLen), &subKeyLen, nullptr, nullptr, nullptr, nullptr); if (errorCode != ERROR_SUCCESS) { SetLastError(errorCode); return false; } buffer.Format(_T("%s\\%s"), keyName, subKeyName); if (!ExportRegistryKey(file, hKeyRoot, buffer)) { return false; } } errorCode = RegCloseKey(hKey); SetLastError(errorCode); return true; } UINT GetAdapter(IDirect3D9* pD3D, HWND hWnd) { if (hWnd == nullptr || pD3D == nullptr) { return D3DADAPTER_DEFAULT; } HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); if (hMonitor == nullptr) { return D3DADAPTER_DEFAULT; } for (UINT adp = 0, num_adp = pD3D->GetAdapterCount(); adp < num_adp; ++adp) { HMONITOR hAdpMon = pD3D->GetAdapterMonitor(adp); if (hAdpMon == hMonitor) { return adp; } } return D3DADAPTER_DEFAULT; } int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX* /*lpelfe*/, NEWTEXTMETRICEX* /*lpntme*/, int /*FontType*/, LPARAM lParam) { LPARAM* l = (LPARAM*)lParam; *l = TRUE; return TRUE; } void GetMessageFont(LOGFONT* lf) { SecureZeroMemory(lf, sizeof(LOGFONT)); NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(NONCLIENTMETRICS); if (!SysVersion::IsVistaOrLater()) { ncm.cbSize -= sizeof(ncm.iPaddedBorderWidth); } SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); *lf = ncm.lfMessageFont; } void GetStatusFont(LOGFONT* lf) { SecureZeroMemory(lf, sizeof(LOGFONT)); NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(NONCLIENTMETRICS); if (!SysVersion::IsVistaOrLater()) { ncm.cbSize -= sizeof(ncm.iPaddedBorderWidth); } SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); *lf = ncm.lfStatusFont; } bool IsFontInstalled(LPCTSTR lpszFont) { // Get the screen DC CDC dc; if (!dc.CreateCompatibleDC(nullptr)) { return false; } LOGFONT lf = {0}; // Any character set will do lf.lfCharSet = DEFAULT_CHARSET; // Set the facename to check for _tcscpy_s(lf.lfFaceName, lpszFont); LPARAM lParam = 0; // Enumerate fonts EnumFontFamiliesEx(dc.GetSafeHdc(), &lf, (FONTENUMPROC)EnumFontFamExProc, (LPARAM)&lParam, 0); return lParam ? true : false; } bool ExploreToFile(LPCTSTR path) { bool success = false; HRESULT res = CoInitialize(nullptr); if (res == S_OK || res == S_FALSE) { PIDLIST_ABSOLUTE pidl; if (SHParseDisplayName(path, nullptr, &pidl, 0, nullptr) == S_OK) { success = SUCCEEDED(SHOpenFolderAndSelectItems(pidl, 0, nullptr, 0)); CoTaskMemFree(pidl); } CoUninitialize(); } return success; } bool FileExists(LPCTSTR fileName) { return (INVALID_FILE_ATTRIBUTES != ::GetFileAttributes(fileName)); } CString GetProgramPath(bool bWithExecutableName /*= false*/) { CString path; DWORD dwLength = ::GetModuleFileName(nullptr, path.GetBuffer(MAX_PATH), MAX_PATH); path.ReleaseBuffer((int)dwLength); if (!bWithExecutableName) { path = path.Left(path.ReverseFind(_T('\\')) + 1); } return path; }