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