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