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