From f6d79d97b106e761e24c61de8e091f23f90f3db1 Mon Sep 17 00:00:00 2001 From: koldo Date: Tue, 14 Jul 2009 22:08:50 +0000 Subject: [PATCH] SysInfo: git-svn-id: svn://ultimatepp.org/upp/trunk@1411 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/SysInfo/SysInfo.cpp | 3211 +++++++++++++++++++ bazaar/SysInfo/SysInfo.h | 401 +++ bazaar/SysInfo/SysInfo.t | 7 + bazaar/SysInfo/SysInfo.upp | 22 + bazaar/SysInfo/init | 4 + bazaar/SysInfo/src.tpp/SysInfo$en-us.tpp | 639 ++++ bazaar/SysInfo/srcdoc.tpp/SysInfo$en-us.tpp | 47 + bazaar/SysInfo/srcimp.tpp/SysInfo$en-us.tpp | 569 ++++ 8 files changed, 4900 insertions(+) create mode 100644 bazaar/SysInfo/SysInfo.cpp create mode 100644 bazaar/SysInfo/SysInfo.h create mode 100644 bazaar/SysInfo/SysInfo.t create mode 100644 bazaar/SysInfo/SysInfo.upp create mode 100644 bazaar/SysInfo/init create mode 100644 bazaar/SysInfo/src.tpp/SysInfo$en-us.tpp create mode 100644 bazaar/SysInfo/srcdoc.tpp/SysInfo$en-us.tpp create mode 100644 bazaar/SysInfo/srcimp.tpp/SysInfo$en-us.tpp diff --git a/bazaar/SysInfo/SysInfo.cpp b/bazaar/SysInfo/SysInfo.cpp new file mode 100644 index 000000000..27730d325 --- /dev/null +++ b/bazaar/SysInfo/SysInfo.cpp @@ -0,0 +1,3211 @@ +#include + +#if defined(PLATFORM_WIN32) +#include +#include +#include +#define CY tagCY +// To compile in MinGW copy files Rpcsal.h, DispEx.h, WbemCli.h, WbemDisp.h, Wbemidl.h, +// WbemProv.h and WbemTran.h from \Microsoft SDKs\Windows\v6.1\Include to MinGW/include and +// wbemuuid.lib from \Microsoft SDKs\Windows\v6.1\Lib to MinGW/lib +#include +#include +#include +#endif +#ifdef PLATFORM_POSIX +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#endif + +using namespace Upp; + +#include "SysInfo.h" + +///////////////////////////////////////////////////////////////////// +// General utilities + +bool FileCat(const char *file, const char *appendFile) +{ + FileAppend f(file); + if(!f.IsOpen()) + return false; + FileIn fi(appendFile); + if(!fi.IsOpen()) + return false; + CopyStream(f, fi, fi.GetLeft()); + fi.Close(); + f.Close(); + if(f.IsError()) + return false; + return true; +} + +String FormatLong(long a) +{ + return Sprintf("%ld", a); +} + +String Replace(String str, String find, String replace) +{ + String ret; + + int lenStr = str.GetCount(); + int lenFind = find.GetCount(); + int i = 0, j; + while ((j = str.Find(find, i)) >= i) { + ret += str.Mid(i, j-i) + replace; + i = j + lenFind; + if (i >= lenStr) + break; + } + ret += str.Mid(i); + return ret; +} + +void SearchFile_Each(String dir, String condFile, String text, Array &files, Array &errorList) +{ + FindFile ff; + if (ff.Search(AppendFileName(dir, condFile))) { + do { + if(ff.IsFile()) { + String p = AppendFileName(dir, ff.GetName()); + if (text.IsEmpty()) + files.Add(p); + else { + FILE *fp = fopen(p, "r"); + if (fp != NULL) { + int i = 0, c; + while ((c = fgetc(fp)) != EOF) { + if (c == text[i]) { + ++i; + if (i == text.GetCount()) { + files.Add(p); + break; + } + } else { + if (i != 0) + fseek(fp, -(i-1), SEEK_CUR); + i = 0; + } + } + fclose(fp); + } else + errorList.Add(AppendFileName(dir, ff.GetName()) + ": Impossible to open file"); + } + } + } while (ff.Next()); + } + + ff.Search(AppendFileName(dir, "*")); + do { + String name = ff.GetName(); + if(ff.IsDirectory() && name != "." && name != "..") { + String p = AppendFileName(dir, name); + SearchFile_Each(p, condFile, text, files, errorList); + } + } while (ff.Next()); +} + +Array SearchFile(String dir, String condFile, String text, Array &errorList) +{ + Array ret; + errorList.Clear(); + SearchFile_Each(dir, condFile, text, ret, errorList); + return ret; +} + +Array SearchFile(String dir, String condFile) +{ + Array errorList; + Array ret; + + errorList.Clear(); + SearchFile_Each(dir, condFile, String(""), ret, errorList); + + return ret; +} + +bool IsFolder(String fileName) +{ + FindFile ff(fileName); + + if (ff) + return ff.IsFolder(); + else + return false; +} + +bool IsFile(String fileName) +{ + FindFile ff(fileName); + + if (ff) + return ff.IsFile(); + else + return false; +} + +#if defined(PLATFORM_WIN32) +Value GetVARIANT(VARIANT &result) +{ + Value ret; + switch(result.vt) { + case VT_EMPTY: + case VT_NULL: + case VT_BLOB: + break; + case VT_BOOL: + ret = result.boolVal;// ? "true" : "false"; + break; + case VT_I2: + ret = result.iVal; + break; + case VT_I4: + ret = (int64)result.lVal; + break; + case VT_R4: + ret = AsString(result.fltVal); + break; + case VT_R8: + ret = AsString(result.dblVal); + break; + case VT_BSTR: + { + char dbcs[1024]; + char *pbstr = (char *)result.bstrVal; + int i = wcstombs(dbcs, result.bstrVal, *((DWORD *)(pbstr-4))); + dbcs[i] = 0; + ret = dbcs; + } + break; + case VT_LPSTR: + //ret = result.pszVal; + ret = "Unknown VT_LPSTR"; + case VT_DATE: + SYSTEMTIME stime; + VariantTimeToSystemTime(result.date, &stime); + { + Time t; + t.day = (Upp::byte)stime.wDay; + t.month = (Upp::byte)stime.wMonth; + t.year = stime.wYear; + t.hour = (Upp::byte)stime.wHour; + t.minute = (Upp::byte)stime.wMinute; + t.second = (Upp::byte)stime.wSecond; + ret = t; + } + break; + case VT_CF: + ret = "(Clipboard format)"; + break; + } + return ret; +} +#endif + +///////////////////////////////////////////////////////////////////// +// LaunchCommand +int LaunchCommand(const char *cmd, void (*readCallBack)(String &)) +{ + LocalProcess p; + if(!p.Start(cmd)) + return -1; + String str; + while(p.IsRunning()) { + str = p.Get(); + if (readCallBack) + readCallBack(str); + DoEvents(); + } + str = p.Get(); + if (readCallBack) + readCallBack(str); + return p.GetExitCode(); +} +int LaunchCommand(const char *cmd, String &ret) +{ + ret = ""; + LocalProcess p; + if(!p.Start(cmd)) + return -1; + while(p.IsRunning()) { + ret.Cat(p.Get()); + DoEvents(); + } + ret.Cat(p.Get()); + return p.GetExitCode(); +} +String LaunchCommand(const char *cmd) +{ + String ret; + LaunchCommand(cmd, ret); + return ret; +} + +///////////////////////////////////////////////////////////////////// +// LaunchFile + +bool LaunchFile(const String file) +{ +#if defined(PLATFORM_WIN32) + HINSTANCE ret; + WString fileName(file); + ret = ShellExecuteW(NULL, L"open", fileName, NULL, L".", SW_SHOWNORMAL); //SW_SHOWMINIMIZED + return (int)ret > 32; +#endif +#ifdef PLATFORM_POSIX + int ret; + if (GetDesktopManagerNew() == "gnome") + ret = system("gnome-open \"" + file + "\""); + else if (GetDesktopManagerNew() == "kde") + ret = system("kfmclient exec \"" + file + "\" &"); + else if (GetDesktopManagerNew() == "enlightenment") { + String mime = GetExtExecutable(GetFileExt(file)); + String program = mime.Left(mime.Find(".")); // Left side of mime executable is the program to run + ret = system(program + " \"" + file + "\" &"); + } else + ret = system("xdg-open \"" + file + "\""); + return (ret >= 0); +#endif +} +String GetExtExecutable(String ext) +{ + String exeFile = ""; + if (ext[0] != '.') + ext = String(".") + ext; +#if defined(PLATFORM_WIN32) + String file = AppendFileName(GetHomeDirectory(), String("dummy") + ext); // Required by FindExecutableW + SaveFile(file, " "); + if (!FileExists(file)) + return ""; + HINSTANCE ret; + WString fileW(file); + WCHAR exe[1024]; + ret = FindExecutableW(fileW, NULL, exe); + if ((long)ret > 32) + exeFile = WString(exe).ToString(); + DeleteFile(file); +#endif +#ifdef PLATFORM_POSIX + StringParse mime; + //if (LaunchCommand(String("xdg-mime query filetype ") + file, mime) >= 0) // xdg-mime query filetype does not work properly in Enlightenment + mime = LoadFile_Safe("/etc/mime.types"); // Search in /etc/mime.types the mime type for the extension + if ((mime.GoAfter_Init(String(" ") + ext.Right(ext.GetCount()-1))) || (mime.GoAfter_Init(String("\t") + ext.Right(ext.GetCount()-1)))) { + mime.GoBeginLine(); + mime = mime.GetText(); + exeFile = TrimRight(LaunchCommand(String("xdg-mime query default ") + mime)); + } +#endif + return exeFile; +} + +///////////////////////////////////////////////////////////////////// +// Special Folders + +String GetFirefoxDownloadFolder() +{ + String profilesPath = "mozilla/firefox"; +#ifdef PLATFORM_POSIX // Is hidden + profilesPath = String(".") + profilesPath; +#endif + StringParse profiles = LoadFile(AppendFileName(GetAppDataFolder(), AppendFileName(profilesPath, "profiles.ini"))); + if (!profiles.GoAfter("Path")) return ""; + if (!profiles.GoAfter("=")) return ""; + String path = profiles.GetText(); + String pathPrefs = AppendFileName(AppendFileName(AppendFileName(GetAppDataFolder(), profilesPath), path), "prefs.js"); + StringParse prefs = LoadFile(pathPrefs); + if (!prefs.GoAfter("\"browser.download.dir\"")) { + if (!prefs.GoAfter("\"browser.download.lastDir\"")) + return ""; + } + if (!prefs.GoAfter(",")) return ""; + return prefs.GetText(); +} + +#if defined(PLATFORM_WIN32) +String GetShellFolder(const char *local, const char *users) +{ + String ret = FromSystemCharset(GetWinRegString(local, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + HKEY_CURRENT_USER)); + if (ret == "" && *users != '\0') + return FromSystemCharset(GetWinRegString(users, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + HKEY_LOCAL_MACHINE)); + return ret; +} +String GetIEDownloadFolder() +{ + String ret = FromSystemCharset(GetWinRegString("Download Directory", "Software\\Microsoft\\Internet Explorer", HKEY_CURRENT_USER)); + if (ret == "") + ret = FromSystemCharset(GetWinRegString("Save Directory", "Software\\Microsoft\\Internet Explorer\\Main", HKEY_CURRENT_USER)); + return ret; +} +String GetDesktopFolder() {return GetShellFolder("Desktop", "Common Desktop");} +String GetProgramsFolder() {return FromSystemCharset(GetWinRegString("ProgramFilesDir", "Software\\Microsoft\\Windows\\CurrentVersion", HKEY_LOCAL_MACHINE));} +String GetAppDataFolder() {return GetShellFolder("AppData", "Common AppData");} +String GetMusicFolder() {return GetShellFolder("My Music", "CommonMusic");} +String GetPicturesFolder() {return GetShellFolder("My Pictures", "CommonPictures");} +String GetVideoFolder() {return GetShellFolder("My Video", "CommonVideo");} +String GetPersonalFolder() {return GetShellFolder("Personal", 0);} +String GetTemplatesFolder() {return GetShellFolder("Templates", "Common Templates");} +String GetDownloadFolder() +{ + String browser = GetExtExecutable("html"); + browser = ToLower(browser); + if (browser.Find("iexplore") >= 0) + return GetIEDownloadFolder(); + else if (browser.Find("firefox") >= 0) + return GetFirefoxDownloadFolder(); + return GetDesktopFolder(); // I do not know to do it in other browsers !! +}; +String GetTempFolder() +{ + String ret; + if ((ret = GetEnv("TEMP")) == "") // One or the other one + ret = GetEnv("TMP"); + return ret; +} +String GetOsFolder() +{ + char ret[MAX_PATH]; + ::GetWindowsDirectory(ret, MAX_PATH); + return String(ret); +} +String GetSystemFolder() +{ + char ret[MAX_PATH]; + ::GetSystemDirectory(ret, MAX_PATH); + return String(ret); +} +#endif +#ifdef PLATFORM_POSIX +String GetPathXdg(String xdgConfigHome, String xdgConfigDirs) +{ + String ret = ""; + if (FileExists(ret = AppendFileName(xdgConfigHome, "user-dirs.dirs"))) ; + else if (FileExists(ret = AppendFileName(xdgConfigDirs, "user-dirs.defaults"))) ; + else if (FileExists(ret = AppendFileName(xdgConfigDirs, "user-dirs.dirs"))) ; + return ret; +} +String GetPathDataXdg(String fileConfig, const char *folder) +{ + StringParse fileData = LoadFile(fileConfig); + + if (!fileData.GoAfter(folder)) return ""; + if (!fileData.GoAfter("=")) return ""; + + String ret = ""; + StringParse path = fileData.GetText(); + if(path.GoAfter("$HOME/")) + ret = AppendFileName(GetHomeDirectory(), path.Right()); + else if (!FileExists(path)) + ret = AppendFileName(GetHomeDirectory(), path); + + return ret; +} +String GetShellFolder(const char *local, const char *users) +{ + String xdgConfigHome = GetEnv("XDG_CONFIG_HOME"); + if (xdgConfigHome == "") // By default + xdgConfigHome = AppendFileName(GetHomeDirectory(), ".config"); + String xdgConfigDirs = GetEnv("XDG_CONFIG_DIRS"); + if (xdgConfigDirs == "") // By default + xdgConfigDirs = "/etc/xdg"; + String xdgFileConfigData = GetPathXdg(xdgConfigHome, xdgConfigDirs); + String ret = GetPathDataXdg(xdgFileConfigData, local); + if (ret == "" && *users != '\0') + return GetPathDataXdg(xdgFileConfigData, users); + else + return ret; +} +String GetDesktopFolder() +{ + String ret = GetShellFolder("XDG_DESKTOP_DIR", "DESKTOP"); + if (ret.IsEmpty()) + return AppendFileName(GetHomeDirectory(), "Desktop"); + else + return ret; +} +String GetProgramsFolder() {return String("/usr/bin");} +String GetAppDataFolder() {return GetHomeDirectory();}; +String GetMusicFolder() {return GetShellFolder("XDG_MUSIC_DIR", "MUSIC");} +String GetPicturesFolder() {return GetShellFolder("XDG_PICTURES_DIR", "PICTURES");} +String GetVideoFolder() {return GetShellFolder("XDG_VIDEOS_DIR", "VIDEOS");} +String GetPersonalFolder() {return GetShellFolder("XDG_DOCUMENTS_DIR", "DOCUMENTS");} +String GetTemplatesFolder() {return GetShellFolder("XDG_TEMPLATES_DIR", "XDG_TEMPLATES_DIR");} +String GetDownloadFolder() +{ + String browser = GetExtExecutable("html"); + browser = ToLower(browser); + if (browser.Find("firefox") >= 0) + return GetFirefoxDownloadFolder(); + return GetShellFolder("XDG_DOWNLOAD_DIR", "DOWNLOAD"); +}; +String GetTempFolder() +{ + return GetHomeDirectory(); +} +String GetOsFolder() +{ + return String("/bin"); +} +String GetSystemFolder() +{ + return String(""); +} +#endif + +///////////////////////////////////////////////////////////////////// +// Hardware Info +#if defined(PLATFORM_WIN32) + +bool GetWMIInfo(String system, Array &data, Array *ret[]) +{ + HRESULT hRes; + + hRes = CoInitialize(NULL); + if (hRes != S_OK && hRes != S_FALSE) + return false; + + hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, + RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0); + if (hRes != S_OK && hRes != RPC_E_TOO_LATE) { + CoUninitialize(); + return false; + } + IWbemLocator* pIWbemLocator = NULL; + if (CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, + CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)&pIWbemLocator) != S_OK) { + CoUninitialize(); + return false; + } + + BSTR bstrNamespace = SysAllocString(L"root\\cimv2"); + IWbemServices* pWbemServices = NULL; + if (pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, NULL, 0, NULL, NULL, + &pWbemServices) != S_OK) { + CoUninitialize(); + return false; + } + SysFreeString(bstrNamespace); + + hRes = CoSetProxyBlanket(pWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); + if (FAILED(hRes)) { + pWbemServices->Release(); + pIWbemLocator->Release(); + CoUninitialize(); + return false; + } + + IEnumWbemClassObject* pEnumerator = NULL; + String query; + query << "Select * from " << system; + WCHAR wquery[1024*sizeof(WCHAR)]; + MultiByteToWideChar(CP_UTF8, 0, query, -1, wquery, sizeof(wquery)/sizeof(wquery[0])); + BSTR strQuery = SysAllocString(wquery); + BSTR strQL = SysAllocString(L"WQL"); + hRes = pWbemServices->ExecQuery(strQL, strQuery, WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); + if (hRes != S_OK) { + pWbemServices->Release(); + pIWbemLocator->Release(); + CoUninitialize(); + return false; + } + SysFreeString(strQuery); + SysFreeString(strQL); + + IWbemClassObject *pClassObject; + ULONG uReturn = 0; + int row = 0; + while (pEnumerator) { + hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObject, &uReturn); + if(0 == uReturn) + break; + if(hRes != S_OK) { + pWbemServices->Release(); + pIWbemLocator->Release(); + pEnumerator->Release(); + pClassObject->Release(); + CoUninitialize(); + return false; + } + for (int col = 0; col < data.GetCount(); ++col) { + VARIANT vProp; + BSTR strClassProp = SysAllocString(data[col].ToWString()); + hRes = pClassObject->Get(strClassProp, 0, &vProp, 0, 0); + if(hRes != S_OK){ + pWbemServices->Release(); + pIWbemLocator->Release(); + pEnumerator->Release(); + pClassObject->Release(); + CoUninitialize(); + return false; + } + SysFreeString(strClassProp); + ret[col]->Add(GetVARIANT(vProp)); + } + row++; + } + pIWbemLocator->Release(); + pWbemServices->Release(); + pEnumerator->Release(); + pClassObject->Release(); + CoUninitialize(); + + return true; +} +bool GetWMIInfo(String system, String data, Value &res) +{ + Array arrRes; + Array *arrResP[1]; + arrResP[0] = &arrRes; + Array arrData; + arrData.Add(data); + bool ret = GetWMIInfo("Win32_ComputerSystem", arrData, arrResP); + if (ret) + res = arrRes[0]; + return ret; +} + +void GetSystemInfo(String &manufacturer, String &productName, String &version, int &numberOfProcessors) +{ + manufacturer = ""; + Value vmanufacturer; + if (GetWMIInfo("Win32_ComputerSystem", "manufacturer", vmanufacturer)) + manufacturer = TrimBoth(vmanufacturer); + if (manufacturer.IsEmpty()) + manufacturer = FromSystemCharset(GetWinRegString("SystemManufacturer", "HARDWARE\\DESCRIPTION\\System\\BIOS", HKEY_LOCAL_MACHINE)); + if (manufacturer.IsEmpty()) { + StringParse fileData = LoadFile(AppendFileName(GetSystemFolder(), "oeminfo.ini")); + fileData.GoAfter("Manufacturer="); + manufacturer = fileData.GetText("\r\n"); + } + productName = ""; + Value vproductName; + if (GetWMIInfo("Win32_ComputerSystem", "model", vproductName)) + productName = TrimBoth(vproductName); + if (productName.IsEmpty()) + productName = FromSystemCharset(GetWinRegString("SystemProductName", "HARDWARE\\DESCRIPTION\\System\\BIOS", HKEY_LOCAL_MACHINE)); + if (productName.IsEmpty()) + productName = FromSystemCharset(GetWinRegString("Model", "SOFTWARE\\Microsoft\\PCHealth\\HelpSvc\\OEMInfo", HKEY_LOCAL_MACHINE)); + + version = FromSystemCharset(GetWinRegString("SystemVersion", "HARDWARE\\DESCRIPTION\\System\\BIOS", HKEY_LOCAL_MACHINE)); + numberOfProcessors = atoi(GetEnv("NUMBER_OF_PROCESSORS")); +} +void GetBiosInfo(String &biosVersion, Date &biosReleaseDate) +{ + // Alternative is "wmic bios get name" and "wmic bios get releasedate" + String strBios = FromSystemCharset(GetWinRegString("BIOSVersion", "HARDWARE\\DESCRIPTION\\System\\BIOS", HKEY_LOCAL_MACHINE)); + if (strBios.IsEmpty()) + strBios = FromSystemCharset(GetWinRegString("SystemBiosVersion", "HARDWARE\\DESCRIPTION\\System", HKEY_LOCAL_MACHINE)); + for (int i = 0; i < strBios.GetLength(); ++i) { + if (strBios[i] == '\0') + biosVersion.Cat(". "); + else + biosVersion.Cat(strBios[i]); + } + String strDate = FromSystemCharset(GetWinRegString("BIOSReleaseDate", "HARDWARE\\DESCRIPTION\\System\\BIOS", HKEY_LOCAL_MACHINE)); + if (strDate.IsEmpty()) + strDate = FromSystemCharset(GetWinRegString("SystemBiosDate", "HARDWARE\\DESCRIPTION\\System", HKEY_LOCAL_MACHINE)); + StrToDate(biosReleaseDate, strDate); +} +bool GetProcessorInfo(int number, String &vendor, String &identifier, String &architecture, int &speed) +{ + String strReg = Format("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", number); + vendor = FromSystemCharset(GetWinRegString("VendorIdentifier", strReg, HKEY_LOCAL_MACHINE)); + identifier = FromSystemCharset(GetWinRegString("ProcessorNameString", strReg, HKEY_LOCAL_MACHINE)); + architecture = FromSystemCharset(GetWinRegString("Identifier", strReg, HKEY_LOCAL_MACHINE)); + speed = GetWinRegInt("~MHz", strReg, HKEY_LOCAL_MACHINE); + return true; +} + +bool GetVideoInfo(Array &name, Array &description, Array &videoProcessor, Array &ram, Array &videoMode) +{ + Array *res[5]; + res[0] = &name; + res[1] = &description; + res[2] = &videoProcessor; + res[3] = &ram; + res[4] = &videoMode; + Array data; + data.Add("Name"); + data.Add("Description"); + data.Add("VideoProcessor"); + data.Add("AdapterRAM"); + data.Add("VideoModeDescription"); + if (!GetWMIInfo("Win32_VideoController", data, res)) + return false; + + for (int row = 0; row < ram.GetCount(); ++row) + ram[row] = (atoi(ram[row].ToString()) + 524288)/1048576; + return true; +} +bool GetPackagesInfo(Array &name, Array &version, Array &vendor, +Array &installDate, Array &caption, Array &description, Array &state) +{ + Array *res[7]; + res[0] = &name; + res[1] = &version; + res[2] = &vendor; + res[3] = &installDate; + res[4] = &caption; + res[5] = &description; + res[6] = &state; + Array data; + data.Add("Name"); + data.Add("Version"); + data.Add("Vendor"); + data.Add("InstallDate2"); + data.Add("Caption"); + data.Add("Description"); + data.Add("InstallState"); + if (!GetWMIInfo("Win32_Product", data, res)) + return false; + + for (int i = 0; i < installDate.GetCount(); ++i) { + String sdate = installDate[i]; + Time t(atoi(sdate.Left(4)), atoi(sdate.Mid(4, 2)), atoi(sdate.Mid(6, 2)), + atoi(sdate.Mid(8, 2)), atoi(sdate.Mid(10, 2)), atoi(sdate.Mid(12, 2))); + installDate[i] = t; + int istate = state[i]; + switch (istate) { + case -6: state[i] = "Bad Configuration"; break; + case -2: state[i] = "Invalid Argument"; break; + case -1: state[i] = "Unknown Package"; break; + case 1: state[i] = "Advertised"; break; + case 2: state[i] = "Absent"; break; + case 5: state[i] = "Ok"; break; + default: return false; + } + } + return true; +} +#endif +#if defined (PLATFORM_POSIX) +void GetSystemInfo(String &manufacturer, String &productName, String &version, int &numberOfProcessors) +{ + manufacturer = LoadFile_Safe("/sys/devices/virtual/dmi/id/board_vendor"); + productName = LoadFile_Safe("/sys/devices/virtual/dmi/id/board_name"); + version = LoadFile_Safe("/sys/devices/virtual/dmi/id/product_version"); + + StringParse cpu(LoadFile_Safe("/proc/cpuinfo")); + numberOfProcessors = 1; + while (cpu.GoAfter("processor")) { + cpu.GoAfter(":"); + numberOfProcessors = atoi(cpu.GetText()) + 1; + } +} +void GetBiosInfo(String &biosVersion, Date &biosReleaseDate) +{ + String biosVendor = LoadFile_Safe("/sys/devices/virtual/dmi/id/bios_vendor"); + biosVersion = LoadFile_Safe("/sys/devices/virtual/dmi/id/bios_version"); + StrToDate(biosReleaseDate, LoadFile_Safe("/sys/devices/virtual/dmi/id/bios_date")); +} +bool GetProcessorInfo(int number, String &vendor, String &identifier, String &architecture, int &speed) +{ + StringParse cpu(LoadFile_Safe("/proc/cpuinfo")); + + int cpuNumber; + do { + if (!cpu.GoAfter("processor", ":")) + return false; + String sCpu = cpu.GetText(); + if (sCpu == "") + return false; + cpuNumber = atoi(sCpu); + } while (cpuNumber != number); + + cpu.GoAfter("vendor_id", ":"); + vendor = cpu.GetText(); + cpu.GoAfter("cpu family", ":"); + String family = cpu.GetText(); // 6 means 686 + cpu.GoAfter("model", ":"); + String model = cpu.GetText(); + cpu.GoAfter("model name", ":"); + identifier = cpu.GetText("\n"); + cpu.GoAfter("stepping", ":"); + String stepping = cpu.GetText(); + architecture = LaunchCommand("uname -m"); // CPU type + architecture << " Family " << family << " Model " << model << " Stepping " << stepping; // And 64 bits ?? uname -m + cpu.GoAfter_Init("cpu MHz", ":"); + speed = cpu.GetInt(); +} +#endif + +///////////////////////////////////////////////////////////////////// +// Memory Info + +#if defined(__MINGW32__) +typedef struct _MEMORYSTATUSEX { + DWORD dwLength; + DWORD dwMemoryLoad; + DWORDLONG ullTotalPhys; + DWORDLONG ullAvailPhys; + DWORDLONG ullTotalPageFile; + DWORDLONG ullAvailPageFile; + DWORDLONG ullTotalVirtual; + DWORDLONG ullAvailVirtual; + DWORDLONG ullAvailExtendedVirtual; +} MEMORYSTATUSEX,*LPMEMORYSTATUSEX; + +WINBASEAPI BOOL WINAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX); + +bool GetMemoryInfo( + int &memoryLoad, // percent of memory in use + uint64 &totalPhys, // physical memory + uint64 &freePhys, // free physical memory + uint64 &totalPageFile, // total paging file + uint64 &freePageFile, // free paging file + uint64 &totalVirtual, // total virtual memory + uint64 &freeVirtual) // free virtual memory +{ + MEMORYSTATUS status; + status.dwLength = sizeof (status); + GlobalMemoryStatus(&status); + + memoryLoad = status.dwMemoryLoad; + totalPhys = status.dwTotalPhys; + freePhys = status.dwAvailPhys; + totalPageFile = status.dwTotalPageFile; + freePageFile = status.dwAvailPageFile; + totalVirtual = status.dwTotalVirtual; + freeVirtual = status.dwAvailVirtual; + + return true; +} +#endif +#ifdef COMPILER_MSC + +bool GetMemoryInfo( + int &memoryLoad, // percent of memory in use + uint64 &totalPhys, // physical memory + uint64 &freePhys, // free physical memory + uint64 &totalPageFile, // total paging file + uint64 &freePageFile, // free paging file + uint64 &totalVirtual, // total virtual memory + uint64 &freeVirtual) // free virtual memory +{ + MEMORYSTATUSEX status; + status.dwLength = sizeof (status); + if (!GlobalMemoryStatusEx(&status)) + return false; + memoryLoad = status.dwMemoryLoad; + totalPhys = status.ullTotalPhys; + freePhys = status.ullAvailPhys; + totalPageFile = status.ullTotalPageFile; + freePageFile = status.ullAvailPageFile; + totalVirtual = status.ullTotalVirtual; + freeVirtual = status.ullAvailVirtual; + + return true; +} +#endif + +#include +#include +#include + +// This system files are like pipes: it is not possible to get the length to size the buffer +String LoadFile_Safe(String fileName) +{ +#ifdef PLATFORM_POSIX + int fid = open(fileName, O_RDONLY); +#else + int fid = _wopen(fileName.ToWString(), O_RDONLY|O_BINARY); +#endif + if (fid < 0) + return String(""); + const int size = 1024; + int nsize; + StringBuffer s; + char buf[size]; + while((nsize = read(fid, buf, size)) == size) + s.Cat(buf, size); + if (nsize > 1) + s.Cat(buf, nsize-1); + close(fid); + return s; +} + +#ifdef PLATFORM_POSIX +bool GetMemoryInfo( +int &memoryLoad, // percent of memory in use +uint64 &totalPhys, // physical memory +uint64 &freePhys, // free physical memory +uint64 &totalPageFile, // total paging file +uint64 &freePageFile, // free paging file +uint64 &totalVirtual, // total virtual memory +uint64 &freeVirtual) +{ + StringParse meminfo = LoadFile_Safe("/proc/meminfo"); + if (meminfo == "") + return false; + meminfo.GoAfter_Init("MemTotal", ":"); totalPhys = 1024*meminfo.GetUInt64(); + meminfo.GoAfter_Init("MemFree", ":"); freePhys = 1024*meminfo.GetUInt64(); + memoryLoad = (int)(100.*(totalPhys-freePhys)/totalPhys); + meminfo.GoAfter_Init("SwapCached", ":");freePageFile = 1024*meminfo.GetUInt64(); + meminfo.GoAfter_Init("Cached", ":"); totalPageFile = 1024*meminfo.GetUInt64() + freePageFile; + meminfo.GoAfter_Init("SwapTotal", ":"); totalVirtual = 1024*meminfo.GetUInt64(); + meminfo.GoAfter_Init("SwapFree", ":"); freeVirtual = 1024*meminfo.GetUInt64(); + + return true; +} +#endif + + +///////////////////////////////////////////////////////////////////// +// Process list + +#if defined(PLATFORM_WIN32) + +// Get the list of process identifiers. +bool GetProcessList(Array &pid, Array &pNames) +{ + PROCESSENTRY32 proc; + HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hSnap == INVALID_HANDLE_VALUE) + return false; + proc.dwSize = sizeof(proc); + long f = Process32First(hSnap, &proc); + while (f) { + pid.Add(proc.th32ProcessID); + pNames.Add(proc.szExeFile); + f = Process32Next(hSnap, &proc); + } + CloseHandle(hSnap); + return true; +} +Array GetProcessList() +{ + PROCESSENTRY32 proc; + Array ret; + HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hSnap == INVALID_HANDLE_VALUE) + return ret; + proc.dwSize = sizeof(proc); + long f = Process32First(hSnap, &proc); + while (f) { + ret.Add(proc.th32ProcessID); + f = Process32Next(hSnap, &proc); + } + CloseHandle(hSnap); + return ret; +} +String GetProcessName(long processID) +{ + WCHAR szProcessName[MAX_PATH]; + // Get a handle to the process. + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); + + // Get the process name. + if (hProcess != NULL) { + HMODULE hMod; + DWORD cbNeeded; + + if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) + GetModuleBaseNameW(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(WCHAR)); + } + CloseHandle(hProcess); + + return FromSystemCharset(WString(szProcessName).ToString()); +} +String GetProcessFileName(long processID) +{ + WCHAR szProcessName[MAX_PATH]; + // Get a handle to the process. + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); + + // Get the process name. + if (hProcess != NULL) { + HMODULE hMod; + DWORD cbNeeded; + + if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) + GetModuleFileNameExW(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(WCHAR)); + } + CloseHandle(hProcess); + + return FromSystemCharset(WString(szProcessName).ToString()); +} +BOOL CALLBACK EnumGetWindowsList(HWND hWnd, LPARAM lParam) +{ + if (!hWnd) + return TRUE; // Not a window + if (GetParent(hWnd) != 0) + return TRUE; // Child window + Array *ret = (Array *)lParam; + ret->Add((int)hWnd); + return TRUE; +} +void GetWindowsList(Array &hWnd, Array &processId, Array &name, Array &fileName, Array &caption) +{ + HANDLE hProcess; + DWORD dwThreadId, dwProcessId; + HINSTANCE hInstance; + WCHAR str[MAX_PATH]; + + EnumWindows(EnumGetWindowsList, (LPARAM)&hWnd); + for (int i = 0; i < hWnd.GetCount(); ++i) { + hInstance = (HINSTANCE)GetWindowLong((HWND)hWnd[i], GWL_HINSTANCE); + dwThreadId = GetWindowThreadProcessId((HWND)hWnd[i], &dwProcessId); + processId.Add(dwProcessId); + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId); + if (GetModuleFileNameExW(hProcess, hInstance, str, sizeof(str)/sizeof(WCHAR))) + fileName.Add(FromSystemCharset(WString(str).ToString())); + else + fileName.Add(t_("UNKNOWN")); + if (GetModuleBaseNameW(hProcess, hInstance, str, sizeof(str)/sizeof(WCHAR))) + name.Add(FromSystemCharset(WString(str).ToString())); + else + name.Add(t_("UNKNOWN")); + CloseHandle(hProcess); + if (IsWindowVisible((HWND)hWnd[i])) { + int count = SendMessageW((HWND)hWnd[i], WM_GETTEXT, sizeof(str)/sizeof(WCHAR), (LPARAM)str); + str[count] = '\0'; + caption.Add(FromSystemCharset(WString(str).ToString())); + } else + caption.Add(""); + } +} +Array GetWindowsList() +{ + Array ret; + EnumWindows(EnumGetWindowsList, (LPARAM)&ret); + return ret; +} +BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM lParam) +{ + DWORD dwID ; + GetWindowThreadProcessId(hwnd, &dwID) ; + if(dwID == (DWORD)lParam) + PostMessage(hwnd, WM_CLOSE, 0, 0) ; + return TRUE ; +} +// pid Process ID of the process to shut down. +// timeout Wait time in milliseconds before shutting down the process. +bool ProcessTerminate(long processId, int timeout) +{ + // If we can't open the process with PROCESS_TERMINATE rights, then we give up immediately. + HANDLE hProc = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, processId); + if(hProc == NULL) + return false ; + // TerminateAppEnum() posts WM_CLOSE to all windows whose PID matches your process's. + ::EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM)processId) ; + + int ret; + // Wait on the handle. If it signals, great. If it times out, + // then you kill it. + int state = ::WaitForSingleObject(hProc, timeout); + if ((state == WAIT_TIMEOUT) || (state == WAIT_FAILED)) + ret = ::TerminateProcess(hProc, 0); + else + ret = true; + CloseHandle(hProc) ; + return ret; +} + +int GetProcessPriority(long pid) +{ + int priority; + HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); + if(hProc == NULL) + return -1; + priority = ::GetPriorityClass(hProc); + CloseHandle(hProc); + + switch(priority) { + case REALTIME_PRIORITY_CLASS: priority = 10; // Process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive. + break; + case HIGH_PRIORITY_CLASS: priority = 8; // Process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles. + break; + case ABOVE_NORMAL_PRIORITY_CLASS: priority = 6; // Process that has priority above NORMAL_PRIORITY_CLASS but below HIGH_PRIORITY_CLASS. + break; + case NORMAL_PRIORITY_CLASS: priority = 5; // Process with no special scheduling needs. + break; + case BELOW_NORMAL_PRIORITY_CLASS: priority = 3; // Process that has priority above IDLE_PRIORITY_CLASS but below NORMAL_PRIORITY_CLASS. + break; + case IDLE_PRIORITY_CLASS: priority = 0; // Process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes. + break; + default: return -1; + } + return priority; +} + +bool SetProcessPriority(long pid, int priority) +{ + HANDLE hProc = ::OpenProcess(PROCESS_SET_INFORMATION , FALSE, pid); + if(hProc == NULL) + return false; + if (priority == 10) + priority = REALTIME_PRIORITY_CLASS; + else if (priority >= 8) + priority = HIGH_PRIORITY_CLASS; + else if (priority >= 6) + priority = ABOVE_NORMAL_PRIORITY_CLASS; + else if (priority >= 5) + priority = NORMAL_PRIORITY_CLASS; + else if (priority >= 3) + priority = BELOW_NORMAL_PRIORITY_CLASS; + else + priority = IDLE_PRIORITY_CLASS; + int ret = ::SetPriorityClass(hProc, priority); // SetProcessAffinityMask + CloseHandle(hProc) ; + return ret; +} + +#endif +#ifdef PLATFORM_POSIX //Check with ps + +bool IsInteger(String s) +{ + for (int i = 0; i < s.GetCount(); ++i) { + if (!isdigit(s[i])) + return false; + } + return true; +} +bool GetProcessList(Array &pid, Array &pNames) +{ + FindFile ff; + if(ff.Search("/proc/*")) { + do { + if (IsInteger(ff.GetName())) { + String exe = Format("/proc/%s/exe", ff.GetName()); + StringBuffer exeb; + exeb = exe; + char procName[2048]; + int procNameLen = readlink(exeb, procName, sizeof(procName)-1); + if (procNameLen > 0) { + procName[procNameLen] = 0; + pNames.Add(procName); + pid.Add(atoi(ff.GetName())); + } + } + } while(ff.Next()); + } + return true; +} +Array GetProcessList() +{ + FindFile ff; + Array pid; + if(ff.Search("/proc/*")) { + do { + if (IsInteger(ff.GetName())) { + String exe = Format("/proc/%s/exe", ff.GetName()); + StringBuffer exeb; + exeb = exe; + char procName[2048]; + int procNameLen = readlink(exeb, procName, sizeof(procName)-1); + if (procNameLen > 0) + pid.Add(atoi(ff.GetName())); + } + } while(ff.Next()); + } + return pid; +} +String GetProcessName(long pid) +{ + return GetFileName(GetProcessFileName(pid)); +} +// ls -l /proc/%d/fd gets also the files opened by the process +String GetProcessFileName(long pid) +{ + String ret = ""; + String exe = Format("/proc/%s/exe", FormatLong(pid)); + StringBuffer exeb; + exeb = exe; + char procName[2048]; + int procNameLen = readlink(exeb, procName, sizeof(procName)-1); + if (procNameLen > 0) { + procName[procNameLen] = 0; + ret = procName; + } + return ret; +} + +#ifdef PLATFORM_POSIX +#ifdef CTRLLIB_H + void SetX11ErrorHandler(); + #define SetSysInfoX11ErrorHandler() {} +#else + #define SetX11ErrorHandler() {} + int SysInfoX11ErrorHandler(Display *, XErrorEvent *) {return 0;} + void SetSysInfoX11ErrorHandler() {XSetErrorHandler(SysInfoX11ErrorHandler);} +#endif +#endif + +void GetWindowsList_Rec (Display *dpy, Window w, int depth, Array &wid) +{ + if (depth > 3) // 1 is enough for Gnome. 2 is necessary for Xfce and Kde + return; + + wid.Add(w); + + Window root, parent; + unsigned int nchildren; + Window *children = NULL; + if (XQueryTree (dpy, w, &root, &parent, &children, &nchildren)) { + for (int i = 0; i < nchildren; i++) { + XWindowAttributes windowattr; + XGetWindowAttributes(dpy, children[i], &windowattr); + if (windowattr.map_state == IsViewable) + GetWindowsList_Rec (dpy, children[i], depth + 1, wid); + } + } + if (children) + XFree((char *)children); + return; +} +Array GetWindowsList() +{ + Array ret; + SetSysInfoX11ErrorHandler(); + + Display *dpy = XOpenDisplay (NULL); + if (!dpy) { + SetX11ErrorHandler(); + return ret; + } + GetWindowsList_Rec (dpy, RootWindow(dpy, DefaultScreen(dpy)), 0, ret); + XCloseDisplay (dpy); + SetX11ErrorHandler(); + return ret; +} +void GetWindowsList(Array &hWnd, Array &processId, Array &nameL, Array &fileName, Array &caption) +{ + SetSysInfoX11ErrorHandler(); + Display *dpy = XOpenDisplay (NULL); + if (!dpy) { + SetX11ErrorHandler(); + return; + } + GetWindowsList_Rec(dpy, RootWindow (dpy, DefaultScreen (dpy)), 0, hWnd); + for (int i = 0; i < hWnd.GetCount(); ++i) { + // Get window name + XTextProperty tp; + if (XGetWMName(dpy, hWnd[i], &tp) == 0) + caption.Add(""); + else { + if (tp.nitems > 0) { + int count = 0, i, ret; + char **list = NULL; + ret = XmbTextPropertyToTextList(dpy, &tp, &list, &count); + if((ret == Success || ret > 0) && list != NULL) { + String sret; + for(i = 0; i < count; i++) + sret << list[i] << " "; + XFreeStringList(list); + caption.Add(FromSystemCharset(sret)); + } else + caption.Add(FromSystemCharset((char *)tp.value)); + } else + caption.Add(""); + } + // Get pid + Atom atomPID = XInternAtom(dpy, "_NET_WM_PID", True); + unsigned long pid = 0; + if (atomPID == None) + processId.Add(0L); + else { + Atom type; + int format; + unsigned long nItems; + unsigned long bytesAfter; + unsigned char *propPID = 0; + if (0 == XGetWindowProperty(dpy, hWnd[i], atomPID, 0, 1024, False, XA_CARDINAL, &type, &format, &nItems, &bytesAfter, &propPID)) { + if(propPID != 0) { + pid = *((unsigned long *)propPID); + processId.Add(pid); + XFree(propPID); + } else + processId.Add(0L); + } else + processId.Add(0L); + } + if (pid != 0L) + fileName.Add(GetProcessFileName(pid)); + else + fileName.Add(""); + // Name and class + XClassHint ch; + ch.res_name = ch.res_class = NULL; + Status status = XGetClassHint (dpy, hWnd[i], &ch); + if (status != BadWindow) { + if (ch.res_name) + nameL.Add(ch.res_name); + else + nameL.Add(""); + } else + nameL.Add(""); + if (ch.res_name) + XFree (ch.res_name); + if (ch.res_class) + XFree (ch.res_class); + } + XCloseDisplay (dpy); + SetX11ErrorHandler(); + return; +} + +bool WindowKill(long wid) +{ + if (wid == 0) + return false; + + Display *dpy = XOpenDisplay (NULL); + if (!dpy) + return false; + + XSync (dpy, 0); + XKillClient (dpy, wid); + XSync (dpy, 0); + + XCloseDisplay (dpy); + return true; +} + +// Also possible to stop or cont +bool ProcessTerminate(long pid, int timeout) +{ + if (!ProcessExists(pid)) + return false; + long wid = GetWindowIdFromProcessId(pid); // Just in case + + // First... SIGTERM + kill(pid, SIGTERM); + Sleep(timeout/3); + if (!ProcessExists(pid)) + return true; + // Second... SIGKILL + kill(pid, SIGKILL); + Sleep(timeout/3); + if (!ProcessExists(pid)) + return true; + // Third ... WindowKill + Sleep((int)(timeout/3)); + return WindowKill(wid); +} + +int GetProcessPriority(long pid) +{ + int priority = getpriority(PRIO_PROCESS, pid); + return 10 - (priority + 20)/4; // Rescale -20/20 to 10/0 +} +bool SetProcessPriority(long pid, int priority) +{ + priority = 20 - 4*priority; + if (0 == setpriority(PRIO_PROCESS, pid, priority)) + return true; + else + return false; +} +#endif + +long GetWindowIdFromCaption(String windowCaption, bool exactMatch) +{ + Array wid, pid; + Array name, fileName, caption; + GetWindowsList(wid, pid, name, fileName, caption); + for (int i = 0; i < wid.GetCount(); ++i) { + if (exactMatch) { + if (caption[i] == windowCaption) + return wid[i]; + } else { + if (caption[i].Find(windowCaption) >= 0) + return wid[i]; + } + } + return -1; +} +long GetProcessIdFromWindowCaption(String windowCaption, bool exactMatch) +{ + Array wid, pid; + Array name, fileName, caption; + GetWindowsList(wid, pid, name, fileName, caption); + for (int i = 0; i < wid.GetCount(); ++i) { + if (exactMatch) { + if (caption[i] == windowCaption) + return pid[i]; + } else { + if (caption[i].Find(windowCaption) >= 0) + return pid[i]; + } + } + return -1; +} +long GetProcessIdFromWindowId(long _wId) +{ + Array wId, pid; + Array name, fileName, caption; + GetWindowsList(wId, pid, name, fileName, caption); + for (int i = 0; i < pid.GetCount(); ++i) { + if (wId[i] == _wId) + return pid[i]; + } + return 0; +} +long GetWindowIdFromProcessId(long _pid) +{ + Array wId, pid; + Array name, fileName, caption; + GetWindowsList(wId, pid, name, fileName, caption); + for (int i = 0; i < pid.GetCount(); ++i) { + if (pid[i] == _pid) + return wId[i]; + } + return 0; +} + +bool ProcessExists(long pid) +{ + return DirectoryExists(Format("/proc/%s", FormatLong(pid))); +} +///////////////////////////////////////////////////////////////////// +// Os Info + +#if defined(PLATFORM_WIN32) + +#if !defined(PRODUCT_ULTIMATE) +//#define PRODUCT_UNDEFINED 0x00000000 +#define PRODUCT_ULTIMATE 0x00000001 +#define PRODUCT_HOME_BASIC 0x00000002 +#define PRODUCT_HOME_PREMIUM 0x00000003 +#define PRODUCT_ENTERPRISE 0x00000004 +#define PRODUCT_HOME_BASIC_N 0x00000005 +#define PRODUCT_BUSINESS 0x00000006 +#define PRODUCT_STANDARD_SERVER 0x00000007 +#define PRODUCT_DATACENTER_SERVER 0x00000008 +#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 +#define PRODUCT_ENTERPRISE_SERVER 0x0000000A +#define PRODUCT_STARTER 0x0000000B +#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C +#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D +#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E +#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F +#define PRODUCT_BUSINESS_N 0x00000010 +#define PRODUCT_WEB_SERVER 0x00000011 +#define PRODUCT_CLUSTER_SERVER 0x00000012 +#define PRODUCT_HOME_SERVER 0x00000013 +#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 +#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 +#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 +#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 +#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 +#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 +#define PRODUCT_UNLICENSED 0xABCDABCD +#endif + +#if !defined(SM_SERVERR2) +#define SM_SERVERR2 89 +#endif + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); +typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); + +bool GetOsInfo(String &kernel, String &kerVersion, String &kerArchitecture, String &distro, String &distVersion, String &desktop, String &deskVersion) +{ + OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + PGNSI pGNSI; + PGPI pGPI; + BOOL bOsVersionInfoEx; + DWORD dwType; + + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi))) + return false; + + // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. + pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); + if(NULL != pGNSI) + pGNSI(&si); + else + GetSystemInfo(&si); + + kerVersion = Format("%d.%d", (int)osvi.dwMajorVersion, (int)osvi.dwMinorVersion); + kernel = "Windows"; + if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) + kerArchitecture = "64 bits"; + else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64) + kerArchitecture = "Itanium 64 bits"; + else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL) + kerArchitecture = "32 bits"; + else + kerArchitecture = "Unknown"; //PROCESSOR_ARCHITECTURE_UNKNOWN + if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4 ) { + // Test for the specific product. + if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 ) { + if( osvi.wProductType == VER_NT_WORKSTATION ) + kernel.Cat(" Vista"); + else + kernel.Cat(" Server 2008"); + pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); + pGPI( 6, 0, 0, 0, &dwType); + + switch( dwType ) { + case PRODUCT_ULTIMATE: + distro = "Ultimate Edition"; + break; + case PRODUCT_HOME_PREMIUM: + distro = "Home Premium Edition"; + break; + case PRODUCT_HOME_BASIC: + distro = "Home Basic Edition"; + break; + case PRODUCT_ENTERPRISE: + distro = "Enterprise Edition"; + break; + case PRODUCT_BUSINESS: + distro = "Business Edition"; + break; + case PRODUCT_STARTER: + distro = "Starter Edition"; + break; + case PRODUCT_CLUSTER_SERVER: + distro = "Cluster Server Edition"; + break; + case PRODUCT_DATACENTER_SERVER: + distro = "Datacenter Edition"; + break; + case PRODUCT_DATACENTER_SERVER_CORE: + distro = "Datacenter Edition (core installation)"; + break; + case PRODUCT_ENTERPRISE_SERVER: + distro = "Enterprise Edition"; + break; + case PRODUCT_ENTERPRISE_SERVER_CORE: + distro = "Enterprise Edition (core installation)"; + break; + case PRODUCT_ENTERPRISE_SERVER_IA64: + distro = "Enterprise Edition for Itanium-based Systems"; + break; + case PRODUCT_SMALLBUSINESS_SERVER: + distro = "Small Business Server"; + break; + case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: + distro = "Small Business Server Premium Edition"; + break; + case PRODUCT_STANDARD_SERVER: + distro = "Standard Edition"; + break; + case PRODUCT_STANDARD_SERVER_CORE: + distro = "Standard Edition (core installation)"; + break; + case PRODUCT_WEB_SERVER: + distro = "Web Server Edition"; + break; + } + } + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { + if (GetSystemMetrics(SM_SERVERR2) ) + kernel.Cat(" Server 2003 R2"); + else if ( osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER ) + kernel.Cat(" Storage Server 2003"); + else if( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) + kernel.Cat(" XP Professional x64 Edition"); + else + kernel.Cat(" Server 2003"); + // Test for the server type. + if (osvi.wProductType != VER_NT_WORKSTATION ) { + if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 ) { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER ) + distro = "Datacenter Edition for Itanium-based Systems"; + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + distro = "Enterprise Edition for Itanium-based Systems"; + } + } else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER ) + distro = "Datacenter x64 Edition"; + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + distro = "Enterprise x64 Edition"; + else + distro = "Standard x64 Edition"; + } else { + if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER ) + distro = "Compute Cluster Edition"; + else if(osvi.wSuiteMask & VER_SUITE_DATACENTER ) + distro = "Datacenter Edition"; + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + distro = "Enterprise Edition"; + else if (osvi.wSuiteMask & VER_SUITE_BLADE ) + distro = "Web Edition"; + else + distro = "Standard Edition"; + } + } + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) { + kernel.Cat(" XP"); + if(osvi.wSuiteMask & VER_SUITE_PERSONAL ) + distro = "Home Edition"; + else + distro = "Professional"; + } + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) { + kernel.Cat(" 2000"); + if ( osvi.wProductType == VER_NT_WORKSTATION ) + distro = "Professional"; + else { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER ) + distro = "Datacenter Server"; + else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + distro = "Advanced Server"; + else + distro = "Server"; + } + } + // Include service pack (if any) and build number. + if(osvi.wServicePackMajor > 0) + kerVersion.Cat(Format(" %s", osvi.szCSDVersion)); + + kerVersion.Cat(Format(" (Build %d)", (int)osvi.dwBuildNumber)); + } else if (osvi.dwPlatformId == 1) { + switch(osvi.dwMinorVersion) { + case 0: + kernel.Cat(" 95"); + break; + case 10: + kernel.Cat(" 98"); + break; + case 90: + kernel.Cat(" Millennium"); + break; + } + distro = ""; + } else if (osvi.dwPlatformId == 2) { + switch(osvi.dwMajorVersion) { + kernel.Cat(" NT"); + case 3: + kernel.Cat(" 3.51"); + break; + case 4: + kernel.Cat(" 4.0"); + break; + } + distro = ""; + } + desktop = kernel; + distVersion = deskVersion = ""; + return true; +} +#endif +#ifdef PLATFORM_POSIX + +bool GetOsInfo_CheckLsb(String &distro, String &distVersion) +{ + StringParse lsb; + lsb = LoadFile_Safe("/etc/lsb-release"); + if (lsb == "") + return false; + if(!lsb.GoAfter("DISTRIB_ID=")) + return false; + distro = ToLower(lsb.GetText()); + if (distro == "") + return false; + lsb.GoAfter_Init("DISTRIB_RELEASE="); + distVersion = lsb.GetText(); + + return true; +} +String GetDesktopManagerNew() +{ + String kernel, kerVersion, kerArchitecture, distro, distVersion, desktop, deskVersion; + if (GetOsInfo(kernel, kerVersion, kerArchitecture, distro, distVersion, desktop, deskVersion)) + return desktop; + else + return String(""); +} +bool GetOsInfo(String &kernel, String &kerVersion, String &kerArchitecture, String &distro, String &distVersion, String &desktop, String &deskVersion) +{ + struct utsname buf; + + if (0 == uname(&buf)) { + kernel = buf.sysname; + kerVersion = String(buf.release) + " " + String(buf.version); + kerArchitecture = buf.machine; + } + if (kernel == "") + kernel = LoadFile_Safe("/proc/sys/kernel/ostype"); + if (kernel == "") + kernel = LoadFile_Safe("/proc/version"); + if (kernel == "") { + if (LaunchCommand("sysctl_cmd -n kern.version").Find("FreeBSD") >= 0) + kernel = "freebsd"; + } + if (kerVersion == "") + kerVersion = LoadFile_Safe("/proc/sys/kernel/osrelease") + " " + LoadFile_Safe("/proc/sys/kernel/version"); + if (kerArchitecture == "") + kerArchitecture = LaunchCommand("uname -m"); // Kernel. See too /proc/version, /proc/version_signature and uname -a looking for architecture + + if (kernel == "") + kernel = kerVersion = kerArchitecture = "UNKNOWN"; + + // Desktop + if(GetEnv("GNOME_DESKTOP_SESSION_ID").GetCount() || GetEnv("GNOME_KEYRING_SOCKET").GetCount()) { + desktop = "gnome"; + StringParse gnomeVersion = LaunchCommand("gnome-about --version"); + gnomeVersion.GoAfter("gnome-about"); + deskVersion = gnomeVersion.GetText(); + } else if(GetEnv("KDE_FULL_SESSION").GetCount() || GetEnv("KDEDIR").GetCount() || GetEnv("KDE_MULTIHEAD").GetCount()) { + desktop = "kde"; + StringParse konsole = LaunchCommand("konsole --version"); + konsole.GoAfter("KDE:"); + deskVersion = konsole.GetText("\r\n"); + if (deskVersion == "") + deskVersion = GetEnv("KDE_SESSION_VERSION"); + } else { + StringParse desktopStr; + if (LaunchCommand("xprop -root _DT_SAVE_MODE").Find("xfce") >= 0) + desktop = "xfce"; + else if ((desktopStr = LaunchCommand("xprop -root")).Find("ENLIGHTENMENT") >= 0) { + desktop = "enlightenment"; + desktopStr.GoAfter("ENLIGHTENMENT_VERSION(STRING)", "="); + desktopStr = desktopStr.GetText(); + if (desktopStr.GetText() == "Enlightenment") + deskVersion = desktopStr.GetText(); + } else + desktop = GetEnv("DESKTOP_SESSION"); + } + if (desktop == "") + desktop = deskVersion = "UNKNOWN"; + + // Distro + if (GetOsInfo_CheckLsb(distro, distVersion)) + ; + else if (FileExists("/usr/share/doc/ubuntu-minimal")) + distro = "ubuntu"; + else if (FileExists("/etc/fedora-release")) { + distro = "fedora"; + StringParse strFile = LoadFile_Safe("/etc/fedora-release"); + String str; + do { + str = strFile.GetText(); + if ((str != "fedora") && (str != "release")) + distVersion << str << " "; + } while (str != ""); + } else if (FileExists("/etc/redhat-release")) { + distro = "redhat"; + distVersion = LoadFile_Safe("/etc/redhat-release"); + } else if (FileExists("/etc/SuSE-release")) { + StringParse strFile = LoadFile_Safe("/etc/SuSE-release"); + distro = strFile.GetText(); + strFile.GoAfter_Init("VERSION", "="); + distVersion = strFile.GetText(); + } else if (FileExists("/etc/mandrake-release")) { + distro = "mandrake"; + distVersion = LoadFile_Safe("/etc/mandrake-release"); + } else if (FileExists("/etc/mandriva-release")) { + distro = "mandriva"; + distVersion = LoadFile_Safe("/etc/mandriva-release"); + } else if (FileExists("/etc/aurox-release")) { + distro = "aurox"; + distVersion = LoadFile_Safe("/etc/aurox-release"); + } else if (FileExists("/etc/altlinux-release")) { + distro = "altlinux"; + distVersion = LoadFile_Safe("/etc/altlinux-releas"); + } else if (FileExists("/etc/gentoo-release")) { + distro = "gentoo"; + distVersion = LoadFile_Safe("/etc/gentoo-release"); + } else if (FileExists("/usr/portage")) { + distro = "gentoo"; + distVersion = LoadFile_Safe("/usr/portage"); + } else if (FileExists("/etc/slackware-version")) { + distro = "slackware"; + StringParse strFile = LoadFile_Safe("/etc/slackware-version"); + strFile.GetText(); + distVersion = strFile.GetText(); + } else if (FileExists("/etc/debian_version")) { + distro = "debian"; + distVersion = LoadFile_Safe("/etc/debian_version"); + } else if (LoadFile_Safe("/etc/release").Find("Solaris") >= 0) + distro = "solaris"; + else if (LaunchCommand("uname -r").Find("solaris") >= 0) + distro = "solaris"; + else { // If not try with /etc/osname_version + distro = LoadFile_Safe("/etc/osname_version"); + distVersion = ""; + } + if (distro == "") + distro = LoadFile_Safe("/etc/issue"); + if (distro == "") + distro = distVersion = "UNKNOWN"; + + return true; +} + +#endif + +///////////////////////////////////////////////////////////////////// +// Others + +long GetProcessId() {return getpid();} + +///////////////////////////////////////////////////////////////////// +// Drives list +#if defined(PLATFORM_WIN32) + +Array GetDriveList() +{ + char drvStr[26*4+1]; // A, B, C, ... + Array ret; + + int lenDrvStrs = ::GetLogicalDriveStrings(sizeof(drvStr), drvStr); + // To get the error call GetLastError() + if (lenDrvStrs == 0) + return ret; + + ret.Add(drvStr); + for (int i = 0; i < lenDrvStrs-1; ++i) { + if (drvStr[i] == '\0') + ret.Add(drvStr + i + 1); + } + return ret; +} + +bool GetDriveSpace(String drive, + //uint64 &totalBytes, // To determine the total number of bytes on a disk or volume, use IOCTL_DISK_GET_LENGTH_INFO. + uint64 &freeBytesUser, // Total number of free bytes on a disk that are available to the user who is associated with the calling thread. + uint64 &totalBytesUser, // Total number of bytes on a disk that are available to the user who is associated with the calling thread. + uint64 &totalFreeBytes) // Total number of free bytes on a disk. +{ + StringBuffer sb(drive); + + if(!GetDiskFreeSpaceEx(sb, (PULARGE_INTEGER)&freeBytesUser, (PULARGE_INTEGER)&totalBytesUser, (PULARGE_INTEGER)&totalFreeBytes)) + return false; + //totalBytes = 0; + return true; +} +// return true if mounted +bool GetDriveInformation(String drive, String &type, String &volume, /*uint64 &serial, */int &maxName, String &fileSystem) +{ + StringBuffer sb(drive); + + switch (::GetDriveType(sb)) { + case DRIVE_UNKNOWN: type = "Drive unknown"; break; + case DRIVE_NO_ROOT_DIR: type = "The root directory does not exist"; break; + case DRIVE_REMOVABLE: + switch (*sb) { + case 'A': + case 'B': type = "Floppy"; + volume = fileSystem = ""; + /*serial = */maxName = 0; + return false; + default: type = "Removable"; break; + } + break; + case DRIVE_FIXED: type = "Hard"; break; + case DRIVE_REMOTE: type = "Network"; break; + case DRIVE_CDROM: type = "Optical"; break; + case DRIVE_RAMDISK: type = "RAM"; break; + } + char vol[MAX_PATH], fs[MAX_PATH]; + long flags; + uint64 serial; + uint64 _maxName; + if(!::GetVolumeInformation(sb, vol, MAX_PATH, (LPDWORD)&serial, (LPDWORD)&_maxName, (LPDWORD)&flags, fs, MAX_PATH)) { + if (type == "Optical") { + volume = ""; + fileSystem = ""; + maxName = 0; + return true; + } else + return false; + } + volume = vol; + fileSystem = fs; + maxName = (int)_maxName; + + return true; +} + +#elif defined(PLATFORM_POSIX) + +Array GetDriveList() +{ + Array ret; + // Search for mountable file systems + String mountableFS; + StringParse sfileSystems(LoadFile_Safe("/proc/filesystems")); + String str; + while (true) { + str = sfileSystems.GetText(); + if (str == "") + break; + else if (str != "nodev") + mountableFS << str << "."; + else + str = sfileSystems.GetText(); + } + // Get mounted drives + StringParse smounts(LoadFile_Safe("/proc/mounts")); + StringParse smountLine(smounts.GetText("\r\n")); + do { + String devPath = smountLine.GetText(); + String mountPath = smountLine.GetText(); + String fs = smountLine.GetText(); + if ((mountableFS.Find(fs) >= 0) && (mountPath.Find("/dev") < 0) && (mountPath.Find("/rofs") < 0)) // Is mountable + ret.Add(mountPath); + smountLine = smounts.GetText("\r\n"); + } while (smountLine != ""); + + return ret; +} +bool GetDriveSpace(String drive, + //uint64 &totalBytes, // To determine the total number of bytes on a disk or volume, use IOCTL_DISK_GET_LENGTH_INFO. + uint64 &freeBytesUser, // Total number of free bytes on a disk that are available to the user who is associated with the calling thread. + uint64 &totalBytesUser, // Total number of bytes on a disk that are available to the user who is associated with the calling thread. + uint64 &totalFreeBytes) // Total number of free bytes on a disk. +{ + freeBytesUser = totalBytesUser = totalFreeBytes = 0; + + StringParse space = LaunchCommand("df -T"); + if (space == "") + return false; + + while (drive != space.GetText()) + ; + space.MoveRel(-10); space.GoBeginLine(); + space.GetText(); space.GetText(); // Jumps over device path and filesystem + totalBytesUser = 1024*space.GetUInt64(); + space.GetText(); // Jumps over used space + freeBytesUser = totalFreeBytes = 1024*space.GetUInt64(); + return true; +} + +// return true if mounted +bool GetDriveInformation(String drive, String &type, String &volume, /*uint64 &serial, */int &maxName, String &fileSystem) +{ + StringParse info = LaunchCommand("mount -l"); + if (info == "") + return false; + String straux; + while (drive != (straux = info.GetText())) + if (straux == "") + return false; + + if("type" != info.GetText()) // Jumps over "type" + return false; + + fileSystem = info.GetText(); + String details = info.GetText(); + info.GoAfter("["); + volume = info.GetText("]"); + //serial = 0; // Unknown + if ((fileSystem == "udf" || fileSystem == "iso9660") && details.Find("ro") >=0) + type = "Optical"; + else if (details.Find("flush") >=0) + type = "Removable"; + else + type = "Hard"; + + struct statfs buf; + if (0 == statfs(drive, &buf)) { + //puts(Format("%x", buf.f_type)); // Filesystem type + maxName = buf.f_namelen; + } else { + maxName = 0; + } +} + +#endif + +#if defined (PLATFORM_WIN32) +unsigned __int64 spstart, spstop; +unsigned __int64 nCtr, nFreq, nCtrStop; + +#if defined(__MINGW32__) +int GetCpuSpeed() +{ + if(!QueryPerformanceFrequency((LARGE_INTEGER *) &nFreq)) + return 0; + + QueryPerformanceCounter((LARGE_INTEGER *)&nCtrStop); + nCtrStop += nFreq/10000; + + __asm__(".byte 0x0F"); + __asm__(".byte 0x31"); + __asm__("mov %eax,_spstart"); + __asm__("mov %edx,4+(_spstart)"); + + do + QueryPerformanceCounter((LARGE_INTEGER *)&nCtr); + while (nCtr < nCtrStop); + + __asm__(".byte 0x0F"); + __asm__(".byte 0x31"); + __asm__("mov %eax,_spstop"); + __asm__("mov %edx,4+(_spstop)"); + + return (int)((spstop-spstart)/100); +} +#elif defined(_MSC_VER) +int GetCpuSpeed() +{ + if(!QueryPerformanceFrequency((LARGE_INTEGER *) &nFreq)) + return 0; + QueryPerformanceCounter((LARGE_INTEGER *) &nCtrStop); + nCtrStop += nFreq/10000; + + _asm { + __asm _emit 0x0f + __asm _emit 0x31 + mov DWORD PTR spstart, eax + mov DWORD PTR [spstart + 4], edx + } + do + QueryPerformanceCounter((LARGE_INTEGER *) &nCtr); + while (nCtr < nCtrStop); + _asm { + __asm _emit 0x0f + __asm _emit 0x31 + mov DWORD PTR spstop, eax + mov DWORD PTR [spstop + 4], edx + } + return (int)((spstop-spstart)/100); +} +#endif +#endif +#if defined(PLATFORM_POSIX) + +#define RDTSC_READ(tm) __asm__ __volatile__ (".byte 0x0f; .byte 0x31" :"=a" (tm)) +#define COUNT_SEC (double)tv.tv_sec + (1.e-6)*tv.tv_usec + +int GetCpuSpeed() +{ + struct timeval tv; + double cnt1,cnt2; + unsigned long start,end; + + RDTSC_READ(start); + gettimeofday(&tv, 0); + cnt1 = COUNT_SEC + 0.01; + + do { + gettimeofday(&tv, 0); + cnt2 = COUNT_SEC; + } while(cnt2 < cnt1); + + RDTSC_READ(end); + + return (int)((end-start)/10000); +} +#endif +#if defined(PLATFORM_WIN32) + +#define SHTDN_REASON_MINOR_OTHER 0 + +bool Shutdown(String action) +{ + unsigned int flag; + if (action == "logoff") + flag = EWX_LOGOFF; +// else if (action == "poweroff") +// flag = EWX_POWEROFF; + else if (action == "reboot") + flag = EWX_REBOOT; + else if (action == "shutdown") + flag = EWX_SHUTDOWN; + else + return false; + + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + + // Get a token for this process. + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) + return false; + + // Get the LUID for the shutdown privilege. + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get the shutdown privilege for this process. + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, + (PTOKEN_PRIVILEGES)NULL, 0); + + if (GetLastError() != ERROR_SUCCESS) + return false; + + // Shut down the system and force all applications to close. + if (!ExitWindowsEx(flag | EWX_FORCE, SHTDN_REASON_MINOR_OTHER)) + return false; + + return true; +} +#endif + +#ifdef PLATFORM_POSIX +bool Shutdown(String action) +{ + if (action == "logoff") { + kill(1, SIGTSTP); + sync(); + signal(SIGTERM, SIG_IGN); + setpgrp(); + kill(-1, SIGTERM); + sleep(1); + kill(-1, SIGHUP); //* Force PPPD's down, too * + sleep(1); + kill(-1, SIGKILL); + sync(); + sleep(1); + } else if (action == "shutdown") { +#if __GNU_LIBRARY__ > 5 + reboot(0xCDEF0123); +#else + reboot(0xfee1dead, 672274793, 0xCDEF0123); +#endif + } else if (action == "reboot") { // LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2 +#if __GNU_LIBRARY__ > 5 + reboot(0x01234567); +#else + reboot(0xfee1dead, 672274793, 0x01234567); +#endif + } + exit(0); + return true; +} +#endif + +String BytesToString(uint64 _bytes) +{ + String ret; + uint64 bytes = _bytes; + + if (bytes >= 1024) { + bytes /= 1024; + if (bytes >= 1024) { + bytes /= 1024; + if (bytes >= 1024) { + bytes /= 1024; + if (bytes >= 1024) { + bytes /= 1024; + ret = Format("%.2f%s", _bytes/(1024*1024*1024*1024.), "Tb"); + } else + ret = Format("%.2f%s", _bytes/(1024*1024*1024.), "Gb"); + } else + ret = Format("%.2f%s", _bytes/(1024*1024.), "Mb"); + } else + ret = Format("%.2f%s", _bytes/1024., "Kb"); + } else + ret << _bytes << "b"; + return ret; +} + +String SecondsToString(double _seconds) +{ + String ret; + bool add0; + long seconds = (long)_seconds; + + if (_seconds >= 60) { + seconds /= 60; + _seconds -= 60*seconds; + ret = FormatDouble(_seconds, 2); + add0 = _seconds < 10; + if (seconds >= 60) { + seconds /= 60; + _seconds -= 60*seconds; + ret = FormatDouble(_seconds) + ":" + (add0 ? "0":"") + ret; + add0 = _seconds < 10; + if (seconds >= 60) { + seconds /= 60; + _seconds -= 60*seconds; + ret = FormatDouble(_seconds) + ":" + (add0 ? "0":"") + ret; + } + } else + ret = FormatDouble(seconds) + ":" + (add0 ? "0":"") + ret; + } else + ret = FormatDouble(_seconds, 2); + return ret; +} + +void GetCompilerInfo(String &name, int &version, String &date) +{ + name = ""; + version = 0; + date = __DATE__; + #if defined(WIN32) + #if defined(__MINGW32__) + name = "mingw"; + version = __GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__; // __VERSION__ + #elif defined(COMPILER_MSC) + name = "msc"; + version = _MSC_FULL_VER; + #elif defined (__BORLANDC__) + name = "borlandc" + version = __BORLANDC__; + #elif defined (__WATCOMC__) + name = "watcomc" + version = __WATCOMC__; + #endif + #elif defined (PLATFORM_POSIX) + #if defined(__GNUC__) + name = "gnuc"; + version = __GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__; + #endif + #elif defined (__APPLE__) + // In a next future? + #endif +} + + +#ifdef PLATFORM_POSIX +bool GetBatteryStatus(bool &discharging, int &percentage, int &remainingMin) +{ + percentage = 100; + Array files = SearchFile("/proc/acpi/battery", "state"); + if (files.GetCount() == 0) + return false; + StringParse state = LoadFile_Safe(files[0]); + if (state == "") + return false; + bool present; + if(!state.GoAfter_Init("present", ":")) + return false; + present = state.GetText() == "yes"; + if (!present) + return false; // No battery inserted + state.GoAfter_Init("charging state", ":"); discharging = state.GetText() == "discharging"; + int presentRate, remainingCapacity; + state.GoAfter_Init("present rate", ":"); presentRate = state.GetInt(); + state.GoAfter_Init("remaining capacity", ":"); remainingCapacity = state.GetInt(); + if (presentRate == 0 || !discharging) + remainingMin = 10000; + else + remainingMin = (int)((60.*remainingCapacity)/presentRate); + + int designCapacity,lastFullCapacity; + String vendor, type, model, serial; + if (!GetBatteryInfo(present/*, designCapacity, lastFullCapacity, vendor, type, model, serial*/)) + percentage = (int)((100.*remainingCapacity)/lastFullCapacity); + return true; +} +bool GetBatteryInfo(bool &present/*, int &designCapacity, int &lastFullCapacity, String &vendor, String &type, String &model, String &serial*/) +{ + Array files = SearchFile("/proc/acpi/battery", "info"); + if (files.GetCount() == 0) + return false; + StringParse info = LoadFile_Safe(files[0]); + if (info == "") + return false; + info.GoAfter_Init("present", ":"); present = info.GetText() == "yes"; + /* + info.GoAfter_Init("design capacity", ":"); designCapacity = info.GetInt(); + info.GoAfter_Init("last full capacity", ":");lastFullCapacity = info.GetInt(); + info.GoAfter_Init("OEM info", ":"); vendor = info.GetText(); + info.GoAfter_Init("battery type", ":"); type = info.GetText(); + info.GoAfter_Init("model number", ":"); model = info.GetText(); + info.GoAfter_Init("serial number", ":"); serial = info.GetText(); + */ + return true; +} + +#endif +#if defined(PLATFORM_WIN32) +bool GetBatteryStatus(bool &discharging, int &percentage, int &remainingMin) +{ + SYSTEM_POWER_STATUS power; + + if(::GetSystemPowerStatus(&power) == 0) + return false; + + if (power.ACLineStatus == 1) + discharging = false; + else + discharging = true; + percentage = power.BatteryLifePercent; + remainingMin = (int)(power.BatteryLifeTime/60); + + return true; +} +bool GetBatteryInfo(bool &present/*, int &designCapacity, int &lastFullCapacity, String &vendor, String &type, String &model, String &serial*/) +{ + SYSTEM_POWER_STATUS power; + + if(::GetSystemPowerStatus(&power) == 0) + return false; + if (power.BatteryFlag == 128) + return false; // No battery + + //designCapacity = (int)(power.BatteryFullLifeTime/60.); + + present = true; + //power.ACLineStatus == 0; + //lastFullCapacity = 0; + //vendor = type = model = serial = "UNKNOWN"; + + return true; +} +#endif + +#if defined(PLATFORM_WIN32) + +void Mouse_LeftDown() +{ + mouse_event (MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); +} +void Mouse_LeftUp() +{ + mouse_event (MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); +} +void Mouse_MiddleDown() +{ + mouse_event (MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0); +} +void Mouse_MiddleUp() +{ + mouse_event (MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0); +} +void Mouse_RightDown() +{ + mouse_event (MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0); +} +void Mouse_RightUp() +{ + mouse_event (MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); +} +void Mouse_LeftClick() +{ + Mouse_LeftDown(); + Mouse_LeftUp(); +} +void Mouse_MiddleClick() +{ + Mouse_MiddleDown(); + Mouse_MiddleUp(); +} +void Mouse_RightClick() +{ + Mouse_RightDown(); + Mouse_RightUp(); +} +void Mouse_LeftDblClick() +{ + Mouse_LeftClick(); + Mouse_LeftClick(); +} +void Mouse_MiddleDblClick() +{ + Mouse_MiddleClick(); + Mouse_MiddleClick(); +} +void Mouse_RightDblClick() +{ + Mouse_RightClick(); + Mouse_RightClick(); +} + +bool PutWindowPlacement(HWND hwnd, RECT rcNormalPosition, POINT ptMinPosition, POINT ptMaxPosition, long showcmd, long flags) +{ + WINDOWPLACEMENT place; + + place.ptMinPosition = ptMinPosition; + place.ptMaxPosition = ptMaxPosition; + place.rcNormalPosition = rcNormalPosition; + place.showCmd = showcmd; + place.flags = flags; + place.length = sizeof(place); + return SetWindowPlacement(hwnd, &place); +} +bool TakeWindowPlacement(HWND hwnd, RECT &rcNormalPosition, POINT &ptMinPosition, POINT &ptMaxPosition, long &showcmd) +{ + WINDOWPLACEMENT place; + + place.length = sizeof(place); + bool ret = GetWindowPlacement(hwnd, &place); + ptMinPosition = place.ptMinPosition; + ptMaxPosition = place.ptMaxPosition; + rcNormalPosition = place.rcNormalPosition; + showcmd = place.showCmd; //SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWNORMAL + //flags = place.flags; // Always 0 + + return ret; +} +bool Window_GetRect(long windowId, long &left, long &top, long &right, long &bottom) +{ + RECT rcNormalPosition; + POINT ptMinPosition, ptMaxPosition; + long showcmd; + + TakeWindowPlacement((HWND)windowId, rcNormalPosition, ptMinPosition, ptMaxPosition, showcmd); + + left = rcNormalPosition.left; + top = rcNormalPosition.top; + right = rcNormalPosition.right; + bottom = rcNormalPosition.bottom; + + return true; +} +void Window_SetRect(long windowId, long left, long top, long right, long bottom) +{ + RECT rcNormalPosition; + POINT ptMinPosition, ptMaxPosition; + long showcmd; + + TakeWindowPlacement((HWND)windowId, rcNormalPosition, ptMinPosition, ptMaxPosition, showcmd); + + rcNormalPosition.left = left; + rcNormalPosition.top = top; + rcNormalPosition.right = right; + rcNormalPosition.bottom = bottom; + PutWindowPlacement((HWND)windowId, rcNormalPosition, ptMinPosition, ptMaxPosition, showcmd, 0); +} +bool Mouse_SetPos(long xMove, long yMove, long windowId) +{ + long left, top, right, bottom; + + if (windowId != 0) { + Window_GetRect(windowId, left, top, right, bottom); + xMove = xMove + left; + yMove = yMove + top; + } + SetCursorPos(xMove, yMove); + DoEvents(); + + return true; +} +bool Mouse_GetPos(long &x, long &y) +{ + POINT p; + + GetCursorPos (&p); + x = p.x; + y = p.y; + + return true; +} + +struct KeyCodes { + String key; + int code; +}; + +KeyCodes keyCodes[60] = { + "NUMPAD7", VK_NUMPAD7, "BACK", VK_BACK, + "NUMPAD8", VK_NUMPAD8, "TAB", VK_TAB, + "NUMPAD9", VK_NUMPAD9, "RETURN", VK_RETURN, + "MULTIPLY", VK_MULTIPLY, "SHIFT", VK_SHIFT, + "ADD", VK_ADD, "CONTROL", VK_CONTROL, + "SEPARATOR", VK_SEPARATOR, "MENU", VK_MENU, + "SUBTRACT", VK_SUBTRACT, "PAUSE", VK_PAUSE, + "DECIMAL", VK_DECIMAL, "CAPITAL", VK_CAPITAL, + "DIVIDE", VK_DIVIDE, "ESCAPE", VK_ESCAPE, + "F1", VK_F1, "SPACE", VK_SPACE, + "F2", VK_F2, "END", VK_END, + "F3", VK_F3, "HOME", VK_HOME, + "F4", VK_F4, "LEFT", VK_LEFT, + "F5", VK_F5, "UP", VK_UP, + "F6", VK_F6, "RIGHT", VK_RIGHT, + "F7", VK_F7, "DOWN", VK_DOWN, + "F8", VK_F8, "PRINT", VK_PRINT, + "F9", VK_F9, "SNAPSHOT", VK_SNAPSHOT, + "F10", VK_F10, "INSERT", VK_INSERT, + "F11", VK_F11, "DELETE", VK_DELETE, + "F12", VK_F12, "LWIN", VK_LWIN, + "NUMLOCK", VK_NUMLOCK, "RWIN", VK_RWIN, + "SCROLL", VK_SCROLL, "NUMPAD0", VK_NUMPAD0, + "LSHIFT", VK_LSHIFT, "NUMPAD1", VK_NUMPAD1, + "RSHIFT", VK_RSHIFT, "NUMPAD2", VK_NUMPAD2, + "LCONTROL", VK_LCONTROL, "NUMPAD3", VK_NUMPAD3, + "RCONTROL", VK_RCONTROL, "NUMPAD4", VK_NUMPAD4, + "LMENU", VK_LMENU, "NUMPAD5", VK_NUMPAD5, + "RMENU", VK_RMENU, "NUMPAD6", VK_NUMPAD6, + "" +}; + +int GetKeyCode(String key) +{ + for (int i = 0; keyCodes[i].code != 0; ++i) + if (keyCodes[i].key == key) + return keyCodes[i].code; + return 0; +} + +void PressKey(int key, bool hold = false, bool release = false) +{ + bool caps, num, scroll; + if (IsLetter(key)) { + GetKeyLockStatus(caps, num, scroll); + if (caps) + SetKeyLockStatus(false, num, scroll); + } + long nVK = VkKeyScan(key); + + if (nVK == 0) + return; + + long nScan, nExtended; + + nScan = MapVirtualKey(nVK, 2); + nExtended = 0; + if (nScan == 0) + nExtended = KEYEVENTF_EXTENDEDKEY; + + nScan = MapVirtualKey(nVK, 0); + + bool shift, ctrl, alt; + + shift = nVK & 0x100; + ctrl = nVK & 0x200; + alt = nVK & 0x400; + nVK = nVK & 0xFF; + + if (!release) { + if (shift) + keybd_event (VK_SHIFT, 0, 0, 0); + if (ctrl) + keybd_event (VK_CONTROL, 0, 0, 0); + if (alt) + keybd_event (VK_MENU, 0, 0, 0); + + keybd_event ((BYTE)nVK, (BYTE)nScan, nExtended, 0); + } + if (!hold) { + keybd_event ((BYTE)nVK, (BYTE)nScan, KEYEVENTF_KEYUP | nExtended, 0); + + if (shift) + keybd_event (VK_SHIFT, 0, KEYEVENTF_KEYUP, 0); + if (ctrl) + keybd_event (VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); + if (alt) + keybd_event (VK_MENU, 0, KEYEVENTF_KEYUP, 0); + } + if (IsLetter(key) && caps) + SetKeyLockStatus(true, num, scroll); +} +void PressKeyVK(int keyVK, bool hold = false, bool release = false, bool compatible = false) +{ + long nScan, nExtended; + + nScan = MapVirtualKey(keyVK, 2); + nExtended = 0; + if (nScan == 0) + nExtended = KEYEVENTF_EXTENDEDKEY; + nScan = MapVirtualKey(keyVK, 0); + + if (compatible) + nExtended = 0; + + if (!release) + keybd_event ((BYTE)keyVK, (BYTE)nScan, nExtended, 0); + + if (!hold) + keybd_event ((BYTE)keyVK, (BYTE)nScan, KEYEVENTF_KEYUP | nExtended, 0); +} + +void Keyb_SendKeys(String text, long finalDelay, long delayBetweenKeys) +{ + bool inKey = false; + String key = ""; + for (int i = 0; i < text.GetCount(); ++i) { + bool vk = false; + Sleep(delayBetweenKeys); + int c = text[i]; + if (c == '{') + inKey = true; + else if (c == '}') { + if (key == "{") + c = '{'; + else { + c = GetKeyCode(key); + vk = true; + } + inKey = false; + key = ""; + } else if (inKey == 1) + key.Cat(c); + + if (inKey == false) { + if (!vk) + PressKey(c); + else + PressKeyVK(c); + } + } + Sleep(finalDelay); +} + +void GetKeyLockStatus(bool &caps, bool &num, bool &scroll) +{ + caps = GetKeyState(VK_CAPITAL); + num = GetKeyState(VK_NUMLOCK); + scroll = GetKeyState(VK_SCROLL); +} +void SetKeyLockStatus(bool caps, bool num, bool scroll) +{ + bool capsnow, numnow, scrollnow; + + GetKeyLockStatus(capsnow, numnow, scrollnow); + if (capsnow != caps) + PressKeyVK(VK_CAPITAL); + if (numnow != num) + PressKeyVK(VK_NUMLOCK); + if (scrollnow != scroll) + PressKeyVK(VK_SCROLL); +} + +#if defined(__MINGW32__) + #define labs(x) labs((Upp::int64)(x)) +#elif defined(_MSC_VER) + #define labs(x) abs(x) +#endif + +bool Window_SaveCapture(long windowId, String fileName, int left, int top, int width, int height) +{ + if (windowId == 0) + windowId = (long)GetDesktopWindow(); + + if (GetFileExt(fileName) != ".bmp") + fileName += ".bmp"; + + RECT rc; + GetWindowRect ((HWND)windowId, &rc); + + if (left == -1) + left = rc.left; + if (top == -1) + top = rc.top; + if (width == -1) + width = rc.right-rc.left; + if (height == -1) + height = rc.bottom-rc.top; + + HDC hDC = GetDC(0); + HDC memDC = CreateCompatibleDC (hDC); + HBITMAP hb = CreateCompatibleBitmap (hDC, width, height); + HBITMAP OldBM = (HBITMAP)SelectObject(memDC, hb); + BitBlt(memDC, 0, 0, width, height , hDC, left, top , SRCCOPY); + + FILE *file = NULL; + LPVOID buf = NULL; + BITMAPINFO bmpInfo; + BITMAPFILEHEADER bmpFileHeader; + ZeroMemory(&bmpInfo, sizeof(BITMAPINFO)); + bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + GetDIBits(hDC, hb, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS); + if(bmpInfo.bmiHeader.biSizeImage <= 0) + bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth*labs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; + if((buf = malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) + return false; + bmpInfo.bmiHeader.biCompression = BI_RGB; + GetDIBits(hDC, hb, 0, bmpInfo.bmiHeader.biHeight, buf, &bmpInfo, DIB_RGB_COLORS); + if((file = fopen(fileName,"wb")) == NULL) + return false; + bmpFileHeader.bfReserved1 = 0; + bmpFileHeader.bfReserved2 = 0; + bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; + bmpFileHeader.bfType = 19778; + bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, file); + fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER), 1, file); + fwrite(buf,bmpInfo.bmiHeader.biSizeImage, 1, file); + + free(buf); + fclose(file); + + SelectObject(hDC, OldBM); + DeleteObject(hb); + DeleteDC(memDC); + ReleaseDC(0, hDC); + + return true; +} + +class ScreenGrab { +private: + enum {GRAB_MODE_DESKTOP, GRAB_MODE_WINDOW, GRAB_MODE_RECT}; + static HDC lDCDest; + static HGDIOBJ lDib; + static void *lDibPtr; + static HGDIOBJ lBmpOld; + static BITMAPINFO tBmpInfo; + static PAVIFILE lAVIPtrFile; + static PAVISTREAM lAVIPtrStrm; + static AVISTREAMINFO tAVIHdr; + static AVIFILEINFO tAVIFile; + long lAVICnt; + double frameRate; + long numFrames; // number of frames in video stream + long firstFrame; // position of the first video frame + String fileName; + bool viewMouse; + bool opened; + int grabMode; + int hwnd; + int left; + int top; + int width; + int height; + + bool AVIOpen(bool create = true); + bool AVIWrite(); + void AVIClose(); + HICON GetCursorHandle(); + bool DIBCreate(HWND lHandleSource, long lWidth, long lHeight, long lPosX, long lPosY); + void DIBClean(); + bool ScreenshotMemory(); + +public: + ScreenGrab(String fileName, int secsFrame = 1, bool viewMouse = true); + ~ScreenGrab(); + + bool IniGrabDesktop(); + bool IniGrabWindow(long handle); + bool IniGrabDesktopRectangle(int left, int top, int width, int height); + bool Grab(int duration); + bool GrabSnapshot(); + void Close(); +}; + +bool Record_Desktop(String fileName, int duration, int secsFrame, bool viewMouse) +{ + ScreenGrab grab(fileName, secsFrame, viewMouse); + if (!grab.IniGrabDesktop()) + return false; + if (!grab.Grab(duration)) + return false; + grab.Close(); + return true; +} +bool Record_DesktopRectangle(String fileName, int duration, int left, int top, int width, int height, int secsFrame, bool viewMouse) +{ + ScreenGrab grab(fileName, secsFrame, viewMouse); + if (!grab.IniGrabDesktopRectangle(left, top, width, height)) + return false; + if (!grab.Grab(duration)) + return false; + grab.Close(); + return true; +} +bool Record_Window(String fileName, int duration, long handle, int secsFrame, bool viewMouse) +{ + ScreenGrab grab(fileName, secsFrame, viewMouse); + if (!grab.IniGrabWindow(handle)) + return false; + if (!grab.Grab(duration)) + return false; + grab.Close(); + return true; +} + +bool ScreenGrab::AVIOpen(bool create) +{ + long lRet, mode, res; + + AVIFileInit(); + if (create) + mode = OF_CREATE | OF_WRITE; + else + mode = OF_SHARE_DENY_WRITE; + + lRet = AVIFileOpen(&lAVIPtrFile, fileName, mode, 0); + if (lRet == AVIERR_OK && create) { + tAVIHdr.fccType = streamtypeVIDEO; + tAVIHdr.fccHandler = 0; + tAVIHdr.dwScale = 100; + tAVIHdr.dwRate = (DWORD)(tAVIHdr.dwScale*frameRate); + //tAVIHdr.dwQuality = -1; + tAVIHdr.dwSuggestedBufferSize = tBmpInfo.bmiHeader.biSizeImage; + SetRect(&(tAVIHdr.rcFrame), 0, 0, tBmpInfo.bmiHeader.biWidth, tBmpInfo.bmiHeader.biHeight); + lRet = AVIFileCreateStream(lAVIPtrFile, &lAVIPtrStrm, &tAVIHdr); + if (lRet == AVIERR_OK) { + lRet = AVIStreamSetFormat(lAVIPtrStrm, 0, &(tBmpInfo.bmiHeader), sizeof(tBmpInfo.bmiHeader)); + if (lRet == AVIERR_OK) + lAVICnt = 0; + } + } else { + res = AVIFileGetStream(lAVIPtrFile, &lAVIPtrStrm, streamtypeVIDEO, 0); + if (res != AVIERR_OK) + return false; + firstFrame = AVIStreamStart(lAVIPtrStrm); + if (firstFrame != -1) + return false; + numFrames = AVIStreamLength(lAVIPtrStrm); + if (numFrames == -1) + return false; + res = AVIFileInfo(lAVIPtrFile, &tAVIFile, sizeof(tAVIFile)); + if (res != AVIERR_OK) + return false; + res = AVIStreamInfo(lAVIPtrStrm, &tAVIHdr, sizeof(tAVIHdr)); + if (res != AVIERR_OK) + return false; + } + return true; +} + +bool ScreenGrab::AVIWrite() +{ + HRESULT lRet; + + lRet = AVIStreamWrite(lAVIPtrStrm, lAVICnt, 1, lDibPtr, tBmpInfo.bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL); + if (lRet == AVIERR_OK) { + lAVICnt++; + return true; + } else + return false; +} + +void ScreenGrab::AVIClose() +{ + if (lAVIPtrStrm != 0) + AVIStreamClose(lAVIPtrStrm); + if (lAVIPtrFile != 0) + AVIFileClose(lAVIPtrFile); + AVIFileExit(); +} + +HICON ScreenGrab::GetCursorHandle() +{ + HWND lHandle; + POINT lpPos; + long lThreadID; + long lCurrentThreadID; + + GetCursorPos(&lpPos); + lHandle = WindowFromPoint(lpPos); + lThreadID = GetWindowThreadProcessId(lHandle, 0); + lCurrentThreadID = GetWindowThreadProcessId((HWND)GetWindowIdFromProcessId(GetProcessId()), 0); + HICON ret; + if (lThreadID != lCurrentThreadID) { + if (AttachThreadInput(lCurrentThreadID, lThreadID, true)) { + ret = GetCursor(); + AttachThreadInput(lCurrentThreadID, lThreadID, false); + } + } else + ret = GetCursor(); + + return ret; +} + +bool ScreenGrab::DIBCreate(HWND lHandleSource, long lWidth, long lHeight, long lPosX, long lPosY) +{ + HDC lDCSource, lDCSourceDesktop; + POINT lpCursorPos; + + lDCSource = GetWindowDC(lHandleSource); + lDCSourceDesktop = GetWindowDC(0); + + bool ret = false; + if (lDCSource != 0 && lDCSourceDesktop != 0) { + lDCDest = CreateCompatibleDC(lDCSource); + if (lDCDest != 0) { + tBmpInfo.bmiHeader.biSize = sizeof(tBmpInfo.bmiHeader); + tBmpInfo.bmiHeader.biWidth = lWidth; + tBmpInfo.bmiHeader.biHeight = lHeight; + tBmpInfo.bmiHeader.biPlanes = 1; + tBmpInfo.bmiHeader.biBitCount = 24; + tBmpInfo.bmiHeader.biCompression = 0; + tBmpInfo.bmiHeader.biSizeImage = ((tBmpInfo.bmiHeader.biWidth * 3 + 3) & 0xFFFFFFFC) * tBmpInfo.bmiHeader.biHeight; + lDib = CreateDIBSection(lDCDest, &tBmpInfo, 0, &lDibPtr, 0, 0); + if (lDib != 0) { + lBmpOld = SelectObject(lDCDest, lDib); + BitBlt(lDCDest, 0, 0, lWidth, lHeight, lDCSourceDesktop, lPosX, lPosY, 0xCC0020); + if (viewMouse) { + GetCursorPos(&lpCursorPos); + DrawIcon(lDCDest, lpCursorPos.x - lPosX, lpCursorPos.y - lPosY, GetCursorHandle()); + } + ret = true; + } + } + } + ReleaseDC(lHandleSource, lDCSource); + ReleaseDC(0, lDCSourceDesktop); + return ret; +} + +void ScreenGrab::DIBClean() +{ + SelectObject(lDCDest, lBmpOld); + DeleteDC(lDCDest); + DeleteObject(lDib); +} + +bool ScreenGrab::ScreenshotMemory() +{ + HWND lHandle; + RECT lpRect; + long lWidth, lHeight; + long lPosX, lPosY; + + switch (grabMode) { + case GRAB_MODE_DESKTOP: + lHandle = GetDesktopWindow(); + GetWindowRect(lHandle, &lpRect); + lWidth = lpRect.right - lpRect.left; + lHeight = lpRect.bottom - lpRect.top; + lPosX = lpRect.left; + lPosY = lpRect.top; + break; + case GRAB_MODE_WINDOW: + lHandle = (HWND)hwnd; + GetWindowRect(lHandle, &lpRect); + lWidth = lpRect.right - lpRect.left; + lHeight = lpRect.bottom - lpRect.top; + lPosX = lpRect.left; + lPosY = lpRect.top; + break; + case GRAB_MODE_RECT: + lHandle = GetDesktopWindow(); + GetWindowRect(lHandle, &lpRect); + lWidth = width; + lHeight = height; + lPosX = left; + lPosY = top; + break; + default: + throw Exc("Unknown grab mode"); + return false; + } + if (DIBCreate(lHandle, lWidth, lHeight, lPosX, lPosY)) + return true; + else + return false; +} + +HDC ScreenGrab::lDCDest; +HGDIOBJ ScreenGrab::lDib; +void *ScreenGrab::lDibPtr; +HGDIOBJ ScreenGrab::lBmpOld; +PAVIFILE ScreenGrab::lAVIPtrFile; +PAVISTREAM ScreenGrab::lAVIPtrStrm; +BITMAPINFO ScreenGrab::tBmpInfo; +AVISTREAMINFO ScreenGrab::tAVIHdr; +AVIFILEINFO ScreenGrab::tAVIFile; + +ScreenGrab::ScreenGrab(String _fileName, int secsFrame, bool _viewMouse) +{ + opened = false; + fileName = _fileName; + viewMouse = _viewMouse; + frameRate = 1./secsFrame; +} + +ScreenGrab::~ScreenGrab() +{ + Close(); +} + +void ScreenGrab::Close() +{ + if (!opened) + return; + AVIClose(); + DIBClean(); + opened = false; +} + +bool ScreenGrab::IniGrabDesktop() +{ + opened = true; + grabMode = GRAB_MODE_DESKTOP; + if (!ScreenshotMemory()) + return false; + if (!AVIOpen()) + return false; + return true; +} + +bool ScreenGrab::IniGrabWindow(long handle) +{ + opened = true; + grabMode = GRAB_MODE_WINDOW; + hwnd = handle; + if (!ScreenshotMemory()) + return false; + if (!AVIOpen()) + return false; + return true; +} + +bool ScreenGrab::IniGrabDesktopRectangle(int _left, int _top, int _width, int _height) +{ + opened = true; + grabMode = GRAB_MODE_RECT; + left = _left; + top = _top; + width = _width; + height = _height; + if (!ScreenshotMemory()) + return false; + if (!AVIOpen()) + return false; + return true; +} + +bool ScreenGrab::Grab(int duration) +{ + if (!opened) + return false; + TimeStop timer; + timer.Reset(); + while (timer.Elapsed() < duration*1000) { + if (!ScreenshotMemory()) + return false; + if (!AVIWrite()) + return false; + while (timer.Elapsed() < (lAVICnt*1000.)/frameRate) + DoEvents(); + } + return true; +} + +bool ScreenGrab::GrabSnapshot() +{ + if (!opened) + return false; + if (!ScreenshotMemory()) + return false; + if (!AVIWrite()) + return false; + return true; +} + +#endif + +#ifdef PLATFORM_POSIX + +bool Window_GetRect(long windowId, long &left, long &top, long &right, long &bottom) +{ + SetSysInfoX11ErrorHandler(); + Display *dpy = XOpenDisplay (NULL); + if (!dpy) { + SetX11ErrorHandler(); + return false; + } + bool ret = false; + Window rt; + int x, y, rx, ry; + unsigned int width, height, bw, depth_; + if (XGetGeometry(dpy, windowId, &rt, &x, &y, &width, &height, &bw, &depth_)) { + left = x; + top = y; + right = x + width; + bottom = y + height; + ret = true; + } +// Window child; +// if (XTranslateCoordinates (dpy, windowId, rt, 0, 0, &rx, &ry, &child)) +// printf (" +%d+%d", rx - bw, ry - bw); + + XCloseDisplay (dpy); + SetX11ErrorHandler(); + return ret; +} + +bool Mouse_GetPos(long &x, long &y) +{ + SetSysInfoX11ErrorHandler(); + Display *dpy = XOpenDisplay (NULL); + if (!dpy) { + SetX11ErrorHandler(); + return false; + } + bool ret = false; + Window root, child; + Window r = DefaultRootWindow(dpy); + int retx, rety; + int wx, wy; + unsigned int keys_buttons; + if (XQueryPointer(dpy, r, &root, &child, &retx, &rety, &wx, &wy, &keys_buttons)) { + x = wx; + y = wy; + ret = true; + } else + x = y = -1; + + XCloseDisplay (dpy); + SetX11ErrorHandler(); + + return ret; +} + +bool Mouse_SetPos(long x, long y, long windowId) +{ + SetSysInfoX11ErrorHandler(); + Display *dpy = XOpenDisplay (NULL); + if (!dpy) { + SetX11ErrorHandler(); + return false; + } + long left, top, right, bottom; + Window r = DefaultRootWindow(dpy); + if (windowId != 0) { + Window_GetRect(windowId, left, top, right, bottom); + x = x + left; + y = y + top; + } + XWarpPointer(dpy, None, r, 0, 0, 0, 0, x, y); + XCloseDisplay (dpy); + SetX11ErrorHandler(); + + return true; +} + +bool Window_SaveCapture(long windowId, String fileName, int left, int top, int width, int height) +{ + if (GetFileExt(fileName) != ".xwd") + fileName += ".xwd"; + + String command; + if (windowId == 0) + command = "xwd -root -silent -out \"" + fileName + "\""; + else + command = "xwd -id " + FormatLong(windowId) + " -silent -out \"" + fileName + "\""; + + String strret; + int ret = LaunchCommand(command, strret); + + return ret == 0 ? true : false; +} + +#endif + +bool Snap_Desktop(String fileName) +{ + return Window_SaveCapture(0, fileName); +} +bool Snap_DesktopRectangle(String fileName, int left, int top, int width, int height) +{ + return Window_SaveCapture(0, fileName, left, top, width, height); +} +bool Snap_Window(String fileName, long handle) +{ + return Window_SaveCapture(handle, fileName); +} + +#ifdef PLATFORM_POSIX + +String GetTrashBinDirectory() +{ + return AppendFileName(GetHomeDirectory(), ".local/share/Trash/files"); +} +void FileToTrashBin(const char *path) +{ + String newPath = AppendFileName(GetTrashBinDirectory(), GetFileName(path)); + FileMove(path, newPath); +} +int64 TrashBinGetCount() +{ + int64 ret = 0; + FindFile ff; + if(ff.Search(AppendFileName(GetTrashBinDirectory(), "*"))) { + do { + String name = ff.GetName(); + if (name != "." && name != "..") + ret++; + } while(ff.Next()); + } + return ret; +} +void TrashBinClear() +{ + FindFile ff; + String trashBinDirectory = GetTrashBinDirectory(); + if(ff.Search(AppendFileName(trashBinDirectory, "*"))) { + do { + String name = ff.GetName(); + if (name != "." && name != "..") { + String path = AppendFileName(trashBinDirectory, name); + if (ff.IsFile()) + FileDelete(path); + else if (ff.IsDirectory()) + DeleteFolderDeep(path); + } + } while(ff.Next()); + } +} + +void SetDesktopWallPaper(const char *path) +{ + String desktopManager = GetDesktopManagerNew(); + + if (desktopManager == "gnome") { + LaunchCommand("gconftool-2 -t str -s /desktop/gnome/background/picture_filename \"" + String(path) + "\""); + String mode; + if (*path == '\0') + mode = "none"; // Values "none", "wallpaper", "centered", "scaled", "stretched" + else + mode = "stretched"; + LaunchCommand("gconftool-2 -t str -s /desktop/gnome/background/picture_options \"" + mode + "\""); + } else if (desktopManager == "kde") { + // 1: disabled, only background color + // 2: tiled with first image in top left corner + // 3: tiled with first image centered + // 4: centered stretched with proportions kept until one side hits screen, space filled by background color + // 5: same as 4, though wallpaper aligned to top left and space after stretching filled by tiling + // 6: stretched to fit screen + int mode; + if (*path == '\0') + mode = 1; + else + mode = 6; + LaunchCommand("dcop kdesktop KBackgroundIface setWallpaper \"" + String(path) + "\" " + AsString(mode)); + } else + throw Exc(t_("Not possible to change Desktop bitmap")); +} +#endif + +#if defined(PLATFORM_WIN32) + +void FileToTrashBin(const char *path) +{ + if (!FileExists(path) && !DirectoryExists(path)) + return; + + SHFILEOPSTRUCT fileOp; + + fileOp.hwnd = NULL; + fileOp.wFunc = FO_DELETE; + fileOp.pFrom = path; + fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT; + + if (0 != SHFileOperation(&fileOp)) + throw Exc(t_("Error sending file to Trash Bin")); +} +int64 TrashBinGetCount() +{ + SHQUERYRBINFO shqbi; + + shqbi.cbSize = sizeof(SHQUERYRBINFO); + if (S_OK != SHQueryRecycleBin(0, &shqbi)) + throw Exc(t_("Error counting elements in Trash Bin")); + return shqbi.i64NumItems; +} +void TrashBinClear() +{ + if (S_OK != SHEmptyRecycleBin(0, 0, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND)) + throw Exc(t_("Error sending file to Trash Bin")); +} +// SetDesktopWallPaper("c:\\Fondo de escritorio.bmp"); +void SetDesktopWallPaper(const char *path) +{ + if (0 == SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (LPVOID)path, SPIF_UPDATEINIFILE || SPIF_SENDWININICHANGE)) + throw Exc(t_("Error " + AsString(GetLastError()) + " changing Desktop bitmap")); +} +#endif diff --git a/bazaar/SysInfo/SysInfo.h b/bazaar/SysInfo/SysInfo.h new file mode 100644 index 000000000..b86339289 --- /dev/null +++ b/bazaar/SysInfo/SysInfo.h @@ -0,0 +1,401 @@ +#ifndef _SysInfo_SysInfo_h +#define _SysInfo_SysInfo_h + +#if defined(PLATFORM_WIN32) +#include +#endif + +using namespace Upp; + +///////////////////////////////////////////////////////////////////// +// Different functions + +// Appends a file after other +bool FileCat(const char *file, const char *appendFile); + +// Replace find with replace in str +String Replace(String str, String find, String replace); + +// Convert a long into a String +String FormatLong(long a); + +// Search a file under dir with name with wildcards in condFile and with certain text inside. +// Errors are got in errorList +Array SearchFile(String dir, String condFile, String text, Array &errorList); +Array SearchFile(String dir, String condFile); + +// As LoadFile but it works in Linux for files automatically generated by the OS +// #ifdef PLATFORM_POSIX +String LoadFile_Safe(String fileName); +// #endif +// #if defined(PLATFORM_WIN32) +// #define LoadFile_Safe LoadFile // Not necessary in Windows +// #endif + +#if defined(PLATFORM_WIN32) +Value GetVARIANT(VARIANT &result); +#endif + +// Gets the program that will open by default the files with extension ext +String GetExtExecutable(String ext); + +// Open the file with the adecuated program defined in the OS by default +bool LaunchFile(const String file); + +// Functions to launch command line programs +// readCallBack is a function to manage the program output +// Returns the command exit code +int LaunchCommand(const char *cmd, void (*readCallBack)(String &)); +// ret gets all the program output +// Returns the command exit code +int LaunchCommand(const char *cmd, String &ret); +// It returns the program output +String LaunchCommand(const char *cmd); + +// A ProcessEvents than can be used in non gui programs +inline void DoEvents() +{ +#ifdef CTRLLIB_H + Ctrl::ProcessEvents(); +#endif +} + +// A String based class to parse into +class StringParse : public String { +public: + void GoInit() {pos = 0; lastSeparator='\0';}; + StringParse():String("") {GoInit();}; + StringParse(String s): String(s) {GoInit();}; + bool GoBefore(const String text) + { + int newpos = Find(text, pos); + if (newpos < 0) + return false; // If it does not find it, it does not move + pos = newpos; + return true; + }; + bool GoAfter(const String text) + { + if(!GoBefore(text)) + return false; + pos += strlen(text); + return true; + }; + bool GoAfter(const String text, const String text2) + { + if(!GoAfter(text)) + return false; + if(!GoAfter(text2)) + return false; + return true; + }; + bool GoAfter(const String text, const String text2, const String text3) + { + if(!GoAfter(text)) + return false; + if(!GoAfter(text2)) + return false; + if(!GoAfter(text3)) + return false; + return true; + }; + bool GoAfter_Init(const String text) {GoInit(); return GoAfter(text);}; + bool GoAfter_Init(const String text, const String text2) {GoInit(); return GoAfter(text, text2);}; + bool GoAfter_Init(const String text, const String text2, const String text3) {GoInit(); return GoAfter(text, text2, text3);}; + + void GoBeginLine() + { + for (; pos >= 0; --pos) { + if ((ToString()[pos-1] == '\r') || (ToString()[pos-1] == '\n')) + return; + } + } + bool IsBeginLine() + { + if (pos == 0) + return true; + if ((ToString()[pos-1] == '\r') || (ToString()[pos-1] == '\n')) + return true; + return false; + } + bool IsSpaceRN(int c) + { + if (IsSpace(c)) + return true; + if ((c == '\r') || (c == '\n')) + return true; + return false; + } + // Gets text between "" or just a word until an space + // It considers special characters with \ if between "" + // If not between "" it gets the word when it finds one of the separator characters + String GetText(String separators = "") + { + String ret = ""; + if (pos > GetCount()) + return ret; + int newpos = pos; + + while ((IsSpaceRN(ToString()[newpos]) && (ToString()[newpos] != '\"') && + (ToString()[newpos] != '\0'))) + newpos++; + if (ToString()[newpos] == '\0') { + pos = newpos; + return ""; + } + + if (ToString()[newpos] == '\"') { // Between "" + newpos++; + while (ToString()[newpos] != '\"' && ToString()[newpos] != '\0') { + if (ToString()[newpos] == '\\') { + newpos++; + if (ToString()[newpos] == '\0') + return ""; + } + ret.Cat(ToString()[newpos]); + newpos++; + } + lastSeparator = '"'; + } else if (separators == "") { // Simple word + while (!IsSpaceRN(ToString()[newpos]) && ToString()[newpos] != '\0') { + if (ToString()[newpos] == '\"') { + newpos--; // This " belongs to the next + break; + } + ret.Cat(ToString()[newpos]); + newpos++; + } + lastSeparator = ToString()[newpos]; + } else { // Simple word, special separator + while (ToString()[newpos] != '\0') {// Only consider included spaces (!IsSpaceRN(ToString()[newpos]) && ToString()[newpos] != '\0') { + if (ToString()[newpos] == '\"') { + newpos--; // This " belongs to the next + break; + } + if (separators.Find(ToString()[newpos]) >= 0) { + lastSeparator = ToString()[newpos]; + break; + } + ret.Cat(ToString()[newpos]); + newpos++; + } + lastSeparator = ToString()[newpos]; + } + pos = ++newpos; // After the separator: ", space or separator + return ret; + } + String GetLine() + { + return GetText("\r\n"); + } + double GetDouble(String separators = "") {return atof(GetText(separators));}; + int GetInt(String separators = "") {return atoi(GetText(separators));}; + long GetLong(String separators = "") {return atol(GetText(separators));}; + uint64 GetUInt64(String separators = "") +#if defined(PLATFORM_WIN32) + {return _atoi64(GetText(separators));}; +#endif +#ifdef PLATFORM_POSIX + {return atoll(GetText(separators));}; +#endif + + String Right() {return String::Right(GetLength()-pos);} + int GetLastSeparator() {return lastSeparator;} + void MoveRel(int val) + { + pos += val; + if (pos < 0) + pos = 0; + else if (pos >= GetCount()) + pos = GetCount() - 1; + } + int GetPos() {return pos;}; + bool SetPos(int i) + { + if (i < 0 || i >= GetCount()) + return false; + else { + pos = i; + return true; + } + } + bool Eof() + { + return pos >= GetCount(); + } + unsigned Count(String s) + { + int from = 0; + unsigned count = 0; + + while ((from = ToString().Find(s, from)) >= 0) { + count++; + from++; + } + return count; + } +private: + int pos; + int lastSeparator; +}; + +///////////////////////////////////////////////////////////////////// +// Special Folders +// Get the path to special folders +String GetDesktopFolder(); +String GetProgramsFolder(); +String GetAppDataFolder(); +String GetMusicFolder(); +String GetPicturesFolder(); +String GetVideoFolder(); +String GetPersonalFolder(); +String GetTemplatesFolder(); +String GetDownloadFolder(); +String GetRootFolder(); +String GetTempFolder(); +String GetOsFolder(); +String GetSystemFolder(); + +///////////////////////////////////////////////////////////////////// +// Processor Info +void GetSystemInfo(String &manufacturer, String &productName, String &version, int &numberOfProcessors); +void GetBiosInfo(String &biosVersion, Date &biosReleaseDate); +bool GetProcessorInfo(int number, String &vendor, String &identifier, String &architecture, int &speed); +// Gets the real CPU speed in MHz +int GetCpuSpeed(); + +#if defined(PLATFORM_WIN32) +bool GetVideoInfo(Array &name, Array &description, Array &videoProcessor, + Array &ram, Array &videoMode); +bool GetPackagesInfo(Array &name, Array &version, Array &vendor, + Array &installDate, Array &caption, Array &description, Array &state); +#endif + +///////////////////////////////////////////////////////////////////// +// Memory Info +bool GetMemoryInfo(int &memoryLoad, uint64 &totalPhys, uint64 &freePhys, uint64 &totalPageFile, uint64 &freePageFile, uint64 &totalVirtual, uint64 &freeVirtual); + +///////////////////////////////////////////////////////////////////// +// Windows list +// They get arrays with handles to all the opened windows with additional info as +// pid: Handle to the process that manages the window +// name: Window name +// fileName: Window process program file name +// title: Window title (caption) +void GetWindowsList(Array &wid, Array &pid, Array &name, Array &fileName, Array &title); +Array GetWindowsList(); + +///////////////////////////////////////////////////////////////////// +// Process list +// They get arrays with handles to all the opened processes and process names +bool GetProcessList(Array &pid, Array &pNames); +Array GetProcessList(); +String GetProcessName(long pid); +// Gets the program file name of a process +String GetProcessFileName(long processID); + +// Gets the process id of a program with a window with certain title +long GetProcessIdFromWindowCaption(String windowCaption, bool exactMatch = false); + +long GetWindowIdFromCaption(String windowCaption, bool exactMatch = false); + +long GetProcessIdFromWindowId(long wid); +long GetWindowIdFromProcessId(long pid); + +// Ends a process by any means +bool ProcessTerminate(long pid, int timeout = 500); + +// Gets the process priority as a number from 0 (minimum) to 10 (maximum) +int GetProcessPriority(long pid); +bool SetProcessPriority(long pid, int priority); + +// True if a process with handle pid exists +bool ProcessExists(long pid); + +///////////////////////////////////////////////////////////////////// +// Os Info +bool GetOsInfo(String &kernel, String &kerVersion, String &kerArchitecture, String &distro, String &distVersion, String &desktop, String &deskVersion); +String GetDesktopManagerNew(); + +///////////////////////////////////////////////////////////////////// +// Drives list +// Get the dirve path list +Array GetDriveList(); +// Get drives info +// Return false if drive is not mounted or it is not accesible +bool GetDriveSpace(String drive, uint64 &freeBytesUser, uint64 &totalBytesUser, uint64 &totalFreeBytes); +bool GetDriveInformation(String drive, String &type, String &volume, /*uint64 &serial, */int &maxName, String &fileSystem); + +///////////////////////////////////////////////////////////////////// +// Others +// Gets process id +long GetProcessId(); + +// I tries to "logoff", "reboot" or "shutdown" +bool Shutdown(String action); + +// It converts an amount of bytes to compact size +String BytesToString(uint64 bytes); + +// It converts an amount of seconds to compact size (h:m:s) +String SecondsToString(double seconds); + +// It gets compiler info +void GetCompilerInfo(String &name, int &version, String &date); + +// It gets info about the battery status +bool GetBatteryStatus(bool &discharging, int &percentage, int &remainingMin); +// Get if there is battery +bool GetBatteryInfo(bool &present/*, int &designCapacity, int &lastFullCapacity, String &vendor, String &type, String &model, String &serial*/); + +///////////////////////////////////////////////////////////////////// +// Key and mouse keys + +bool Window_GetRect(long windowId, long &left, long &top, long &right, long &bottom); +void Window_SetRect(long windowId, long left, long top, long right, long bottom); + +bool Mouse_GetPos(long &x, long &y); +bool Mouse_SetPos(long x, long y, long windowId); + +bool Window_SaveCapture(long windowId, String fileName, int left = -1, int top = -1, int width = -1, int height = -1); + +bool Snap_Desktop(String fileName); +bool Snap_DesktopRectangle(String fileName, int left, int top, int width, int height); +bool Snap_Window(String fileName, long handle); + +#if defined(PLATFORM_WIN32) + +void Mouse_LeftClick(); +void Mouse_MiddleClick(); +void Mouse_RightClick(); +void Mouse_LeftDblClick(); +void Mouse_MiddleDblClick(); +void Mouse_RightDblClick(); + +void Keyb_SendKeys(String text, long finalDelay = 100, long delayBetweenKeys = 50); + +void GetKeyLockStatus(bool &caps, bool &num, bool &scroll); +void SetKeyLockStatus(bool caps, bool num, bool scroll); + +bool Record_Desktop(String fileName, int duration, int secsFrame = 1, bool viewMouse = true); +bool Record_DesktopRectangle(String fileName, int duration, int left, int top, int width, int height, int secsFrame = 1, bool viewMouse = true); +bool Record_Window(String fileName, int duration, long handle, int secsFrame = 1, bool viewMouse = true); + +#endif + +///////////////////////////////////////////////////////////////////// +// Trash bin handling + +void FileToTrashBin(const char *path); +int64 TrashBinGetCount(); +void TrashBinClear(); + + +void SetDesktopWallPaper(const char *path); + +#endif + + +// Known bugs +// GetWindowsList does not get the window title in Kde +// Shutdown in Linux only works with option "logoff", probably because of user permissions diff --git a/bazaar/SysInfo/SysInfo.t b/bazaar/SysInfo/SysInfo.t new file mode 100644 index 000000000..41db6f7a8 --- /dev/null +++ b/bazaar/SysInfo/SysInfo.t @@ -0,0 +1,7 @@ +#ifdef _MSC_VER +#pragma setlocale("C") +#endif +// SysInfo.cpp + +T_("UNKNOWN") +esES("DESCONOCIDO") diff --git a/bazaar/SysInfo/SysInfo.upp b/bazaar/SysInfo/SysInfo.upp new file mode 100644 index 000000000..1479c3d76 --- /dev/null +++ b/bazaar/SysInfo/SysInfo.upp @@ -0,0 +1,22 @@ +description "OS, hardware and Desktop handling functions\377BI128,0,0"; + +noblitz; + +uses + Core; + +library(WIN32) "psapi gdi32 vfw32 oleaut32 wbemuuid"; + +library(!WIN32) X11; + +file + SysInfo.h, + SysInfo.cpp, + srcdoc.tpp, + srcimp.tpp, + src.tpp, + SysInfo.t; + +mainconfig + "" = ""; + diff --git a/bazaar/SysInfo/init b/bazaar/SysInfo/init new file mode 100644 index 000000000..af1966657 --- /dev/null +++ b/bazaar/SysInfo/init @@ -0,0 +1,4 @@ +#ifndef _SysInfo_icpp_init_stub +#define _SysInfo_icpp_init_stub +#include "Core/init" +#endif diff --git a/bazaar/SysInfo/src.tpp/SysInfo$en-us.tpp b/bazaar/SysInfo/src.tpp/SysInfo$en-us.tpp new file mode 100644 index 000000000..74c08bccd --- /dev/null +++ b/bazaar/SysInfo/src.tpp/SysInfo$en-us.tpp @@ -0,0 +1,639 @@ +topic "SysInfo function reference"; +[2 $$0,0#00000000000000000000000000000000:Default] +[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] +[l288;2 $$2,0#27521748481378242620020725143825:desc] +[0 $$3,0#96390100711032703541132217272105:end] +[H6;0 $$4,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item] +[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement] +[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] +[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] +[b42;2 $$9,9#13035079074754324216151401829390:normal] +[{_}%EN-US +[s0;%- [*R6 SysInfo]&] +[s0; &] +[s0; &] +[ {{10000@1 [s0; [* Running files and commands]]}}&] +[s3; &] +[s5;:GetExtExecutable`(const String`):%- [_^String^ String]_[* GetExtExecutable]([@(0.0.255) c +onst]_[_^String^ String]_[*@3 ext])&] +[s2; Gets the program that will open by default the files with extension +[%-*@3 ext].&] +[s0; &] +[s0; -|[/ Example:]&] +[s0; [/ -|GetExtExecutable(`"html`") `-> `"Firefox.exe`"]&] +[s3; &] +[s4;%- &] +[s5;:LaunchFile`(const String`):%- [@(0.0.255) bool]_[* LaunchFile]([@(0.0.255) const]_[_^String^ S +tring]_[*@3 file])&] +[s2; Opens the file [%-*@3 file ]with the adecuated program defined +in the OS by default.&] +[s0; &] +[s0; [/ -|Example:]&] +[s0; [/ -|LaunchFile(`"c:`\`\My spreadsheet.txt`"). It will open default +program (probably Notepad) with document `"My spreadsheet.txt`".]&] +[s3; &] +[s4;%- &] +[s5;:LaunchCommand`(const char`*`,void`(`*`)`(String`&`)`):%- [@(0.0.255) int]_[* LaunchC +ommand]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cmd], [@(0.0.255) void]_(`*[*@3 readCal +lBack])(String_`&))&] +[s2; Launches command line program [%-*@3 cmd. readCallBack ]is a function +to manage the program output.&] +[s0; -|Program launched has to be in .exe folder, referenced in the +OS default program folders or it has to be included the full +path in [%-*@3 cmd].&] +[s2; Returns the command exit code .&] +[s0; -|&] +[s0; [/ -|Example:]&] +[s0; [/ -|LaunchCommand(`"mencoder film.mpg `-o film.avi`", MyHandler);]&] +[s3; &] +[s4;%- &] +[s5;:LaunchCommand`(const char`*`,String`&`):%- [@(0.0.255) int]_[* LaunchCommand]([@(0.0.255) c +onst]_[@(0.0.255) char]_`*[*@3 cmd], [_^String^ String]_`&[*@3 ret])&] +[s2; Launches command line program [%-*@3 cmd. ret ]gets all the program +output.&] +[s0; -|Program launched has to be in .exe folder, referenced in the +OS default program folders or it has to be included the full +path in [%-*@3 cmd].&] +[s2; Returns the command exit code.&] +[s0; -|&] +[s0; [/ -|Example:]&] +[s0; [/ -|String strOutput;]&] +[s0; [/ -|LaunchCommand(`"mencoder film.mpg `-o film.avi`", strOutput);]&] +[s3; &] +[s4;%- &] +[s5;:LaunchCommand`(const char`*`):%- [_^String^ String]_[* LaunchCommand]([@(0.0.255) cons +t]_[@(0.0.255) char]_`*[*@3 cmd])&] +[s2;%- [%% Launches command line program ][*@3 cmd.]&] +[s0; -|Program launched has to be in .exe folder, referenced in the +OS default program folders or it has to be included the full +path in [%-*@3 cmd].&] +[s0; -|Returns the program output.&] +[s0; -|&] +[s0; [/ -|Example:]&] +[s0; [/ -|String strOutput `= LaunchCommand(`"mencoder film.mpg `-o +film.avi`");]&] +[s0; &] +[ {{10000@1 [s0; [* Obtaining special folders]]}}&] +[s0;%- &] +[s5;:GetDesktopFolder`(`):%- [_^String^ String]_[* GetDesktopFolder]()&] +[s2; Gets the default Desktop folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetProgramsFolder`(`):%- [_^String^ String]_[* GetProgramsFolder]()&] +[s2; Gets the default programs folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetAppDataFolder`(`):%- [_^String^ String]_[* GetAppDataFolder]()&] +[s2; Gets the default application data folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetMusicFolder`(`):%- [_^String^ String]_[* GetMusicFolder]()&] +[s2; Gets the default music files folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetPicturesFolder`(`):%- [_^String^ String]_[* GetPicturesFolder]()&] +[s2; Gets the default picture files folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetVideoFolder`(`):%- [_^String^ String]_[* GetVideoFolder]()&] +[s2; Gets the default video files folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetPersonalFolder`(`):%- [_^String^ String]_[* GetPersonalFolder]()&] +[s2; Gets the default personal files folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetTemplatesFolder`(`):%- [_^String^ String]_[* GetTemplatesFolder]()&] +[s2; Gets the default templates files folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetDownloadFolder`(`):%- [_^String^ String]_[* GetDownloadFolder]()&] +[s2; Gets the default file download folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetRootFolder`(`):%- [_^String^ String]_[* GetRootFolder]()&] +[s2; Gets the default root folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetTempFolder`(`):%- [_^String^ String]_[* GetTempFolder]()&] +[s2; Gets the default temp files folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetOsFolder`(`):%- [_^String^ String]_[* GetOsFolder]()&] +[s2; Gets the default operating system files folder path.&] +[s3;%- &] +[s4;%- &] +[s5;:GetSystemFolder`(`):%- [_^String^ String]_[* GetSystemFolder]()&] +[s2; Gets the default system files folder path.&] +[s3;%- &] +[s0; &] +[ {{10000@1 [s0; [* Hardware, BIOS, OS and Distro info]]}}&] +[s0;%- &] +[s5;:GetSystemInfo`(String`&`,String`&`,String`&`,int`&`):%- [@(0.0.255) void]_[* GetSyst +emInfo]([_^String^ String]_`&[*@3 manufacturer], [_^String^ String]_`&[*@3 productName], +[_^String^ String]_`&[*@3 version], [@(0.0.255) int]_`&[*@3 numberOfProcessors])&] +[s2; Returns hardware information including computer [%-*@3 manufacturer, +] [%-*@3 productName, ] [%-*@3 version ]and [%-*@3 numberOfProcessors].&] +[s3; &] +[s4;%- &] +[s5;:GetBiosInfo`(String`&`,Date`&`):%- [@(0.0.255) void]_[* GetBiosInfo]([_^String^ String +]_`&[*@3 biosVersion], [_^Date^ Date]_`&[*@3 biosReleaseDate])&] +[s2; Returns bios information including [%-*@3 biosVersion] and [%-*@3 biosReleaseDate].&] +[s3; &] +[s4;%- &] +[s5;:GetProcessorInfo`(int`,String`&`,String`&`,String`&`,int`&`):%- [@(0.0.255) bool]_ +[* GetProcessorInfo]([@(0.0.255) int]_[*@3 number], [_^String^ String]_`&[*@3 vendor], +[_^String^ String]_`&[*@3 identifier], [_^String^ String]_`&[*@3 architecture], +[@(0.0.255) int]_`&[*@3 speed])&] +[s2; Returns information about the different cpu cores.&] +[s2; [%-*@3 number] is the core number to get the information&] +[s2; [%-*@3 vendor] is the core vendor&] +[s2; [%-*@3 identifier] is the core identifier&] +[s2; [%-*@3 architecture] is the core architecture (32, 64)&] +[s2; [%-*@3 speed].is the core speed in MHz.&] +[s0; &] +[s4;%- &] +[s5;:GetCpuSpeed`(`):%- [@(0.0.255) int]_[* GetCpuSpeed]()&] +[s2; Gets the real time main CPU speed in MHz.&] +[s0; -|This data is directly calculated by the function.&] +[s3; &] +[s4;%- &] +[s5;:GetVideoInfo`(Array``&`,Array``&`,Array``&`,Array``&`,Array``&`):%- [@(0.0.255) b +ool]_[* GetVideoInfo]([_^Array^ Array]_<[_^Value^ Value]>_`&[*@3 name], +Array__`&[*@3 description], Array__`&[*@3 videoProcessor], +Array__`&[*@3 ram], Array__`&[*@3 videoMode])&] +[s2; If true gets information about video systems installed:&] +[s2; [%-*@3 name] is the video system name&] +[s2; [%-*@3 description] is the video description&] +[s2; [%-*@3 videoProcessor] is the processor used&] +[s2; [%-*@3 ram ]is the available memory in the video hardware in Mb&] +[s2; [%-*@3 videoMode] is the video mode actually selected including +screen resolution and number of colors&] +[s3; &] +[s4;%- &] +[s5;:GetPackagesInfo`(Array``&`,Array``&`,Array``&`,Array``&`,Array``&`,Array``&`,Array``&`):%- [@(0.0.255) b +ool]_[* GetPackagesInfo]([_^Array^ Array]_<[_^Value^ Value]>_`&[*@3 name], +Array__`&[*@3 version], Array__`&[*@3 vendor], Array__`&[*@3 insta +llDate], Array__`&[*@3 caption], Array__`&[*@3 description], +Array__`&[*@3 state])&] +[s2; If true gets information about installed software:&] +[s2;%- [*@3 name]&] +[s2;%- [*@3 version]&] +[s2;%- [*@3 vendor]&] +[s2;%- [*@3 installDate]&] +[s2; [%-*@3 caption] is a summary of the software description&] +[s2;%- [*@3 description]&] +[s2; [%-*@3 state] is the status of the software. Values are:&] +[s0; -|-|`- `"Bad Configuration`"&] +[s0; -|-|`- `"Invalid Argument`"&] +[s0; -|-|`- `"Unknown Package`"&] +[s0; -|-|`- `"Advertised`"&] +[s0; -|-|`- `"Absent`"&] +[s0; -|-|`- `"Ok`"&] +[s3; &] +[s4;%- &] +[s5;:GetMemoryInfo`(int`&`,uint64`&`,uint64`&`,uint64`&`,uint64`&`,uint64`&`,uint64`&`):%- [@(0.0.255) b +ool]_[* GetMemoryInfo]([@(0.0.255) int]_`&[*@3 memoryLoad], [_^uint64^ uint64]_`&[*@3 total +Phys], [_^uint64^ uint64]_`&[*@3 freePhys], [_^uint64^ uint64]_`&[*@3 totalPageFile], +[_^uint64^ uint64]_`&[*@3 freePageFile], [_^uint64^ uint64]_`&[*@3 totalVirtual], +[_^uint64^ uint64]_`&[*@3 freeVirtual])&] +[s2; Gets information about the system memory:&] +[s2; [%-*@3 memoryLoad ]is the percent of memory in use&] +[s2; [%-*@3 totalPhys ]is the total physical memory&] +[s2; [%-*@3 freePhys] is the free physical memory&] +[s2; [%-*@3 totalPageFile ]is the total paging file&] +[s2; [%-*@3 freePageFile ]is the free paging file&] +[s2; [%-*@3 totalVirtual ]is the total virtual memory&] +[s2; [%-*@3 freeVirtual ]is the free virtual memory.&] +[s3; &] +[s4;%- &] +[s5;:GetOsInfo`(String`&`,String`&`,String`&`,String`&`,String`&`,String`&`,String`&`):%- [@(0.0.255) b +ool]_[* GetOsInfo]([_^String^ String]_`&[*@3 kernel], [_^String^ String]_`&[*@3 kerVersion], + [_^String^ String]_`&[*@3 kerArchitecture], [_^String^ String]_`&[*@3 distro], +[_^String^ String]_`&[*@3 distVersion], [_^String^ String]_`&[*@3 desktop], +[_^String^ String]_`&[*@3 deskVersion])&] +[s2; Gets many information to identify the operating system and Desktop +where the application is being run. &] +[s2; [%-*@3 kernel]: Kernel name&] +[s2; [%-*@3 kerVersion]: Kernel version&] +[s2; [%-*@3 kerArchitecture]: Kernel architecture&] +[s2; [%-*@3 distro]: Distro name&] +[s2; [%-*@3 distVersion]: Distro version&] +[s2; [%-*@3 desktop]: Desktop manager name&] +[s2; [%-*@3 deskVersion].: Desktop manager version&] +[s3; &] +[s4;%- &] +[s5;:GetDesktopManagerNew`(`):%- [_^String^ String]_[* GetDesktopManagerNew]()&] +[s2; A more complete version of GetDesktopManager() based on GetOsInfo().&] +[s0; &] +[s4;%- &] +[s5;:GetDriveList`(`):%- [_^Array^ Array]<[_^String^ String]>_[* GetDriveList]()&] +[s2; Returns an array with the paths to all drives, internal or external, +identified in the system.&] +[s3;%- &] +[s4;%- &] +[s5;:GetDriveSpace`(String`,uint64`&`,uint64`&`,uint64`&`):%- [@(0.0.255) bool]_[* GetDri +veSpace]([_^String^ String]_[*@3 drive], [_^uint64^ uint64]_`&[*@3 freeBytesUser], +[_^uint64^ uint64]_`&[*@3 totalBytesUser], [_^uint64^ uint64]_`&[*@3 totalFreeBytes])&] +[s2; Gets [%-*@3 drive] space.&] +[s2; [%-*@3 freeBytesUser]: Amount of free bytes available to the user&] +[s2; [%-*@3 totalBytesUser]: Size of drive visible for the user&] +[s2; [%-*@3 totalFreeBytes]: Amount of free bytes.&] +[s0; -|Returns false if drive is not mounted or it is not accessible&] +[s3; &] +[s4;%- &] +[s5;:GetDriveInformation`(String`,String`&`,String`&`,int`&`,String`&`):%- [@(0.0.255) b +ool]_[* GetDriveInformation]([_^String^ String]_[*@3 drive], [_^String^ String]_`&[*@3 type +], [_^String^ String]_`&[*@3 volume], [@(0.0.255) int]_`&[*@3 maxName], +[_^String^ String]_`&[*@3 fileSystem])&] +[s2; Gets [%-*@3 drive] information&] +[s2;%- [*@3 type]: Gets the type of the drive.&] +[s2;%- Available types are `"Hard`", `"Network`", `"Optical`", `"RAM`", +`"Removable`".&] +[s2;%- [*@3 volume]: Gets the name of the drive&] +[s2;%- [*@3 maxName]: Gets the maximum length permitted for a file name&] +[s2;%- [*@3 fileSystem]: Gets the drive formatting system.&] +[s0; -|Returns false if drive is not mounted or it is not accessible&] +[s3; &] +[s4;%- &] +[s5;:GetCompilerInfo`(String`&`,int`&`,String`&`):%- [@(0.0.255) void]_[* GetCompilerInfo +]([_^String^ String]_`&[*@3 name], [@(0.0.255) int]_`&[*@3 version], +[_^String^ String]_`&[*@3 date])&] +[s2; Returns compiling information, like compiler [%-*@3 name, ]compiler +[%-*@3 version] and program compilation [%-*@3 date].&] +[s3; &] +[s4;%- &] +[s5;:GetBatteryStatus`(bool`&`,int`&`,int`&`):%- [@(0.0.255) bool]_[* GetBatteryStatus]([@(0.0.255) b +ool]_`&[*@3 discharging], [@(0.0.255) int]_`&[*@3 percentage], [@(0.0.255) int]_`&[*@3 rema +iningMin])&] +[s2; Gets battery information like if it is [%-*@3 discharging] or +connected to the grid, [%-*@3 percentage] of charging where 100% +means full charge, and number of expected computer running minutes +in [%-*@3 remainingMin].&] +[s0; -|Returns true if the values got are valid.&] +[s3; &] +[s4;%- &] +[s5;:GetBatteryInfo`(bool`&`):%- [@(0.0.255) bool]_[* GetBatteryInfo]([@(0.0.255) bool]_`&[*@3 p +resent]_)&] +[s2; Gets if battery is [%-*@3 present ]or not.&] +[s0; -|Returns true if the values got are valid.&] +[s0; &] +[s0; &] +[ {{10000@1 [s0; [* Process handling]]}}&] +[s4;%- &] +[s5;:GetWindowsList`(Array``&`,Array``&`,Array``&`,Array``&`,Array``&`):%- [@(0.0.255) v +oid]_[* GetWindowsList]([_^Array^ Array]<[@(0.0.255) long]>_`&[*@3 wid], +[_^Array^ Array]<[@(0.0.255) long]>_`&[*@3 pid], [_^Array^ Array]<[_^String^ String]>_`&[*@3 n +ame], [_^Array^ Array]<[_^String^ String]>_`&[*@3 fileName], [_^Array^ Array]<[_^String^ St +ring]>_`&[*@3 title])&] +[s2; Gets arrays with handles to all the opened windows with additional +info as:&] +[s2; [%-*@3 wid]: Handle to the the window&] +[s2; [%-*@3 pid]: Handle to the process that manages the window&] +[s2; [%-*@3 name]: Window name&] +[s2; [%-*@3 fileName]: Window process program file name&] +[s2; [%-*@3 title]: Window title (caption)&] +[s3; &] +[s4;%- &] +[s5;:GetWindowsList`(`):%- [_^Array^ Array]<[@(0.0.255) long]>_[* GetWindowsList]()&] +[s2; Gets an array with handles to all the opened windows.&] +[s3;%- &] +[s4;%- &] +[s5;:GetProcessList`(Array``&`,Array``&`):%- [@(0.0.255) bool]_[* GetProc +essList]([_^Array^ Array]<[@(0.0.255) long]>_`&[*@3 pid], [_^Array^ Array]<[_^String^ Strin +g]>_`&[*@3 pNames])&] +[s2; Gets arrays with handles to all the opened processes [%-*@3 pid +]and process names [%-*@3 pNames].&] +[s3; &] +[s4;%- &] +[s5;:GetProcessList`(`):%- [_^Array^ Array]<[@(0.0.255) long]>_[* GetProcessList]()&] +[s2; Gets an array with handles to all the opened processes&] +[s3;%- &] +[s4;%- &] +[s5;:GetProcessName`(long`):%- [_^String^ String]_[* GetProcessName]([@(0.0.255) long]_[*@3 p +id])&] +[s2; Returns the process name for a process with handle [%-*@3 pid].&] +[s3; &] +[s4;%- &] +[s5;:GetProcessFileName`(long`):%- [_^String^ String]_[* GetProcessFileName]([@(0.0.255) lo +ng]_[*@3 processID])&] +[s2; Gets the program file name of a process with handle [%-*@3 processID].&] +[s3; &] +[s4;%- &] +[s5;:GetProcessIdFromWindowCaption`(String`,bool`):%- [@(0.0.255) long]_[* GetProcessIdFr +omWindowCaption]([_^String^ String]_[*@3 windowCaption], [@(0.0.255) bool]_[*@3 exactMatc +h]_`=_[@(0.0.255) false])&] +[s2;%- [%% Gets the process handle of a program with a window with +title ][*@3 windowCaption.]&] +[s2;%- [%% If ][*@3 exactMatch][%% .is true it only returns the process +handle of a process with a window title that is equal to ][*@3 windowCaption. +][%% If it is false then the handle is returned if only part of +the window title matches with ][*@3 windowCaption.]&] +[s3; &] +[s4;%- &] +[s5;:GetWindowIdFromCaption`(String`,bool`):%- [@(0.0.255) long]_[* GetWindowIdFromCaptio +n]([_^String^ String]_[*@3 windowCaption], [@(0.0.255) bool]_[*@3 exactMatch]_`=_[@(0.0.255) f +alse])&] +[s2;%- [%% Gets the window handle of a program with a window with title +][*@3 windowCaption.]&] +[s2;%- [%% If ][*@3 exactMatch][%% .is true it only returns the process +handle of a process with a window title that is equal to ][*@3 windowCaption. +][%% If it is false then the handle is returned if only part of +the window title matches with ][*@3 windowCaption.]&] +[s3; &] +[s4;%- &] +[s5;:GetProcessIdFromWindowId`(long`):%- [@(0.0.255) long]_[* GetProcessIdFromWindowId]([@(0.0.255) l +ong]_[*@3 wid])&] +[s2;%- [%% Returns the process handle of a program with window handle +][*@3 wid.]&] +[s3; &] +[s4;%- &] +[s5;:GetWindowIdFromProcessId`(long`):%- [@(0.0.255) long]_[* GetWindowIdFromProcessId]([@(0.0.255) l +ong]_[*@3 pid])&] +[s2;%- [%% Returns the window handle of a program with process handle +][*@3 pid.]&] +[s3; &] +[s4;%- &] +[s5;:ProcessTerminate`(long`,int`):%- [@(0.0.255) bool]_[* ProcessTerminate]([@(0.0.255) lo +ng]_[*@3 pid], [@(0.0.255) int]_[*@3 timeout]_`=_[@3 500])&] +[s2;%- [%% Ends the program with handle ][*@3 pid.]&] +[s2; If after asking the process to end [%-*@3 timeout ]is over, it +will kill the process by different means in order of increasing +`"aggressivity`".&] +[s0; -|For example in Posix it will send the process first a SIGTERM, +if the process does not stop it will send a SIGKILL, and if the +process remains running it will simply call WindowKill() to do +the dirty job.&] +[s3; &] +[s4;%- &] +[s5;:GetProcessPriority`(long`):%- [@(0.0.255) int]_[* GetProcessPriority]([@(0.0.255) long +]_[*@3 pid])&] +[s2; Gets the process priority of the process with handle [%-*@3 pid] +as a number from 0 (minimum) to 10 (maximum), if possible.&] +[s3; &] +[s4;%- &] +[s5;:SetProcessPriority`(long`,int`):%- [@(0.0.255) bool]_[* SetProcessPriority]([@(0.0.255) l +ong]_[*@3 pid], [@(0.0.255) int]_[*@3 priority])&] +[s2; Sets the process priority to [%-*@3 priority ]of the process with +handle [%-*@3 pid] as a number from 0 (minimum) to 10 (maximum), +if possible.&] +[s3; &] +[s4;%- &] +[s5;:ProcessExists`(long`):%- [@(0.0.255) bool]_[* ProcessExists]([@(0.0.255) long]_[*@3 pid]) +&] +[s2; Returns true if a process with handle [%-*@3 pid ]exists.&] +[s4;%- &] +[s5;:GetProcessId`(`):%- [@(0.0.255) long]_[* GetProcessId]()&] +[s2; Gets actual running process handle.&] +[s3;%- &] +[s4;%- &] +[s5;:Shutdown`(String`):%- [@(0.0.255) bool]_[* Shutdown]([_^String^ String]_[*@3 action])&] +[s2; Tries to logoff, reboot or shutdown the actual running session.&] +[s0; -|Actual valid [%-*@3 action ]values are `"logoff`", `"reboot`" +and `"shutdown`".&] +[s3; &] +[s0; &] +[ {{10000@1 [s0; [* Windows handling]]}}&] +[s0; &] +[s5;:Window`_GetRect`(long`,long`&`,long`&`,long`&`,long`&`):%- [@(0.0.255) bool]_[* Wind +ow`_GetRect]([@(0.0.255) long]_[*@3 windowId], [@(0.0.255) long]_`&[*@3 left], +[@(0.0.255) long]_`&[*@3 top], [@(0.0.255) long]_`&[*@3 right], [@(0.0.255) long]_`&[*@3 bott +om])&] +[s2; Giving this function the [%-*@3 windowId], it returns the window +location in the screen in [%-*@3 left], [%-*@3 top], [%-*@3 right] +and [%-*@3 bottom].&] +[s0; -|Returns true if the values got are valid.&] +[s3; &] +[s4;%- &] +[s5;:Window`_SetRect`(long`,long`,long`,long`,long`):%- [@(0.0.255) void]_[* Window`_SetR +ect]([@(0.0.255) long]_[*@3 windowId], [@(0.0.255) long]_[*@3 left], +[@(0.0.255) long]_[*@3 top], [@(0.0.255) long]_[*@3 right], [@(0.0.255) long]_[*@3 bottom])&] +[s2; Giving this function the [%-*@3 windowId], it sets the window +location in the screen in [%-*@3 left], [%-*@3 top], [%-*@3 right] +and [%-*@3 bottom].&] +[s2; -|Returns true if the window is relocated correctly..&] +[s0; &] +[ {{10000@1 [s0; [* Mouse and keyboard handling]]}}&] +[s3; &] +[s5;:Mouse`_GetPos`(long`&`,long`&`):%- [@(0.0.255) bool]_[* Mouse`_GetPos]([@(0.0.255) lon +g]_`&[*@3 x], [@(0.0.255) long]_`&[*@3 y])&] +[s2; Gets the mouse position [%-*@3 x, y].in screen pixels where upper +left corner is (0, 0).&] +[s0; -|Returns true if the operation has been done successfully.&] +[s3; &] +[s4;%- &] +[s5;:Mouse`_SetPos`(long`,long`,long`):%- [@(0.0.255) bool]_[* Mouse`_SetPos]([@(0.0.255) l +ong]_[*@3 x], [@(0.0.255) long]_[*@3 y], [@(0.0.255) long]_[*@3 windowId])&] +[s2; Sets the mouse position to [%-*@3 x] [%-*@3 y] referenced to the +upper left vertex of window with window handle [%-*@3 windowId].&] +[s0; -|Returns true if the operation has been done successfully.&] +[s3; &] +[s4;%- &] +[s5;:Mouse`_LeftClick`(`):%- [@(0.0.255) void]_[* Mouse`_LeftClick]()&] +[s2; Simulates by software a mouse click with the left button as +if it would have been done with the mouse.&] +[s3;%- &] +[s4;%- &] +[s5;:Mouse`_MiddleClick`(`):%- [@(0.0.255) void]_[* Mouse`_MiddleClick]()&] +[s2; Simulates by software a mouse click with the middle button as +if it would have been done with the mouse.&] +[s3;%- &] +[s4;%- &] +[s5;:Mouse`_RightClick`(`):%- [@(0.0.255) void]_[* Mouse`_RightClick]()&] +[s2; Simulates by software a mouse click with the right button as +if it would have been done with the mouse.&] +[s3;%- &] +[s4;%- &] +[s5;:Mouse`_LeftDblClick`(`):%- [@(0.0.255) void]_[* Mouse`_LeftDblClick]()&] +[s2; Simulates by software a mouse double click with the left button +as if it would have been done with the mouse.&] +[s3;%- &] +[s4;%- &] +[s5;:Mouse`_MiddleDblClick`(`):%- [@(0.0.255) void]_[* Mouse`_MiddleDblClick]()&] +[s2; Simulates by software a mouse double click with the middle button +as if it would have been done with the mouse.&] +[s3;%- &] +[s4;%- &] +[s5;:Mouse`_RightDblClick`(`):%- [@(0.0.255) void]_[* Mouse`_RightDblClick]()&] +[s2; Simulates by software a mouse double click with the right button +as if it would have been done with the mouse.&] +[s3;%- &] +[s4;%- &] +[s5;:Keyb`_SendKeys`(String`,long`,long`):%- [@(0.0.255) void]_[* Keyb`_SendKeys]([_^String^ S +tring]_[*@3 text], [@(0.0.255) long]_[*@3 finalDelay]_`=_[@3 100], [@(0.0.255) long]_[*@3 del +ayBetweenKeys]_`=_[@3 50])&] +[s2; Simulates by software a text entered using the keyboard as if +it would have been entered with the keyboard.&] +[s2; To really simulate manual key typing the function lets to enter +delays between keys and after entering the text.&] +[s2; [%-*@3 text]: Is the text to be entered&] +[s2; [%-*@3 finalDelay]: Is the delay in ms that is forced after entering +text&] +[s2; [%-*@3 delayBetweenKeys]: Is the delay in ms that is forced between +text keys.&] +[s3; &] +[s4;%- &] +[s5;:GetKeyLockStatus`(bool`&`,bool`&`,bool`&`):%- [@(0.0.255) void]_[* GetKeyLockStatus]( +[@(0.0.255) bool]_`&[*@3 caps], [@(0.0.255) bool]_`&[*@3 num], [@(0.0.255) bool]_`&[*@3 scrol +l])&] +[s2; Gets the status of keys [%-*@3 caps ]lock, [%-*@3 num ]lock and +[%-*@3 scroll] [%-*@3 ]lock.&] +[s3; &] +[s4;%- &] +[s5;:SetKeyLockStatus`(bool`,bool`,bool`):%- [@(0.0.255) void]_[* SetKeyLockStatus]([@(0.0.255) b +ool]_[*@3 caps], [@(0.0.255) bool]_[*@3 num], [@(0.0.255) bool]_[*@3 scroll])&] +[s2; Sets the status of keys [%-*@3 caps ]lock, [%-*@3 num ]lock and +[%-*@3 scroll] [%-*@3 ]lock.&] +[s3; &] +[ {{10000@1 [s0; [* Screen recording]]}}&] +[s3; &] +[s5;:Snap`_Desktop`(String`):%- [@(0.0.255) bool]_[* Snap`_Desktop]([_^String^ String]_[*@3 f +ileName])&] +[s2; Saves the desktop in [%-*@3 fileName].as an image file.&] +[s0; -|Allowed formats are:&] +[s0; -|-|`- Posix: .xwd&] +[s0; -|-|`- Windows: .bmp&] +[s3; &] +[s4;%- &] +[s5;:Snap`_DesktopRectangle`(String`,int`,int`,int`,int`):%- [@(0.0.255) bool]_[* Snap`_D +esktopRectangle]([_^String^ String]_[*@3 fileName], [@(0.0.255) int]_[*@3 left], +[@(0.0.255) int]_[*@3 top], [@(0.0.255) int]_[*@3 width], [@(0.0.255) int]_[*@3 height])&] +[s2; Saves a rectangle of the desktop defined by [%-*@3 left], [%-*@3 top], +[%-*@3 width ]and [%-*@3 height].in [%-*@3 fileName] as an image file.&] +[s0; -|Allowed formats are:&] +[s0; -|-|`- Posix: .xwd&] +[s0; -|-|`- Windows: .bmp&] +[s3; &] +[s4;%- &] +[s5;:Snap`_Window`(String`,long`):%- [@(0.0.255) bool]_[* Snap`_Window]([_^String^ String]_ +[*@3 fileName], [@(0.0.255) long]_[*@3 handle])&] +[s2; Saves a window defined by its [%-*@3 handle] in [%-*@3 fileName] +as an image file.&] +[s0; -|Allowed formats are:&] +[s0; -|-|`- Posix: .xwd&] +[s0; -|-|`- Windows: .bmp&] +[s3; &] +[s4;%- &] +[s5;:Record`_Desktop`(String`,int`,int`,bool`):%- [@(0.0.255) bool]_[* Record`_Desktop]([_^String^ S +tring]_[*@3 fileName], [@(0.0.255) int]_[*@3 duration], [@(0.0.255) int]_[*@3 secsFrame]_`= +_[@3 1], [@(0.0.255) bool]_[*@3 viewMouse]_`=_[@(0.0.255) true])&] +[s2; Records the desktop activity in [%-*@3 fileName] as a video file +of [%-*@3 duration] in seconds with [%-*@3 secsFrame] seconds between +frames and recording also mouse movement if [%-*@3 viewMouse].is +true.&] +[s0; -|Allowed formats are:&] +[s0; -|-|`- Windows: Uncompressed .avi &] +[s3; &] +[s4;%- &] +[s5;:Record`_DesktopRectangle`(String`,int`,int`,int`,int`,int`,int`,bool`):%- [@(0.0.255) b +ool]_[* Record`_DesktopRectangle]([_^String^ String]_[*@3 fileName], +[@(0.0.255) int]_[*@3 duration], [@(0.0.255) int]_[*@3 left], [@(0.0.255) int]_[*@3 top], +[@(0.0.255) int]_[*@3 width], [@(0.0.255) int]_[*@3 height], [@(0.0.255) int]_[*@3 secsFrame]_ +`=_[@3 1], [@(0.0.255) bool]_[*@3 viewMouse]_`=_[@(0.0.255) true])&] +[s2; Records the desktop activity in the rectangle defined by [%-*@3 left], +[%-*@3 top], [%-*@3 width ]and [%-*@3 height]. in [%-*@3 fileName] as +a video file of [%-*@3 duration] in seconds with [%-*@3 secsFrame] +seconds between frames and recording also mouse movement if [%-*@3 viewMouse].is +true.&] +[s0; -|Allowed formats are:&] +[s2; -|-|`- Windows: Uncompressed .avi&] +[s3; &] +[s4;%- &] +[s5;:Record`_Window`(String`,int`,long`,int`,bool`):%- [@(0.0.255) bool]_[* Record`_Windo +w]([_^String^ String]_[*@3 fileName], [@(0.0.255) int]_[*@3 duration], +[@(0.0.255) long]_[*@3 handle], [@(0.0.255) int]_[*@3 secsFrame]_`=_[@3 1], +[@(0.0.255) bool]_[*@3 viewMouse]_`=_[@(0.0.255) true])&] +[s2; Records the activity of a window defined by its [%-*@3 handle] +in [%-*@3 fileName] as a video file of [%-*@3 duration] in seconds +with [%-*@3 secsFrame] seconds between frames and recording also +mouse movement if [%-*@3 viewMouse].is true.&] +[s0; -|Allowed formats are:&] +[s2; -|-|`- Windows: Uncompressed .avi&] +[s3; &] +[ {{10000@1 [s0; [* Miscellaneous functions]]}}&] +[s0; &] +[s5;:LoadFile`_Safe`(String`):%- [_^String^ String]_[* LoadFile`_Safe]([_^String^ String]_[*@3 f +ileName])&] +[s2; Same as LoadFile([%-*@3 fileName]) but it works in Posix for files +automatically generated by the OS.&] +[s0; &] +[s0; U`+`+ LoadFile() functions prior to loading the file into a +String, get the length of the file to dimension the String that +will get the file. This is not valid for OS generated virtual +files where the file length returned by the OS is 0 (for example +files under folder /proc)&] +[s0; &] +[s0; LoadFile`_Safe() just get the file bytes returned by the OS +until the file end.&] +[s3; &] +[s4;%- &] +[s5;:FileToTrashBin`(const char`*`):%- [@(0.0.255) void]_[* FileToTrashBin]([@(0.0.255) con +st]_[@(0.0.255) char]_`*[*@3 path])&] +[s2; Deletes file [%-*@3 path].by sending it to the Trash Bin.&] +[s3; &] +[s4;%- &] +[s5;:TrashBinGetCount`(`):%- [_^int64^ int64]_[* TrashBinGetCount]()&] +[s2; Returns the number of items (files and directories) located +in the Trash Bin.&] +[s3;%- &] +[s4;%- &] +[s5;:TrashBinClear`(`):%- [@(0.0.255) void]_[* TrashBinClear]()&] +[s2; Removes all the items (files and directories) located in the +Trash Bin.&] +[s3;%- &] +[s4;%- &] +[s5;:SetDesktopWallPaper`(const char`*`):%- [@(0.0.255) void]_[* SetDesktopWallPaper]([@(0.0.255) c +onst]_[@(0.0.255) char]_`*[*@3 path])&] +[s2; Sets [%-*@3 path].file as desktop wallpaper. Supports Gnome, Kde +v3 and Windows desktops.&] +[s0; &] +[s0;i150;O0; In Gnome, [%-*@3 path] has to be .png&] +[s0;i150;O0; In Kde, [%-*@3 path] has to be .png, .gif or .jpg&] +[s0;i150;O0; In Windows, [%-*@3 path] has to be .bmp&] +[s0; &] +[s0; If [%-*@3 path].is empty, the desktop wallpaper is removed. &] +[s0; &] +[s4;%- &] +[s5;:FileCat`(const char`*`,const char`*`):%- [@(0.0.255) bool]_[* FileCat]([@(0.0.255) con +st]_[@(0.0.255) char]_`*[*@3 file], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 appendFile]) +&] +[s2; Appends at the end of [%-*@3 file] the contents of file [%-*@3 appendFile]. +[%-*@3 file] will be modified and [%-*@3 appendFile ]remains unchanged.&] +[s0; -|Returns true if the operations has been done succesfully.&] +[s3;%- &] +[s4;%- &] +[s5;:Replace`(String`,String`,String`):%- [_^String^ String]_[* Replace]([_^String^ String]_ +[*@3 str], [_^String^ String]_[*@3 find], [_^String^ String]_[*@3 replace])&] +[s2; Returns the resulting String obtained by replacing in [%-*@3 str] +String [%-*@3 find] with [%-*@3 replace ]all the times that [%-*@3 find +]appears in [%-*@3 str].&] +[s3; &] +[s4;%- &] +[s5;:FormatLong`(long`):%- [_^String^ String]_[* FormatLong]([@(0.0.255) long]_[*@3 a])&] +[s2; Returns the long number [%-*@3 a ]converted into a String.&] +[s0; &] +[s4;%- &] +[s5;:BytesToString`(uint64`):%- [_^String^ String]_[* BytesToString]([_^uint64^ uint64]_[*@3 b +ytes])&] +[s2; Converts an amount of [%-*@3 bytes ]to a short String.&] +[s3; &] +[s4;%- &] +[s5;:SecondsToString`(double`):%- [_^String^ String]_[* SecondsToString]([@(0.0.255) double +]_[*@3 seconds])&] +[s2; Converts an amount of [%-*@3 seconds] to a String formatted as +HH:MM:SS.&] +[s3; &] +[s4;%- &] +[s5;:DoEvents`(`):%- [@(0.0.255) void]_[* DoEvents]()&] +[s2; A ProcessEvents just for old Visual Basic programmers.&] +[s3; &] +[s4;%- &] +[s5;:SearchFile`(String`,String`,String`):%- [_^Array^ Array]<[_^String^ String]>_[* Search +File]([_^String^ String]_[*@3 dir], [_^String^ String]_[*@3 condFile], +[_^String^ String]_[*@3 text]_`=_`"`")&] +[s2; Returns an Array of Strings containing the file names with full +path of the files under folder [%-*@3 dir] that comply with condition +(with wildcards) [%-*@3 condFile] and that contain inside the text +[%-*@3 text].&] +[s0; ] \ No newline at end of file diff --git a/bazaar/SysInfo/srcdoc.tpp/SysInfo$en-us.tpp b/bazaar/SysInfo/srcdoc.tpp/SysInfo$en-us.tpp new file mode 100644 index 000000000..d5e5ba9b6 --- /dev/null +++ b/bazaar/SysInfo/srcdoc.tpp/SysInfo$en-us.tpp @@ -0,0 +1,47 @@ +topic "SysInfo general description"; +[2 $$0,0#00000000000000000000000000000000:Default] +[l288;i1120;a17;O9;~~~.1408;2 $$1,0#10431211400427159095818037425705:param] +[a83;*R6 $$2,5#31310162474203024125188417583966:caption] +[H4;b83;*4 $$3,5#07864147445237544204411237157677:title] +[i288;O9;C2 $$4,6#40027414424643823182269349404212:item] +[b42;a42;2 $$5,5#45413000475342174754091244180557:text] +[l288;b17;a17;2 $$6,6#27521748481378242620020725143825:desc] +[l321;C@5;1 $$7,7#20902679421464641399138805415013:code] +[b2503;2 $$8,0#65142375456100023862071332075487:separator] +[*@(0.0.255)2 $$9,0#83433469410354161042741608181528:base] +[C2 $$10,0#37138531426314131251341829483380:class] +[l288;a17;*1 $$11,11#70004532496200323422659154056402:requirement] +[i417;b42;a42;O9;~~~.416;2 $$12,12#10566046415157235020018451313112:tparam] +[b167;C2 $$13,13#92430459443460461911108080531343:item1] +[i288;a42;O9;C2 $$14,14#77422149456609303542238260500223:item2] +[*@2$(0.128.128)2 $$15,15#34511555403152284025741354420178:NewsDate] +[l321;*C$7;2 $$16,16#03451589433145915344929335295360:result] +[l321;b83;a83;*C$7;2 $$17,17#07531550463529505371228428965313:result`-line] +[l160;*C+117 $$18,5#88603949442205825958800053222425:package`-title] +[2 $$19,0#53580023442335529039900623488521:gap] +[C2 $$20,20#70211524482531209251820423858195:class`-nested] +[b50;2 $$21,21#03324558446220344731010354752573:Par] +[{_}%EN-US +[s2; SysInfo&] +[s0; Functions to get information and handle Desktop, OS and hardware +internals.&] +[s0; &] +[s0; Includes functions for:&] +[s0; &] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#GetExtExecutable`(const String`)^ R +unning files and commands]&] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#GetDesktopFolder`(`)^ Obtainin +g special folders]&] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#GetSystemInfo`(String`&`,String`&`,String`&`,int`&`)^ H +ardware, BIOS and OS info]&] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#GetWindowsList`(Array``&`,Array``&`,Array``&`,Array``&`,Array``&`)^ P +rocess handling]&] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#Window`_GetRect`(long`,long`&`,long`&`,long`&`,long`&`)^ W +indows handling]&] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#Mouse`_GetPos`(long`&`,long`&`)^ M +ouse and keyboard handling]&] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#Mouse`_GetPos`(long`&`,long`&`)^ S +creen recording]&] +[s0;i150;O0; [^topic`:`/`/SysInfo`/src`/SysInfo`$en`-us`#LoadFile`_Safe`(String`)^ Misc +ellaneous functions]&] +[s0; ] \ No newline at end of file diff --git a/bazaar/SysInfo/srcimp.tpp/SysInfo$en-us.tpp b/bazaar/SysInfo/srcimp.tpp/SysInfo$en-us.tpp new file mode 100644 index 000000000..0f4a418ea --- /dev/null +++ b/bazaar/SysInfo/srcimp.tpp/SysInfo$en-us.tpp @@ -0,0 +1,569 @@ +topic "SysInfo implementation details"; +[2 $$0,0#00000000000000000000000000000000:Default] +[l288;i1120;a17;O9;~~~.1408;2 $$1,0#10431211400427159095818037425705:param] +[a83;*R6 $$2,5#31310162474203024125188417583966:caption] +[H4;b83;*4 $$3,5#07864147445237544204411237157677:title] +[i288;O9;C2 $$4,6#40027414424643823182269349404212:item] +[b42;a42;2 $$5,5#45413000475342174754091244180557:text] +[l288;b17;a17;2 $$6,6#27521748481378242620020725143825:desc] +[l321;C@5;1 $$7,7#20902679421464641399138805415013:code] +[b2503;2 $$8,0#65142375456100023862071332075487:separator] +[*@(0.0.255)2 $$9,0#83433469410354161042741608181528:base] +[C2 $$10,0#37138531426314131251341829483380:class] +[l288;a17;*1 $$11,11#70004532496200323422659154056402:requirement] +[i417;b42;a42;O9;~~~.416;2 $$12,12#10566046415157235020018451313112:tparam] +[b167;C2 $$13,13#92430459443460461911108080531343:item1] +[i288;a42;O9;C2 $$14,14#77422149456609303542238260500223:item2] +[*@2$(0.128.128)2 $$15,15#34511555403152284025741354420178:NewsDate] +[l321;*C$7;2 $$16,16#03451589433145915344929335295360:result] +[l321;b83;a83;*C$7;2 $$17,17#07531550463529505371228428965313:result`-line] +[l160;*C+117 $$18,5#88603949442205825958800053222425:package`-title] +[2 $$19,0#53580023442335529039900623488521:gap] +[C2 $$20,20#70211524482531209251820423858195:class`-nested] +[b50;2 $$21,21#03324558446220344731010354752573:Par] +[{_}%EN-US +[s2; SysInfo&] +[s0; &] +[s0; [*+92 1. Introduction]&] +[s0; &] +[s0; A goal in the design of these functions has been to avoid accessing +external software not included internally in the OS by default.&] +[s5;i150;O0; Windows implementation use internal DLL and wmi.&] +[s0;i150;O0; Posix implementation uses X11 libraries and OS related +utilities like mount and xdg.&] +[s0; &] +[s0; Another goal is to provide the running program information about +the environment including hardware and software to adapt itself +after program compiling. This way for example a program compiled +in Ubuntu can run properly in Fedora without recompiling.&] +[s0; &] +[s0; &] +[s0; [*+92 2. Compiler support]&] +[s0; &] +[s0; SysInfo has been tested in Linux using Gcc and in Windows using +MinGW and MSC 9.&] +[s0; &] +[s0; [* IMPORTANT:] To compile using MinGW it is required to copy the +next files from the MSC install or from other sources:&] +[s0;i150;O0; To MinGW/include: &] +[s0; -|`- Files Rpcsal.h, DispEx.h, WbemCli.h, WbemDisp.h, Wbemidl.h, +WbemProv.h and WbemTran.h&] +[s0; -|`- They can be taken from: `\Microsoft SDKs`\Windows`\v6.1`\Include&] +[s0; &] +[s0;i150;O0;%- To MinGW/lib: &] +[s0; -|`- File wbemuuid.lib&] +[s0; -|`- It can be taken from `\Microsoft SDKs`\Windows`\v6.1`\Lib&] +[s0; &] +[s0; &] +[s0; [*+92 3. OS and Desktop implementation]&] +[s0; &] +[s0; OS and Desktop implementation is a work in process as in some +implementations it requires a level of hacking so all feedback +will be acknowledged.&] +[s0; &] +[s0; Here are enclosed the testing results divided in two tables:&] +[s0; &] +[ {{10000@(128) [s0; [* Testing results]]}}&] +[s0; &] +[ {{833:833:833:833:833:833:833:833:833:833:833:837h1;@1 [s0; Distro] +:: [s0; Version] +:: [s0; Architecture] +:: [s0; Desktop] +:: [s0; Version] +:: [s0; Comments] +:: [s0; Special folders] +:: [s0; System Info] +:: [s0; Memory Info] +:: [s0; OS Info] +:: [s0; Distro Info] +:: [s0; Default Exes] +::@2 [s0; Fedora] +:: [s0; 9] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Fedora] +:: [s0; 9] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.0.3] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Kubuntu] +:: [s0; 8.10] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.1.2] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Mandriva] +:: [s0; 2009] +:: [s0; 32] +:: [s0; Kde] +:: [s0; ] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Mandriva] +:: [s0; 2009] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.24] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +::@9 [s0; No virtual memory] +::@2 [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Opengeu] +:: [s0; 8.04] +:: [s0; 32] +:: [s0; Enlightenment] +:: [s0; 0.16] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; OpenSuse] +:: [s0; 11] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; ] +::@9 [s0; Some not detected] +::@2 [s0; Ok] +::@9 [s0; No virtual memory] +::@2 [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; OpenSuse] +:: [s0; 11] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.0.4] +:: [s0; ] +::@9 [s0; Some not detected] +::@2 [s0; Ok] +::@9 [s0; No virtual memory] +::@2 [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Slax] +:: [s0; ] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 3.5.9] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ubuntu] +:: [s0; 8.04] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ubuntu] +:: [s0; 8.04] +:: [s0; 64] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Xubuntu] +:: [s0; 8.10] +:: [s0; 32] +:: [s0; Xfce] +:: [s0; ] +::@9 [s0; Partial test. Expected better results] +:: [s0; Some not detected] +::@2 [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +::@9 [s0; No version] +::@2 [s0; Ok] +:: [s0; Vista] +:: [s0; Home Premium Edition] +:: [s0; 32] +:: [s0; Vista] +:: [s0; ] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; XP] +:: [s0; 5.1 SP3] +:: [s0; 32] +:: [s0; XP] +:: [s0; ] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok]}}&] +[s0;0 &] +[s0;%- &] +[ {{998:998:998:998:998:998:998:998:998:1018h1;@1 [s0; Distro] +:: [s0; Version] +:: [s0; Architecture] +:: [s0; Desktop] +:: [s0; Version] +:: [s0; Drives Info] +:: [s0; Launch File] +:: [s0; Find and Kill Window] +:: [s0; Windows List] +:: [s0; Process List] +::@2 [s0; Fedora] +:: [s0; 9] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Fedora] +:: [s0; 9] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.0.3] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Kubuntu] +:: [s0; 8.10] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.1.2] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Mandriva] +:: [s0; 2009] +:: [s0; 32] +:: [s0; Kde] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Mandriva] +:: [s0; 2009] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.24] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Opengeu] +:: [s0; 8.04] +:: [s0; 32] +:: [s0; Enlightenment] +:: [s0; 0.16] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; OpenSuse] +:: [s0; 11] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; OpenSuse] +:: [s0; 11] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.0.4] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Slax] +:: [s0; ] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 3.5.9] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ubuntu] +:: [s0; 8.04] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ubuntu] +:: [s0; 8.04] +:: [s0; 64] +:: [s0; Gnome] +:: [s0; 2.22] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Xubuntu] +:: [s0; 8.10] +:: [s0; 32] +:: [s0; Xfce] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Vista] +:: [s0; Home Premium Edition] +:: [s0; 32] +:: [s0; Vista] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; XP] +:: [s0; 5.1 SP3] +:: [s0; 32] +:: [s0; XP] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok]}}&] +[s0; &] +[s0; It seems OS CPU speed report is not reliable in Linux as it +varies between program runs.&] +[s0; The same error has been found in system reporting programs and +desktop cpu speed icons.&] +[s0;%- &] +[ {{1250:1250:1250:1250:1250:1250:1250:1250h1;@1 [s0; Distro] +:: [s0; Version] +:: [s0; Architecture] +:: [s0; Desktop] +:: [s0; Version] +:: [s0; Screen Snap] +:: [s0; Screen Record] +:: [s0; Installed software list] +::@2 [s0; Fedora] +:: [s0; 9] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Fedora] +:: [s0; 9] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.0.3] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Kubuntu] +:: [s0; 8.10] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.1.2] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Mandriva] +:: [s0; 2009] +:: [s0; 32] +:: [s0; Kde] +:: [s0; ] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Mandriva] +:: [s0; 2009] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.24] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Opengeu] +:: [s0; 8.04] +:: [s0; 32] +:: [s0; Enlightenment] +:: [s0; 0.16] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; OpenSuse] +:: [s0; 11] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; OpenSuse] +:: [s0; 11] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 4.0.4] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Slax] +:: [s0; ] +:: [s0; 32] +:: [s0; Kde] +:: [s0; 3.5.9] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Ubuntu] +:: [s0; 8.04`-9.04] +:: [s0; 32] +:: [s0; Gnome] +:: [s0; 2.22`-] +:: [s0; Ok] +::@9 [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Ubuntu] +:: [s0; 8.04`-9.04] +:: [s0; 64] +:: [s0; Gnome] +:: [s0; 2.22`-] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Xubuntu] +:: [s0; 8.10] +:: [s0; 32] +:: [s0; Xfce] +:: [s0; ] +::@9 [s0; Not tested] +:: [s0;%- Not implement.] +:: [s0;%- Not implement.] +::@2 [s0; Vista] +:: [s0; Home Premium Edition] +:: [s0; 32] +:: [s0; Vista] +:: [s0; ] +::@9 [s0; Not tested] +:: [s0; Not tested] +:: [s0; Not tested] +::@2 [s0; XP] +:: [s0; 5.1 SP2`-3 Professional] +:: [s0; 32] +:: [s0; XP] +:: [s0; ] +:: [s0; Ok] +:: [s0; Ok] +:: [s0; Ok]}}&] +[s0; &] +[s0; &] +[s0; Next table includes the list of OS and Distros unsuccesfully +tried and the reason:&] +[s0; &] +[ {{10000@(128) [s0; [* OS and Distros not tested]]}}&] +[s0;%- &] +[ {{1665:1665:1665:1665:1665:1675h1;@1 [s0; Distro] +:: [s0; Version] +:: [s0; Architecture] +:: [s0; Desktop] +:: [s0; Version] +:: [s0; Comments] +::@2 [s0; Freesbie] +:: [s0; 2.0] +:: [s0; 32] +:: [s0; ] +:: [s0; ] +:: [s0; [$2 Not possible to run without password]] +:: [s0; Fluxbox] +:: [s0; 7.10] +:: [s0; 32] +:: [s0; ] +:: [s0; ] +:: [s0; [$2 Live version not found]] +:: [s0; Gentoo] +:: [s0; ] +:: [s0; 32] +:: [s0; Xfce] +:: [s0; ] +:: [s0; [$2 Not possible to mount internal or usb HD]] +:: [s0; Knoppix] +:: [s0; 5.11] +:: [s0; 32] +:: [s0; Kde] +:: [s0; ] +:: [s0; [$2 Old Glib version]] +:: [s0; Slackware] +:: [s0; ] +:: [s0; 32] +:: [s0; ] +:: [s0; ] +:: [s0; [$2 Live version not found]]}}&] +[s0; ] \ No newline at end of file