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)
13 /* SESSION Operation */
14 #define EXTRACT_FILLFILELIST 0x00000001
15 #define EXTRACT_EXTRACTFILES 0x00000002
17 static HANDLE hLog
= NULL
;
18 ATL::CStringW szCachedINISectionLocale
= L
"Section.";
19 ATL::CStringW szCachedINISectionLocaleNeutral
;
20 BYTE bCachedSectionStatus
= FALSE
;
22 #define LOCALIZED_STRING_LEN MAX_PATH
23 #define STR_VERSION_CURRENT L"CURRENT"
35 struct FILELIST
*next
;
43 struct FILELIST
*FileList
;
46 CHAR Destination
[MAX_PATH
];
47 CHAR CurrentFile
[MAX_PATH
];
48 CHAR Reserved
[MAX_PATH
];
49 struct FILELIST
*FilterList
;
52 typedef HRESULT(WINAPI
*fnExtract
)(SESSION
*dest
, LPCSTR szCabName
);
57 GetSystemColorDepth(VOID
)
62 pDevMode
.dmSize
= sizeof(pDevMode
);
63 pDevMode
.dmDriverExtra
= 0;
65 if (!EnumDisplaySettings(NULL
, ENUM_CURRENT_SETTINGS
, &pDevMode
))
67 /* TODO: Error message */
71 switch (pDevMode
.dmBitsPerPel
)
73 case 32: ColorDepth
= ILC_COLOR32
; break;
74 case 24: ColorDepth
= ILC_COLOR24
; break;
75 case 16: ColorDepth
= ILC_COLOR16
; break;
76 case 8: ColorDepth
= ILC_COLOR8
; break;
77 case 4: ColorDepth
= ILC_COLOR4
; break;
78 default: ColorDepth
= ILC_COLOR
; break;
85 GetWindowWidth(HWND hwnd
)
89 GetWindowRect(hwnd
, &Rect
);
90 return (Rect
.right
- Rect
.left
);
94 GetWindowHeight(HWND hwnd
)
98 GetWindowRect(hwnd
, &Rect
);
99 return (Rect
.bottom
- Rect
.top
);
103 GetClientWindowWidth(HWND hwnd
)
107 GetClientRect(hwnd
, &Rect
);
108 return (Rect
.right
- Rect
.left
);
112 GetClientWindowHeight(HWND hwnd
)
116 GetClientRect(hwnd
, &Rect
);
117 return (Rect
.bottom
- Rect
.top
);
121 CopyTextToClipboard(LPCWSTR lpszText
)
125 if (OpenClipboard(NULL
))
132 cchBuffer
= wcslen(lpszText
) + 1;
133 ClipBuffer
= GlobalAlloc(GMEM_DDESHARE
, cchBuffer
* sizeof(WCHAR
));
134 Buffer
= (PWCHAR
) GlobalLock(ClipBuffer
);
135 hr
= StringCchCopyW(Buffer
, cchBuffer
, lpszText
);
136 GlobalUnlock(ClipBuffer
);
139 SetClipboardData(CF_UNICODETEXT
, ClipBuffer
);
148 ATL::CStringW szText
;
150 szText
.LoadStringW(hInst
, IDS_WELCOME_TITLE
);
151 NewRichEditText(szText
, CFE_BOLD
);
153 szText
.LoadStringW(hInst
, IDS_WELCOME_TEXT
);
154 InsertRichEditText(szText
, 0);
156 szText
.LoadStringW(hInst
, IDS_WELCOME_URL
);
157 InsertRichEditText(szText
, CFM_LINK
);
161 ShowPopupMenu(HWND hwnd
, UINT MenuID
, UINT DefaultItem
)
170 hMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(MenuID
));
171 hPopupMenu
= GetSubMenu(hMenu
, 0);
174 hPopupMenu
= GetMenu(hwnd
);
176 ZeroMemory(&mii
, sizeof(mii
));
177 mii
.cbSize
= sizeof(mii
);
178 mii
.fMask
= MIIM_STATE
;
179 GetMenuItemInfo(hPopupMenu
, DefaultItem
, FALSE
, &mii
);
181 if (!(mii
.fState
& MFS_GRAYED
))
182 SetMenuDefaultItem(hPopupMenu
, DefaultItem
, FALSE
);
186 SetForegroundWindow(hwnd
);
187 TrackPopupMenu(hPopupMenu
, 0, pt
.x
, pt
.y
, 0, hMainWnd
, NULL
);
194 StartProcess(ATL::CStringW
&Path
, BOOL Wait
)
196 BOOL result
= StartProcess(Path
.GetBuffer(), Wait
);
197 Path
.ReleaseBuffer();
202 StartProcess(LPWSTR lpPath
, BOOL Wait
)
204 PROCESS_INFORMATION pi
;
209 ZeroMemory(&si
, sizeof(si
));
211 si
.dwFlags
= STARTF_USESHOWWINDOW
;
212 si
.wShowWindow
= SW_SHOW
;
214 if (!CreateProcessW(NULL
, lpPath
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
))
219 CloseHandle(pi
.hThread
);
220 if (Wait
) EnableWindow(hMainWnd
, FALSE
);
224 dwRet
= MsgWaitForMultipleObjects(1, &pi
.hProcess
, FALSE
, INFINITE
, QS_ALLEVENTS
);
225 if (dwRet
== WAIT_OBJECT_0
+ 1)
227 while (PeekMessageW(&msg
, NULL
, 0, 0, PM_REMOVE
))
229 TranslateMessage(&msg
);
230 DispatchMessage(&msg
);
235 if (dwRet
== WAIT_OBJECT_0
|| dwRet
== WAIT_FAILED
)
240 CloseHandle(pi
.hProcess
);
244 EnableWindow(hMainWnd
, TRUE
);
245 SetForegroundWindow(hMainWnd
);
253 GetStorageDirectory(ATL::CStringW
& Directory
)
255 if (!SHGetSpecialFolderPathW(NULL
, Directory
.GetBuffer(MAX_PATH
), CSIDL_LOCAL_APPDATA
, TRUE
))
257 Directory
.ReleaseBuffer();
261 Directory
.ReleaseBuffer();
262 Directory
+= L
"\\rapps";
264 return (CreateDirectoryW(Directory
.GetString(), NULL
) || GetLastError() == ERROR_ALREADY_EXISTS
);
268 ExtractFilesFromCab(const ATL::CStringW
&CabName
, const ATL::CStringW
&OutputPath
)
270 return ExtractFilesFromCab(CabName
.GetString(), OutputPath
.GetString());
274 ExtractFilesFromCab(LPCWSTR lpCabName
, LPCWSTR lpOutputPath
)
276 HINSTANCE hCabinetDll
;
277 CHAR szCabName
[MAX_PATH
];
281 hCabinetDll
= LoadLibraryW(L
"cabinet.dll");
284 pfnExtract
= (fnExtract
) GetProcAddress(hCabinetDll
, "Extract");
287 ZeroMemory(&Dest
, sizeof(Dest
));
289 WideCharToMultiByte(CP_ACP
, 0, lpOutputPath
, -1, Dest
.Destination
, MAX_PATH
, NULL
, NULL
);
290 WideCharToMultiByte(CP_ACP
, 0, lpCabName
, -1, szCabName
, MAX_PATH
, NULL
, NULL
);
291 Dest
.Operation
= EXTRACT_FILLFILELIST
;
293 Result
= pfnExtract(&Dest
, szCabName
);
296 Dest
.Operation
= EXTRACT_EXTRACTFILES
;
297 Result
= pfnExtract(&Dest
, szCabName
);
300 FreeLibrary(hCabinetDll
);
305 FreeLibrary(hCabinetDll
);
314 WCHAR szBuf
[MAX_PATH
] = L
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\ReactOS Application Manager";
315 WCHAR szPath
[MAX_PATH
];
316 DWORD dwCategoryNum
= 1;
317 DWORD dwDisp
, dwData
;
320 if (!SettingsInfo
.bLogEnabled
) return;
322 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
324 REG_OPTION_NON_VOLATILE
,
325 KEY_WRITE
, NULL
, &hKey
, &dwDisp
) != ERROR_SUCCESS
)
330 if (!GetModuleFileNameW(NULL
, szPath
, _countof(szPath
)))
333 if (RegSetValueExW(hKey
,
338 (DWORD
) (wcslen(szPath
) + 1) * sizeof(WCHAR
)) != ERROR_SUCCESS
)
344 dwData
= EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
|
345 EVENTLOG_INFORMATION_TYPE
;
347 if (RegSetValueExW(hKey
,
352 sizeof(DWORD
)) != ERROR_SUCCESS
)
358 if (RegSetValueExW(hKey
,
359 L
"CategoryMessageFile",
363 (DWORD
) (wcslen(szPath
) + 1) * sizeof(WCHAR
)) != ERROR_SUCCESS
)
369 if (RegSetValueExW(hKey
,
373 (LPBYTE
) &dwCategoryNum
,
374 sizeof(DWORD
)) != ERROR_SUCCESS
)
382 hLog
= RegisterEventSourceW(NULL
, L
"ReactOS Application Manager");
389 if (hLog
) DeregisterEventSource(hLog
);
394 WriteLogMessage(WORD wType
, DWORD dwEventID
, LPCWSTR lpMsg
)
396 if (!SettingsInfo
.bLogEnabled
) return TRUE
;
398 if (!ReportEventW(hLog
, wType
, 0, dwEventID
,
399 NULL
, 1, 0, &lpMsg
, NULL
))
408 ATL::CStringW
GetINIFullPath(const ATL::CStringW
& FileName
)
411 static ATL::CStringW szBuffer
;
413 GetStorageDirectory(szDir
);
414 szBuffer
.Format(L
"%ls\\rapps\\%ls", szDir
, FileName
);
419 UINT
ParserGetString(const ATL::CStringW
& KeyName
, const ATL::CStringW
& FileName
, ATL::CStringW
& ResultString
)
421 ATL::CStringW FullFileName
= GetINIFullPath(FileName
);
424 /* we don't have cached section strings for the current system language, create them */
425 if (bCachedSectionStatus
== FALSE
)
427 ATL::CStringW szLocale
;
428 const INT LocaleSize
= 5;
430 /* find out what is the current system lang code (e.g. "0a") and append it to SectionLocale */
431 GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_ILANGUAGE
,
432 szLocale
.GetBuffer(LocaleSize
), LocaleSize
);
433 szLocale
.ReleaseBuffer();
435 /* turn "Section.0c0a" into "Section.0a", keeping just the neutral lang part */
436 szCachedINISectionLocaleNeutral
= szCachedINISectionLocale
+ szLocale
.Right(2);
437 szCachedINISectionLocale
+= szLocale
;
439 /* finally, mark us as cache-friendly for the next time */
440 bCachedSectionStatus
= TRUE
;
443 LPWSTR ResultStringBuffer
= ResultString
.GetBuffer(MAX_PATH
);
444 /* 1st - find localized strings (e.g. "Section.0c0a") */
445 dwResult
= GetPrivateProfileStringW(szCachedINISectionLocale
.GetString(),
449 LOCALIZED_STRING_LEN
,
450 FullFileName
.GetString());
454 /* 2nd - if they weren't present check for neutral sub-langs/ generic translations (e.g. "Section.0a") */
455 dwResult
= GetPrivateProfileStringW(szCachedINISectionLocaleNeutral
.GetString(),
459 LOCALIZED_STRING_LEN
,
460 FullFileName
.GetString());
463 /* 3rd - if they weren't present fallback to standard english strings (just "Section") */
464 dwResult
= GetPrivateProfileStringW(L
"Section",
468 LOCALIZED_STRING_LEN
,
469 FullFileName
.GetString());
473 ResultString
.ReleaseBuffer();
474 return (dwResult
!= 0 ? TRUE
: FALSE
);
477 UINT
ParserGetInt(const ATL::CStringW
& KeyName
, const ATL::CStringW
& FileName
)
479 ATL::CStringW Buffer
;
480 UNICODE_STRING BufferW
;
483 /* grab the text version of our entry */
484 if (!ParserGetString(KeyName
, FileName
, Buffer
))
487 if (Buffer
.IsEmpty())
490 /* convert it to an actual integer */
491 RtlInitUnicodeString(&BufferW
, Buffer
.GetString());
492 RtlUnicodeStringToInteger(&BufferW
, 0, &Result
);
494 return (UINT
) Result
;