[RAPPS]
[reactos.git] / reactos / base / applications / rapps / misc.cpp
1 /*
2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/rapps/misc.cpp
5 * PURPOSE: Misc functions
6 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
7 * Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
8 * Alexander Shaposhnikov (chaez.san@gmail.com)
9 */
10 #include "defines.h"
11
12 #include "gui.h"
13 #include "misc.h"
14
15 /* SESSION Operation */
16 #define EXTRACT_FILLFILELIST 0x00000001
17 #define EXTRACT_EXTRACTFILES 0x00000002
18
19 static HANDLE hLog = NULL;
20
21 typedef struct
22 {
23 int erfOper;
24 int erfType;
25 BOOL fError;
26 } ERF, *PERF;
27
28 struct FILELIST
29 {
30 LPSTR FileName;
31 FILELIST *next;
32 BOOL DoExtract;
33 };
34
35 struct SESSION
36 {
37 INT FileSize;
38 ERF Error;
39 FILELIST *FileList;
40 INT FileCount;
41 INT Operation;
42 CHAR Destination[MAX_PATH];
43 CHAR CurrentFile[MAX_PATH];
44 CHAR Reserved[MAX_PATH];
45 FILELIST *FilterList;
46 };
47
48 typedef HRESULT(WINAPI *fnExtract)(SESSION *dest, LPCSTR szCabName);
49 fnExtract pfnExtract;
50
51
52 int
53 GetWindowWidth(HWND hwnd)
54 {
55 RECT Rect;
56
57 GetWindowRect(hwnd, &Rect);
58 return (Rect.right - Rect.left);
59 }
60
61 int
62 GetWindowHeight(HWND hwnd)
63 {
64 RECT Rect;
65
66 GetWindowRect(hwnd, &Rect);
67 return (Rect.bottom - Rect.top);
68 }
69
70 int
71 GetClientWindowWidth(HWND hwnd)
72 {
73 RECT Rect;
74
75 GetClientRect(hwnd, &Rect);
76 return (Rect.right - Rect.left);
77 }
78
79 int
80 GetClientWindowHeight(HWND hwnd)
81 {
82 RECT Rect;
83
84 GetClientRect(hwnd, &Rect);
85 return (Rect.bottom - Rect.top);
86 }
87
88 VOID
89 CopyTextToClipboard(LPCWSTR lpszText)
90 {
91 HRESULT hr;
92
93 if (OpenClipboard(NULL))
94 {
95 HGLOBAL ClipBuffer;
96 WCHAR *Buffer;
97 DWORD cchBuffer;
98
99 EmptyClipboard();
100 cchBuffer = wcslen(lpszText) + 1;
101 ClipBuffer = GlobalAlloc(GMEM_DDESHARE, cchBuffer * sizeof(WCHAR));
102 Buffer = (PWCHAR) GlobalLock(ClipBuffer);
103 hr = StringCchCopyW(Buffer, cchBuffer, lpszText);
104 GlobalUnlock(ClipBuffer);
105
106 if (SUCCEEDED(hr))
107 SetClipboardData(CF_UNICODETEXT, ClipBuffer);
108
109 CloseClipboard();
110 }
111 }
112
113 VOID
114 SetWelcomeText(VOID)
115 {
116 ATL::CStringW szText;
117
118 szText.LoadStringW(hInst, IDS_WELCOME_TITLE);
119 NewRichEditText(szText, CFE_BOLD);
120
121 szText.LoadStringW(hInst, IDS_WELCOME_TEXT);
122 InsertRichEditText(szText, 0);
123
124 szText.LoadStringW(hInst, IDS_WELCOME_URL);
125 InsertRichEditText(szText, CFM_LINK);
126 }
127
128 VOID
129 ShowPopupMenu(HWND hwnd, UINT MenuID, UINT DefaultItem)
130 {
131 HMENU hMenu = NULL;
132 HMENU hPopupMenu;
133 MENUITEMINFO mii;
134 POINT pt;
135
136 if (MenuID)
137 {
138 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(MenuID));
139 hPopupMenu = GetSubMenu(hMenu, 0);
140 }
141 else
142 hPopupMenu = GetMenu(hwnd);
143
144 ZeroMemory(&mii, sizeof(mii));
145 mii.cbSize = sizeof(mii);
146 mii.fMask = MIIM_STATE;
147 GetMenuItemInfoW(hPopupMenu, DefaultItem, FALSE, &mii);
148
149 if (!(mii.fState & MFS_GRAYED))
150 SetMenuDefaultItem(hPopupMenu, DefaultItem, FALSE);
151
152 GetCursorPos(&pt);
153
154 SetForegroundWindow(hwnd);
155 TrackPopupMenu(hPopupMenu, 0, pt.x, pt.y, 0, hMainWnd, NULL);
156
157 if (hMenu)
158 DestroyMenu(hMenu);
159 }
160
161 BOOL
162 StartProcess(ATL::CStringW &Path, BOOL Wait)
163 {
164 BOOL result = StartProcess(const_cast<LPWSTR>(Path.GetString()), Wait);
165 return result;
166 }
167
168 BOOL
169 StartProcess(LPWSTR lpPath, BOOL Wait)
170 {
171 PROCESS_INFORMATION pi;
172 STARTUPINFOW si;
173 DWORD dwRet;
174 MSG msg;
175
176 ZeroMemory(&si, sizeof(si));
177 si.cb = sizeof(si);
178 si.dwFlags = STARTF_USESHOWWINDOW;
179 si.wShowWindow = SW_SHOW;
180
181 if (!CreateProcessW(NULL, lpPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
182 {
183 return FALSE;
184 }
185
186 CloseHandle(pi.hThread);
187 if (Wait) EnableWindow(hMainWnd, FALSE);
188
189 while (Wait)
190 {
191 dwRet = MsgWaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE, QS_ALLEVENTS);
192 if (dwRet == WAIT_OBJECT_0 + 1)
193 {
194 while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
195 {
196 TranslateMessage(&msg);
197 DispatchMessage(&msg);
198 }
199 }
200 else
201 {
202 if (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_FAILED)
203 break;
204 }
205 }
206
207 CloseHandle(pi.hProcess);
208
209 if (Wait)
210 {
211 EnableWindow(hMainWnd, TRUE);
212 SetForegroundWindow(hMainWnd);
213 SetFocus(hMainWnd);
214 }
215
216 return TRUE;
217 }
218
219 BOOL
220 GetStorageDirectory(ATL::CStringW& Directory)
221 {
222 if (!SHGetSpecialFolderPathW(NULL, Directory.GetBuffer(MAX_PATH), CSIDL_LOCAL_APPDATA, TRUE))
223 {
224 Directory.ReleaseBuffer();
225 return FALSE;
226 }
227
228 Directory.ReleaseBuffer();
229 Directory += L"\\rapps";
230
231 return (CreateDirectoryW(Directory.GetString(), NULL) || GetLastError() == ERROR_ALREADY_EXISTS);
232 }
233
234 BOOL
235 ExtractFilesFromCab(const ATL::CStringW &CabName, const ATL::CStringW &OutputPath)
236 {
237 return ExtractFilesFromCab(CabName.GetString(), OutputPath.GetString());
238 }
239
240 BOOL
241 ExtractFilesFromCab(LPCWSTR lpCabName, LPCWSTR lpOutputPath)
242 {
243 HINSTANCE hCabinetDll;
244 CHAR szCabName[MAX_PATH];
245 SESSION Dest;
246 HRESULT Result;
247
248 hCabinetDll = LoadLibraryW(L"cabinet.dll");
249 if (hCabinetDll)
250 {
251 pfnExtract = (fnExtract) GetProcAddress(hCabinetDll, "Extract");
252 if (pfnExtract)
253 {
254 ZeroMemory(&Dest, sizeof(Dest));
255
256 WideCharToMultiByte(CP_ACP, 0, lpOutputPath, -1, Dest.Destination, MAX_PATH, NULL, NULL);
257 WideCharToMultiByte(CP_ACP, 0, lpCabName, -1, szCabName, MAX_PATH, NULL, NULL);
258 Dest.Operation = EXTRACT_FILLFILELIST;
259
260 Result = pfnExtract(&Dest, szCabName);
261 if (Result == S_OK)
262 {
263 Dest.Operation = EXTRACT_EXTRACTFILES;
264 Result = pfnExtract(&Dest, szCabName);
265 if (Result == S_OK)
266 {
267 FreeLibrary(hCabinetDll);
268 return TRUE;
269 }
270 }
271 }
272 FreeLibrary(hCabinetDll);
273 }
274
275 return FALSE;
276 }
277
278 VOID
279 InitLogs(VOID)
280 {
281 WCHAR szBuf[MAX_PATH] = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\ReactOS Application Manager";
282 WCHAR szPath[MAX_PATH];
283 DWORD dwCategoryNum = 1;
284 DWORD dwDisp, dwData;
285 HKEY hKey;
286
287 if (!SettingsInfo.bLogEnabled) return;
288
289 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
290 szBuf, 0, NULL,
291 REG_OPTION_NON_VOLATILE,
292 KEY_WRITE, NULL, &hKey, &dwDisp) != ERROR_SUCCESS)
293 {
294 return;
295 }
296
297 if (!GetModuleFileNameW(NULL, szPath, _countof(szPath)))
298 return;
299
300 if (RegSetValueExW(hKey,
301 L"EventMessageFile",
302 0,
303 REG_EXPAND_SZ,
304 (LPBYTE) szPath,
305 (DWORD) (wcslen(szPath) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS)
306 {
307 RegCloseKey(hKey);
308 return;
309 }
310
311 dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
312 EVENTLOG_INFORMATION_TYPE;
313
314 if (RegSetValueExW(hKey,
315 L"TypesSupported",
316 0,
317 REG_DWORD,
318 (LPBYTE) &dwData,
319 sizeof(DWORD)) != ERROR_SUCCESS)
320 {
321 RegCloseKey(hKey);
322 return;
323 }
324
325 if (RegSetValueExW(hKey,
326 L"CategoryMessageFile",
327 0,
328 REG_EXPAND_SZ,
329 (LPBYTE) szPath,
330 (DWORD) (wcslen(szPath) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS)
331 {
332 RegCloseKey(hKey);
333 return;
334 }
335
336 if (RegSetValueExW(hKey,
337 L"CategoryCount",
338 0,
339 REG_DWORD,
340 (LPBYTE) &dwCategoryNum,
341 sizeof(DWORD)) != ERROR_SUCCESS)
342 {
343 RegCloseKey(hKey);
344 return;
345 }
346
347 RegCloseKey(hKey);
348
349 hLog = RegisterEventSourceW(NULL, L"ReactOS Application Manager");
350 }
351
352
353 VOID
354 FreeLogs(VOID)
355 {
356 if (hLog) DeregisterEventSource(hLog);
357 }
358
359
360 BOOL
361 WriteLogMessage(WORD wType, DWORD dwEventID, LPCWSTR lpMsg)
362 {
363 if (!SettingsInfo.bLogEnabled) return TRUE;
364
365 if (!ReportEventW(hLog, wType, 0, dwEventID,
366 NULL, 1, 0, &lpMsg, NULL))
367 {
368 return FALSE;
369 }
370
371 return TRUE;
372 }
373
374 BOOL
375 GetInstalledVersion_WowUser(_Out_opt_ ATL::CStringW* szVersionResult,
376 _In_z_ const ATL::CStringW& RegName,
377 _In_ BOOL IsUserKey,
378 _In_ REGSAM keyWow)
379 {
380 HKEY hKey;
381 BOOL bHasSucceded = FALSE;
382 ATL::CStringW szVersion;
383 ATL::CStringW szPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + RegName;
384
385 if (RegOpenKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
386 szPath.GetString(), 0, keyWow | KEY_READ,
387 &hKey) == ERROR_SUCCESS)
388 {
389 if (szVersionResult != NULL)
390 {
391 DWORD dwSize = MAX_PATH * sizeof(WCHAR);
392 DWORD dwType = REG_SZ;
393 if (RegQueryValueExW(hKey,
394 L"DisplayVersion",
395 NULL,
396 &dwType,
397 (LPBYTE) szVersion.GetBuffer(MAX_PATH),
398 &dwSize) == ERROR_SUCCESS)
399 {
400 szVersion.ReleaseBuffer();
401 *szVersionResult = szVersion;
402 bHasSucceded = TRUE;
403 }
404 else
405 {
406 szVersion.ReleaseBuffer();
407 }
408 }
409 else
410 {
411 bHasSucceded = TRUE;
412 szVersion.ReleaseBuffer();
413 }
414
415 }
416
417 RegCloseKey(hKey);
418 return bHasSucceded;
419 }
420
421 BOOL GetInstalledVersion(ATL::CStringW * pszVersion, const ATL::CStringW & szRegName)
422 {
423 return (!szRegName.IsEmpty()
424 && (GetInstalledVersion_WowUser(pszVersion, szRegName, TRUE, KEY_WOW64_32KEY)
425 || GetInstalledVersion_WowUser(pszVersion, szRegName, FALSE, KEY_WOW64_32KEY)
426 || GetInstalledVersion_WowUser(pszVersion, szRegName, TRUE, KEY_WOW64_64KEY)
427 || GetInstalledVersion_WowUser(pszVersion, szRegName, FALSE, KEY_WOW64_64KEY)));
428 }