Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12 kB · 536 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537/* * Copyright 2003, 2004, 2005 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// // Explorer clone // // utility.cpp // // Martin Fuchs, 23.07.2003 //
#include <precomp.h>
//#include <shellapi.h>
#include <time.h>#include <sstream>
DWORD WINAPI Thread::ThreadProc(void* para){ Thread* pThis = (Thread*) para;
int ret = pThis->Run();
pThis->_alive = false;
return ret;}
void CenterWindow(HWND hwnd){ RECT rt, prt; GetWindowRect(hwnd, &rt);
DWORD style; HWND owner = 0;
for(HWND wh=hwnd; (wh=GetWindow(wh,GW_OWNER))!=0; ) if (((style=GetWindowStyle(wh))&WS_VISIBLE) && !(style&WS_MINIMIZE)) {owner=wh; break;}
if (owner) GetWindowRect(owner, &prt); else SystemParametersInfo(SPI_GETWORKAREA, 0, &prt, 0); //@@ GetDesktopWindow() w�re auch hilfreich.
SetWindowPos(hwnd, 0, (prt.left+prt.right+rt.left-rt.right)/2, (prt.top+prt.bottom+rt.top-rt.bottom)/2, 0,0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
MoveVisible(hwnd);}
void MoveVisible(HWND hwnd){ RECT rc; GetWindowRect(hwnd, &rc); int left=rc.left, top=rc.top;
int xmax = GetSystemMetrics(SM_CXSCREEN); int ymax = GetSystemMetrics(SM_CYSCREEN);
if (rc.left < 0) rc.left = 0; else if (rc.right > xmax) if ((rc.left-=rc.right-xmax) < 0) rc.left = 0;
if (rc.top < 0) rc.top = 0; else if (rc.bottom > ymax) if ((rc.top-=rc.bottom-ymax) < 0) rc.top = 0;
if (rc.left!=left || rc.top!=top) SetWindowPos(hwnd, 0, rc.left,rc.top, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);}
void display_error(HWND hwnd, DWORD error) //@@ CONTEXT mit ausgeben -> display_error(HWND hwnd, const Exception& e){ PTSTR msg;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) { LOG(FmtString(TEXT("display_error(%#x): %s"), error, msg));
SetLastError(0); MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK);
if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE) MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK); } else { LOG(FmtString(TEXT("Unknown Error %#x"), error));
FmtString msg(TEXT("Unknown Error %#x"), error);
SetLastError(0); MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK);
if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE) MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK); }
LocalFree(msg);}
Context Context::s_main("-NO-CONTEXT-");Context* Context::s_current = &Context::s_main;
String Context::toString() const{ String str = _ctx;
if (!_obj.empty()) str.appendf(TEXT("\nObject: %s"), (LPCTSTR)_obj);
return str;}
String Context::getStackTrace() const{ ostringstream str;
str << "Context Trace:\n";
for(const Context*p=this; p && p!=&s_main; p=p->_last) { str << "- " << p->_ctx;
if (!p->_obj.empty()) str << " obj=" << ANS(p->_obj);
str << '\n'; }
return str.str();}
BOOL time_to_filetime(const time_t* t, FILETIME* ftime){#if defined(__STDC_WANT_SECURE_LIB__) && defined(_MS_VER) SYSTEMTIME stime; struct tm tm_; struct tm* tm = &tm_;
if (gmtime_s(tm, t) != 0) return FALSE;#else struct tm* tm = gmtime(t); SYSTEMTIME stime;
if (!tm) return FALSE;#endif
stime.wYear = tm->tm_year+1900; stime.wMonth = tm->tm_mon+1; stime.wDayOfWeek = (WORD)-1; stime.wDay = tm->tm_mday; stime.wHour = tm->tm_hour; stime.wMinute = tm->tm_min; stime.wSecond = tm->tm_sec; stime.wMilliseconds = 0;
return SystemTimeToFileTime(&stime, ftime);}
BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow, LPCTSTR parameters){ CONTEXT("launch_file()");
HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow);
if ((INT_PTR)hinst <= 32) { display_error(hwnd, GetLastError()); return FALSE; }
return TRUE;}
#ifdef UNICODEBOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow, LPCSTR parameters){ HINSTANCE hinst = ShellExecuteA(hwnd, NULL/*operation*/, cmd, parameters, NULL/*dir*/, nCmdShow);
if ((INT_PTR)hinst <= 32) { display_error(hwnd, GetLastError()); return FALSE; }
return TRUE;}#endif
/* search for already running instance */
static int g_foundPrevInstance = 0;
static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lparam){ TCHAR cls[128];
GetClassName(hwnd, cls, 128);
if (!lstrcmp(cls, (LPCTSTR)lparam)) { g_foundPrevInstance++; return FALSE; }
return TRUE;}
/* search for window of given class name to allow only one running instance */int find_window_class(LPCTSTR classname){ EnumWindows(EnumWndProc, (LPARAM)classname);
if (g_foundPrevInstance) return 1;
return 0;}
String get_windows_version_str(){ OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)}; BOOL osvie_val; String str;
if (!(osvie_val = GetVersionEx((OSVERSIONINFO*)&osvi))) { osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx((OSVERSIONINFO*)&osvi)) return TEXT("???"); }
switch(osvi.dwPlatformId) { case VER_PLATFORM_WIN32_NT:#ifdef __REACTOS__ // This work around can be removed if ReactOS gets a unique version number. str = TEXT("ReactOS");#else if (osvi.dwMajorVersion <= 4) str = TEXT("Microsoft Windows NT"); else if (osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0) str = TEXT("Microsoft Windows 2000"); else if (osvi.dwMajorVersion==5 && osvi.dwMinorVersion==1) str = TEXT("Microsoft Windows XP");#endif
if (osvie_val) { if (osvi.wProductType == VER_NT_WORKSTATION) { if (osvi.wSuiteMask & VER_SUITE_PERSONAL) str += TEXT(" Personal"); else str += TEXT(" Professional"); } else if (osvi.wProductType == VER_NT_SERVER) { if (osvi.wSuiteMask & VER_SUITE_DATACENTER) str += TEXT(" DataCenter Server"); else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) str += TEXT(" Advanced Server"); else str += TEXT(" Server"); } else if (osvi.wProductType == VER_NT_DOMAIN_CONTROLLER) { str += TEXT(" Domain Controller"); } } else { TCHAR type[80]; DWORD dwBufLen; HKEY hkey;
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hkey)) { RegQueryValueEx(hkey, TEXT("ProductType"), NULL, NULL, (LPBYTE)type, &dwBufLen); RegCloseKey(hkey);
if (!_tcsicmp(TEXT("WINNT"), type)) str += TEXT(" Workstation"); else if (!_tcsicmp(TEXT("LANMANNT"), type)) str += TEXT(" Server"); else if (!_tcsicmp(TEXT("SERVERNT"), type)) str += TEXT(" Advanced Server"); } } break;
case VER_PLATFORM_WIN32_WINDOWS: if (osvi.dwMajorVersion>4 || (osvi.dwMajorVersion==4 && osvi.dwMinorVersion>0)) { if (osvi.dwMinorVersion == 90) str = TEXT("Microsoft Windows ME"); else str = TEXT("Microsoft Windows 98");
if (osvi.szCSDVersion[1] == 'A') str += TEXT(" SE"); } else { str = TEXT("Microsoft Windows 95");
if (osvi.szCSDVersion[1]=='B' || osvi.szCSDVersion[1]=='C') str += TEXT(" OSR2"); } break;
case VER_PLATFORM_WIN32s: str = TEXT("Microsoft Win32s");
default: return TEXT("???"); }
String vstr;
if (osvi.dwMajorVersion <= 4) vstr.printf(TEXT(" Version %d.%d %s Build %d"), osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.szCSDVersion, osvi.dwBuildNumber&0xFFFF); else vstr.printf(TEXT(" %s (Build %d)"), osvi.szCSDVersion, osvi.dwBuildNumber&0xFFFF);
return str + vstr;}
typedef void (WINAPI*RUNDLLPROC)(HWND hwnd, HINSTANCE hinst, LPCTSTR cmdline, DWORD nCmdShow);
BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow){ HMODULE hmod = LoadLibrary(dllname); if (!hmod) return FALSE;
/*TODO <Windows NT/2000> It is possible to create a Unicode version of the function. Rundll32 first tries to find a function named EntryPointW. If it cannot find this function, it tries EntryPointA, then EntryPoint. To create a DLL that supports ANSI on Windows 95/98/Me and Unicode otherwise, export two functions: EntryPointW and EntryPoint.*/ RUNDLLPROC proc = (RUNDLLPROC)GetProcAddress(hmod, procname); if (!proc) { FreeLibrary(hmod); return FALSE; }
proc(hwnd, hmod, cmdline, nCmdShow);
FreeLibrary(hmod);
return TRUE;}
#ifdef UNICODE#define CONTROL_RUNDLL "Control_RunDLLW"#else#define CONTROL_RUNDLL "Control_RunDLLA"#endif
BOOL launch_cpanel(HWND hwnd, LPCTSTR applet){ TCHAR parameters[MAX_PATH]; _tcscpy(parameters, TEXT("shell32.dll,Control_RunDLL ")); _tcscat(parameters, applet);
return ((INT_PTR)ShellExecute(hwnd, TEXT("open"), TEXT("rundll32.exe"), parameters, NULL, SW_SHOWDEFAULT) > 32);}
BOOL RecursiveCreateDirectory(LPCTSTR path_in){ TCHAR path[MAX_PATH], hole_path[MAX_PATH];
_tcscpy(hole_path, path_in);
int drv_len = 0; LPCTSTR d;
for(d=hole_path; *d && *d!='/' && *d!='\\'; ++d) { ++drv_len;
if (*d == ':') break; }
LPTSTR dir = hole_path + drv_len;
int l; LPTSTR p = hole_path + (l=_tcslen(hole_path));
while(--p>=hole_path && (*p=='/' || *p=='\\')) *p = '\0';
WIN32_FIND_DATA w32fd;
HANDLE hFind = FindFirstFile(hole_path, &w32fd);
if (hFind == INVALID_HANDLE_VALUE) { _tcsncpy(path, hole_path, drv_len); int i = drv_len;
for(p=dir; *p=='/'||*p=='\\'; p++) path[i++] = *p++;
for(; i<l; i++) { memcpy(path, hole_path, i*sizeof(TCHAR));
for(; hole_path[i] && hole_path[i]!='/' && hole_path[i]!='\\'; i++) path[i] = hole_path[i];
path[i] = '\0';
hFind = FindFirstFile(path, &w32fd);
if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); else { LOG(FmtString(TEXT("CreateDirectory(\"%s\")"), path));
if (!CreateDirectory(path, 0)) return FALSE; } } } else FindClose(hFind);
return TRUE;}
DWORD RegGetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD def){ HKEY hkey; DWORD ret;
if (!RegOpenKey(root, path, &hkey)) { DWORD len = sizeof(ret);
if (RegQueryValueEx(hkey, valueName, 0, NULL, (LPBYTE)&ret, &len)) ret = def;
RegCloseKey(hkey);
return ret; } else return def;}
BOOL RegSetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD value){ HKEY hkey; BOOL ret = FALSE;
if (!RegOpenKey(root, path, &hkey)) { ret = RegSetValueEx(hkey, valueName, 0, REG_DWORD, (LPBYTE)&value, sizeof(value));
RegCloseKey(hkey); }
return ret;}
BOOL exists_path(LPCTSTR path){ WIN32_FIND_DATA fd;
HANDLE hfind = FindFirstFile(path, &fd);
if (hfind != INVALID_HANDLE_VALUE) { FindClose(hfind);
return TRUE; } else return FALSE;}
bool SplitFileSysURL(LPCTSTR url, String& dir_out, String& fname_out){ if (!_tcsnicmp(url, TEXT("file://"), 7)) { url += 7;
// remove third slash in front of drive characters if (*url == '/') ++url; }
if (exists_path(url)) { TCHAR path[_MAX_PATH];
// convert slashes to back slashes GetFullPathName(url, COUNTOF(path), path, NULL);
if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) fname_out.erase(); else { TCHAR drv[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
_tsplitpath_s(path, drv, COUNTOF(drv), dir, COUNTOF(dir), fname, COUNTOF(fname), ext, COUNTOF(ext)); _stprintf(path, TEXT("%s%s"), drv, dir);
fname_out.printf(TEXT("%s%s"), fname, ext); }
dir_out = path;
return true; } else return false;}