|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "CEHHelper.h" |
|
7 #include <tlhelp32.h> |
|
8 #include "mozilla/widget/MetroD3DCheckHelper.h" |
|
9 |
|
10 #ifdef SHOW_CONSOLE |
|
11 #include <io.h> // _open_osfhandle |
|
12 #endif |
|
13 |
|
14 HANDLE sCon; |
|
15 LPCWSTR metroDX10Available = L"MetroD3DAvailable"; |
|
16 LPCWSTR metroLastAHE = L"MetroLastAHE"; |
|
17 LPCWSTR cehDumpDebugStrings = L"CEHDump"; |
|
18 extern const WCHAR* kFirefoxExe; |
|
19 |
|
20 void |
|
21 Log(const wchar_t *fmt, ...) |
|
22 { |
|
23 #if !defined(SHOW_CONSOLE) |
|
24 DWORD dwRes = 0; |
|
25 if (!GetDWORDRegKey(cehDumpDebugStrings, dwRes) || !dwRes) { |
|
26 return; |
|
27 } |
|
28 #endif |
|
29 va_list a = nullptr; |
|
30 wchar_t szDebugString[1024]; |
|
31 if(!lstrlenW(fmt)) |
|
32 return; |
|
33 va_start(a,fmt); |
|
34 vswprintf(szDebugString, 1024, fmt, a); |
|
35 va_end(a); |
|
36 if(!lstrlenW(szDebugString)) |
|
37 return; |
|
38 |
|
39 DWORD len; |
|
40 WriteConsoleW(sCon, szDebugString, lstrlenW(szDebugString), &len, nullptr); |
|
41 WriteConsoleW(sCon, L"\n", 1, &len, nullptr); |
|
42 |
|
43 OutputDebugStringW(szDebugString); |
|
44 OutputDebugStringW(L"\n"); |
|
45 } |
|
46 |
|
47 #if defined(SHOW_CONSOLE) |
|
48 void |
|
49 SetupConsole() |
|
50 { |
|
51 FILE *fp; |
|
52 AllocConsole(); |
|
53 sCon = GetStdHandle(STD_OUTPUT_HANDLE); |
|
54 int fd = _open_osfhandle(reinterpret_cast<intptr_t>(sCon), 0); |
|
55 fp = _fdopen(fd, "w"); |
|
56 *stdout = *fp; |
|
57 setvbuf(stdout, nullptr, _IONBF, 0); |
|
58 } |
|
59 #endif |
|
60 |
|
61 bool |
|
62 IsImmersiveProcessDynamic(HANDLE process) |
|
63 { |
|
64 HMODULE user32DLL = LoadLibraryW(L"user32.dll"); |
|
65 if (!user32DLL) { |
|
66 return false; |
|
67 } |
|
68 |
|
69 decltype(IsImmersiveProcess)* IsImmersiveProcessPtr = |
|
70 (decltype(IsImmersiveProcess)*) GetProcAddress(user32DLL, |
|
71 "IsImmersiveProcess"); |
|
72 if (!IsImmersiveProcessPtr) { |
|
73 FreeLibrary(user32DLL); |
|
74 return false; |
|
75 } |
|
76 |
|
77 BOOL bImmersiveProcess = IsImmersiveProcessPtr(process); |
|
78 FreeLibrary(user32DLL); |
|
79 return bImmersiveProcess; |
|
80 } |
|
81 |
|
82 bool |
|
83 IsProcessRunning(const wchar_t *processName, bool bCheckIfMetro) |
|
84 { |
|
85 bool exists = false; |
|
86 PROCESSENTRY32W entry; |
|
87 entry.dwSize = sizeof(PROCESSENTRY32W); |
|
88 |
|
89 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
|
90 |
|
91 if (Process32First(snapshot, &entry)) { |
|
92 while (!exists && Process32Next(snapshot, &entry)) { |
|
93 if (!_wcsicmp(entry.szExeFile, processName)) { |
|
94 HANDLE process = OpenProcess(GENERIC_READ, FALSE, entry.th32ProcessID); |
|
95 bool isImmersiveProcess = IsImmersiveProcessDynamic(process); |
|
96 if ((bCheckIfMetro && isImmersiveProcess) || |
|
97 (!bCheckIfMetro && !isImmersiveProcess)) { |
|
98 exists = true; |
|
99 } |
|
100 CloseHandle(process); |
|
101 } |
|
102 } |
|
103 } |
|
104 |
|
105 CloseHandle(snapshot); |
|
106 return exists; |
|
107 } |
|
108 |
|
109 bool |
|
110 IsMetroProcessRunning() |
|
111 { |
|
112 return IsProcessRunning(kFirefoxExe, true); |
|
113 } |
|
114 |
|
115 bool |
|
116 IsDesktopProcessRunning() |
|
117 { |
|
118 return IsProcessRunning(kFirefoxExe, false); |
|
119 } |
|
120 |
|
121 /* |
|
122 * Retrieve the last front end ui we launched so we can target it |
|
123 * again. This value is updated down in nsAppRunner when the browser |
|
124 * starts up. |
|
125 */ |
|
126 AHE_TYPE |
|
127 GetLastAHE() |
|
128 { |
|
129 DWORD ahe; |
|
130 if (GetDWORDRegKey(metroLastAHE, ahe)) { |
|
131 return (AHE_TYPE) ahe; |
|
132 } |
|
133 return AHE_DESKTOP; |
|
134 } |
|
135 |
|
136 bool |
|
137 IsDX10Available() |
|
138 { |
|
139 DWORD isDX10Available; |
|
140 if (GetDWORDRegKey(metroDX10Available, isDX10Available)) { |
|
141 return isDX10Available; |
|
142 } |
|
143 bool check = D3DFeatureLevelCheck(); |
|
144 SetDWORDRegKey(metroDX10Available, check); |
|
145 return check; |
|
146 } |
|
147 |
|
148 bool |
|
149 GetDWORDRegKey(LPCWSTR name, DWORD &value) |
|
150 { |
|
151 HKEY key; |
|
152 LONG result = RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Mozilla\\Firefox", |
|
153 0, KEY_READ, &key); |
|
154 if (result != ERROR_SUCCESS) { |
|
155 return false; |
|
156 } |
|
157 |
|
158 DWORD bufferSize = sizeof(DWORD); |
|
159 DWORD type; |
|
160 result = RegQueryValueExW(key, name, nullptr, &type, |
|
161 reinterpret_cast<LPBYTE>(&value), |
|
162 &bufferSize); |
|
163 RegCloseKey(key); |
|
164 return result == ERROR_SUCCESS; |
|
165 } |
|
166 |
|
167 bool |
|
168 SetDWORDRegKey(LPCWSTR name, DWORD value) |
|
169 { |
|
170 HKEY key; |
|
171 LONG result = RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Mozilla\\Firefox", |
|
172 0, KEY_WRITE, &key); |
|
173 if (result != ERROR_SUCCESS) { |
|
174 return false; |
|
175 } |
|
176 |
|
177 result = RegSetValueEx(key, name, 0, REG_DWORD, |
|
178 reinterpret_cast<LPBYTE>(&value), |
|
179 sizeof(DWORD)); |
|
180 RegCloseKey(key); |
|
181 return result == ERROR_SUCCESS; |
|
182 } |