00001 /* 00002 * Copyright 2003, 2004, 2005 Martin Fuchs 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 00020 // 00021 // Explorer clone 00022 // 00023 // utility.cpp 00024 // 00025 // Martin Fuchs, 23.07.2003 00026 // 00027 00028 00029 #include <precomp.h> 00030 00031 //#include <shellapi.h> 00032 00033 #include <time.h> 00034 #include <sstream> 00035 00036 00037 DWORD WINAPI Thread::ThreadProc(void* para) 00038 { 00039 Thread* pThis = (Thread*) para; 00040 00041 int ret = pThis->Run(); 00042 00043 pThis->_alive = false; 00044 00045 return ret; 00046 } 00047 00048 00049 void CenterWindow(HWND hwnd) 00050 { 00051 RECT rt, prt; 00052 GetWindowRect(hwnd, &rt); 00053 00054 DWORD style; 00055 HWND owner = 0; 00056 00057 for(HWND wh=hwnd; (wh=GetWindow(wh,GW_OWNER))!=0; ) 00058 if (((style=GetWindowStyle(wh))&WS_VISIBLE) && !(style&WS_MINIMIZE)) 00059 {owner=wh; break;} 00060 00061 if (owner) 00062 GetWindowRect(owner, &prt); 00063 else 00064 SystemParametersInfo(SPI_GETWORKAREA, 0, &prt, 0); //@@ GetDesktopWindow() wäre auch hilfreich. 00065 00066 SetWindowPos(hwnd, 0, (prt.left+prt.right+rt.left-rt.right)/2, 00067 (prt.top+prt.bottom+rt.top-rt.bottom)/2, 0,0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER); 00068 00069 MoveVisible(hwnd); 00070 } 00071 00072 void MoveVisible(HWND hwnd) 00073 { 00074 RECT rc; 00075 GetWindowRect(hwnd, &rc); 00076 int left=rc.left, top=rc.top; 00077 00078 int xmax = GetSystemMetrics(SM_CXSCREEN); 00079 int ymax = GetSystemMetrics(SM_CYSCREEN); 00080 00081 if (rc.left < 0) 00082 rc.left = 0; 00083 else if (rc.right > xmax) 00084 if ((rc.left-=rc.right-xmax) < 0) 00085 rc.left = 0; 00086 00087 if (rc.top < 0) 00088 rc.top = 0; 00089 else if (rc.bottom > ymax) 00090 if ((rc.top-=rc.bottom-ymax) < 0) 00091 rc.top = 0; 00092 00093 if (rc.left!=left || rc.top!=top) 00094 SetWindowPos(hwnd, 0, rc.left,rc.top, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE); 00095 } 00096 00097 00098 void display_error(HWND hwnd, DWORD error) //@@ CONTEXT mit ausgeben -> display_error(HWND hwnd, const Exception& e) 00099 { 00100 PTSTR msg; 00101 00102 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 00103 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) { 00104 LOG(FmtString(TEXT("display_error(%#x): %s"), error, msg)); 00105 00106 SetLastError(0); 00107 MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK); 00108 00109 if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE) 00110 MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK); 00111 } else { 00112 LOG(FmtString(TEXT("Unknown Error %#x"), error)); 00113 00114 FmtString msg(TEXT("Unknown Error %#x"), error); 00115 00116 SetLastError(0); 00117 MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK); 00118 00119 if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE) 00120 MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK); 00121 } 00122 00123 LocalFree(msg); 00124 } 00125 00126 00127 Context Context::s_main("-NO-CONTEXT-"); 00128 Context* Context::s_current = &Context::s_main; 00129 00130 String Context::toString() const 00131 { 00132 String str = _ctx; 00133 00134 if (!_obj.empty()) 00135 str.appendf(TEXT("\nObject: %s"), (LPCTSTR)_obj); 00136 00137 return str; 00138 } 00139 00140 String Context::getStackTrace() const 00141 { 00142 ostringstream str; 00143 00144 str << "Context Trace:\n"; 00145 00146 for(const Context*p=this; p && p!=&s_main; p=p->_last) { 00147 str << "- " << p->_ctx; 00148 00149 if (!p->_obj.empty()) 00150 str << " obj=" << ANS(p->_obj); 00151 00152 str << '\n'; 00153 } 00154 00155 return str.str(); 00156 } 00157 00158 00159 BOOL time_to_filetime(const time_t* t, FILETIME* ftime) 00160 { 00161 #ifdef __STDC_WANT_SECURE_LIB__ 00162 SYSTEMTIME stime; 00163 struct tm tm_; 00164 struct tm* tm = &tm_; 00165 00166 if (gmtime_s(tm, t) != 0) 00167 return FALSE; 00168 #else 00169 struct tm* tm = gmtime(t); 00170 SYSTEMTIME stime; 00171 00172 if (!tm) 00173 return FALSE; 00174 #endif 00175 00176 stime.wYear = tm->tm_year+1900; 00177 stime.wMonth = tm->tm_mon+1; 00178 stime.wDayOfWeek = (WORD)-1; 00179 stime.wDay = tm->tm_mday; 00180 stime.wHour = tm->tm_hour; 00181 stime.wMinute = tm->tm_min; 00182 stime.wSecond = tm->tm_sec; 00183 stime.wMilliseconds = 0; 00184 00185 return SystemTimeToFileTime(&stime, ftime); 00186 } 00187 00188 00189 BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow, LPCTSTR parameters) 00190 { 00191 CONTEXT("launch_file()"); 00192 00193 HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow); 00194 00195 if ((int)hinst <= 32) { 00196 display_error(hwnd, GetLastError()); 00197 return FALSE; 00198 } 00199 00200 return TRUE; 00201 } 00202 00203 #ifdef UNICODE 00204 BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow, LPCSTR parameters) 00205 { 00206 HINSTANCE hinst = ShellExecuteA(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow); 00207 00208 if ((int)hinst <= 32) { 00209 display_error(hwnd, GetLastError()); 00210 return FALSE; 00211 } 00212 00213 return TRUE; 00214 } 00215 #endif 00216 00217 00218 /* search for already running instance */ 00219 00220 static int g_foundPrevInstance = 0; 00221 00222 static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lparam) 00223 { 00224 TCHAR cls[128]; 00225 00226 GetClassName(hwnd, cls, 128); 00227 00228 if (!lstrcmp(cls, (LPCTSTR)lparam)) { 00229 g_foundPrevInstance++; 00230 return FALSE; 00231 } 00232 00233 return TRUE; 00234 } 00235 00236 /* search for window of given class name to allow only one running instance */ 00237 int find_window_class(LPCTSTR classname) 00238 { 00239 EnumWindows(EnumWndProc, (LPARAM)classname); 00240 00241 if (g_foundPrevInstance) 00242 return 1; 00243 00244 return 0; 00245 } 00246 00247 00248 String get_windows_version_str() 00249 { 00250 OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)}; 00251 BOOL osvie_val; 00252 String str; 00253 00254 if (!(osvie_val = GetVersionEx((OSVERSIONINFO*)&osvi))) { 00255 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 00256 00257 if (!GetVersionEx((OSVERSIONINFO*)&osvi)) 00258 return TEXT("???"); 00259 } 00260 00261 switch(osvi.dwPlatformId) { 00262 case VER_PLATFORM_WIN32_NT: 00263 #ifdef __REACTOS__ // This work around can be removed if ReactOS gets a unique version number. 00264 str = TEXT("ReactOS"); 00265 #else 00266 if (osvi.dwMajorVersion <= 4) 00267 str = TEXT("Microsoft Windows NT"); 00268 else if (osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0) 00269 str = TEXT("Microsoft Windows 2000"); 00270 else if (osvi.dwMajorVersion==5 && osvi.dwMinorVersion==1) 00271 str = TEXT("Microsoft Windows XP"); 00272 #endif 00273 00274 if (osvie_val) { 00275 if (osvi.wProductType == VER_NT_WORKSTATION) { 00276 if (osvi.wSuiteMask & VER_SUITE_PERSONAL) 00277 str += TEXT(" Personal"); 00278 else 00279 str += TEXT(" Professional"); 00280 } else if (osvi.wProductType == VER_NT_SERVER) { 00281 if (osvi.wSuiteMask & VER_SUITE_DATACENTER) 00282 str += TEXT(" DataCenter Server"); 00283 else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) 00284 str += TEXT(" Advanced Server"); 00285 else 00286 str += TEXT(" Server"); 00287 } else if (osvi.wProductType == VER_NT_DOMAIN_CONTROLLER) { 00288 str += TEXT(" Domain Controller"); 00289 } 00290 } else { 00291 TCHAR type[80]; 00292 DWORD dwBufLen; 00293 HKEY hkey; 00294 00295 if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hkey)) { 00296 RegQueryValueEx(hkey, TEXT("ProductType"), NULL, NULL, (LPBYTE)type, &dwBufLen); 00297 RegCloseKey(hkey); 00298 00299 if (!_tcsicmp(TEXT("WINNT"), type)) 00300 str += TEXT(" Workstation"); 00301 else if (!_tcsicmp(TEXT("LANMANNT"), type)) 00302 str += TEXT(" Server"); 00303 else if (!_tcsicmp(TEXT("SERVERNT"), type)) 00304 str += TEXT(" Advanced Server"); 00305 } 00306 } 00307 break; 00308 00309 case VER_PLATFORM_WIN32_WINDOWS: 00310 if (osvi.dwMajorVersion>4 || 00311 (osvi.dwMajorVersion==4 && osvi.dwMinorVersion>0)) { 00312 if (osvi.dwMinorVersion == 90) 00313 str = TEXT("Microsoft Windows ME"); 00314 else 00315 str = TEXT("Microsoft Windows 98"); 00316 00317 if (osvi.szCSDVersion[1] == 'A') 00318 str += TEXT(" SE"); 00319 } else { 00320 str = TEXT("Microsoft Windows 95"); 00321 00322 if (osvi.szCSDVersion[1]=='B' || osvi.szCSDVersion[1]=='C') 00323 str += TEXT(" OSR2"); 00324 } 00325 break; 00326 00327 case VER_PLATFORM_WIN32s: 00328 str = TEXT("Microsoft Win32s"); 00329 00330 default: 00331 return TEXT("???"); 00332 } 00333 00334 String vstr; 00335 00336 if (osvi.dwMajorVersion <= 4) 00337 vstr.printf(TEXT(" Version %d.%d %s Build %d"), 00338 osvi.dwMajorVersion, osvi.dwMinorVersion, 00339 osvi.szCSDVersion, osvi.dwBuildNumber&0xFFFF); 00340 else 00341 vstr.printf(TEXT(" %s (Build %d)"), osvi.szCSDVersion, osvi.dwBuildNumber&0xFFFF); 00342 00343 return str + vstr; 00344 } 00345 00346 00347 typedef void (WINAPI*RUNDLLPROC)(HWND hwnd, HINSTANCE hinst, LPCTSTR cmdline, DWORD nCmdShow); 00348 00349 BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow) 00350 { 00351 HMODULE hmod = LoadLibrary(dllname); 00352 if (!hmod) 00353 return FALSE; 00354 00355 /*TODO 00356 <Windows NT/2000> 00357 It is possible to create a Unicode version of the function. 00358 Rundll32 first tries to find a function named EntryPointW. 00359 If it cannot find this function, it tries EntryPointA, then EntryPoint. 00360 To create a DLL that supports ANSI on Windows 95/98/Me and Unicode otherwise, 00361 export two functions: EntryPointW and EntryPoint. 00362 */ 00363 RUNDLLPROC proc = (RUNDLLPROC)GetProcAddress(hmod, procname); 00364 if (!proc) { 00365 FreeLibrary(hmod); 00366 return FALSE; 00367 } 00368 00369 proc(hwnd, hmod, cmdline, nCmdShow); 00370 00371 FreeLibrary(hmod); 00372 00373 return TRUE; 00374 } 00375 00376 00377 #ifdef UNICODE 00378 #define CONTROL_RUNDLL "Control_RunDLLW" 00379 #else 00380 #define CONTROL_RUNDLL "Control_RunDLLA" 00381 #endif 00382 00383 BOOL launch_cpanel(HWND hwnd, LPCTSTR applet) 00384 { 00385 TCHAR parameters[MAX_PATH]; 00386 00387 _tcscpy(parameters, TEXT("shell32.dll,Control_RunDLL ")); 00388 _tcscat(parameters, applet); 00389 00390 return ((int)ShellExecute(hwnd, TEXT("open"), TEXT("rundll32.exe"), parameters, NULL, SW_SHOWDEFAULT) > 32); 00391 } 00392 00393 00394 BOOL RecursiveCreateDirectory(LPCTSTR path_in) 00395 { 00396 TCHAR path[MAX_PATH], hole_path[MAX_PATH]; 00397 00398 _tcscpy(hole_path, path_in); 00399 00400 int drv_len = 0; 00401 LPCTSTR d; 00402 00403 for(d=hole_path; *d && *d!='/' && *d!='\\'; ++d) { 00404 ++drv_len; 00405 00406 if (*d == ':') 00407 break; 00408 } 00409 00410 LPTSTR dir = hole_path + drv_len; 00411 00412 int l; 00413 LPTSTR p = hole_path + (l=_tcslen(hole_path)); 00414 00415 while(--p>=hole_path && (*p=='/' || *p=='\\')) 00416 *p = '\0'; 00417 00418 WIN32_FIND_DATA w32fd; 00419 00420 HANDLE hFind = FindFirstFile(hole_path, &w32fd); 00421 00422 if (hFind == INVALID_HANDLE_VALUE) { 00423 _tcsncpy(path, hole_path, drv_len); 00424 int i = drv_len; 00425 00426 for(p=dir; *p=='/'||*p=='\\'; p++) 00427 path[i++] = *p++; 00428 00429 for(; i<l; i++) { 00430 memcpy(path, hole_path, i*sizeof(TCHAR)); 00431 00432 for(; hole_path[i] && hole_path[i]!='/' && hole_path[i]!='\\'; i++) 00433 path[i] = hole_path[i]; 00434 00435 path[i] = '\0'; 00436 00437 hFind = FindFirstFile(path, &w32fd); 00438 00439 if (hFind != INVALID_HANDLE_VALUE) 00440 FindClose(hFind); 00441 else { 00442 LOG(FmtString(TEXT("CreateDirectory(\"%s\")"), path)); 00443 00444 if (!CreateDirectory(path, 0)) 00445 return FALSE; 00446 } 00447 } 00448 } else 00449 FindClose(hFind); 00450 00451 return TRUE; 00452 } 00453 00454 00455 DWORD RegGetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD def) 00456 { 00457 HKEY hkey; 00458 DWORD ret; 00459 00460 if (!RegOpenKey(root, path, &hkey)) { 00461 DWORD len = sizeof(ret); 00462 00463 if (RegQueryValueEx(hkey, valueName, 0, NULL, (LPBYTE)&ret, &len)) 00464 ret = def; 00465 00466 RegCloseKey(hkey); 00467 00468 return ret; 00469 } else 00470 return def; 00471 } 00472 00473 00474 BOOL RegSetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD value) 00475 { 00476 HKEY hkey; 00477 BOOL ret = FALSE; 00478 00479 if (!RegOpenKey(root, path, &hkey)) { 00480 ret = RegSetValueEx(hkey, valueName, 0, REG_DWORD, (LPBYTE)&value, sizeof(value)); 00481 00482 RegCloseKey(hkey); 00483 } 00484 00485 return ret; 00486 } 00487 00488 00489 BOOL exists_path(LPCTSTR path) 00490 { 00491 WIN32_FIND_DATA fd; 00492 00493 HANDLE hfind = FindFirstFile(path, &fd); 00494 00495 if (hfind != INVALID_HANDLE_VALUE) { 00496 FindClose(hfind); 00497 00498 return TRUE; 00499 } else 00500 return FALSE; 00501 } 00502 00503 00504 bool SplitFileSysURL(LPCTSTR url, String& dir_out, String& fname_out) 00505 { 00506 if (!_tcsnicmp(url, TEXT("file://"), 7)) { 00507 url += 7; 00508 00509 // remove third slash in front of drive characters 00510 if (*url == '/') 00511 ++url; 00512 } 00513 00514 if (exists_path(url)) { 00515 TCHAR path[_MAX_PATH]; 00516 00517 // convert slashes to back slashes 00518 GetFullPathName(url, COUNTOF(path), path, NULL); 00519 00520 if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) 00521 fname_out.erase(); 00522 else { 00523 TCHAR drv[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; 00524 00525 _tsplitpath_s(path, drv, COUNTOF(drv), dir, COUNTOF(dir), fname, COUNTOF(fname), ext, COUNTOF(ext)); 00526 _stprintf(path, TEXT("%s%s"), drv, dir); 00527 00528 fname_out.printf(TEXT("%s%s"), fname, ext); 00529 } 00530 00531 dir_out = path; 00532 00533 return true; 00534 } else 00535 return false; 00536 }
ROS Explorer Source Code Documentation
generated on 02.01.2013 by ![]() |