1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Copyright 2003, 2004, 2005 Martin Fuchs
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck  *
9c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12c2c66affSColin Finck  * Lesser General Public License for more details.
13c2c66affSColin Finck  *
14c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17c2c66affSColin Finck  */
18c2c66affSColin Finck 
19c2c66affSColin Finck 
20c2c66affSColin Finck  //
21c2c66affSColin Finck  // Explorer clone
22c2c66affSColin Finck  //
23c2c66affSColin Finck  // utility.cpp
24c2c66affSColin Finck  //
25c2c66affSColin Finck  // Martin Fuchs, 23.07.2003
26c2c66affSColin Finck  //
27c2c66affSColin Finck 
28c2c66affSColin Finck 
29c2c66affSColin Finck #include <precomp.h>
30c2c66affSColin Finck 
31c2c66affSColin Finck //#include <shellapi.h>
32c2c66affSColin Finck 
33c2c66affSColin Finck #include <time.h>
34c2c66affSColin Finck #include <sstream>
35c2c66affSColin Finck 
36c2c66affSColin Finck 
ThreadProc(void * para)37c2c66affSColin Finck DWORD WINAPI Thread::ThreadProc(void* para)
38c2c66affSColin Finck {
39c2c66affSColin Finck 	Thread* pThis = (Thread*) para;
40c2c66affSColin Finck 
41c2c66affSColin Finck 	int ret = pThis->Run();
42c2c66affSColin Finck 
43c2c66affSColin Finck 	pThis->_alive = false;
44c2c66affSColin Finck 
45c2c66affSColin Finck 	return ret;
46c2c66affSColin Finck }
47c2c66affSColin Finck 
48c2c66affSColin Finck 
CenterWindow(HWND hwnd)49c2c66affSColin Finck void CenterWindow(HWND hwnd)
50c2c66affSColin Finck {
51c2c66affSColin Finck 	RECT rt, prt;
52c2c66affSColin Finck 	GetWindowRect(hwnd, &rt);
53c2c66affSColin Finck 
54c2c66affSColin Finck 	DWORD style;
55c2c66affSColin Finck 	HWND owner = 0;
56c2c66affSColin Finck 
57c2c66affSColin Finck 	for(HWND wh=hwnd; (wh=GetWindow(wh,GW_OWNER))!=0; )
58c2c66affSColin Finck 		if (((style=GetWindowStyle(wh))&WS_VISIBLE) && !(style&WS_MINIMIZE))
59c2c66affSColin Finck 			{owner=wh; break;}
60c2c66affSColin Finck 
61c2c66affSColin Finck 	if (owner)
62c2c66affSColin Finck 		GetWindowRect(owner, &prt);
63c2c66affSColin Finck 	else
64c2c66affSColin Finck 		SystemParametersInfo(SPI_GETWORKAREA, 0, &prt, 0);	//@@ GetDesktopWindow() w�re auch hilfreich.
65c2c66affSColin Finck 
66c2c66affSColin Finck 	SetWindowPos(hwnd, 0, (prt.left+prt.right+rt.left-rt.right)/2,
67c2c66affSColin Finck 					   (prt.top+prt.bottom+rt.top-rt.bottom)/2, 0,0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
68c2c66affSColin Finck 
69c2c66affSColin Finck 	MoveVisible(hwnd);
70c2c66affSColin Finck }
71c2c66affSColin Finck 
MoveVisible(HWND hwnd)72c2c66affSColin Finck void MoveVisible(HWND hwnd)
73c2c66affSColin Finck {
74c2c66affSColin Finck 	RECT rc;
75c2c66affSColin Finck 	GetWindowRect(hwnd, &rc);
76c2c66affSColin Finck 	int left=rc.left, top=rc.top;
77c2c66affSColin Finck 
78c2c66affSColin Finck 	int xmax = GetSystemMetrics(SM_CXSCREEN);
79c2c66affSColin Finck 	int ymax = GetSystemMetrics(SM_CYSCREEN);
80c2c66affSColin Finck 
81c2c66affSColin Finck 	if (rc.left < 0)
82c2c66affSColin Finck 		rc.left = 0;
83c2c66affSColin Finck 	else if (rc.right > xmax)
84c2c66affSColin Finck 		if ((rc.left-=rc.right-xmax) < 0)
85c2c66affSColin Finck 			rc.left = 0;
86c2c66affSColin Finck 
87c2c66affSColin Finck 	if (rc.top < 0)
88c2c66affSColin Finck 		rc.top = 0;
89c2c66affSColin Finck 	else if (rc.bottom > ymax)
90c2c66affSColin Finck 		if ((rc.top-=rc.bottom-ymax) < 0)
91c2c66affSColin Finck 			rc.top = 0;
92c2c66affSColin Finck 
93c2c66affSColin Finck 	if (rc.left!=left || rc.top!=top)
94c2c66affSColin Finck 		SetWindowPos(hwnd, 0, rc.left,rc.top, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
95c2c66affSColin Finck }
96c2c66affSColin Finck 
97c2c66affSColin Finck 
display_error(HWND hwnd,DWORD error)98c2c66affSColin Finck void display_error(HWND hwnd, DWORD error)	//@@ CONTEXT mit ausgeben -> display_error(HWND hwnd, const Exception& e)
99c2c66affSColin Finck {
100c2c66affSColin Finck 	PTSTR msg;
101c2c66affSColin Finck 
102c2c66affSColin Finck 	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
103c2c66affSColin Finck 		0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) {
104c2c66affSColin Finck 		LOG(FmtString(TEXT("display_error(%#x): %s"), error, msg));
105c2c66affSColin Finck 
106c2c66affSColin Finck 		SetLastError(0);
107c2c66affSColin Finck 		MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK);
108c2c66affSColin Finck 
109c2c66affSColin Finck 		if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
110c2c66affSColin Finck 			MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK);
111c2c66affSColin Finck 	} else {
112c2c66affSColin Finck 		LOG(FmtString(TEXT("Unknown Error %#x"), error));
113c2c66affSColin Finck 
114c2c66affSColin Finck 		FmtString msg(TEXT("Unknown Error %#x"), error);
115c2c66affSColin Finck 
116c2c66affSColin Finck 		SetLastError(0);
117c2c66affSColin Finck 		MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK);
118c2c66affSColin Finck 
119c2c66affSColin Finck 		if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
120c2c66affSColin Finck 			MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK);
121c2c66affSColin Finck 	}
122c2c66affSColin Finck 
123c2c66affSColin Finck 	LocalFree(msg);
124c2c66affSColin Finck }
125c2c66affSColin Finck 
126c2c66affSColin Finck 
127c2c66affSColin Finck Context Context::s_main("-NO-CONTEXT-");
128c2c66affSColin Finck Context* Context::s_current = &Context::s_main;
129c2c66affSColin Finck 
toString() const130c2c66affSColin Finck String Context::toString() const
131c2c66affSColin Finck {
132c2c66affSColin Finck 	String str = _ctx;
133c2c66affSColin Finck 
134c2c66affSColin Finck 	if (!_obj.empty())
135c2c66affSColin Finck 		str.appendf(TEXT("\nObject: %s"), (LPCTSTR)_obj);
136c2c66affSColin Finck 
137c2c66affSColin Finck 	return str;
138c2c66affSColin Finck }
139c2c66affSColin Finck 
getStackTrace() const140c2c66affSColin Finck String Context::getStackTrace() const
141c2c66affSColin Finck {
142c2c66affSColin Finck 	ostringstream str;
143c2c66affSColin Finck 
144c2c66affSColin Finck 	str << "Context Trace:\n";
145c2c66affSColin Finck 
146c2c66affSColin Finck 	for(const Context*p=this; p && p!=&s_main; p=p->_last) {
147c2c66affSColin Finck 		str << "- " << p->_ctx;
148c2c66affSColin Finck 
149c2c66affSColin Finck 		if (!p->_obj.empty())
150c2c66affSColin Finck 			str << " obj=" << ANS(p->_obj);
151c2c66affSColin Finck 
152c2c66affSColin Finck 		str << '\n';
153c2c66affSColin Finck 	}
154c2c66affSColin Finck 
155c2c66affSColin Finck 	return str.str();
156c2c66affSColin Finck }
157c2c66affSColin Finck 
158c2c66affSColin Finck 
time_to_filetime(const time_t * t,FILETIME * ftime)159c2c66affSColin Finck BOOL time_to_filetime(const time_t* t, FILETIME* ftime)
160c2c66affSColin Finck {
161c2c66affSColin Finck #if defined(__STDC_WANT_SECURE_LIB__) && defined(_MS_VER)
162c2c66affSColin Finck 	SYSTEMTIME stime;
163c2c66affSColin Finck 	struct tm tm_;
164c2c66affSColin Finck 	struct tm* tm = &tm_;
165c2c66affSColin Finck 
166c2c66affSColin Finck 	if (gmtime_s(tm, t) != 0)
167c2c66affSColin Finck 		return FALSE;
168c2c66affSColin Finck #else
169c2c66affSColin Finck 	struct tm* tm = gmtime(t);
170c2c66affSColin Finck 	SYSTEMTIME stime;
171c2c66affSColin Finck 
172c2c66affSColin Finck 	if (!tm)
173c2c66affSColin Finck 		return FALSE;
174c2c66affSColin Finck #endif
175c2c66affSColin Finck 
176c2c66affSColin Finck 	stime.wYear = tm->tm_year+1900;
177c2c66affSColin Finck 	stime.wMonth = tm->tm_mon+1;
178c2c66affSColin Finck 	stime.wDayOfWeek = (WORD)-1;
179c2c66affSColin Finck 	stime.wDay = tm->tm_mday;
180c2c66affSColin Finck 	stime.wHour = tm->tm_hour;
181c2c66affSColin Finck 	stime.wMinute = tm->tm_min;
182c2c66affSColin Finck 	stime.wSecond = tm->tm_sec;
183c2c66affSColin Finck 	stime.wMilliseconds = 0;
184c2c66affSColin Finck 
185c2c66affSColin Finck 	return SystemTimeToFileTime(&stime, ftime);
186c2c66affSColin Finck }
187c2c66affSColin Finck 
188c2c66affSColin Finck 
launch_file(HWND hwnd,LPCTSTR cmd,UINT nCmdShow,LPCTSTR parameters)189c2c66affSColin Finck BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow, LPCTSTR parameters)
190c2c66affSColin Finck {
191c2c66affSColin Finck 	CONTEXT("launch_file()");
192c2c66affSColin Finck 
193c2c66affSColin Finck 	HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow);
194c2c66affSColin Finck 
195*a2f7de7eSTimo Kreuzer 	if ((INT_PTR)hinst <= 32) {
196c2c66affSColin Finck 		display_error(hwnd, GetLastError());
197c2c66affSColin Finck 		return FALSE;
198c2c66affSColin Finck 	}
199c2c66affSColin Finck 
200c2c66affSColin Finck 	return TRUE;
201c2c66affSColin Finck }
202c2c66affSColin Finck 
203c2c66affSColin Finck #ifdef UNICODE
launch_fileA(HWND hwnd,LPSTR cmd,UINT nCmdShow,LPCSTR parameters)204c2c66affSColin Finck BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow, LPCSTR parameters)
205c2c66affSColin Finck {
206c2c66affSColin Finck 	HINSTANCE hinst = ShellExecuteA(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow);
207c2c66affSColin Finck 
208*a2f7de7eSTimo Kreuzer 	if ((INT_PTR)hinst <= 32) {
209c2c66affSColin Finck 		display_error(hwnd, GetLastError());
210c2c66affSColin Finck 		return FALSE;
211c2c66affSColin Finck 	}
212c2c66affSColin Finck 
213c2c66affSColin Finck 	return TRUE;
214c2c66affSColin Finck }
215c2c66affSColin Finck #endif
216c2c66affSColin Finck 
217c2c66affSColin Finck 
218c2c66affSColin Finck /* search for already running instance */
219c2c66affSColin Finck 
220c2c66affSColin Finck static int g_foundPrevInstance = 0;
221c2c66affSColin Finck 
EnumWndProc(HWND hwnd,LPARAM lparam)222c2c66affSColin Finck static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lparam)
223c2c66affSColin Finck {
224c2c66affSColin Finck 	TCHAR cls[128];
225c2c66affSColin Finck 
226c2c66affSColin Finck 	GetClassName(hwnd, cls, 128);
227c2c66affSColin Finck 
228c2c66affSColin Finck 	if (!lstrcmp(cls, (LPCTSTR)lparam)) {
229c2c66affSColin Finck 		g_foundPrevInstance++;
230c2c66affSColin Finck 		return FALSE;
231c2c66affSColin Finck 	}
232c2c66affSColin Finck 
233c2c66affSColin Finck 	return TRUE;
234c2c66affSColin Finck }
235c2c66affSColin Finck 
236c2c66affSColin Finck /* search for window of given class name to allow only one running instance */
find_window_class(LPCTSTR classname)237c2c66affSColin Finck int find_window_class(LPCTSTR classname)
238c2c66affSColin Finck {
239c2c66affSColin Finck 	EnumWindows(EnumWndProc, (LPARAM)classname);
240c2c66affSColin Finck 
241c2c66affSColin Finck 	if (g_foundPrevInstance)
242c2c66affSColin Finck 		return 1;
243c2c66affSColin Finck 
244c2c66affSColin Finck 	return 0;
245c2c66affSColin Finck }
246c2c66affSColin Finck 
247c2c66affSColin Finck 
get_windows_version_str()248c2c66affSColin Finck String get_windows_version_str()
249c2c66affSColin Finck {
250c2c66affSColin Finck 	OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)};
251c2c66affSColin Finck 	BOOL osvie_val;
252c2c66affSColin Finck 	String str;
253c2c66affSColin Finck 
254c2c66affSColin Finck 	if (!(osvie_val = GetVersionEx((OSVERSIONINFO*)&osvi))) {
255c2c66affSColin Finck 		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
256c2c66affSColin Finck 
257c2c66affSColin Finck 		if (!GetVersionEx((OSVERSIONINFO*)&osvi))
258c2c66affSColin Finck 			return TEXT("???");
259c2c66affSColin Finck 	}
260c2c66affSColin Finck 
261c2c66affSColin Finck 	switch(osvi.dwPlatformId) {
262c2c66affSColin Finck 	  case VER_PLATFORM_WIN32_NT:
263c2c66affSColin Finck #ifdef __REACTOS__	// This work around can be removed if ReactOS gets a unique version number.
264c2c66affSColin Finck 		str = TEXT("ReactOS");
265c2c66affSColin Finck #else
266c2c66affSColin Finck 		if (osvi.dwMajorVersion <= 4)
267c2c66affSColin Finck 			str = TEXT("Microsoft Windows NT");
268c2c66affSColin Finck 		else if (osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0)
269c2c66affSColin Finck 			str = TEXT("Microsoft Windows 2000");
270c2c66affSColin Finck 		else if (osvi.dwMajorVersion==5 && osvi.dwMinorVersion==1)
271c2c66affSColin Finck 			str = TEXT("Microsoft Windows XP");
272c2c66affSColin Finck #endif
273c2c66affSColin Finck 
274c2c66affSColin Finck 		if (osvie_val) {
275c2c66affSColin Finck 			if (osvi.wProductType == VER_NT_WORKSTATION) {
276c2c66affSColin Finck 			   if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
277c2c66affSColin Finck 				  str += TEXT(" Personal");
278c2c66affSColin Finck 			   else
279c2c66affSColin Finck 				  str += TEXT(" Professional");
280c2c66affSColin Finck 			} else if (osvi.wProductType == VER_NT_SERVER) {
281c2c66affSColin Finck 			   if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
282c2c66affSColin Finck 				  str += TEXT(" DataCenter Server");
283c2c66affSColin Finck 			   else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
284c2c66affSColin Finck 				  str += TEXT(" Advanced Server");
285c2c66affSColin Finck 			   else
286c2c66affSColin Finck 				  str += TEXT(" Server");
287c2c66affSColin Finck 			} else if (osvi.wProductType == VER_NT_DOMAIN_CONTROLLER) {
288c2c66affSColin Finck 				str += TEXT(" Domain Controller");
289c2c66affSColin Finck 			}
290c2c66affSColin Finck 		} else {
291c2c66affSColin Finck 			TCHAR type[80];
292c2c66affSColin Finck 			DWORD dwBufLen;
293c2c66affSColin Finck 			HKEY hkey;
294c2c66affSColin Finck 
295c2c66affSColin Finck 			if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hkey)) {
296c2c66affSColin Finck 				RegQueryValueEx(hkey, TEXT("ProductType"), NULL, NULL, (LPBYTE)type, &dwBufLen);
297c2c66affSColin Finck 				RegCloseKey(hkey);
298c2c66affSColin Finck 
299c2c66affSColin Finck 				if (!_tcsicmp(TEXT("WINNT"), type))
300c2c66affSColin Finck 				   str += TEXT(" Workstation");
301c2c66affSColin Finck 				else if (!_tcsicmp(TEXT("LANMANNT"), type))
302c2c66affSColin Finck 				   str += TEXT(" Server");
303c2c66affSColin Finck 				else if (!_tcsicmp(TEXT("SERVERNT"), type))
304c2c66affSColin Finck 					str += TEXT(" Advanced Server");
305c2c66affSColin Finck 			}
306c2c66affSColin Finck 		}
307c2c66affSColin Finck 		break;
308c2c66affSColin Finck 
309c2c66affSColin Finck 	  case VER_PLATFORM_WIN32_WINDOWS:
310c2c66affSColin Finck 		if (osvi.dwMajorVersion>4 ||
311c2c66affSColin Finck 			(osvi.dwMajorVersion==4 && osvi.dwMinorVersion>0)) {
312c2c66affSColin Finck 			if (osvi.dwMinorVersion == 90)
313c2c66affSColin Finck 				str = TEXT("Microsoft Windows ME");
314c2c66affSColin Finck 			else
315c2c66affSColin Finck 				str = TEXT("Microsoft Windows 98");
316c2c66affSColin Finck 
317c2c66affSColin Finck             if (osvi.szCSDVersion[1] == 'A')
318c2c66affSColin Finck 				str += TEXT(" SE");
319c2c66affSColin Finck 		} else {
320c2c66affSColin Finck 			str = TEXT("Microsoft Windows 95");
321c2c66affSColin Finck 
322c2c66affSColin Finck             if (osvi.szCSDVersion[1]=='B' || osvi.szCSDVersion[1]=='C')
323c2c66affSColin Finck 				str += TEXT(" OSR2");
324c2c66affSColin Finck 		}
325c2c66affSColin Finck 		break;
326c2c66affSColin Finck 
327c2c66affSColin Finck 	  case VER_PLATFORM_WIN32s:
328c2c66affSColin Finck 		str = TEXT("Microsoft Win32s");
329c2c66affSColin Finck 
330c2c66affSColin Finck 	  default:
331c2c66affSColin Finck 		return TEXT("???");
332c2c66affSColin Finck 	}
333c2c66affSColin Finck 
334c2c66affSColin Finck 	String vstr;
335c2c66affSColin Finck 
336c2c66affSColin Finck 	if (osvi.dwMajorVersion <= 4)
337c2c66affSColin Finck 		vstr.printf(TEXT(" Version %d.%d %s Build %d"),
338c2c66affSColin Finck 						osvi.dwMajorVersion, osvi.dwMinorVersion,
339c2c66affSColin Finck 						osvi.szCSDVersion, osvi.dwBuildNumber&0xFFFF);
340c2c66affSColin Finck 	else
341c2c66affSColin Finck 		vstr.printf(TEXT(" %s (Build %d)"), osvi.szCSDVersion, osvi.dwBuildNumber&0xFFFF);
342c2c66affSColin Finck 
343c2c66affSColin Finck 	return str + vstr;
344c2c66affSColin Finck }
345c2c66affSColin Finck 
346c2c66affSColin Finck 
347c2c66affSColin Finck typedef void (WINAPI*RUNDLLPROC)(HWND hwnd, HINSTANCE hinst, LPCTSTR cmdline, DWORD nCmdShow);
348c2c66affSColin Finck 
RunDLL(HWND hwnd,LPCTSTR dllname,LPCSTR procname,LPCTSTR cmdline,UINT nCmdShow)349c2c66affSColin Finck BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow)
350c2c66affSColin Finck {
351c2c66affSColin Finck 	HMODULE hmod = LoadLibrary(dllname);
352c2c66affSColin Finck 	if (!hmod)
353c2c66affSColin Finck 		return FALSE;
354c2c66affSColin Finck 
355c2c66affSColin Finck /*TODO
356c2c66affSColin Finck 	<Windows NT/2000>
357c2c66affSColin Finck 	It is possible to create a Unicode version of the function.
358c2c66affSColin Finck 	Rundll32 first tries to find a function named EntryPointW.
359c2c66affSColin Finck 	If it cannot find this function, it tries EntryPointA, then EntryPoint.
360c2c66affSColin Finck 	To create a DLL that supports ANSI on Windows 95/98/Me and Unicode otherwise,
361c2c66affSColin Finck 	export two functions: EntryPointW and EntryPoint.
362c2c66affSColin Finck */
363c2c66affSColin Finck 	RUNDLLPROC proc = (RUNDLLPROC)GetProcAddress(hmod, procname);
364c2c66affSColin Finck 	if (!proc) {
365c2c66affSColin Finck 		FreeLibrary(hmod);
366c2c66affSColin Finck 		return FALSE;
367c2c66affSColin Finck 	}
368c2c66affSColin Finck 
369c2c66affSColin Finck 	proc(hwnd, hmod, cmdline, nCmdShow);
370c2c66affSColin Finck 
371c2c66affSColin Finck 	FreeLibrary(hmod);
372c2c66affSColin Finck 
373c2c66affSColin Finck 	return TRUE;
374c2c66affSColin Finck }
375c2c66affSColin Finck 
376c2c66affSColin Finck 
377c2c66affSColin Finck #ifdef UNICODE
378c2c66affSColin Finck #define CONTROL_RUNDLL "Control_RunDLLW"
379c2c66affSColin Finck #else
380c2c66affSColin Finck #define CONTROL_RUNDLL "Control_RunDLLA"
381c2c66affSColin Finck #endif
382c2c66affSColin Finck 
launch_cpanel(HWND hwnd,LPCTSTR applet)383c2c66affSColin Finck BOOL launch_cpanel(HWND hwnd, LPCTSTR applet)
384c2c66affSColin Finck {
385c2c66affSColin Finck 	TCHAR parameters[MAX_PATH];
386c2c66affSColin Finck 
387c2c66affSColin Finck 	_tcscpy(parameters, TEXT("shell32.dll,Control_RunDLL "));
388c2c66affSColin Finck 	_tcscat(parameters, applet);
389c2c66affSColin Finck 
390*a2f7de7eSTimo Kreuzer 	return ((INT_PTR)ShellExecute(hwnd, TEXT("open"), TEXT("rundll32.exe"), parameters, NULL, SW_SHOWDEFAULT) > 32);
391c2c66affSColin Finck }
392c2c66affSColin Finck 
393c2c66affSColin Finck 
RecursiveCreateDirectory(LPCTSTR path_in)394c2c66affSColin Finck BOOL RecursiveCreateDirectory(LPCTSTR path_in)
395c2c66affSColin Finck {
396c2c66affSColin Finck 	TCHAR path[MAX_PATH], hole_path[MAX_PATH];
397c2c66affSColin Finck 
398c2c66affSColin Finck 	_tcscpy(hole_path, path_in);
399c2c66affSColin Finck 
400c2c66affSColin Finck 	int drv_len = 0;
401c2c66affSColin Finck 	LPCTSTR d;
402c2c66affSColin Finck 
403c2c66affSColin Finck 	for(d=hole_path; *d && *d!='/' && *d!='\\'; ++d) {
404c2c66affSColin Finck 		++drv_len;
405c2c66affSColin Finck 
406c2c66affSColin Finck 		if (*d == ':')
407c2c66affSColin Finck 			break;
408c2c66affSColin Finck 	}
409c2c66affSColin Finck 
410c2c66affSColin Finck 	LPTSTR dir = hole_path + drv_len;
411c2c66affSColin Finck 
412c2c66affSColin Finck 	int l;
413c2c66affSColin Finck 	LPTSTR p = hole_path + (l=_tcslen(hole_path));
414c2c66affSColin Finck 
415c2c66affSColin Finck 	while(--p>=hole_path && (*p=='/' || *p=='\\'))
416c2c66affSColin Finck 		*p = '\0';
417c2c66affSColin Finck 
418c2c66affSColin Finck 	WIN32_FIND_DATA w32fd;
419c2c66affSColin Finck 
420c2c66affSColin Finck 	HANDLE hFind = FindFirstFile(hole_path, &w32fd);
421c2c66affSColin Finck 
422c2c66affSColin Finck 	if (hFind == INVALID_HANDLE_VALUE) {
423c2c66affSColin Finck 		_tcsncpy(path, hole_path, drv_len);
424c2c66affSColin Finck 		int i = drv_len;
425c2c66affSColin Finck 
426c2c66affSColin Finck 		for(p=dir; *p=='/'||*p=='\\'; p++)
427c2c66affSColin Finck 			path[i++] = *p++;
428c2c66affSColin Finck 
429c2c66affSColin Finck 		for(; i<l; i++) {
430c2c66affSColin Finck 			memcpy(path, hole_path, i*sizeof(TCHAR));
431c2c66affSColin Finck 
432c2c66affSColin Finck 			for(; hole_path[i] && hole_path[i]!='/' && hole_path[i]!='\\'; i++)
433c2c66affSColin Finck 				path[i] = hole_path[i];
434c2c66affSColin Finck 
435c2c66affSColin Finck 			path[i] = '\0';
436c2c66affSColin Finck 
437c2c66affSColin Finck 			hFind = FindFirstFile(path, &w32fd);
438c2c66affSColin Finck 
439c2c66affSColin Finck 			if (hFind != INVALID_HANDLE_VALUE)
440c2c66affSColin Finck 				FindClose(hFind);
441c2c66affSColin Finck 			else {
442c2c66affSColin Finck 				LOG(FmtString(TEXT("CreateDirectory(\"%s\")"), path));
443c2c66affSColin Finck 
444c2c66affSColin Finck 				if (!CreateDirectory(path, 0))
445c2c66affSColin Finck 					return FALSE;
446c2c66affSColin Finck 			}
447c2c66affSColin Finck 		}
448c2c66affSColin Finck 	} else
449c2c66affSColin Finck 		FindClose(hFind);
450c2c66affSColin Finck 
451c2c66affSColin Finck 	return TRUE;
452c2c66affSColin Finck }
453c2c66affSColin Finck 
454c2c66affSColin Finck 
RegGetDWORDValue(HKEY root,LPCTSTR path,LPCTSTR valueName,DWORD def)455c2c66affSColin Finck DWORD RegGetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD def)
456c2c66affSColin Finck {
457c2c66affSColin Finck 	HKEY hkey;
458c2c66affSColin Finck 	DWORD ret;
459c2c66affSColin Finck 
460c2c66affSColin Finck 	if (!RegOpenKey(root, path, &hkey)) {
461c2c66affSColin Finck 		DWORD len = sizeof(ret);
462c2c66affSColin Finck 
463c2c66affSColin Finck 		if (RegQueryValueEx(hkey, valueName, 0, NULL, (LPBYTE)&ret, &len))
464c2c66affSColin Finck 			ret = def;
465c2c66affSColin Finck 
466c2c66affSColin Finck 		RegCloseKey(hkey);
467c2c66affSColin Finck 
468c2c66affSColin Finck 		return ret;
469c2c66affSColin Finck 	} else
470c2c66affSColin Finck 		return def;
471c2c66affSColin Finck }
472c2c66affSColin Finck 
473c2c66affSColin Finck 
RegSetDWORDValue(HKEY root,LPCTSTR path,LPCTSTR valueName,DWORD value)474c2c66affSColin Finck BOOL RegSetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD value)
475c2c66affSColin Finck {
476c2c66affSColin Finck 	HKEY hkey;
477c2c66affSColin Finck 	BOOL ret = FALSE;
478c2c66affSColin Finck 
479c2c66affSColin Finck 	if (!RegOpenKey(root, path, &hkey)) {
480c2c66affSColin Finck 		ret = RegSetValueEx(hkey, valueName, 0, REG_DWORD, (LPBYTE)&value, sizeof(value));
481c2c66affSColin Finck 
482c2c66affSColin Finck 		RegCloseKey(hkey);
483c2c66affSColin Finck 	}
484c2c66affSColin Finck 
485c2c66affSColin Finck 	return ret;
486c2c66affSColin Finck }
487c2c66affSColin Finck 
488c2c66affSColin Finck 
exists_path(LPCTSTR path)489c2c66affSColin Finck BOOL exists_path(LPCTSTR path)
490c2c66affSColin Finck {
491c2c66affSColin Finck 	WIN32_FIND_DATA fd;
492c2c66affSColin Finck 
493c2c66affSColin Finck 	HANDLE hfind = FindFirstFile(path, &fd);
494c2c66affSColin Finck 
495c2c66affSColin Finck 	if (hfind != INVALID_HANDLE_VALUE) {
496c2c66affSColin Finck 		FindClose(hfind);
497c2c66affSColin Finck 
498c2c66affSColin Finck 		return TRUE;
499c2c66affSColin Finck 	} else
500c2c66affSColin Finck 		return FALSE;
501c2c66affSColin Finck }
502c2c66affSColin Finck 
503c2c66affSColin Finck 
SplitFileSysURL(LPCTSTR url,String & dir_out,String & fname_out)504c2c66affSColin Finck bool SplitFileSysURL(LPCTSTR url, String& dir_out, String& fname_out)
505c2c66affSColin Finck {
506c2c66affSColin Finck 	if (!_tcsnicmp(url, TEXT("file://"), 7)) {
507c2c66affSColin Finck 		url += 7;
508c2c66affSColin Finck 
509c2c66affSColin Finck 		 // remove third slash in front of drive characters
510c2c66affSColin Finck 		if (*url == '/')
511c2c66affSColin Finck 			++url;
512c2c66affSColin Finck 	}
513c2c66affSColin Finck 
514c2c66affSColin Finck 	if (exists_path(url)) {
515c2c66affSColin Finck 		TCHAR path[_MAX_PATH];
516c2c66affSColin Finck 
517c2c66affSColin Finck 		 // convert slashes to back slashes
518c2c66affSColin Finck 		GetFullPathName(url, COUNTOF(path), path, NULL);
519c2c66affSColin Finck 
520c2c66affSColin Finck 		if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY)
521c2c66affSColin Finck 			fname_out.erase();
522c2c66affSColin Finck 		else {
523c2c66affSColin Finck 			TCHAR drv[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
524c2c66affSColin Finck 
525c2c66affSColin Finck 			_tsplitpath_s(path, drv, COUNTOF(drv), dir, COUNTOF(dir), fname, COUNTOF(fname), ext, COUNTOF(ext));
526c2c66affSColin Finck 			_stprintf(path, TEXT("%s%s"), drv, dir);
527c2c66affSColin Finck 
528c2c66affSColin Finck 			fname_out.printf(TEXT("%s%s"), fname, ext);
529c2c66affSColin Finck 		}
530c2c66affSColin Finck 
531c2c66affSColin Finck 		dir_out = path;
532c2c66affSColin Finck 
533c2c66affSColin Finck 		return true;
534c2c66affSColin Finck 	} else
535c2c66affSColin Finck 		return false;
536c2c66affSColin Finck }
537