DXGL r413 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r412‎ | r413 | r414 >
Date:17:19, 29 March 2014
Author:admin
Status:new
Tags:
Comment:
Move registry management to functions AddCompatFlag (incomplete) and DelCompatFlag.
Fix registry permission error deleting compatibility flags.
Modified paths:
  • /cfgmgr/cfgmgr.cpp (modified) (history)

Diff [purge]

Index: cfgmgr/cfgmgr.cpp
@@ -32,12 +32,201 @@
3333 TCHAR regkeybase[] = _T("Software\\DXGL\\");
3434
3535 DXGLCFG defaultmask;
 36+UINT_PTR timerid;
3637
 38+INT_PTR CALLBACK CompatDialogCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 39+{
 40+ switch (Msg)
 41+ {
 42+ case WM_INITDIALOG:
 43+ timerid = SetTimer(hWnd, NULL, 5000, NULL);
 44+ return TRUE;
 45+ case WM_TIMER:
 46+ if (wParam == timerid) EndDialog(hWnd, 0);
 47+ break;
 48+ default:
 49+ return FALSE;
 50+ }
 51+}
 52+
 53+void ShowRestartDialog()
 54+{
 55+ BOOL(*_GetModuleHandleEx)(DWORD dwFlags, LPCTSTR lpModuleName, HMODULE* phModule) = FALSE;
 56+ HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
 57+ HMODULE hddraw;
 58+ if (hKernel32) _GetModuleHandleEx = (BOOL(*)(DWORD,LPCTSTR,HMODULE*))GetProcAddress(hKernel32, "GetModuleHandleEx");
 59+ if (_GetModuleHandleEx) _GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)ShowRestartDialog, &hddraw);
 60+ else hddraw = GetModuleHandle(_T("ddraw.dll")); //For old versions of Windows, may fail but they shouldn't have AppCompat anyways.
 61+ if (hKernel32) FreeLibrary(hKernel32);
 62+ DialogBox(hddraw, MAKEINTRESOURCE(IDD_COMPAT), NULL, CompatDialogCallback);
 63+ LPTSTR cmdline = GetCommandLine();
 64+ LPTSTR cmdline2 = (LPTSTR)malloc((_tcslen(cmdline) + 1)*sizeof(TCHAR));
 65+ _tcscpy(cmdline2, cmdline);
 66+ STARTUPINFO startupinfo;
 67+ PROCESS_INFORMATION procinfo;
 68+ ZeroMemory(&startupinfo, sizeof(STARTUPINFO));
 69+ startupinfo.cb = sizeof(STARTUPINFO);
 70+ CreateProcess(NULL, cmdline2, NULL, NULL, FALSE, 0, NULL, NULL, &startupinfo, &procinfo);
 71+ CloseHandle(procinfo.hProcess);
 72+ CloseHandle(procinfo.hThread);
 73+ free(cmdline2);
 74+ ExitProcess(0);
 75+}
 76+
3777 bool AddCompatFlag(LPTSTR flag)
3878 {
 79+ HKEY hKey;
 80+ HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
 81+ BOOL(WINAPI *iswow64)(HANDLE, PBOOL) = NULL;
 82+ if (hKernel32) iswow64 = (BOOL(WINAPI*)(HANDLE, PBOOL))GetProcAddress(hKernel32, "IsWow64Process");
 83+ BOOL is64 = FALSE;
 84+ if (iswow64) iswow64(GetCurrentProcess(), &is64);
 85+ if (hKernel32) FreeLibrary(hKernel32);
 86+ LRESULT error;
 87+ TCHAR filename[MAX_PATH + 1];
 88+ TCHAR buffer[1024];
 89+ TCHAR *bufferpos;
3990
 91+ return false;
4092 }
4193
 94+bool DelCompatFlag(LPTSTR flag)
 95+{
 96+ HKEY hKey;
 97+ HKEY hKeyWrite;
 98+ HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
 99+ BOOL(WINAPI *iswow64)(HANDLE, PBOOL) = NULL;
 100+ if (hKernel32) iswow64 = (BOOL(WINAPI*)(HANDLE, PBOOL))GetProcAddress(hKernel32, "IsWow64Process");
 101+ BOOL is64 = FALSE;
 102+ if (iswow64) iswow64(GetCurrentProcess(), &is64);
 103+ if (hKernel32) FreeLibrary(hKernel32);
 104+ LRESULT error;
 105+ TCHAR filename[MAX_PATH + 1];
 106+ TCHAR buffer[1024];
 107+ TCHAR *bufferpos;
 108+ tstring writekey;
 109+ bool accessdenied = false;
 110+ // Check system first.
 111+ if (is64) writekey.assign(_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"));
 112+ else writekey.assign(_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"));
 113+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, writekey.c_str(), 0, KEY_READ, &hKey);
 114+ if (error == ERROR_SUCCESS)
 115+ {
 116+ GetModuleFileName(NULL, filename, MAX_PATH);
 117+ ZeroMemory(buffer, 1024 * sizeof(TCHAR));
 118+ DWORD sizeout = 1024 * sizeof(TCHAR);
 119+ if (RegQueryValueEx(hKey, filename, NULL, NULL, (LPBYTE)buffer, &sizeout) == ERROR_SUCCESS)
 120+ {
 121+ bufferpos = _tcsstr(buffer, flag);
 122+ if (bufferpos)
 123+ {
 124+ memmove(bufferpos, bufferpos + _tcslen(flag), (_tcslen(bufferpos + _tcslen(flag)))*sizeof(TCHAR));
 125+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, writekey.c_str(), 0, KEY_WRITE, &hKeyWrite);
 126+ if (error == ERROR_SUCCESS)
 127+ {
 128+ error = RegSetValueEx(hKeyWrite, filename, 0, REG_SZ, (BYTE*)buffer, (_tcslen(bufferpos + _tcslen(flag)))*sizeof(TCHAR)+sizeof(TCHAR));
 129+ RegCloseKey(hKeyWrite);
 130+ }
 131+ if (error == ERROR_ACCESS_DENIED)
 132+ {
 133+ if (MessageBox(NULL, _T("DXGL has detected an incompatible AppCompat flag for the program you are currently running and requires administrative rights to remove it.\nWould you like to continue?"),
 134+ _T("AppCompat error"), MB_YESNO | MB_ICONWARNING) == IDYES)
 135+ {
 136+ tstring command;
 137+ if (is64) command.assign(_T("ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers\" /reg:64 /f /v \""));
 138+ else command.assign(_T("ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers\" /f /v \""));
 139+ command.append(filename);
 140+ command.append(_T("\" /t REG_SZ /d \""));
 141+ command.append(buffer);
 142+ command.append(_T("\""));
 143+ SHELLEXECUTEINFO info;
 144+ ZeroMemory(&info, sizeof(SHELLEXECUTEINFO));
 145+ info.cbSize = sizeof(SHELLEXECUTEINFO);
 146+ info.lpVerb = _T("runas");
 147+ info.lpFile = _T("reg.exe");
 148+ info.lpParameters = command.c_str();
 149+ info.nShow = SW_SHOWNORMAL;
 150+ info.fMask = SEE_MASK_NOCLOSEPROCESS;
 151+ ShellExecuteEx(&info);
 152+ WaitForSingleObject(info.hProcess, INFINITE);
 153+ GetExitCodeProcess(info.hProcess, (LPDWORD)&error);
 154+ }
 155+ if (!error)
 156+ {
 157+ ShowRestartDialog();
 158+ }
 159+ else MessageBox(NULL, _T("Registry value could not be updated. Your program may crash as a result."), _T("Error"), MB_OK | MB_ICONWARNING);
 160+ return false;
 161+ }
 162+ else if (error == ERROR_SUCCESS)
 163+ {
 164+ ShowRestartDialog();
 165+ }
 166+ }
 167+ }
 168+ RegCloseKey(hKey);
 169+ }
 170+ // Next check user.
 171+ writekey.assign(_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"));
 172+ error = RegOpenKeyEx(HKEY_CURRENT_USER, writekey.c_str(), 0, KEY_READ, &hKey);
 173+ if (error == ERROR_SUCCESS)
 174+ {
 175+ GetModuleFileName(NULL, filename, MAX_PATH);
 176+ ZeroMemory(buffer, 1024 * sizeof(TCHAR));
 177+ DWORD sizeout = 1024 * sizeof(TCHAR);
 178+ if (RegQueryValueEx(hKey, filename, NULL, NULL, (LPBYTE)buffer, &sizeout) == ERROR_SUCCESS)
 179+ {
 180+ bufferpos = _tcsstr(buffer, flag);
 181+ if (bufferpos)
 182+ {
 183+ memmove(bufferpos, bufferpos + _tcslen(flag), (_tcslen(bufferpos + _tcslen(flag)))*sizeof(TCHAR));
 184+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, writekey.c_str(), 0, KEY_WRITE, &hKeyWrite);
 185+ if (error == ERROR_SUCCESS)
 186+ {
 187+ error = RegSetValueEx(hKeyWrite, filename, 0, REG_SZ, (BYTE*)buffer, (_tcslen(bufferpos + _tcslen(flag)))*sizeof(TCHAR)+sizeof(TCHAR));
 188+ RegCloseKey(hKeyWrite);
 189+ }
 190+ if (error == ERROR_ACCESS_DENIED)
 191+ {
 192+ if (MessageBox(NULL, _T("DXGL has detected an incompatible AppCompat flag for the program you are currently running and requires administrative rights to remove it.\nWould you like to continue?"),
 193+ _T("AppCompat error"), MB_YESNO | MB_ICONWARNING) == IDYES)
 194+ {
 195+ tstring command;
 196+ command.assign(_T("ADD \"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers\" /f /v \""));
 197+ command.append(filename);
 198+ command.append(_T("\" /t REG_SZ /d \""));
 199+ command.append(buffer);
 200+ command.append(_T("\""));
 201+ SHELLEXECUTEINFO info;
 202+ ZeroMemory(&info, sizeof(SHELLEXECUTEINFO));
 203+ info.cbSize = sizeof(SHELLEXECUTEINFO);
 204+ info.lpVerb = _T("runas");
 205+ info.lpFile = _T("reg.exe");
 206+ info.lpParameters = command.c_str();
 207+ info.nShow = SW_SHOWNORMAL;
 208+ info.fMask = SEE_MASK_NOCLOSEPROCESS;
 209+ ShellExecuteEx(&info);
 210+ WaitForSingleObject(info.hProcess, INFINITE);
 211+ GetExitCodeProcess(info.hProcess, (LPDWORD)&error);
 212+ }
 213+ if (!error)
 214+ {
 215+ ShowRestartDialog();
 216+ }
 217+ else MessageBox(NULL, _T("Registry value could not be updated. Your program may crash as a result."), _T("Error"), MB_OK | MB_ICONWARNING);
 218+ return false;
 219+ }
 220+ else if (error == ERROR_SUCCESS)
 221+ {
 222+ ShowRestartDialog();
 223+ }
 224+ }
 225+ }
 226+ RegCloseKey(hKey);
 227+ }
 228+ return true;
 229+}
 230+
42231 void GetDirFromPath(LPTSTR path)
43232 {
44233 int len = _tcslen(path);
@@ -342,6 +531,8 @@
343532 HMODULE hUser32 = NULL;
344533 if (initial)
345534 {
 535+ if (cfg->DPIScale == 2) AddCompatFlag(_T("HIGHDPIAWARE"));
 536+ else DelCompatFlag(_T("HIGHDPIAWARE"));
346537 if (cfg->DPIScale == 1)
347538 {
348539 bool DPIAwarePM = false;
@@ -369,101 +560,7 @@
370561 if (hSHCore) FreeLibrary(hSHCore);
371562 if (hUser32) FreeLibrary(hUser32);
372563 }
373 - HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
374 - BOOL (WINAPI *iswow64)(HANDLE,PBOOL) = NULL;
375 - if(hKernel32) iswow64 = (BOOL(WINAPI*)(HANDLE,PBOOL))GetProcAddress(hKernel32,"IsWow64Process");
376 - BOOL is64 = FALSE;
377 - if(iswow64) iswow64(GetCurrentProcess(),&is64);
378 - if(hKernel32) FreeLibrary(hKernel32);
379 - LRESULT error;
380 - if(is64) error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"),0,KEY_READ|KEY_WOW64_64KEY,&hKey);
381 - else error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"),0,KEY_READ,&hKey);
382 - if(error == ERROR_SUCCESS)
383 - {
384 - GetModuleFileName(NULL,filename,MAX_PATH);
385 - TCHAR buffer[1024];
386 - ZeroMemory(buffer,1024*sizeof(TCHAR));
387 - DWORD sizeout = 1024*sizeof(TCHAR);
388 - if(RegQueryValueEx(hKey,filename,NULL,NULL,(LPBYTE)buffer,&sizeout) == ERROR_SUCCESS)
389 - {
390 - if(_tcsstr(buffer,_T("DWM8And16BitMitigation")))
391 - {
392 - MessageBox(NULL,_T("DXGL has detected an incompatible AppCompat flag for the program you are currently running. To continue, the registry value must be deleted.\nIf you see a UAC prompt, you must click Yes."),
393 - _T("AppCompat error"),MB_OK|MB_ICONHAND);
394 - error = RegDeleteValue(hKey,filename);
395 - if(error == ERROR_ACCESS_DENIED)
396 - {
397 - tstring command;
398 - if(is64) command.assign(_T("DELETE \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers\" /reg:64 /f /v \""));
399 - else command.assign(_T("DELETE \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers\" /f /v \""));
400 - command.append(filename);
401 - command.append(_T("\""));
402 - SHELLEXECUTEINFO info;
403 - ZeroMemory(&info,sizeof(SHELLEXECUTEINFO));
404 - info.cbSize = sizeof(SHELLEXECUTEINFO);
405 - info.lpVerb = _T("runas");
406 - info.lpFile = _T("reg.exe");
407 - info.lpParameters = command.c_str();
408 - info.nShow = SW_SHOWNORMAL;
409 - info.fMask = SEE_MASK_NOCLOSEPROCESS;
410 - ShellExecuteEx(&info);
411 - WaitForSingleObject(info.hProcess,INFINITE);
412 - GetExitCodeProcess(info.hProcess,(LPDWORD)&error);
413 - }
414 - if(!error)
415 - {
416 - MessageBox(NULL,_T("Registry value successfully deleted. Please restart the program."),_T("Success"),MB_OK|MB_ICONINFORMATION);
417 - exit(0);
418 - }
419 - else MessageBox(NULL,_T("Registry value could not be deleted. Your program may crash as a result."),_T("Error"),MB_OK|MB_ICONWARNING);
420 - }
421 - }
422 - RegCloseKey(hKey);
423 - }
424 - if(is64) error = RegOpenKeyEx(HKEY_CURRENT_USER,_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"),0,KEY_READ|KEY_WOW64_64KEY,&hKey);
425 - else error = RegOpenKeyEx(HKEY_CURRENT_USER,_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"),0,KEY_READ,&hKey);
426 - if(error == ERROR_SUCCESS)
427 - {
428 - GetModuleFileName(NULL,filename,MAX_PATH);
429 - TCHAR buffer[1024];
430 - ZeroMemory(buffer,1024*sizeof(TCHAR));
431 - DWORD sizeout = 1024*sizeof(TCHAR);
432 - if(RegQueryValueEx(hKey,filename,NULL,NULL,(LPBYTE)buffer,&sizeout) == ERROR_SUCCESS)
433 - {
434 - if(_tcsstr(buffer,_T("DWM8And16BitMitigation")))
435 - {
436 - MessageBox(NULL,_T("DXGL has detected an incompatible AppCompat flag for the program you are currently running. To continue, the registry value must be deleted.\nIf you see a UAC prompt, you must click Yes."),
437 - _T("AppCompat error"),MB_OK|MB_ICONHAND);
438 - error = RegDeleteValue(hKey,filename);
439 - if(error == ERROR_ACCESS_DENIED)
440 - {
441 - tstring command;
442 - if(is64) command.assign(_T("DELETE \"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers\" /reg:64 /f /v \""));
443 - else command.assign(_T("DELETE \"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers\" /f /v \""));
444 - command.append(filename);
445 - command.append(_T("\""));
446 - SHELLEXECUTEINFO info;
447 - ZeroMemory(&info,sizeof(SHELLEXECUTEINFO));
448 - info.cbSize = sizeof(SHELLEXECUTEINFO);
449 - info.lpVerb = _T("runas");
450 - info.lpFile = _T("reg.exe");
451 - info.lpParameters = command.c_str();
452 - info.nShow = SW_SHOWNORMAL;
453 - info.fMask = SEE_MASK_NOCLOSEPROCESS;
454 - ShellExecuteEx(&info);
455 - WaitForSingleObject(info.hProcess,INFINITE);
456 - GetExitCodeProcess(info.hProcess,(LPDWORD)&error);
457 - }
458 - if(!error)
459 - {
460 - MessageBox(NULL,_T("Registry value successfully deleted. Please restart the program."),_T("Success"),MB_OK|MB_ICONINFORMATION);
461 - exit(0);
462 - }
463 - else MessageBox(NULL,_T("Registry value could not be deleted. Your program may crash as a result."),_T("Error"),MB_OK|MB_ICONWARNING);
464 - }
465 - }
466 - RegCloseKey(hKey);
467 - }
 564+ DelCompatFlag(_T("DWM8and16BitMitigation"));
468565 }
469566 }
470567 void GetGlobalConfig(DXGLCFG *cfg)