utility.cpp

Go to the documentation of this file.
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 doxygen

ROS Explorer Homepage