From a089c8f17cca1cdf688e91be38ec315803168ed8 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 16 Jul 2012 20:35:50 +0000 Subject: Svc_dbepp is renamed to DbeditorPP Svc_crshdmp is renamed to CrashDumper Svc_vi is renamed to VersionInfo git-svn-id: http://svn.miranda-ng.org/main/trunk@992 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/VersionInfo/utils.cpp | 526 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 526 insertions(+) create mode 100644 plugins/VersionInfo/utils.cpp (limited to 'plugins/VersionInfo/utils.cpp') diff --git a/plugins/VersionInfo/utils.cpp b/plugins/VersionInfo/utils.cpp new file mode 100644 index 0000000000..9be552c8cc --- /dev/null +++ b/plugins/VersionInfo/utils.cpp @@ -0,0 +1,526 @@ +/* +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. +*/ + +//#define USE_LOG_FUNCTIONS + +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include "common.h" +#include "utils.h" + +/* +My usual MessageBoxes :-) +*/ +void MB(const TCHAR* message) +{ + if (verbose) MessageBox(NULL, message, _T("VersionInfo"), MB_OK | MB_ICONEXCLAMATION); +} + +void Log(const TCHAR* message) +{ + if (ServiceExists(MS_POPUP_ADDPOPUPT)) { + POPUPDATAT pu = {0}; + pu.lchIcon = hiVIIcon; + _tcsncpy(pu.lptzContactName, TranslateT("Version Information"), MAX_CONTACTNAME); + _tcsncpy(pu.lptzText, message, MAX_SECONDLINE); + PUAddPopUpT(&pu); + } + else MessageBox(NULL, message, _T("VersionInfo"), MB_OK | MB_ICONINFORMATION); +} + +int SplitStringInfo(const TCHAR *szWholeText, TCHAR *szStartText, TCHAR *szEndText) +{ + const TCHAR *pos = _tcschr(szWholeText, '|'); + if (pos) { + size_t index = pos - szWholeText; + lstrcpyn(szStartText, szWholeText, (int)index); + szStartText[index] = '\0'; + StrTrim(szStartText, _T(" ")); + lstrcpyn(szEndText, pos + 1, (int)_tcslen(pos)); //copies the \0 as well ... :) + StrTrim(szEndText, _T(" ")); + } + else szStartText[0] = szEndText[0] = '\0'; + + return 0; +} + +int GetStringFromDatabase(char *szSettingName, TCHAR *szError, TCHAR *szResult, size_t size) +{ + DBVARIANT dbv = {0}; + int res = 1; + size_t len; + if ( DBGetContactSettingTString(NULL, ModuleName, szSettingName, &dbv) == 0) { + res = 0; + size_t tmp = _tcslen(dbv.ptszVal); + len = (tmp < size - 1) ? tmp : size - 1; + _tcsncpy(szResult, dbv.ptszVal, len); + szResult[len] = '\0'; + mir_free(dbv.ptszVal); + } + else { + res = 1; + size_t tmp = _tcslen(szError); + len = (tmp < size - 1) ? tmp : size - 1; + _tcsncpy(szResult, szError, len); + szResult[len] = '\0'; + } + return res; +} + +TCHAR *RelativePathToAbsolute(TCHAR *szRelative, TCHAR *szAbsolute, size_t size) +{ + if (size < MAX_PATH) { + TCHAR buffer[MAX_PATH]; //new path should be at least MAX_PATH chars + CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM) szRelative, (LPARAM) buffer); + _tcsncpy(szAbsolute, buffer, size); + } + else CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM) szRelative, (LPARAM) szAbsolute); + + return szAbsolute; +} + +TCHAR *AbsolutePathToRelative(TCHAR *szAbsolute, TCHAR *szRelative, size_t size) +{ + if (size < MAX_PATH) { + TCHAR buffer[MAX_PATH]; + CallService(MS_UTILS_PATHTORELATIVET, (WPARAM) szAbsolute, (LPARAM) szRelative); + _tcsncpy(szRelative, buffer, size); + } + else CallService(MS_UTILS_PATHTORELATIVET, (WPARAM) szAbsolute, (LPARAM) szRelative); + + return szRelative; +} + +#define GetFacility(dwError) (HIWORD(dwError) && 0x0000111111111111) +#define GetErrorCode(dwError) (LOWORD(dwError)) + +void NotifyError(DWORD dwError, const TCHAR* szSetting, int iLine) +{ + TCHAR str[1024]; + mir_sntprintf(str, SIZEOF(str), TranslateT("Ok, something went wrong in the \"%s\" setting. Report back the following values:\nFacility: %X\nError code: %X\nLine number: %d"), szSetting, GetFacility(dwError), GetErrorCode(dwError), iLine); + Log(str); +} + +TCHAR *StrTrim(TCHAR *szText, const TCHAR *szTrimChars) +{ + size_t i = _tcslen(szText) - 1; + while (i >= 0 && _tcschr(szTrimChars, szText[i])) + szText[i--] = '\0'; + + i = 0; + while (((unsigned int )i < _tcslen(szText)) && _tcschr(szTrimChars, szText[i])) + i++; + + if (i) { + size_t size = _tcslen(szText); + size_t j; + for (j = i; j <= size; j++) //shift the \0 as well + szText[j - i] = szText[j]; + } + return szText; +} + +bool DoesDllExist(char *dllName) +{ + HMODULE dllHandle; + dllHandle = LoadLibraryExA(dllName, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (dllHandle) + { + FreeLibrary(dllHandle); + return true; + } + return false; +} + +//========== From Cyreve ========== +PLUGININFOEX *GetPluginInfo(const TCHAR *filename,HINSTANCE *hPlugin) +{ + TCHAR szMirandaPath[MAX_PATH], szPluginPath[MAX_PATH]; + PLUGININFOEX *(*MirandaPluginInfo)(DWORD); + PLUGININFOEX *pPlugInfo; + HMODULE hLoadedModule; + DWORD mirandaVersion = CallService(MS_SYSTEM_GETVERSION,0,0); + + GetModuleFileName(GetModuleHandle(NULL), szMirandaPath, SIZEOF(szMirandaPath)); + TCHAR* str2 = _tcsrchr(szMirandaPath,'\\'); + if(str2!=NULL) *str2=0; + + hLoadedModule = GetModuleHandle(filename); + if(hLoadedModule!=NULL) { + *hPlugin=NULL; + MirandaPluginInfo=(PLUGININFOEX *(*)(DWORD))GetProcAddress(hLoadedModule,"MirandaPluginInfo"); + return MirandaPluginInfo(mirandaVersion); + } + wsprintf(szPluginPath, _T("%s\\Plugins\\%s"), szMirandaPath, filename); + *hPlugin=LoadLibrary(szPluginPath); + if (*hPlugin==NULL) return NULL; + MirandaPluginInfo=(PLUGININFOEX *(*)(DWORD))GetProcAddress(*hPlugin,"MirandaPluginInfo"); + if(MirandaPluginInfo==NULL) {FreeLibrary(*hPlugin); *hPlugin=NULL; return NULL;} + pPlugInfo=MirandaPluginInfo(mirandaVersion); + if(pPlugInfo==NULL) {FreeLibrary(*hPlugin); *hPlugin=NULL; return NULL;} + if(pPlugInfo->cbSize != sizeof(PLUGININFOEX)) {FreeLibrary(*hPlugin); *hPlugin=NULL; return NULL;} + return pPlugInfo; +} + +//========== from Frank Cheng (wintime98) ========== +// I've changed something to suit VersionInfo :-) +#include + +void TimeStampToSysTime(DWORD Unix,SYSTEMTIME* SysTime) +{ + SYSTEMTIME S; + DWORDLONG FileReal,UnixReal; + S.wYear=1970; + S.wMonth=1; + S.wDay=1; + S.wHour=0; + S.wMinute=0; + S.wSecond=0; + S.wMilliseconds=0; + SystemTimeToFileTime(&S,(FILETIME*)&FileReal); + UnixReal = Unix; + UnixReal*=10000000; + FileReal+=UnixReal; + FileTimeToSystemTime((FILETIME*)&FileReal,SysTime); +} + +void GetModuleTimeStamp(TCHAR* ptszDate, TCHAR* ptszTime) +{ + TCHAR tszModule[MAX_PATH]; + HANDLE mapfile,file; + DWORD timestamp,filesize; + LPVOID mapmem; + SYSTEMTIME systime; + GetModuleFileName(NULL,tszModule,SIZEOF(tszModule)); + file = CreateFile(tszModule,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + filesize = GetFileSize(file,NULL); + mapfile = CreateFileMapping(file, NULL, PAGE_READONLY, 0, filesize, NULL); + mapmem = MapViewOfFile(mapfile, FILE_MAP_READ, 0, 0, 0); + timestamp = GetTimestampForLoadedLibrary((HINSTANCE)mapmem); + TimeStampToSysTime(timestamp,&systime); + GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systime, _T("HH':'mm':'ss"), ptszTime, 40 ); + GetDateFormat(EnglishLocale, 0, &systime, _T("dd' 'MMMM' 'yyyy"), ptszDate, 40); + UnmapViewOfFile(mapmem); + CloseHandle(mapfile); + CloseHandle(file); +} + +//From Egodust or Cyreve... I don't really know. +PLUGININFOEX *CopyPluginInfo(PLUGININFOEX *piSrc) +{ + if(piSrc==NULL) + return NULL; + + PLUGININFOEX *pi = (PLUGININFOEX *)malloc(sizeof(PLUGININFOEX)); + *pi = *piSrc; + + if (piSrc->cbSize >= sizeof(PLUGININFOEX)) + pi->uuid = piSrc->uuid; + else + pi->uuid = UUID_NULL; + + if (pi->author) pi->author = _strdup(pi->author); + if (pi->authorEmail) pi->authorEmail = _strdup(pi->authorEmail); + if (pi->copyright) pi->copyright = _strdup(pi->copyright); + if (pi->description) pi->description = _strdup(pi->description); + if (pi->homepage) pi->homepage = _strdup(pi->homepage); + if (pi->shortName) pi->shortName = _strdup(pi->shortName); + return pi; +} + +void FreePluginInfo(PLUGININFOEX *pi) +{ + if (pi->author) free(pi->author); + if (pi->authorEmail) free(pi->authorEmail); + if (pi->copyright) free(pi->copyright); + if (pi->description) free(pi->description); + if (pi->homepage) free(pi->homepage); + if (pi->shortName) free(pi->shortName); + free(pi); +} + +BOOL IsCurrentUserLocalAdministrator(void) +{ + BOOL fReturn = FALSE; + DWORD dwStatus; + DWORD dwAccessMask; + DWORD dwAccessDesired; + DWORD dwACLSize; + DWORD dwStructureSize = sizeof(PRIVILEGE_SET); + PACL pACL = NULL; + PSID psidAdmin = NULL; + + HANDLE hToken = NULL; + HANDLE hImpersonationToken = NULL; + + PRIVILEGE_SET ps; + GENERIC_MAPPING GenericMapping; + + PSECURITY_DESCRIPTOR psdAdmin = NULL; + SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; + + /* + Determine if the current thread is running as a user that is a member of + the local admins group. To do this, create a security descriptor that + has a DACL which has an ACE that allows only local aministrators access. + Then, call AccessCheck with the current thread's token and the security + descriptor. It will say whether the user could access an object if it + had that security descriptor. Note: you do not need to actually create + the object. Just checking access against the security descriptor alone + will be sufficient. + */ + const DWORD ACCESS_READ = 1; + const DWORD ACCESS_WRITE = 2; + + + __try + { + + /* + AccessCheck() requires an impersonation token. We first get a primary + token and then create a duplicate impersonation token. The + impersonation token is not actually assigned to the thread, but is + used in the call to AccessCheck. Thus, this function itself never + impersonates, but does use the identity of the thread. If the thread + was impersonating already, this function uses that impersonation context. + */ + if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken)) + { + if (GetLastError() != ERROR_NO_TOKEN) + __leave; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken)) + __leave; + } + + if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken)) + __leave; + + + /* + Create the binary representation of the well-known SID that + represents the local administrators group. Then create the security + descriptor and DACL with an ACE that allows only local admins access. + After that, perform the access check. This will determine whether + the current user is a local admin. + */ + if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) + __leave; + + psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); + if (psdAdmin == NULL) + __leave; + + if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION)) + __leave; + + // Compute size needed for the ACL. + dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD); + + pACL = (PACL)LocalAlloc(LPTR, dwACLSize); + if (pACL == NULL) + __leave; + + if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2)) + __leave; + + dwAccessMask= ACCESS_READ | ACCESS_WRITE; + + if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin)) + __leave; + + if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) + __leave; + + /* + AccessCheck validates a security descriptor somewhat; set the group + and owner so that enough of the security descriptor is filled out to + make AccessCheck happy. + */ + SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE); + SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE); + + if (!IsValidSecurityDescriptor(psdAdmin)) + __leave; + + dwAccessDesired = ACCESS_READ; + + /* + Initialize GenericMapping structure even though you + do not use generic rights. + */ + GenericMapping.GenericRead = ACCESS_READ; + GenericMapping.GenericWrite = ACCESS_WRITE; + GenericMapping.GenericExecute = 0; + GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE; + + if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired, &GenericMapping, &ps, &dwStructureSize, &dwStatus, &fReturn)) + { + fReturn = FALSE; + __leave; + } + } + __finally + { + // Clean up. + if (pACL) LocalFree(pACL); + if (psdAdmin) LocalFree(psdAdmin); + if (psidAdmin) FreeSid(psidAdmin); + if (hImpersonationToken) CloseHandle (hImpersonationToken); + if (hToken) CloseHandle (hToken); + } + + return fReturn; +} + +BOOL GetWindowsShell(TCHAR *shellPath, size_t shSize) +{ + OSVERSIONINFO vi = {0}; + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&vi); + + TCHAR szShell[1024] = {0}; + DWORD size = SIZEOF(szShell); + + if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + HKEY hKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\system.ini\\boot"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + RegQueryValueEx(hKey, _T("Shell"), NULL, NULL, (LPBYTE) szShell, &size); + _tcslwr(szShell); + HKEY hRootKey = ( _tcsstr(szShell, _T("sys:")) == szShell) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + RegCloseKey(hKey); + + _tcscpy(szShell, _T("")); + if (RegOpenKeyEx(hRootKey, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + size = SIZEOF(szShell); + RegQueryValueEx(hKey, _T("Shell"), NULL, NULL, (LPBYTE) szShell, &size); + RegCloseKey(hKey); + } + } + } + else{ + TCHAR szSystemIniPath[2048]; + GetWindowsDirectory(szSystemIniPath, SIZEOF(szSystemIniPath)); + size_t len = lstrlen(szSystemIniPath); + if (len > 0) + { + if (szSystemIniPath[len - 1] == '\\') { szSystemIniPath[--len] = '\0'; } + _tcscat(szSystemIniPath, _T("\\system.ini")); + GetPrivateProfileString( _T("boot"), _T("shell"), _T(""), szShell, size, szSystemIniPath); + } + } + + TCHAR *pos = _tcsrchr(szShell, '\\'); + TCHAR *res = (pos) ? pos + 1 : szShell; + _tcsncpy(shellPath, res, shSize); + + return TRUE; +} + +BOOL GetInternetExplorerVersion(TCHAR *ieVersion, size_t ieSize) +{ + HKEY hKey; + TCHAR ieVer[1024]; + DWORD size = SIZEOF(ieVer); + TCHAR ieBuild[64] = {0}; + + _tcsncpy(ieVer, _T(""), size); + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Internet Explorer"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + if (RegQueryValueEx(hKey, _T("Version"), NULL, NULL, (LPBYTE) ieVer, &size) == ERROR_SUCCESS) + { + TCHAR *pos = _tcschr(ieVer, '.'); + if (pos) + { + pos = _tcschr(pos + 1, '.'); + if (pos) { *pos = 0; } + _tcsncpy(ieBuild, pos + 1, SIZEOF(ieBuild)); + pos = _tcschr(ieBuild, '.'); + if (pos) { *pos = 0; } + } + } + else{ + size = SIZEOF(ieVer); + if (RegQueryValueEx(hKey, _T("Build"), NULL, NULL, (LPBYTE) ieVer, &size) == ERROR_SUCCESS) + { + TCHAR *pos = ieVer + 1; + _tcsncpy(ieBuild, pos, SIZEOF(ieBuild)); + *pos = 0; + pos = _tcschr(ieBuild, '.'); + if (pos) { *pos = 0; } + } + else{ + _tcsncpy(ieVer, _T(""), size); + } + } + RegCloseKey(hKey); + } + + _tcsncpy(ieVersion, ieVer, ieSize); + if ( ieBuild[0] ) + { + _tcsncat(ieVersion, _T("."), ieSize); + _tcsncat(ieVersion, ieBuild, ieSize); + } + + return TRUE; +} + + +TCHAR *GetLanguageName(LANGID language) +{ + LCID lc = MAKELCID(language, SORT_DEFAULT); + return GetLanguageName(lc); +} + +extern TCHAR *GetLanguageName(LCID locale) +{ + static TCHAR name[1024]; + GetLocaleInfo(locale, LOCALE_SENGLANGUAGE, name, SIZEOF(name)); + return name; +} + +BOOL UUIDToString(MUUID uuid, TCHAR *str, size_t len) +{ + if ( len < sizeof(MUUID) || !str ) + return 0; + + mir_sntprintf(str, len, _T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"), uuid.a, uuid.b, uuid.c, uuid.d[0], uuid.d[1], uuid.d[2], uuid.d[3], uuid.d[4], uuid.d[5], uuid.d[6], uuid.d[7]); + return 1; +} + +BOOL IsUUIDNull(MUUID uuid) +{ + int i; + for (i = 0; i < sizeof(uuid.d); i++) + { + if (uuid.d[i]) + { + return 0; + } + } + + return ((uuid.a == 0) && (uuid.b == 0) && (uuid.c == 0)); +} \ No newline at end of file -- cgit v1.2.3