#define _WIN32_WINNT 0xFFFF // Required by MinGW #include "Core/Core.h" #if defined(PLATFORM_WIN32) #include #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 /plugin to MinGW/include and // wbemuuid.lib from /plugin to MinGW/lib #include #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 #include #include #include #endif using namespace Upp; #define _Browser_Browser_h #include "SysInfo.h" ///////////////////////////////////////////////////////////////////// // Hardware Info #if defined(PLATFORM_WIN32) bool GetWMIInfo(String system, Array &data, Array *ret[], String nameSpace = "root\\cimv2") { 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(nameSpace.ToWString()); 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; bool rt = false; while (pEnumerator) { hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObject, &uReturn); if(0 == uReturn) { if (rt) break; else { pIWbemLocator->Release(); pWbemServices->Release(); pEnumerator->Release(); CoUninitialize(); return false; } } 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)); rt = true; } row++; } pIWbemLocator->Release(); pWbemServices->Release(); pEnumerator->Release(); pClassObject->Release(); CoUninitialize(); return true; } bool GetWMIInfo(String system, String data, Value &res, String nameSpace = "root\\cimv2") { Array arrRes; Array *arrResP[1]; arrResP[0] = &arrRes; Array arrData; arrData.Add(data); bool ret = GetWMIInfo(system, arrData, arrResP, nameSpace); if (ret) res = arrRes[0]; return ret; } void GetSystemInfo(String &manufacturer, String &productName, String &version, int &numberOfProcessors, String &mbSerial) { manufacturer = ""; Value vmanufacturer; if (GetWMIInfo("Win32_ComputerSystem", "manufacturer", vmanufacturer)) manufacturer = Trim(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 = Trim(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")); Value vmbSerial; if (GetWMIInfo("Win32_BaseBoard", "SerialNumber", vmbSerial)) mbSerial = Trim(vmbSerial); } void GetBiosInfo(String &biosVersion, Date &biosReleaseDate, String &biosSerial) { // 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)); int lang = GetCurrentLanguage(); SetLanguage(LNG_ENGLISH); if (!StrToDate(biosReleaseDate, strDate)) biosReleaseDate = Null; SetLanguage(lang); Value vmbSerial; if (GetWMIInfo("Win32_BIOS", "SerialNumber", vmbSerial)) biosSerial = Trim(vmbSerial); } 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; } /* String GetMacAddressWMI() { Value vmac; if (!GetWMIInfo("Win32_NetworkAdapterConfiguration", "MacAddress", vmac)) return Null; String mac = Trim(vmac); if (mac.GetCount() > 0) return mac; return Null; } */ #include #include Array GetAdapterInfo() { PIP_ADAPTER_ADDRESSES pAddresses = NULL; ULONG family = AF_UNSPEC; DWORD flags = GAA_FLAG_INCLUDE_PREFIX; ULONG outBufLen = 0; Buffer pBuffer; Array ret; switch (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen)) { case ERROR_BUFFER_OVERFLOW: pBuffer.Alloc(outBufLen); pAddresses = (PIP_ADAPTER_ADDRESSES)~pBuffer; break; case ERROR_NO_DATA: case ERROR_INVALID_FUNCTION: default: return ret; } if (NO_ERROR != GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen)) return ret; for (PIP_ADAPTER_ADDRESSES pAdd = pAddresses; pAdd; pAdd = pAdd->Next) { NetAdapter &adapter = ret.Add(); int len = min((DWORD)6, pAdd->PhysicalAddressLength); if (len > 0) adapter.mac = ToUpper(HexString(pAdd->PhysicalAddress, len, 1, ':')); adapter.description = Trim(WideToString(pAdd->Description)); adapter.fullname = Trim(WideToString(pAdd->FriendlyName)); switch (pAdd->IfType) { case IF_TYPE_ETHERNET_CSMACD: adapter.type = "ETHERNET"; break; case IF_TYPE_ISO88025_TOKENRING: adapter.type = "TOKENRING"; break; case IF_TYPE_PPP: adapter.type = "MODEM"; break; case IF_TYPE_SOFTWARE_LOOPBACK: adapter.type = "SOFTWARE_LOOPBACK"; break; case IF_TYPE_ATM: adapter.type = "ATM"; break; case IF_TYPE_IEEE80211: adapter.type = "IEEE80211"; break; case IF_TYPE_TUNNEL: adapter.type = "TUNNEL"; break; case IF_TYPE_IEEE1394: adapter.type = "IEEE1394"; break; default: adapter.type = "OTHER"; } if (adapter.type == "ETHERNET" && ToLower(adapter.description).Find("wireless") >= 0) adapter.type = "IEEE80211"; } return ret; } String GetHDSerial() { Value vmbSerial; if (!GetWMIInfo("Win32_PhysicalMedia", "SerialNumber", vmbSerial)) return Null; String serial = Trim(vmbSerial); if (serial.GetCount() > 0) return serial; return Null; } 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; } double GetCpuTemperature() { Value data; if (GetWMIInfo("MSAcpi_ThermalZoneTemperature", "CurrentTemperature", data, "root\\wmi")) return (double(data) - 2732.) / 10.; if (GetWMIInfo("Win32_TemperatureProbe", "CurrentReading", data)) return data; return Null; } #endif String GetMacAddress() { Array ret = GetAdapterInfo(); if (!ret.IsEmpty()) return ret[0].mac; else return Null; } #if defined (PLATFORM_POSIX) void GetSystemInfo(String &manufacturer, String &productName, String &version, int &numberOfProcessors, String &mbSerial) { 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"); mbSerial = LoadFile_Safe("/sys/devices/virtual/dmi/id/board_serial"); if (mbSerial.IsEmpty()) mbSerial = FormatInt(gethostid()); 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 &biosSerial) { 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")); biosSerial = LoadFile_Safe("/sys/devices/virtual/dmi/id/chassis_serial"); } 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 = Sys("uname -m"); // CPU type architecture << " Family " << family << " Model " << model << " Stepping " << stepping; // And 64 bits ?? uname -m cpu.GoAfter_Init("cpu MHz", ":"); speed = cpu.GetInt(); } double GetCpuTemperature() { /* This is only if acpi package is present StringParse data = Sys("acpi -V"); data.GoAfter("Thermal", ","); return data.GetDouble(); */ FindFile ff; if(ff.Search("/proc/acpi/thermal_zone/*")) { do { if (ff.IsDirectory()) { String name = ff.GetName(); if (name != "." && name != "..") { StringParse str = LoadFile_Safe(AppendFileName(AppendFileName("/proc/acpi/thermal_zone", name), "temperature")); str.GoAfter("temperature:"); return str.GetDouble(); } } } while(ff.Next()); } return Null; } Array GetAdapterInfo() { Array ret; StringParse data = Sys("ifconfig -a"); for (StringParse line = data.GetLine(); !data.Eof(); line = data.GetLine()) { NetAdapter &adapter = ret.Add(); String str = line.GetText(); if (str.Find("eth") >= 0) adapter.type = "ETHERNET"; else if (str.Find("lo") >= 0) adapter.type = "SOFTWARE_LOOPBACK"; else if (str.Find("ppp") >= 0) adapter.type = "MODEM"; else if (str.Find("hci") >= 0) adapter.type = "BLUETOOTH"; else if (str.Find("tr") >= 0) adapter.type = "TOKENRING"; else if (str.Find("vbox") >= 0 || str.Find("wifi") >= 0 || str.Find("ath") >= 0) adapter.type = "VIRTUALBOX"; else if (str.Find("wlan") >= 0) adapter.type = "IEEE80211"; else adapter.type = "OTHER"; line.GoAfter(":"); int pos = line.GetPos(); int npos = line.Find(" ", pos); if (npos >= 0) { adapter.fullname = line.Mid(pos, npos-pos); line.SetPos(npos+1); } if (line.GetText() != "") adapter.mac = ToUpper(Trim(line.GetText())); do { data.GoAfter("\n"); } while (data[data.GetPos()] == ' '); } return ret; } #endif ///////////////////////////////////////////////////////////////////// // Memory Info #if defined(PLATFORM_WIN32) 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; } #else 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 flagGUI #define SetX11ErrorHandler() {} #define SetSysInfoX11ErrorHandler() {} #else #define SetX11ErrorHandler() {} int SysInfoX11ErrorHandler(_XDisplay *, XErrorEvent *) {return 0;} void SetSysInfoX11ErrorHandler() {XSetErrorHandler(SysInfoX11ErrorHandler);} #endif #endif void GetWindowsList_Rec (_XDisplay *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(); _XDisplay *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(); _XDisplay *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; _XDisplay *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) { String s = caption[i]; 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 #if !defined(VER_SUITE_WH_SERVER) #define VER_SUITE_WH_SERVER 0x00008000 #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) { if (osvi.dwMinorVersion == 1) { if (osvi.wProductType == VER_NT_WORKSTATION) kernel.Cat(" Seven"); else kernel.Cat(" Server 2008 R2"); } else if (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(osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.wServicePackMajor, osvi.wServicePackMinor, &dwType); switch(dwType) { case PRODUCT_UNLICENSED: distro = "Unlicensed"; break; case PRODUCT_ULTIMATE: distro = "Ultimate Edition"; break; case PRODUCT_HOME_PREMIUM: distro = "Home Premium Edition"; break; case PRODUCT_HOME_BASIC: case PRODUCT_HOME_BASIC_N: distro = "Home Basic Edition"; break; case PRODUCT_ENTERPRISE: distro = "Enterprise Edition"; break; case PRODUCT_BUSINESS: case PRODUCT_BUSINESS_N: 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; } } else 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.wSuiteMask & VER_SUITE_WH_SERVER) kernel.Cat(" Home Server"); 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"; } } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) { kernel.Cat(" XP"); if(osvi.wSuiteMask & VER_SUITE_PERSONAL ) distro = "Home Edition"; else distro = "Professional"; } else 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; } 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 (Sys("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 = Sys("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 = Sys("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 = Sys("konsole --version"); konsole.GoAfter("KDE:"); deskVersion = konsole.GetText("\r\n"); if (deskVersion == "") deskVersion = GetEnv("KDE_SESSION_VERSION"); } else { StringParse desktopStr; if (Sys("xprop -root _DT_SAVE_MODE").Find("xfce") >= 0) desktop = "xfce"; else if ((desktopStr = Sys("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 (Sys("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) 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) 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 = Sys("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 = Sys("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; return true; } #endif #if defined (PLATFORM_WIN32) unsigned long start, end; unsigned long 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,_start"); __asm__("mov %edx,4+(_start)"); do QueryPerformanceCounter((LARGE_INTEGER *)&nCtr); while (nCtr < nCtrStop); __asm__(".byte 0x0F"); __asm__(".byte 0x31"); __asm__("mov %eax,_end"); __asm__("mov %edx,4+(_end)"); return int((end-start)/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 start, eax mov DWORD PTR [start + 4], edx } do QueryPerformanceCounter((LARGE_INTEGER *) &nCtr); while (nCtr < nCtrStop); _asm { __asm _emit 0x0f __asm _emit 0x31 mov DWORD PTR end, eax mov DWORD PTR [end + 4], edx } return int((end-start)/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 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) { /* This is only if acpi package is present StringParse data = Sys("acpi -V"); data.GoAfter("AC Adapter", ":"); String sacStatus = data.GetText(); discharging = sacStatus != "on-line"; data.GoInit(); data.GoAfter("Battery", ":"); data.GoAfter(","); percentage = data.GetInt("%"); data.GoAfter(","); String remaining; if (discharging) { remaining = data.GetText(" "); int hour, min; double secs; StringToHMS(remaining, hour, min, secs); // It is really days:hour:min in this case remainingMin = int(secs) + min*60 + hour*24*60; } else remainingMin = Null; */ 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 = Null; 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; } bool OpenCDTray(String drive) { String dummy; return Sys("eject", dummy) > 0; } bool CloseCDTray(String drive) { String dummy; return Sys("eject -t", dummy) > 0; } #endif #if defined(PLATFORM_WIN32) bool GetBatteryStatus(bool &discharging, int &percentage, int &remainingMin) { SYSTEM_POWER_STATUS power; if(::GetSystemPowerStatus(&power) != 1) return false; if (power.ACLineStatus == 1) discharging = false; else discharging = true; if (power.BatteryLifePercent <= 100) percentage = power.BatteryLifePercent; else percentage = Null; if (discharging && power.BatteryLifeTime != -1) remainingMin = int(power.BatteryLifeTime/60); else remainingMin = Null; 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; } bool DriveOpenClose(String drive, bool open) { int operation; if (open) operation = IOCTL_STORAGE_EJECT_MEDIA; else operation = IOCTL_STORAGE_LOAD_MEDIA; if (drive.IsEmpty()) return false; else if (drive.GetCount() == 1) drive += ":"; else { drive = drive.Left(2); if (drive[1] != ':') return false; } HANDLE hDrive; hDrive = CreateFile("\\\\.\\" + drive, GENERIC_READ || GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hDrive == INVALID_HANDLE_VALUE) return false; bool ret = false; DWORD dummyBytesReturned; if (DeviceIoControl(hDrive, operation, 0, 0, 0, 0, &dummyBytesReturned, 0)) ret = true; CloseHandle(hDrive); return ret; } bool OpenCDTray(String drive) { return DriveOpenClose(drive, true); } bool CloseCDTray(String drive) { return DriveOpenClose(drive, false); } #endif void Mouse_LeftClick() { Mouse_LeftDown(); Mouse_LeftUp(); } void Mouse_RightClick() { Mouse_RightDown(); Mouse_RightUp(); } void Mouse_MiddleClick() { Mouse_MiddleDown(); Mouse_MiddleUp(); } void Mouse_LeftDblClick() { Mouse_LeftClick(); Mouse_LeftClick(); } void Mouse_MiddleDblClick() { Mouse_MiddleClick(); Mouse_MiddleClick(); } void Mouse_RightDblClick() { Mouse_RightClick(); Mouse_RightClick(); } struct KeyCodes { String key; int code; }; #if defined(PLATFORM_WIN32) Array GetWinRegSubkeys(const String& key, HKEY base) { HKEY hkey; Array subkeys; if(RegOpenKeyEx(base, key, 0, KEY_READ, &hkey) != ERROR_SUCCESS) return subkeys; char temp[_MAX_PATH]; dword len; for(dword dw = 0; len = sizeof(temp), RegEnumKeyEx(hkey, dw, temp, &len, 0, 0, 0, 0) == ERROR_SUCCESS; dw++) subkeys.Add(temp); RegCloseKey(hkey); return subkeys; } 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); } 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; } bool Window_SetRect(long windowId, long left, long top, long right, long bottom) { RECT rcNormalPosition; POINT ptMinPosition, ptMaxPosition; long showcmd; if (!TakeWindowPlacement((HWND)windowId, rcNormalPosition, ptMinPosition, ptMaxPosition, showcmd)) return false; rcNormalPosition.left = left; rcNormalPosition.top = top; rcNormalPosition.right = right; rcNormalPosition.bottom = bottom; return 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); return true; } bool Mouse_GetPos(long &x, long &y) { POINT p; GetCursorPos (&p); x = p.x; y = p.y; return true; } 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, /*"PGUP", XK_Page_Up, "PGDOWN", XK_Page_Down "CAPSLOCK", XK_Caps_Lock, "BACKSPACE",XK_BackSpace */ "" }; 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); } #if defined(__MINGW32__) #define MAPVK_VK_TO_VSC 0 #define MAPVK_VSC_TO_VK 1 #define MAPVK_VK_TO_CHAR 2 #define MAPVK_VSC_TO_VK_EX 3 #endif #define MAPVK_VK_TO_VSC_EX 4 // This is less nice but more compatible for Notepad and MSWord for example void PressKey(wchar key, bool hold = false, bool release = false) { if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z') || (key >= '0' && key <= '9')) { char buff[120]; GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, buff, sizeof(buff)); HKL hKeyboardLayout = ::LoadKeyboardLayout(buff, KLF_ACTIVATE); SHORT nVK = VkKeyScanExW(key, hKeyboardLayout); UINT nScan = MapVirtualKeyExW(nVK, MAPVK_VK_TO_CHAR, hKeyboardLayout); if (!release) keybd_event((BYTE)nVK, (BYTE)nScan, 0, 0); if (!hold) keybd_event((BYTE)nVK, (BYTE)nScan, KEYEVENTF_KEYUP, 0); } else { String numStr = FormatIntDec(key, 5, '0'); PressKeyVK(VK_LMENU, true); PressKeyVK(VK_NUMPAD0 + numStr[0] - '0'); PressKeyVK(VK_NUMPAD0 + numStr[1] - '0'); PressKeyVK(VK_NUMPAD0 + numStr[2] - '0'); PressKeyVK(VK_NUMPAD0 + numStr[3] - '0'); PressKeyVK(VK_NUMPAD0 + numStr[4] - '0'); PressKeyVK(VK_LMENU, false, true); } } /* void PressKey(wchar key, bool hold = false, bool release = false) { bool caps, num, scroll; if (IsLetter(key)) { GetKeyLockStatus(caps, num, scroll); if (caps) SetKeyLockStatus(false, num, scroll); } char buff[120]; GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, buff, sizeof(buff)); HKL hKeyboardLayout = ::LoadKeyboardLayout(buff, KLF_ACTIVATE); SHORT nVK = VkKeyScanExW(key, hKeyboardLayout); if (nVK == -1) { // Last resource !! String numStr = FormatIntDec(key, 4, '0'); PressKeyVK(VK_LMENU, true); PressKeyVK(VK_NUMPAD0 + numStr[0] - '0'); PressKeyVK(VK_NUMPAD0 + numStr[1] - '0'); PressKeyVK(VK_NUMPAD0 + numStr[2] - '0'); PressKeyVK(VK_NUMPAD0 + numStr[3] - '0'); PressKeyVK(VK_LMENU, false, true); return; } UINT nScan = MapVirtualKeyExW(nVK, MAPVK_VK_TO_CHAR, hKeyboardLayout); long nExtended = 0; if (nScan == 0) nExtended = KEYEVENTF_EXTENDEDKEY; nScan = MapVirtualKeyExW(nVK, MAPVK_VK_TO_VSC, hKeyboardLayout); 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); } */ bool GetKeyLockStatus(bool &caps, bool &num, bool &scroll) { caps = GetKeyState(VK_CAPITAL); num = GetKeyState(VK_NUMLOCK); scroll = GetKeyState(VK_SCROLL); return true; } bool 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); return true; } #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; 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; char *cbuf = new char[bmpInfo.bmiHeader.biSizeImage]; LPVOID buf = cbuf; bmpInfo.bmiHeader.biCompression = BI_RGB; GetDIBits(hDC, hb, 0, bmpInfo.bmiHeader.biHeight, buf, &bmpInfo, DIB_RGB_COLORS); if((file = _wfopen(fileName.ToWString(),L"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); delete[] cbuf; 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(unsigned 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(t_("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(unsigned 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) Sleep(10);//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(); _XDisplay *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 Window_SetRect(long windowId, long left, long top, long right, long bottom) { SetSysInfoX11ErrorHandler(); _XDisplay *dpy = XOpenDisplay (NULL); if (!dpy) { SetX11ErrorHandler(); return false; } bool ret = false; if (XMoveWindow(dpy, windowId, left, top)) { if (!XResizeWindow(dpy, windowId, right-left, bottom-top)) ret = false; else ret = true; } XCloseDisplay (dpy); SetX11ErrorHandler(); return ret; } bool Mouse_GetPos(long &x, long &y) { SetSysInfoX11ErrorHandler(); _XDisplay *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(); _XDisplay *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; } // libxtst-dev void Mouse_FakeClick(int button, int press) { _XDisplay *dpy = XOpenDisplay(NULL); XTestFakeButtonEvent(dpy, button, press, CurrentTime); XFlush(dpy); XCloseDisplay(dpy); } void Mouse_LeftDown() { Mouse_FakeClick(1, True); } void Mouse_LeftUp() { Mouse_FakeClick(1, False); } void Mouse_MiddleDown() { Mouse_FakeClick(2, True); } void Mouse_MiddleUp() { Mouse_FakeClick(2, False); } void Mouse_RightDown() { Mouse_FakeClick(3, True); } void Mouse_RightUp() { Mouse_FakeClick(3, False); } void PressKeyVK(int key, _XDisplay *dpy = NULL) { bool local = false; if (!dpy) { if (!(dpy = XOpenDisplay(NULL))) return; local = true; } XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, key), True, CurrentTime); XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, key), False, CurrentTime); if (local) { XFlush(dpy); XCloseDisplay(dpy); } } void PressKey(wchar key, _XDisplay *dpy = NULL) { bool local = false; if (!dpy) { if (!(dpy = XOpenDisplay(NULL))) return; local = true; } wchar k = key; if (key > 0x00ff) key = key | 0x01000000; bool shift = false; KeyCode code = XKeysymToKeycode(dpy, key); if (code != 0) { if (XKeycodeToKeysym(dpy, code, 0) != key) { if (XKeycodeToKeysym(dpy, code, 1) == key) shift = true; else code = 0; } } else { int firstKeycode, maxKeycode; int keysymsPerKeycode; XDisplayKeycodes(dpy, &firstKeycode, &maxKeycode); KeySym *keysyms = XGetKeyboardMapping(dpy, firstKeycode, maxKeycode-firstKeycode+1, &keysymsPerKeycode); int indx = (maxKeycode-firstKeycode-1)*keysymsPerKeycode; keysyms[indx] = key; XChangeKeyboardMapping(dpy, firstKeycode, keysymsPerKeycode, keysyms, maxKeycode-firstKeycode); XSync(dpy, False); code = maxKeycode-1; if (XKeycodeToKeysym(dpy, code, 0) != key) { if (XKeycodeToKeysym(dpy, code, 1) == key) shift = true; } } if (code != 0) { if (shift) XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, XK_Shift_L), True, CurrentTime); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); if (shift) XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, XK_Shift_L), False, CurrentTime); } if (local) { XFlush(dpy); XCloseDisplay(dpy); } } bool GetKeyLockStatus0(bool &caps, bool &num, bool &scroll, _XDisplay *dpy) { int x, y, xx, yy; Window dm1, dm2; unsigned int sKbdState; if(!XQueryPointer(dpy, DefaultRootWindow(dpy), &dm1, &dm2, &x, &y, &xx, &yy, &sKbdState)) return false; caps = sKbdState & LockMask; num = sKbdState & Mod2Mask; scroll = sKbdState & Mod5Mask; return true; } bool GetKeyLockStatus(bool &caps, bool &num, bool &scroll) { _XDisplay *dpy; if (!(dpy = XOpenDisplay(NULL))) return false; if (!GetKeyLockStatus0(caps, num, scroll, dpy)) { XCloseDisplay(dpy); return false; } XFlush(dpy); XCloseDisplay(dpy); return true; } bool SetKeyLockStatus(bool caps, bool num, bool scroll) { _XDisplay *dpy; if (!(dpy = XOpenDisplay(NULL))) return false; bool oldcaps, oldnum, oldscroll; if (!GetKeyLockStatus0(oldcaps, oldnum, oldscroll, dpy)) { XCloseDisplay(dpy); return false; } if (caps != oldcaps) PressKeyVK(XK_Caps_Lock, dpy); if (num != oldnum) PressKeyVK(XK_Num_Lock, dpy); if (scroll != oldscroll) PressKeyVK(XK_Scroll_Lock, dpy); XFlush(dpy); XCloseDisplay(dpy); 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; return Sys(command, strret) >= 0; } KeyCodes keyCodes[] = { "NUMPAD7", XK_KP_7, "BACK", XK_BackSpace, "NUMPAD8", XK_KP_8, "TAB", XK_Tab, "NUMPAD9", XK_KP_9, "RETURN", XK_Return, "MULTIPLY", XK_KP_Multiply, "SHIFT", XK_Shift_Lock, "ADD", XK_KP_Add, "CONTROL", XK_Control_L, "SEPARATOR", XK_KP_Separator,"MENU", XK_Super_L, "SUBTRACT", XK_KP_Subtract, "PAUSE", XK_Pause, "DECIMAL", XK_KP_Decimal, /*"CAPITAL", VK_CAPITAL,*/ "DIVIDE", XK_KP_Divide, "ESCAPE", XK_Escape, "F1", XK_F1, "SPACE", XK_KP_Space, "F2", XK_F2, "END", XK_End, "F3", XK_F3, "HOME", XK_Home, "F4", XK_F4, "LEFT", XK_Left, "F5", XK_F5, "UP", XK_Up, "F6", XK_F6, "RIGHT", XK_Right, "F7", XK_F7, "DOWN", XK_Down, "F8", XK_F8, "PRINT", XK_Sys_Req, "F9", XK_F9, /*"SNAPSHOT", VK_SNAPSHOT,*/ "F10", XK_F10, "INSERT", XK_Insert, "F11", XK_F11, "DELETE", XK_Delete, "F12", XK_F12, "LWIN", XK_Meta_L, "NUMLOCK", XK_Num_Lock, "RWIN", XK_Meta_R, "SCROLL", XK_Scroll_Lock, "NUMPAD0", XK_KP_0, "LSHIFT", XK_Shift_L, "NUMPAD1", XK_KP_1, "RSHIFT", XK_Shift_R, "NUMPAD2", XK_KP_2, "LCONTROL", XK_Control_L, "NUMPAD3", XK_KP_3, "RCONTROL", XK_Control_R, "NUMPAD4", XK_KP_4, "LMENU", XK_Super_L, "NUMPAD5", XK_KP_5, "RMENU", XK_Super_R, "NUMPAD6", XK_KP_6, "PGUP", XK_Page_Up, "PGDOWN", XK_Page_Down, "CAPSLOCK", XK_Caps_Lock, "BACKSPACE",XK_BackSpace, "" }; #endif 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 Keyb_SendKeys(String text, long finalDelay, long delayBetweenKeys) { Array virt; bool inKey = false; String key = ""; WString wtext(text); for (int i = 0; i < wtext.GetCount(); ++i) { bool vk = false; Sleep(delayBetweenKeys); wchar c = wtext[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); else if (c == '\n') { c = GetKeyCode("RETURN"); vk = true; } if (inKey == false) { if (!vk) PressKey(c); #if defined(PLATFORM_WIN32) else { PressKeyVK(c, true); virt.Add(c); } #endif } } #if defined(PLATFORM_WIN32) for (int i = 0; i < virt.GetCount(); ++i) PressKeyVK(virt[i], false, true); #endif Sleep(finalDelay); } 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 void SetDesktopWallPaper(const char *path) { String desktopManager = GetDesktopManagerNew(); if (desktopManager == "gnome") { Sys("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"; Sys("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; Sys("dcop kdesktop KBackgroundIface setWallpaper \"" + String(path) + "\" " + AsString(mode)); } else throw Exc(t_("Not possible to change Desktop bitmap")); } #endif #if defined(PLATFORM_WIN32) void SetDesktopWallPaper(const char *path) { if (0 == SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (LPVOID)path, SPIF_UPDATEINIFILE || SPIF_SENDWININICHANGE)) throw Exc(Format(t_("Error %s changing Desktop bitmap"), AsString(GetLastError()))); } #endif