summaryrefslogtreecommitdiff
path: root/plugins/VersionInfo/CVersionInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/VersionInfo/CVersionInfo.cpp')
-rw-r--r--plugins/VersionInfo/CVersionInfo.cpp1588
1 files changed, 1588 insertions, 0 deletions
diff --git a/plugins/VersionInfo/CVersionInfo.cpp b/plugins/VersionInfo/CVersionInfo.cpp
new file mode 100644
index 0000000000..43087c3837
--- /dev/null
+++ b/plugins/VersionInfo/CVersionInfo.cpp
@@ -0,0 +1,1588 @@
+/*
+Version information plugin for Miranda IM
+
+Copyright © 2002-2006 Luca Santarelli, Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include "CVersionInfo.h"
+//#include "AggressiveOptimize.h"
+
+#include "common.h"
+
+//using namespace std;
+
+BOOL (WINAPI *MyGetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
+BOOL (WINAPI *MyIsWow64Process)(HANDLE, PBOOL);
+void (WINAPI *MyGetSystemInfo)(LPSYSTEM_INFO);
+BOOL (WINAPI *MyGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer) = NULL;
+
+LANGID (WINAPI *MyGetUserDefaultUILanguage)() = NULL;
+LANGID (WINAPI *MyGetSystemDefaultUILanguage)() = NULL;
+
+static int ValidExtension(char *fileName, char *extension)
+{
+ char *dot = strrchr(fileName, '.');
+ if ((dot != NULL) && (lstrcmpiA(dot + 1, extension) == 0))
+ {
+ if (dot[strlen(extension) + 1] == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+int EnumSettings(const char *setting, LPARAM lParam)
+{
+ char *name = (char *) lParam;
+ char *tmp = _strdup(setting);
+ _strlwr(tmp);
+
+ int res = 0;
+
+ if (strcmp(tmp, name) == 0)
+ {
+ strcpy((char *) lParam, setting);
+ res = 1;
+ }
+
+ free(tmp);
+
+ return res;
+}
+
+int IsPluginDisabled(char *fileName)
+{
+ char *name = _strdup(fileName);
+ _strlwr(name);
+ DBCONTACTENUMSETTINGS dbEnum = {0};
+ dbEnum.pfnEnumProc = EnumSettings;
+ dbEnum.lParam = (LPARAM) name;
+ dbEnum.szModule = "PluginDisable";
+
+ int res = -1;
+
+ CallService(MS_DB_CONTACT_ENUMSETTINGS, NULL, (LPARAM) &dbEnum);
+ DBVARIANT dbv = {0};
+ dbv.type = DBVT_BYTE;
+
+ int exists = !(DBGetContactSetting(NULL, "PluginDisable", name, &dbv));
+ if (exists)
+ {
+ res = dbv.bVal;
+ }
+ free(name);
+
+ return res;
+}
+*/
+
+void FillLocalTime(std::string &output, FILETIME *fileTime)
+{
+ TIME_ZONE_INFORMATION tzInfo = {0};
+ FILETIME local = {0};
+ SYSTEMTIME sysTime;
+ char date[1024];
+ char time[256];
+
+ FileTimeToLocalFileTime(fileTime, &local);
+ FileTimeToSystemTime(&local, &sysTime);
+
+ GetDateFormat(EnglishLocale, 0, &sysTime, "dd' 'MMM' 'yyyy", date, sizeof(date));
+ GetTimeFormat(NULL, TIME_FORCE24HOURFORMAT, &sysTime, "HH':'mm':'ss", time, sizeof(time)); //americans love 24hour format ;)
+ output = std::string(date) + " at " + std::string(time);
+
+ int res = GetTimeZoneInformation(&tzInfo);
+ char tzName[32] = {0};
+ char tzOffset[64] = {0};
+ int offset = 0;
+ switch (res)
+ {
+ case TIME_ZONE_ID_DAYLIGHT:
+ {
+ offset = -(tzInfo.Bias + tzInfo.DaylightBias);
+ WideCharToMultiByte(CP_ACP, 0, tzInfo.DaylightName, -1, tzName, sizeof(tzName), NULL, NULL);
+
+ break;
+ }
+
+ case TIME_ZONE_ID_STANDARD:
+ {
+ WideCharToMultiByte(CP_ACP, 0, tzInfo.StandardName, -1, tzName, sizeof(tzName), NULL, NULL);
+ offset = -(tzInfo.Bias + tzInfo.StandardBias);
+
+ break;
+ }
+
+ case TIME_ZONE_ID_UNKNOWN:
+ {
+ WideCharToMultiByte(CP_ACP, 0, tzInfo.StandardName, -1, tzName, sizeof(tzName), NULL, NULL);
+ offset = -tzInfo.Bias;
+
+ break;
+ }
+ }
+
+ sprintf(tzOffset, "UTC %+02d:%02d", offset / 60, offset % 60);
+ output += " (" /*+ std::string(tzName) + ", " */ + std::string(tzOffset) + ")";
+}
+
+CVersionInfo::CVersionInfo() {
+ luiFreeDiskSpace = 0;
+ bDEPEnabled = 0;
+};
+
+CVersionInfo::~CVersionInfo() {
+
+ listInactivePlugins.clear();
+ listActivePlugins.clear();
+ listUnloadablePlugins.clear();
+
+ lpzMirandaVersion.~basic_string();
+ lpzNightly.~basic_string();
+ lpzUnicodeBuild.~basic_string();
+ lpzBuildTime.~basic_string();
+ lpzOSVersion.~basic_string();
+ lpzMirandaPath.~basic_string();
+ lpzCPUName.~basic_string();
+ lpzCPUIdentifier.~basic_string();
+};
+
+void CVersionInfo::Initialize() {
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetMirandaVersion().", SM_NOTIFY);
+#endif
+ GetMirandaVersion();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetProfileSettings().", SM_NOTIFY);
+#endif
+ GetProfileSettings();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetLangpackInfo().", SM_NOTIFY);
+#endif
+ GetOSLanguages();
+ GetLangpackInfo();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetPluginLists().", SM_NOTIFY);
+#endif
+ GetPluginLists();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetOSVersion().", SM_NOTIFY);
+#endif
+ GetOSVersion();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Before GetHWSettings().", SM_NOTIFY);
+#endif
+ GetHWSettings();
+
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("Done with GetHWSettings().", SM_NOTIFY);
+#endif
+}
+
+bool CVersionInfo::GetMirandaVersion() {
+ const BYTE str_size = 64;
+ char str[str_size];
+ //Miranda version
+
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)str_size, (LPARAM)(char*)str);
+ this->lpzMirandaVersion = std::string(str);
+ //Is it a nightly?
+ if (lpzMirandaVersion.find("alpha",0) != std::string::npos)
+ lpzNightly = "Yes";
+ else
+ lpzNightly = "No";
+ if (lpzMirandaVersion.find("Unicode", 0) != std::string::npos)
+ {
+ lpzUnicodeBuild = "Yes";
+ }
+ else{
+ lpzUnicodeBuild = "No";
+ }
+ char time[128], date[128];
+ GetModuleTimeStamp(date, time);
+ lpzBuildTime = std::string(time) + " on " + std::string(date);
+ return TRUE;
+}
+
+bool CVersionInfo::GetOSVersion() {
+ //Operating system informations
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx(&osvi);
+ //Now fill the private members.
+ char aux[256];
+ wsprintf(aux, "%d.%d.%d %s", osvi.dwMajorVersion, osvi.dwMinorVersion, LOWORD(osvi.dwBuildNumber), osvi.szCSDVersion);
+ lpzOSVersion = std::string(aux);
+ //OSName
+ //Let's read the registry.
+ HKEY hKey;
+ char szKey[MAX_PATH], szValue[MAX_PATH];
+
+
+ lstrcpyn(szKey, "Hardware\\Description\\System\\CentralProcessor\\0", MAX_PATH);
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ DWORD type, size, result;
+
+ lstrcpyn(szValue, "Identifier", MAX_PATH);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, NULL, &size);
+ if (result == ERROR_SUCCESS)
+ {
+ char *aux = (char *) malloc(size);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, (LPBYTE) aux, &size);
+ lpzCPUIdentifier = std::string(aux);
+ free(aux);
+ }
+ else{
+ NotifyError(GetLastError(), "RegQueryValueEx()", __LINE__);
+ lpzCPUIdentifier = "<Error in RegQueryValueEx()>";
+ }
+ lstrcpyn(szValue, "ProcessorNameString", MAX_PATH);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, NULL, &size); //get the size
+ if (result == ERROR_SUCCESS)
+ {
+// MessageBox(0, "ProcessorNameString available in the registry", "Info", 0);
+ char *aux = (char *) malloc(size);
+ result = RegQueryValueEx(hKey, szValue, 0, &type, (LPBYTE) aux, &size);
+ lpzCPUName = std::string(aux);
+ free(aux);
+ }
+ else{ //else try to use cpuid instruction to get the proc name
+ char szName[49] = "<cpuid extension N/A>";
+ #if (!defined(WIN64) && !defined(_WIN64))
+ __asm
+ {
+ push eax //save the registers
+ push ebx
+ push ecx
+ push edx
+
+ xor eax, eax //get simple name
+ cpuid
+ mov DWORD PTR szName[0], ebx
+ mov DWORD PTR szName[4], edx
+ mov DWORD PTR szName[8], ecx
+ mov DWORD PTR szName[12], 0
+
+ mov eax, 0x80000000 //try to get pretty name
+ cpuid
+
+ cmp eax, 0x80000004
+ jb end //if we don't have the extension end the check
+
+ mov DWORD PTR szName[0], 0 //make the string null
+
+ mov eax, 0x80000002 //first part of the string
+ cpuid
+ mov DWORD PTR szName[0], eax
+ mov DWORD PTR szName[4], ebx
+ mov DWORD PTR szName[8], ecx
+ mov DWORD PTR szName[12], edx
+
+ mov eax, 0x80000003 //second part of the string
+ cpuid
+ mov DWORD PTR szName[16], eax
+ mov DWORD PTR szName[20], ebx
+ mov DWORD PTR szName[24], ecx
+ mov DWORD PTR szName[28], edx
+
+ mov eax, 0x80000004 //third part of the string
+ cpuid
+ mov DWORD PTR szName[32], eax
+ mov DWORD PTR szName[36], ebx
+ mov DWORD PTR szName[40], ecx
+ mov DWORD PTR szName[44], edx
+
+ end:
+ pop edx //load them back
+ pop ecx
+ pop ebx
+ pop eax
+ }
+ szName[sizeof(szName) - 1] = '\0';
+ #endif
+ if (strlen(szName) == 0)
+ {
+ lpzCPUName = "<name N/A>";
+ }
+ else{
+ lpzCPUName = std::string(szName);
+ }
+ }
+ }
+
+ bDEPEnabled = IsProcessorFeaturePresent(PF_NX_ENABLED);
+ /*
+ if (!bDEPEnabled)
+ {
+ int x = 0;
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 0x80000001
+ cpuid
+ mov eax, 1
+ shl eax, 20
+ xor edx, eax
+ cmp edx, 0
+ je end_DEP
+ mov x, 1
+
+ end_DEP:
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+ bDEPEnabled = x;
+ }
+ */
+ switch (osvi.dwPlatformId) {
+ case VER_PLATFORM_WIN32_WINDOWS:
+ lstrcpyn(szKey, "Software\\Microsoft\\Windows\\CurrentVersion", MAX_PATH);
+ lstrcpyn(szValue, "Version", MAX_PATH);
+ break;
+ case VER_PLATFORM_WIN32_NT:
+
+ lstrcpyn(szKey, "Software\\Microsoft\\Windows NT\\CurrentVersion", MAX_PATH);
+ lstrcpyn(szValue, "ProductName", MAX_PATH);
+ break;
+ }
+
+ RegCloseKey(hKey);
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,szKey,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) {
+ DWORD type, size, result;
+ //Get the size of the value we'll read.
+ result = RegQueryValueEx((HKEY)hKey,szValue,(LPDWORD)NULL, (LPDWORD)&type,(LPBYTE)NULL,
+ (LPDWORD)&size);
+ if (result == ERROR_SUCCESS) {
+ //Read it.
+ char *aux = (char*)malloc(size);
+ result = RegQueryValueEx((HKEY)hKey,szValue,(LPDWORD)NULL, (LPDWORD)&type,(LPBYTE)aux,(LPDWORD)&size);
+ lpzOSName = std::string(aux);
+ free(aux);
+ }
+ else {
+ NotifyError(GetLastError(), "RegQueryValueEx()", __LINE__);
+ lpzOSName = "<Error in RegQueryValueEx()>";
+ }
+ }
+ else {
+ NotifyError(GetLastError(), "RegOpenKeyEx()", __LINE__);
+ lpzOSName = "<Error in RegOpenKeyEx()>";
+ }
+
+ //Now we can improve it if we can.
+ switch (LOWORD(osvi.dwBuildNumber)) {
+ case 950: lpzOSName = "Microsoft Windows 95"; break;
+ case 1111: lpzOSName = "Microsoft Windows 95 OSR2"; break;
+ case 1998: lpzOSName = "Microsoft Windows 98"; break;
+ case 2222: lpzOSName = "Microsoft Windows 98 SE"; break;
+ case 3000: lpzOSName = "Microsoft Windows ME"; break; //Even if this is wrong, we have already read it in the registry.
+ case 1381: lpzOSName = "Microsoft Windows NT"; break; //What about service packs?
+ case 2195: lpzOSName = "Microsoft Windows 2000"; break; //What about service packs?
+ case 2600: lpzOSName = "Microsoft Windows XP"; break;
+ case 3790:
+ {
+ if (GetSystemMetrics(89)) { //R2 ?
+ lpzOSName = "Microsoft Windows 2003 R2";
+ }
+ else{
+ lpzOSName = "Microsoft Windows 2003";
+ }
+
+ break; //added windows 2003 info
+ }
+ }
+
+ return TRUE;
+}
+
+bool CVersionInfo::GetHWSettings() {
+ //Free space on Miranda Partition.
+ char szMirandaPath[MAX_PATH] = { 0 };
+ { char *str2;
+ GetModuleFileName(GetModuleHandle(NULL),szMirandaPath,sizeof(szMirandaPath));
+ str2=strrchr(szMirandaPath,'\\');
+ if(str2!=NULL) *str2=0;
+ }
+ HMODULE hKernel32;
+ hKernel32 = LoadLibrary("kernel32.dll");
+ if (hKernel32) {
+ MyGetDiskFreeSpaceEx = (BOOL (WINAPI *)(LPCTSTR,PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER))GetProcAddress(hKernel32, "GetDiskFreeSpaceExA");
+ MyIsWow64Process = (BOOL (WINAPI *) (HANDLE, PBOOL)) GetProcAddress(hKernel32, "IsWow64Process");
+ MyGetSystemInfo = (void (WINAPI *) (LPSYSTEM_INFO)) GetProcAddress(hKernel32, "GetNativeSystemInfo");
+ MyGlobalMemoryStatusEx = (BOOL (WINAPI *) (LPMEMORYSTATUSEX)) GetProcAddress(hKernel32, "GlobalMemoryStatusEx");
+ if (!MyGetSystemInfo)
+ {
+ MyGetSystemInfo = GetSystemInfo;
+ }
+
+ FreeLibrary(hKernel32);
+ }
+ if (MyGetDiskFreeSpaceEx) {
+ ULARGE_INTEGER FreeBytes, a, b;
+ MyGetDiskFreeSpaceEx(szMirandaPath, &FreeBytes, &a, &b);
+ //Now we need to convert it.
+ __int64 aux = FreeBytes.QuadPart;
+ aux /= (1024*1024);
+ luiFreeDiskSpace = (unsigned long int)aux;
+ }
+ else {
+ luiFreeDiskSpace = 0;
+ }
+
+ char szInfo[1024];
+ GetWindowsShell(szInfo, sizeof(szInfo));
+ lpzShell = szInfo;
+ GetInternetExplorerVersion(szInfo, sizeof(szInfo));
+ lpzIEVersion = szInfo;
+
+
+ lpzAdministratorPrivileges = (IsCurrentUserLocalAdministrator()) ? "Yes" : "No";
+
+ bIsWOW64 = 0;
+ if (MyIsWow64Process)
+ {
+ if (!MyIsWow64Process(GetCurrentProcess(), &bIsWOW64))
+ {
+ bIsWOW64 = 0;
+ }
+ }
+
+ SYSTEM_INFO sysInfo = {0};
+ GetSystemInfo(&sysInfo);
+ luiProcessors = sysInfo.dwNumberOfProcessors;
+
+ //Installed RAM
+ if (MyGlobalMemoryStatusEx) //windows 2000+
+ {
+ MEMORYSTATUSEX ms = {0};
+ ms.dwLength = sizeof(ms);
+ MyGlobalMemoryStatusEx(&ms);
+ luiRAM = (unsigned int) ((ms.ullTotalPhys / (1024 * 1024)) + 1);
+ }
+ else{
+ MEMORYSTATUS ms = {0};
+ ZeroMemory(&ms, sizeof(ms));
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatus(&ms);
+ luiRAM = (ms.dwTotalPhys/(1024*1024))+1; //Ugly hack!!!!
+ }
+
+ return TRUE;
+}
+
+bool CVersionInfo::GetProfileSettings()
+{
+ char profileName[MAX_PATH] = {0};
+ char profilePath[MAX_PATH] = {0};
+ ServiceExists(MS_DB_GETPROFILEPATH_BASIC) ? CallService(MS_DB_GETPROFILEPATH_BASIC, MAX_PATH, (LPARAM) profilePath) : CallService(MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM) profilePath); //get the profile path
+ CallService(MS_DB_GETPROFILENAME, MAX_PATH, (LPARAM) profileName); //get the profile name
+// strcat(profileName, ".dat"); //add the .dat extension to the profile name
+ lpzProfilePath = std::string(profilePath); //save the profile path
+
+ strcat(profilePath, "\\"); //add the last \\ to the path
+ strcat(profilePath, profileName); //now profilePath is drive:\path\profilename.dat
+ HANDLE fin = CreateFile(profilePath, FILE_READ_ATTRIBUTES | FILE_READ_EA | STANDARD_RIGHTS_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (fin == INVALID_HANDLE_VALUE) { fin = CreateFile(profilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); }
+ if (fin != INVALID_HANDLE_VALUE)
+ {
+ DWORD size;
+ FILETIME creation, modified, accessed;
+ size = GetFileSize(fin, NULL);
+ TCHAR number[1024];
+ char tmp[1024];
+ double fileSize = (double) size / 1024;
+
+ sprintf(tmp, "%f", fileSize);
+ GetNumberFormat(EnglishLocale, NULL, tmp, NULL, number, 1024);
+
+ lpzProfileSize = std::string(number) + " KBytes";
+ GetFileTime(fin, &creation, &accessed, &modified);
+ FillLocalTime(lpzProfileCreationDate, &creation);
+
+ CloseHandle(fin);
+ }
+ else{
+ DWORD error = GetLastError();
+ char tmp[1024];
+ sprintf(tmp, "%d", error);
+ lpzProfileCreationDate = "<error " + std::string(tmp) + " at FileOpen>" + std::string(profilePath);
+ lpzProfileSize = "<error " + std::string(tmp) + " at FileOpen>" + std::string(profilePath);
+ }
+
+ return true;
+}
+
+static char szSystemLocales[4096] = {0};
+static WORD systemLangID;
+#define US_LANG_ID 0x00000409
+
+BOOL CALLBACK EnumSystemLocalesProc(char *szLocale)
+{
+ DWORD locale = atoi(szLocale);
+ char *name = GetLanguageName(locale);
+ if (!strstr(szSystemLocales, name))
+ {
+ strcat(szSystemLocales, name);
+ strcat(szSystemLocales, ", ");
+ }
+
+ return TRUE;
+}
+
+BOOL CALLBACK EnumResLangProc(HMODULE hModule, LPCTSTR lpszType, LPCTSTR lpszName, WORD wIDLanguage, LONG_PTR lParam)
+{
+ if (!lpszName)
+ return FALSE;
+
+ if (wIDLanguage != US_LANG_ID)
+ systemLangID = wIDLanguage;
+
+ return TRUE;
+}
+
+bool CVersionInfo::GetOSLanguages()
+{
+ lpzOSLanguages = "(UI | Locale (User/System)) : ";
+
+ LANGID UILang;
+
+ OSVERSIONINFO os = {0};
+ os.dwOSVersionInfoSize = sizeof(os);
+ GetVersionEx(&os);
+ switch (os.dwMajorVersion)
+ {
+ case 4: //Win 95-Me, NT
+ {
+ if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) //Win NT
+ {
+ HMODULE hLib = LoadLibrary("ntdll.dll");
+
+ if (hLib)
+ {
+ EnumResourceLanguages(hLib, RT_VERSION, MAKEINTRESOURCE(1), EnumResLangProc, NULL);
+
+ FreeLibrary(hLib);
+
+ if (systemLangID == US_LANG_ID)
+ {
+ UINT uiACP;
+
+ uiACP = GetACP();
+ switch (uiACP)
+ {
+ case 874: // Thai code page activated, it's a Thai enabled system
+ systemLangID = MAKELANGID(LANG_THAI, SUBLANG_DEFAULT);
+ break;
+
+ case 1255: // Hebrew code page activated, it's a Hebrew enabled system
+ systemLangID = MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT);
+ break;
+
+ case 1256: // Arabic code page activated, it's a Arabic enabled system
+ systemLangID = MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_SAUDI_ARABIA);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ else{ //Win 95-Me
+ HKEY hKey = NULL;
+ char szLangID[128] = "0x";
+ DWORD size = sizeof(szLangID) - 2;
+ char err[512];
+
+ if (RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\Desktop\\ResourceLocale", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ if (RegQueryValueEx(hKey, "", 0, NULL, (LPBYTE) &szLangID + 2, &size) == ERROR_SUCCESS)
+ {
+ sscanf(szLangID, "%lx", &systemLangID);
+ }
+ else{
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), LANG_SYSTEM_DEFAULT, err, size, NULL);
+ MessageBox(0, err, "Error at RegQueryValueEx()", MB_OK);
+ }
+ RegCloseKey(hKey);
+ }
+ else{
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), LANG_SYSTEM_DEFAULT, err, size, NULL);
+ MessageBox(0, err, "Error at RegOpenKeyEx()", MB_OK);
+ }
+ }
+
+ lpzOSLanguages += GetLanguageName(systemLangID);
+
+ break;
+ }
+
+ case 5: //Win 2000, XP
+ default:
+ {
+ HMODULE hKernel32 = LoadLibrary("kernel32.dll");
+ if (hKernel32)
+ {
+ MyGetUserDefaultUILanguage = (LANGID (WINAPI *)()) GetProcAddress(hKernel32, "GetUserDefaultUILanguage");
+ MyGetSystemDefaultUILanguage = (LANGID (WINAPI *)()) GetProcAddress(hKernel32, "GetSystemDefaultUILanguage");
+
+ FreeLibrary(hKernel32);
+ }
+
+ if ((MyGetUserDefaultUILanguage) && (MyGetSystemDefaultUILanguage))
+ {
+ UILang = MyGetUserDefaultUILanguage();
+ lpzOSLanguages += GetLanguageName(UILang);
+ lpzOSLanguages += "/";
+ UILang = MyGetSystemDefaultUILanguage();
+ lpzOSLanguages += GetLanguageName(UILang);
+ }
+ else{
+ lpzOSLanguages += "Missing functions in kernel32.dll (GetUserDefaultUILanguage, GetSystemDefaultUILanguage)";
+ }
+
+ break;
+ }
+ }
+
+ lpzOSLanguages += " | ";
+ lpzOSLanguages += GetLanguageName(LOCALE_USER_DEFAULT);
+ lpzOSLanguages += "/";
+ lpzOSLanguages += GetLanguageName(LOCALE_SYSTEM_DEFAULT);
+
+ if (DBGetContactSettingByte(NULL, ModuleName, "ShowInstalledLanguages", 0))
+ {
+ szSystemLocales[0] = '\0';
+ lpzOSLanguages += " [";
+ EnumSystemLocales(EnumSystemLocalesProc, LCID_INSTALLED);
+ if (strlen(szSystemLocales) > 2)
+ {
+ szSystemLocales[strlen(szSystemLocales) - 2] = '\0';
+ }
+ lpzOSLanguages += szSystemLocales;
+ lpzOSLanguages += "]";
+ }
+
+ return true;
+}
+
+int SaveInfo(const char *data, const char *lwrData, const char *search, char *dest, int size)
+{
+ const char *pos = strstr(lwrData, search);
+ int res = 1;
+ if (pos == lwrData)
+ {
+ strncpy(dest, &data[strlen(search)], size);
+ res = 0;
+ }
+
+ return res;
+}
+
+bool CVersionInfo::GetLangpackInfo()
+{
+ char langpackPath[MAX_PATH] = {0};
+ char search[MAX_PATH] = {0};
+ char *p;
+ lpzLangpackModifiedDate = "";
+ GetModuleFileName(GetModuleHandle(NULL), langpackPath, sizeof(langpackPath));
+ p = strrchr(langpackPath, '\\');
+ if (p)
+ {
+ WIN32_FIND_DATA data = {0};
+ HANDLE hLangpack;
+
+ p[1] = '\0';
+ strcpy(search, langpackPath);
+ strcat(search, "langpack_*.txt");
+ hLangpack = FindFirstFile(search, &data);
+ if (hLangpack != INVALID_HANDLE_VALUE)
+ {
+ char buffer[1024];
+ char temp[1024];
+ //FILETIME localWriteTime;
+ //SYSTEMTIME sysTime;
+ FillLocalTime(lpzLangpackModifiedDate, &data.ftLastWriteTime);
+
+ char locale[128] = {0};
+ char language[128] = {0};
+ char version[128] = {0};
+ strcpy(version, "N/A");
+ char *p;
+ strncpy(temp, data.cFileName, sizeof(temp));
+ p = strrchr(temp, '.');
+ p[0] = '\0';
+ strncpy(language, strchr(temp, '_') + 1, sizeof(language));
+
+ strcat(langpackPath, data.cFileName);
+ FILE *fin = fopen(langpackPath, "rt");
+
+ if (fin)
+ {
+ size_t len;
+ while (!feof(fin))
+ {
+ fgets(buffer, sizeof(buffer), fin);
+ len = strlen(buffer);
+ if (buffer[len - 1] == '\n') buffer[len - 1] = '\0';
+ strncpy(temp, buffer, sizeof(temp));
+ _strlwr(temp);
+ if (SaveInfo(buffer, temp, "language: ", language, sizeof(language)))
+ {
+ if (SaveInfo(buffer, temp, "locale: ", locale, sizeof(locale)))
+ {
+ p = strstr(buffer, "; FLID: ");
+ if (p)
+ {
+ int ok = 1;
+ int i;
+ for (i = 0; ((i < 3) && (ok)); i++)
+ {
+ p = strrchr(temp, '.');
+ if (p)
+ {
+ p[0] = '\0';
+ }
+ else{
+ ok = 0;
+ }
+ }
+ p = strrchr(temp, ' ');
+ if ((ok) && (p))
+ {
+ strncpy(version, &buffer[p - temp + 1], sizeof(version));
+ }
+ else{
+ strncpy(version, "<unknown>", sizeof(version));
+ }
+ }
+ }
+ }
+ }
+
+ lpzLangpackInfo = std::string(language) + " [" + std::string(locale) + "]";
+ if (strlen(version) > 0)
+ {
+ lpzLangpackInfo += " v. " + std::string(version);
+ }
+ fclose(fin);
+ }
+ else{
+ int err = GetLastError();
+ lpzLangpackInfo = "<error> Could not open file " + std::string(data.cFileName);
+ }
+ FindClose(hLangpack);
+ }
+ else{
+ lpzLangpackInfo = "No language pack installed";
+ }
+ }
+
+ return true;
+}
+
+std::string GetPluginTimestamp(FILETIME *fileTime)
+{
+ SYSTEMTIME sysTime;
+ FileTimeToSystemTime(fileTime, &sysTime); //convert the file tyme to system time
+ //char time[256];
+ char date[256]; //lovely
+ GetDateFormat(EnglishLocale, 0, &sysTime, "dd' 'MMM' 'yyyy", date, sizeof(date));
+ //GetTimeFormat(NULL, TIME_FORCE24HOURFORMAT, &sysTime, "HH':'mm':'ss", time, sizeof(time)); //americans love 24hour format :)
+ std::string timedate(date);
+ return timedate;
+}
+
+bool CVersionInfo::GetPluginLists() {
+
+ HANDLE hFind;
+ char szMirandaPath[MAX_PATH] = { 0 }, szSearchPath[MAX_PATH] = { 0 }; //For search purpose
+ WIN32_FIND_DATA fd;
+ char szMirandaPluginsPath[MAX_PATH] = { 0 }, szPluginPath[MAX_PATH] = { 0 }; //For info reading purpose
+ BYTE PluginIsEnabled = 0;
+ HINSTANCE hInstPlugin = NULL;
+ PLUGININFOEX *(*MirandaPluginInfo)(DWORD); //These two are used to get informations from the plugin.
+ PLUGININFOEX *pluginInfo = NULL; //Read above.
+ DWORD mirandaVersion = 0;
+ BOOL asmCheckOK = FALSE;
+ DWORD loadError;
+// SYSTEMTIME sysTime; //for timestamp
+
+ mirandaVersion=(DWORD)CallService(MS_SYSTEM_GETVERSION,0,0);
+
+ { char *str2;
+ GetModuleFileName(GetModuleHandle(NULL),szMirandaPath,sizeof(szMirandaPath));
+ str2=strrchr(szMirandaPath,'\\');
+ if(str2!=NULL) *str2=0;
+ }
+ lpzMirandaPath = std::string(szMirandaPath);
+ //We got Miranda path, now we'll use it for two different purposes.
+ //1) finding plugins.
+ //2) Reading plugin infos
+ lstrcpyn(szSearchPath,szMirandaPath, MAX_PATH); //We got the path, now we copy it into szSearchPath. We'll use szSearchPath as am auxiliary variable, while szMirandaPath will keep a "fixed" value.
+ lstrcat(szSearchPath,"\\Plugins\\*.dll");
+
+ lstrcpyn(szMirandaPluginsPath, szMirandaPath, MAX_PATH);
+ lstrcat(szMirandaPluginsPath,"\\Plugins\\");
+
+ hFind=FindFirstFile(szSearchPath,&fd);
+ LogToFile("Starting to load plugins");
+ if(hFind != INVALID_HANDLE_VALUE) {
+ do {
+ if (verbose) PUShowMessage(fd.cFileName, SM_NOTIFY);
+ if (!ValidExtension(fd.cFileName, "dll"))
+ {
+ continue; //do not report plugins that do not have extension .dll
+ }
+
+ hInstPlugin = GetModuleHandle(fd.cFileName); //try to get the handle of the module
+
+ if (hInstPlugin) //if we got it then the dll is loaded (enabled)
+ {
+ PluginIsEnabled = 1;
+ LogToFile("Plugin '%s' is enabled and loaded", fd.cFileName);
+ }
+ else{
+ PluginIsEnabled = 0;
+ LogToFile("Plugin '%s' is not loaded, going to load it", fd.cFileName);
+ lstrcpyn(szPluginPath, szMirandaPluginsPath, MAX_PATH); // szPluginPath becomes "drive:\path\Miranda\Plugins\"
+ lstrcat(szPluginPath, fd.cFileName); // szPluginPath becomes "drive:\path\Miranda\Plugins\popup.dll"
+ hInstPlugin = LoadLibrary(szPluginPath);
+/*
+ PluginIsEnabled = !(
+ DBGetContactSettingByte(NULL, "PluginDisable", fd.cFileName, FALSE)
+ || DBGetContactSettingByte(NULL, "PluginDisable", CharUpper(fd.cFileName), FALSE)
+ || DBGetContactSettingByte(NULL, "PluginDisable", CharLower(fd.cFileName), FALSE)
+
+ }; //If the DB does not contain that value, the plugin is enabled => default: FALSE; action: !read
+*/
+ //Let's read the informations.
+/*
+ }
+ if (PluginIsEnabled) {
+ hInstPlugin = GetModuleHandle(fd.cFileName);
+ }
+ else{
+ lstrcpyn(szPluginPath, szMirandaPluginsPath, MAX_PATH); // szPluginPath becomes "drive:\path\Miranda\Plugins\"
+ lstrcat(szPluginPath, fd.cFileName); // szPluginPath becomes "drive:\path\Miranda\Plugins\popup.dll"
+ hInstPlugin = LoadLibrary(szPluginPath);
+ }
+*/
+ }
+ if (!hInstPlugin) { //It wasn't loaded.
+ loadError = GetLastError();
+ int bUnknownError = 1; //assume plugin didn't load because of unknown error
+ //Some error messages.
+ //get the dlls the plugin statically links to
+ if (DBGetContactSettingByte(NULL, ModuleName, "CheckForDependencies", TRUE))
+ {
+ std::string linkedModules = "";
+
+ lstrcpyn(szPluginPath, szMirandaPluginsPath, MAX_PATH); // szPluginPath becomes "drive:\path\Miranda\Plugins\"
+ lstrcat(szPluginPath, fd.cFileName); // szPluginPath becomes "drive:\path\Miranda\Plugins\popup.dll"
+ if (GetLinkedModulesInfo(szPluginPath, linkedModules))
+ {
+ LogToFile("Plugin %s has unresolved dependencies, adding to unloadable list", szPluginPath);
+ std::string time = GetPluginTimestamp(&fd.ftLastWriteTime);
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName), "<unknown>", UUID_NULL, "", 0, time, linkedModules);
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ bUnknownError = 0; //we know why the plugin didn't load
+ }
+ }
+ if (bUnknownError) //if cause is unknown then report it
+ {
+ LogToFile("Plugin %s doesn't load", szPluginPath);
+ std::string time = GetPluginTimestamp(&fd.ftLastWriteTime);
+ char buffer[4096];
+ char error[2048];
+ //DWORD_PTR arguments[2] = {loadError, 0};
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, loadError, 0, error, sizeof(error), NULL);
+ sprintf(buffer, " Error %ld - %s", loadError, error);
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName), "<unknown>", UUID_NULL, "", 0, time, buffer);
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ }
+ }
+ else { //It was successfully loaded.
+ LogToFile("Plugin '%s' was loaded successfully", fd.cFileName);
+ MirandaPluginInfo = (PLUGININFOEX *(*)(DWORD))GetProcAddress(hInstPlugin, "MirandaPluginInfoEx");
+ if (!MirandaPluginInfo)
+ {
+ MirandaPluginInfo = (PLUGININFOEX *(*)(DWORD))GetProcAddress(hInstPlugin, "MirandaPluginInfo");
+ }
+ if (!MirandaPluginInfo) { //There is no function: it's not a valid plugin. Let's move on to the next file.
+ continue;
+ }
+ else {
+ //It's a valid plugin, since we could find MirandaPluginInfo
+ #if (!defined(WIN64) && !defined(_WIN64))
+ asmCheckOK = FALSE;
+ __asm {
+ push mirandaVersion
+ push mirandaVersion
+ call MirandaPluginInfo
+ pop eax
+ pop eax
+ cmp eax, mirandaVersion
+ jne a1
+ mov asmCheckOK, 0xffffffff
+ // jmp a2
+ a1:
+ // a2:
+ }
+ #else
+ asmCheckOK = TRUE;
+ #endif
+ if (asmCheckOK)
+ pluginInfo = CopyPluginInfo(MirandaPluginInfo(mirandaVersion));
+ else {
+ ZeroMemory(&pluginInfo, sizeof(pluginInfo));
+ MessageBox(NULL, fd.cFileName, "Invalid plugin", MB_OK);
+ }
+ }
+ }
+ //Let's get the info.
+ if (MirandaPluginInfo != NULL) {//a valid miranda plugin
+ if (pluginInfo != NULL) {
+ LogToFile("Plugin '%s' is a miranda plugin", fd.cFileName);
+ //We have loaded the informations into pluginInfo.
+ std::string timedate = GetPluginTimestamp(&fd.ftLastWriteTime);
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName),std::string(pluginInfo->shortName), pluginInfo->uuid, std::string((pluginInfo->flags & 1) ? "Unicode aware" : ""), (DWORD) pluginInfo->version, timedate, "");
+
+ if (PluginIsEnabled)
+ {
+ AddPlugin(thePlugin, listActivePlugins);
+ }
+ else {
+ if ((IsUUIDNull(pluginInfo->uuid)) && (mirandaVersion >= PLUGIN_MAKE_VERSION(0,8,0,9)))
+ {
+ thePlugin.SetErrorMessage(" Plugin does not have an UUID and will not work with Miranda 0.8.\r\n");
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ }
+ else{
+ AddPlugin(thePlugin, listInactivePlugins);
+ }
+ FreeLibrary(hInstPlugin); //We don't need it anymore.
+ }
+ FreePluginInfo(pluginInfo);
+ MirandaPluginInfo = NULL;
+#ifdef _DEBUG
+ if (verbose)
+ {
+ char szMsg[4096] = { 0 };
+ wsprintf(szMsg, "Done with: %s", fd.cFileName);
+ PUShowMessage(szMsg, SM_NOTIFY);
+ }
+#endif
+ }
+ else{//pluginINFO == NULL
+ LogToFile("Plugin '%s' refuses to load", fd.cFileName);
+ pluginInfo = CopyPluginInfo(MirandaPluginInfo(PLUGIN_MAKE_VERSION(9, 9, 9, 9))); //let's see if the plugin likes this miranda version
+ char *szShortName = "<unknown>";
+ std::string time = GetPluginTimestamp(&fd.ftLastWriteTime); //get the plugin timestamp;
+ DWORD version = 0;
+ if (pluginInfo)
+ {
+ szShortName = pluginInfo->shortName;
+ version = pluginInfo->version;
+ }
+
+ CPlugin thePlugin = CPlugin(std::string(fd.cFileName), std::string(szShortName), (pluginInfo) ? (pluginInfo->uuid) : UUID_NULL, std::string(((pluginInfo) && (pluginInfo->flags & 1)) ? "Unicode aware" : ""), version, time, " Plugin refuses to load. Miranda version too old.");
+
+ AddPlugin(thePlugin, listUnloadablePlugins);
+ if (pluginInfo)
+ {
+ FreePluginInfo(pluginInfo);
+ }
+ }
+ }
+ } while (FindNextFile(hFind,&fd));
+ FindClose(hFind);
+ }
+ LogToFile("Done loading plugins");
+ return TRUE;
+}
+
+bool CVersionInfo::AddPlugin(CPlugin &aPlugin, std::list<CPlugin> &aList) {
+ std::list<CPlugin>::iterator pos = aList.begin();
+ bool inserted = FALSE;
+
+ if (aList.begin() == aList.end()) { //It's empty
+ aList.push_back(aPlugin);
+ return TRUE;
+ }
+ else { //It's not empty
+ while (pos != aList.end()) {
+ //It can be either < or >, not equal.
+ if (aPlugin < (*pos)) {
+ aList.insert(pos, aPlugin);
+ return TRUE;
+ }
+ else { //It's greater: we need to insert it.
+ pos++;
+ }
+ }
+ }
+ if (inserted == FALSE) {
+ aList.push_back(aPlugin);
+ return TRUE;
+ }
+ return TRUE;
+};
+
+static char *GetStringFromRVA(DWORD RVA, const LOADED_IMAGE *image)
+{
+ char *moduleName;
+ moduleName = (char *) ImageRvaToVa(image->FileHeader, image->MappedAddress, RVA, NULL);
+ return moduleName;
+}
+
+bool CVersionInfo::GetLinkedModulesInfo(char *moduleName, std::string &linkedModules)
+{
+ LogToFile("Checking dll %s for unresolved dll dependencies ...", moduleName);
+ LOADED_IMAGE image;
+ ULONG importTableSize;
+ IMAGE_IMPORT_DESCRIPTOR *importData;
+ //HMODULE dllModule;
+ linkedModules = "";
+ bool result = false;
+// LogToFile(" Before LoadLibraryEx", moduleName);
+// dllModule = LoadLibraryEx(moduleName, NULL, DONT_RESOLVE_DLL_REFERENCES);
+ //dllModule = 0;
+ //LogToFile(" Before MapAndLoad (dll handle %ld)", moduleName, dllModule);
+ if (MapAndLoad(moduleName, NULL, &image, TRUE, TRUE) == FALSE)
+ {
+ char tmp[20];
+ sprintf(tmp, "%d", GetLastError());
+ LogToFile(" MapAndLoad failed with error %s", tmp);
+ linkedModules = "<error " + std::string(tmp) + " at MapAndLoad()>\r\n";
+// FreeLibrary(dllModule);
+ return result;
+ }
+ LogToFile(" Before ImageDirectoryEntryToData (base address %ld)", image.MappedAddress);
+ importData = (IMAGE_IMPORT_DESCRIPTOR *) ImageDirectoryEntryToData(image.MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &importTableSize);
+ if (!importData)
+ {
+ char tmp[20];
+ sprintf(tmp, "%d", GetLastError());
+ LogToFile(" ImageDirectoryEntryToData failed with error %s", tmp);
+ linkedModules = "<error " + std::string(tmp) + " at ImageDirectoryEntryToDataEx()>\r\n";
+ }
+ else{
+ LogToFile(" Checking dll dependencies");
+ while (importData->Name)
+ {
+ char *moduleName;
+ moduleName = GetStringFromRVA(importData->Name, &image);
+ LogToFile(" Checking link to dll %s", moduleName);
+ if (!DoesDllExist(moduleName))
+ {
+ LogToFile(" Dll %s not found, adding to list", moduleName);
+ linkedModules.append(" Plugin statically links to missing dll file: " + std::string(moduleName) + "\r\n");
+ result = true;
+ }
+ else{
+ LogToFile(" Dll %s found", moduleName);
+ }
+ LogToFile(" Moving to next import entry");
+ importData++; //go to next record
+ }
+ }
+ LogToFile(" Done checking dependencies");
+ LogToFile(" Cleaning up; before {FreeLibrary()} and UnMapAndLoad");
+// FreeLibrary(dllModule);
+ UnMapAndLoad(&image); //unload the image
+ return result;
+}
+
+std::string CVersionInfo::GetListAsString(std::list<CPlugin> &aList, DWORD flags, int beautify) {
+ std::list<CPlugin>::iterator pos = aList.begin();
+ std::string out = "";
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("CVersionInfo::GetListAsString, begin.", SM_NOTIFY);
+#endif
+
+ char szHeader[32] = {0};
+ char szFooter[32] = {0};
+ if ((((flags & VISF_FORUMSTYLE) == VISF_FORUMSTYLE) || beautify) && (DBGetContactSettingByte(NULL, ModuleName, "BoldVersionNumber", TRUE)))
+ {
+ GetStringFromDatabase("BoldBegin", "[b]", szHeader, sizeof(szHeader));
+ GetStringFromDatabase("BoldEnd", "[/b]", szFooter, sizeof(szFooter));
+ }
+
+ while (pos != aList.end()) {
+ out.append(std::string((*pos).getInformations(flags, szHeader, szFooter)));
+ pos++;
+ }
+#ifdef _DEBUG
+ if (verbose) PUShowMessage("CVersionInfo::GetListAsString, end.", SM_NOTIFY);
+#endif
+ return out;
+};
+
+void CVersionInfo::BeautifyReport(int beautify, char *szBeautifyText, char *szNonBeautifyText, std::string &out)
+{
+ if (beautify)
+ {
+ out.append(szBeautifyText);
+ }
+ else{
+ out.append(szNonBeautifyText);
+ }
+}
+
+void CVersionInfo::AddInfoHeader(int suppressHeader, int forumStyle, int beautify, std::string &out)
+{
+ if (forumStyle) //forum style
+ {
+ char szSize[256];
+ char szQuote[256];
+
+ GetStringFromDatabase("SizeBegin", "[size=1]", szSize, sizeof(szSize));
+ GetStringFromDatabase("QuoteBegin", "[quote]", szQuote, sizeof(szQuote));
+ out.append(szQuote);
+ out.append(szSize);
+ }
+ else{
+ out = "";
+ }
+ if (!suppressHeader)
+ {
+ out.append("Miranda IM - VersionInformation plugin by Hrk, modified by Eblis\r\n");
+ if (!forumStyle)
+ {
+ out.append("Miranda's homepage: http://www.miranda-im.org/\r\n"); //changed homepage
+ out.append("Miranda tools: http://miranda-im.org/download/\r\n\r\n"); //was missing a / before download
+ }
+ }
+ char buffer[1024]; //for beautification
+ GetStringFromDatabase("BeautifyHorizLine", "<hr />", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, "", out);
+ GetStringFromDatabase("BeautifyBlockStart", "<blockquote>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, "", out);
+ if (!suppressHeader)
+ {
+ //Time of report:
+ char lpzTime[12]; GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm':'ss",lpzTime, sizeof(lpzTime));
+ char lpzDate[32]; GetDateFormat(EnglishLocale, 0, NULL,"dd' 'MMMM' 'yyyy",lpzDate, sizeof(lpzDate));
+ out.append("Report generated at: " + std::string(lpzTime) + " on " + std::string(lpzDate) + "\r\n\r\n");
+ }
+ //Operating system
+ out.append("CPU: " + lpzCPUName + " [" + lpzCPUIdentifier + "]");
+ if (bDEPEnabled)
+ {
+ out.append(" [DEP enabled]");
+ }
+ if (luiProcessors > 1)
+ {
+ char noProcs[128];
+ sprintf(noProcs, " [%d CPUs]", luiProcessors);
+ out.append(noProcs);
+ }
+ out.append("\r\n");
+
+ //RAM
+ char szRAM[64]; wsprintf(szRAM, "%d", luiRAM);
+ out.append("Installed RAM: " + std::string(szRAM) + " MBytes\r\n");
+
+ //operating system
+ out.append("Operating System: " + lpzOSName + " [version: " + lpzOSVersion + "]\r\n");
+
+ //shell, IE, administrator
+ out.append("Shell: " + lpzShell + ", Internet Explorer " + lpzIEVersion + "\r\n");
+ out.append("Administrator privileges: " + lpzAdministratorPrivileges + "\r\n");
+
+ //languages
+ out.append("OS Languages: " + lpzOSLanguages + "\r\n");
+
+
+ //FreeDiskSpace
+ if (luiFreeDiskSpace) {
+ char szDiskSpace[64]; wsprintf(szDiskSpace, "%d", luiFreeDiskSpace);
+ out.append("Free disk space on Miranda partition: " + std::string(szDiskSpace) + " MBytes\r\n");
+ }
+
+ //Miranda
+ out.append("Miranda path: " + lpzMirandaPath + "\r\n");
+
+ out.append("Miranda IM version: " + lpzMirandaVersion);
+ if (bIsWOW64)
+ {
+ out.append(" [running inside WOW64]");
+ }
+ if (bServiceMode)
+ {
+ out.append(" [service mode]");
+ }
+ out.append("\r\nBuild time: " + lpzBuildTime + "\r\n");
+ out.append("Profile path: " + lpzProfilePath + "\r\n");
+ //if (lpzProfileSize.find("error", 0) == std::string::npos) //only show the profile size of no error occured
+ //{
+ out.append("Profile size: " + lpzProfileSize + "\r\n");
+ out.append("Profile creation date: " + lpzProfileCreationDate + "\r\n");
+ //}
+ out.append("Language pack: " + lpzLangpackInfo);
+ out.append((lpzLangpackModifiedDate.size() > 0) ? ", modified: " + lpzLangpackModifiedDate : "");
+ out.append("\r\n");
+
+ out.append("Nightly: " + lpzNightly + "\r\n");
+ out.append("Unicode core: " + lpzUnicodeBuild);
+
+ GetStringFromDatabase("BeautifyBlockEnd", "</blockquote>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, "\r\n", out);
+ //out.append("\r\n");
+}
+
+void CVersionInfo::AddInfoFooter(int suppressFooter, int forumStyle, int beautify, std::string &out)
+{
+ //End of report
+ char buffer[1024]; //for beautification purposes
+ GetStringFromDatabase("BeautifyHorizLine", "<hr />", buffer, sizeof(buffer));
+ if (!suppressFooter)
+ {
+ BeautifyReport(beautify, buffer, "\r\n", out);
+ out.append("\r\nEnd of report.\r\n");
+ }
+ if (!forumStyle)
+ {
+ if (!suppressFooter)
+ {
+ out.append(Translate("If you are going to use this report to submit a bug, remember to check the website for questions or help the developers may need.\r\nIf you don't check your bug report and give feedback, it will not be fixed!"));
+ }
+ }
+ else{
+ char szSize[256];
+ char szQuote[256];
+
+ GetStringFromDatabase("SizeEnd", "[/size]", szSize, sizeof(szSize));
+ GetStringFromDatabase("QuoteEnd", "[/quote]", szQuote, sizeof(szQuote));
+ out.append(szSize);
+ out.append(szQuote);
+ }
+}
+
+static void AddSectionAndCount(std::list<CPlugin> list, char *listText, std::string &out)
+{
+ char tmp[64];
+ sprintf(tmp, " (%u)", list.size());
+ out.append(listText);
+ out.append(tmp);
+ out.append(":");
+}
+
+std::string CVersionInfo::GetInformationsAsString(int bDisableForumStyle) {
+ //Begin of report
+ std::string out;
+ int forumStyle = (bDisableForumStyle) ? 0 : DBGetContactSettingByte(NULL, ModuleName, "ForumStyle", TRUE);
+ int showUUID = DBGetContactSettingByte(NULL, ModuleName, "ShowUUIDs", FALSE);
+ int beautify = DBGetContactSettingByte(NULL, ModuleName, "Beautify", 0) & (!forumStyle);
+ int suppressHeader = DBGetContactSettingByte(NULL, ModuleName, "SuppressHeader", TRUE);
+
+ DWORD flags = (forumStyle) | (showUUID << 1);
+
+ AddInfoHeader(suppressHeader, forumStyle, beautify, out);
+ char normalPluginsStart[1024]; //for beautification purposes, for normal plugins text (start)
+ char normalPluginsEnd[1024]; //for beautification purposes, for normal plugins text (end)
+ char horizLine[1024]; //for beautification purposes
+ char buffer[1024]; //for beautification purposes
+
+ char headerHighlightStart[10] = "";
+ char headerHighlightEnd[10] = "";
+ if (forumStyle)
+ {
+ char start[128], end[128];
+ GetStringFromDatabase("BoldBegin", "[b]", start, sizeof(start));
+ GetStringFromDatabase("BoldEnd", "[/b]", end, sizeof(end));
+ strncpy(headerHighlightStart, start, sizeof(headerHighlightStart));
+ strncpy(headerHighlightEnd, end, sizeof(headerHighlightEnd));
+ }
+
+ //Plugins: list of active (enabled) plugins.
+ GetStringFromDatabase("BeautifyHorizLine", "<hr />", horizLine, sizeof(horizLine));
+ BeautifyReport(beautify, horizLine, "\r\n", out);
+ GetStringFromDatabase("BeautifyActiveHeaderBegin", "<b><font size=\"-1\" color=\"DarkGreen\">", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightStart, out);
+ AddSectionAndCount(listActivePlugins, "Active Plugins", out);
+ GetStringFromDatabase("BeautifyActiveHeaderEnd", "</font></b>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightEnd, out);
+ out.append("\r\n");
+
+ GetStringFromDatabase("BeautifyPluginsBegin", "<font size=\"-2\" color=\"black\">", normalPluginsStart, sizeof(normalPluginsStart));
+ BeautifyReport(beautify, normalPluginsStart, "", out);
+ out.append(GetListAsString(listActivePlugins, flags, beautify));
+ GetStringFromDatabase("BeautifyPluginsEnd", "</font>", normalPluginsEnd, sizeof(normalPluginsEnd));
+ BeautifyReport(beautify, normalPluginsEnd, "", out);
+ //Plugins: list of inactive (disabled) plugins.
+ if ((!forumStyle) && ((DBGetContactSettingByte(NULL, ModuleName, "ShowInactive", TRUE)) || (bServiceMode))) {
+ BeautifyReport(beautify, horizLine, "\r\n", out);
+ GetStringFromDatabase("BeautifyInactiveHeaderBegin", "<b><font size=\"-1\" color=\"DarkRed\">", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightStart, out);
+ AddSectionAndCount(listInactivePlugins, "Inactive Plugins", out);
+ GetStringFromDatabase("BeautifyInactiveHeaderEnd", "</font></b>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightEnd, out);
+ out.append("\r\n");
+ BeautifyReport(beautify, normalPluginsStart, "", out);
+ out.append(GetListAsString(listInactivePlugins, flags, beautify));
+ BeautifyReport(beautify, normalPluginsEnd, "", out);
+ }
+ if (listUnloadablePlugins.size() > 0)
+ {
+ //out.append("\r\n");
+ BeautifyReport(beautify, horizLine, "\r\n", out);
+ GetStringFromDatabase("BeautifyUnloadableHeaderBegin", "<b><font size=\"-1\"><font color=\"Red\">", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightStart, out);
+ AddSectionAndCount(listUnloadablePlugins, "Unloadable Plugins", out);
+ GetStringFromDatabase("BeautifyUnloadableHeaderEnd", "</font></b>", buffer, sizeof(buffer));
+ BeautifyReport(beautify, buffer, headerHighlightEnd, out);
+ out.append("\r\n");
+ BeautifyReport(beautify, normalPluginsStart, "", out);
+ out.append(GetListAsString(listUnloadablePlugins, flags, beautify));
+ BeautifyReport(beautify, normalPluginsEnd, "", out);
+ }
+ AddInfoFooter(suppressHeader, forumStyle, beautify, out);
+ return out;
+}
+
+//========== Print functions =====
+
+void CVersionInfo::PrintInformationsToFile(const char *info)
+{
+ char buffer[MAX_PATH];
+ char outputFileName[MAX_PATH];
+ if (bFoldersAvailable)
+ {
+ FoldersGetCustomPath(hOutputLocation, buffer, sizeof(buffer), "%miranda_path%");
+ strcat(buffer, "\\VersionInfo.txt");
+ }
+ else{
+ GetStringFromDatabase("OutputFile", "VersionInfo.txt", buffer, sizeof(buffer));
+ }
+
+ RelativePathToAbsolute(buffer, outputFileName, sizeof(buffer));
+
+ FILE *fp = fopen(outputFileName, "wb");
+ if (fp != NULL) {
+ fprintf(fp, info);
+ fclose(fp);
+ char mex[512];
+ mir_snprintf(mex, sizeof(mex), Translate("Information successfully written to file: \"%s\"."), outputFileName);
+ Log(mex);
+ }
+ else {
+ char mex[512];
+ mir_snprintf(mex, sizeof(mex), Translate("Error during the creation of file \"%s\". Disk may be full or write protected."), outputFileName);
+ Log(mex);
+ }
+}
+
+void CVersionInfo::PrintInformationsToFile() {
+ PrintInformationsToFile((*this).GetInformationsAsString().c_str());
+}
+
+void CVersionInfo::PrintInformationsToMessageBox() {
+ MessageBox(NULL, (*this).GetInformationsAsString().c_str(), ModuleName, MB_OK);
+ return;
+}
+
+void CVersionInfo::PrintInformationsToOutputDebugString() {
+ OutputDebugString((*this).GetInformationsAsString().c_str());
+ return;
+}
+
+#include "resource.h"
+//extern HINSTANCE hInst;
+
+void CVersionInfo::PrintInformationsToDialogBox() {
+// HWND parent = DBGetContactSettingByte(NULL, ModuleName, "ShowInTaskbar", TRUE)?GetDesktopWindow():NULL;
+ HWND parent = NULL;
+ HWND DialogBox = CreateDialogParam(hInst,
+ MAKEINTRESOURCE(IDD_DIALOGINFO),
+ parent, DialogBoxProc, (LPARAM) this);
+
+ SetDlgItemText(DialogBox, IDC_TEXT, (*this).GetInformationsAsString().c_str());
+ return;
+}
+
+void CVersionInfo::PrintInformationsToClipboard(bool showLog) {
+
+ if (GetOpenClipboardWindow()) {
+ Log(Translate("The clipboard is not available, retry."));
+ }
+ else {
+ OpenClipboard(NULL);
+ //Ok, let's begin, then.
+ EmptyClipboard();
+ //Storage data we'll use.
+ LPTSTR lptstrCopy;
+ std::string aux = (*this).GetInformationsAsString();
+ size_t length = aux.length() + 1;
+ HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, length + 5);
+ //Lock memory, copy it, release it.
+ lptstrCopy = (LPTSTR)GlobalLock(hData);
+ memcpy(lptstrCopy, aux.c_str(), length);
+ lptstrCopy[length] = '\0';
+ GlobalUnlock(hData);
+ //Now set the clipboard data.
+ SetClipboardData(CF_TEXT, hData);
+ //Remove the lock on the clipboard.
+ CloseClipboard();
+ if (showLog)
+ {
+ Log(Translate("Information successfully copied into clipboard."));
+ }
+ }
+ return;
+}
+
+/*int MyReceive(SOCKET sClient, char *message, int size, int bShow)
+{
+ int len = recv(sClient, message, size - 1, 0);
+ int success = 0;
+ if (len != SOCKET_ERROR)
+ {
+ message[len] = '\0';
+ if (bShow)
+ {
+ PUShowMessage(message, SM_NOTIFY);
+ }
+ char *pos = message;
+ while ((pos = strchr(pos + 1, '\n')))
+ {
+ success++;
+ }
+ if (success <= 0) success = 1; //make sure success is at least 1
+ }
+ else{
+ success = 0;
+ closesocket(sClient);
+ }
+ return success;
+}*/
+
+#define UPLOAD_ERROR() {PUShowMessage("Error while trying to upload data", SM_WARNING); return 1;}
+
+DWORD WINAPI UploadWorkerTread(LPVOID param)
+{
+ //PUShowMessage("Uploading to site", SM_NOTIFY);
+ /*
+ char *text = (char *) param;
+ char message[2048];
+
+ char server[1024];
+ int port;
+ char user[512];
+ char password[512];
+
+ GetStringFromDatabase("UploadServer", "vi.cass.cz", server, sizeof(server));
+ port = DBGetContactSettingWord(NULL, ModuleName, "UploadPort", DEFAULT_UPLOAD_PORT);
+ GetStringFromDatabase("UploadUser", "", user, sizeof(user));
+ GetStringFromDatabase("UploadPassword", "", password, sizeof(password));
+ CallService(MS_DB_CRYPT_DECODESTRING, sizeof(password), (LPARAM) password);
+
+ SOCKET sClient = socket(AF_INET, SOCK_STREAM, 0);
+ if (!sClient)
+ {
+ MB("Could not create connection socket ...");
+ return 1;
+ }
+
+ sockaddr_in addr = {0};
+ hostent *localHost = gethostbyname(server);
+ char *localIP = (localHost) ? inet_ntoa(*(struct in_addr *) *localHost->h_addr_list) : server;
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr(localIP);
+ addr.sin_port = htons(port);
+
+ int res = connect(sClient, (sockaddr *) &addr, sizeof(addr));
+ if (res)
+ {
+ char buffer[1024];
+ mir_snprintf(buffer, sizeof(buffer), "Could not connect to server '%s' on port %d", server, port);
+ MB(buffer);
+ return 1;
+ }
+ res = MyReceive(sClient, message, sizeof(message), TRUE); //get the welcome message
+ switch (res)
+ {
+ case 1:
+ if (!MyReceive(sClient, message, sizeof(message), 0)) UPLOAD_ERROR(); //get the enter username message
+ break;
+
+ case 2: //the enter user message was received already
+ break;
+
+ default: //assume error by default
+ UPLOAD_ERROR();
+ }
+
+ send(sClient, user, strlen(user), 0);
+ if (!MyReceive(sClient, message, sizeof(message), FALSE)) UPLOAD_ERROR(); //get the enter password message
+ send(sClient, password, strlen(password), 0);
+ if (!MyReceive(sClient, message, sizeof(message), FALSE)) UPLOAD_ERROR(); //get the upload data message
+ send(sClient, text, strlen(text) + 1, 0); //data message needs to send \0 so the server knows when to stop.
+ if (!MyReceive(sClient, message, sizeof(message), TRUE)) UPLOAD_ERROR();
+ closesocket(sClient);
+ //PUShowMessage("Done uploading to site", SM_NOTIFY);
+
+ if (text)
+ {
+ free(text);
+ }
+ */
+ return 0;
+}
+
+void CVersionInfo::UploadToSite(char *text){
+
+ DWORD threadID;
+ HANDLE thread;
+ char *data = NULL;
+ if (!text)
+ {
+ data = _strdup(GetInformationsAsString().c_str());
+ }
+ else{
+ data = _strdup(text);
+ }
+
+ thread = CreateThread(NULL, NULL, UploadWorkerTread, data, 0, &threadID); //the thread will free the buffer
+ if (!thread)
+ {
+ MB("Upload worker thread could not be created");
+ }
+ if ((thread != NULL) && (thread != INVALID_HANDLE_VALUE))
+ {
+ CloseHandle(thread);
+ }
+} \ No newline at end of file