From acd44e01e1a9b0e0fb6b526e86d90b0a00d8a18b Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 30 Mar 2013 10:55:35 +0000 Subject: missing file git-svn-id: http://svn.miranda-ng.org/main/trunk@4247 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/AvatarHistory/src/utils.cpp | 334 ++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 plugins/AvatarHistory/src/utils.cpp (limited to 'plugins/AvatarHistory') diff --git a/plugins/AvatarHistory/src/utils.cpp b/plugins/AvatarHistory/src/utils.cpp new file mode 100644 index 0000000000..69122d6621 --- /dev/null +++ b/plugins/AvatarHistory/src/utils.cpp @@ -0,0 +1,334 @@ +/* +Avatar History Plugin +--------- + + This plugin uses the event provided by Avatar Service to + automatically back up contacts' avatars when they change. + Copyright (C) 2006 Matthew Wild - Email: mwild1@gmail.com + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "AvatarHistory.h" + +extern HANDLE hFolder; +extern TCHAR basedir[]; + +BOOL ProtocolEnabled(const char *proto) +{ + if (proto == NULL) + return FALSE; + + char setting[256]; + mir_snprintf(setting, sizeof(setting), "%sEnabled", proto); + return (BOOL) db_get_b(NULL, MODULE_NAME, setting, TRUE); +} + +BOOL ContactEnabled(HANDLE hContact, char *setting, int def) +{ + if (hContact == NULL) + return FALSE; + + char *proto = GetContactProto(hContact); + if (!ProtocolEnabled(proto)) + return FALSE; + + BYTE globpref = db_get_b(NULL, MODULE_NAME, setting, def); + BYTE userpref = db_get_b(hContact, MODULE_NAME, setting, BST_INDETERMINATE); + + return (globpref && userpref == BST_INDETERMINATE) || userpref == BST_CHECKED; +} + +// Returns true if the unicode buffer only contains 7-bit characters. +BOOL IsUnicodeAscii(const WCHAR * pBuffer, int nSize) +{ + for (int nIndex = 0; nIndex < nSize; nIndex++) + if (pBuffer[nIndex] > 0x7F) + return FALSE; + + return TRUE; +} + +void ConvertToFilename(TCHAR *str, size_t size) +{ + for(size_t i = 0; i < size && str[i] != '\0'; i++) { + switch(str[i]) { + case '/': + case '\\': + case ':': + case '*': + case '?': + case '"': + case '<': + case '>': + case '|': + str[i] = '_'; + } + } +} + +void ErrorExit(HANDLE hContact,LPTSTR lpszFunction) +{ + // Retrieve the system error message for the last-error code + + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), + (LPTSTR) &lpMsgBuf, + 0, NULL ); + + // Display the error message and exit the process + + lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); + StringCchPrintf((LPTSTR)lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), + lpszFunction, dw, lpMsgBuf); + ShowDebugPopup(hContact,TEXT("Error"), (LPCTSTR)lpDisplayBuf); + + LocalFree(lpMsgBuf); + LocalFree(lpDisplayBuf); +} + +int GetUIDFromHContact(HANDLE contact, TCHAR* uinout, int uinout_len) +{ + bool found = true; + + CONTACTINFO cinfo = { sizeof(cinfo) }; + cinfo.hContact = contact; + cinfo.dwFlag = CNF_UNIQUEID | CNF_TCHAR; + if (CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&cinfo) == 0) { + if (cinfo.type == CNFT_ASCIIZ) { + lstrcpyn(uinout, cinfo.pszVal, uinout_len); + // It is up to us to free the string + // The catch? We need to use Miranda's free(), not our CRT's :) + mir_free(cinfo.pszVal); + } + else if (cinfo.type == CNFT_DWORD) + _itot(cinfo.dVal,uinout,10); + else if (cinfo.type == CNFT_WORD) + _itot(cinfo.wVal,uinout,10); + else + found = false; + } + else found = false; + + if (!found) + lstrcpyn(uinout, TranslateT("Unknown UIN"), uinout_len); + + return 0; +} + +TCHAR * GetExtension(TCHAR *file) +{ + if (file == NULL) return _T(""); + TCHAR *ext = _tcsrchr(file, _T('.')); + if (ext != NULL) + ext++; + else + ext = _T(""); + + return ext; +} + +TCHAR* GetHistoryFolder(TCHAR *fn) +{ + if (fn == NULL) return NULL; + FoldersGetCustomPathT(hFolder, fn, MAX_PATH, basedir); + if (!CreateDirectory(fn, NULL)) + ErrorExit(NULL,_T("GetHistoryFolder")); + + return fn; +} + +TCHAR* GetProtocolFolder(TCHAR *fn, char *proto) +{ + GetHistoryFolder(fn); + + if (proto == NULL) + proto = Translate("Unknown Protocol"); + + mir_sntprintf(fn, MAX_PATH, _T("%s\\%S"), fn, proto); + if (!CreateDirectory(fn, NULL)) + ErrorExit(NULL,_T("CreateDirectory")); + + return fn; +} + +TCHAR* GetContactFolder(TCHAR *fn, HANDLE hContact) +{ + TCHAR uin[MAX_PATH]; + + char *proto = GetContactProto(hContact); + GetProtocolFolder(fn, proto); + + GetUIDFromHContact(hContact, uin, MAX_REGS(uin)); + mir_sntprintf(fn, MAX_PATH, _T("%s\\%s"), fn, uin); + if (!CreateDirectory(fn, NULL)) + ErrorExit(hContact,_T("CreateDirectory")); + ConvertToFilename(uin, sizeof(uin)); //added so that weather id's like "yw/CI0000" work + +#ifdef DBGPOPUPS + TCHAR log[1024]; + mir_sntprintf(log, MAX_REGS(log), _T("Path: %s\nProto: %S\nUIN: %s"), fn, proto, uin); + ShowPopup(hContact, _T("AVH Debug: GetContactFolder"), log); +#endif + + return fn; +} + +TCHAR* GetOldStyleAvatarName(TCHAR *fn, HANDLE hContact) +{ + GetContactFolder(fn, hContact); + + SYSTEMTIME curtime; + GetLocalTime(&curtime); + mir_sntprintf(fn, MAX_PATH, + _T("%s\\%04d-%02d-%02d %02dh%02dm%02ds"), fn, + curtime.wYear, curtime.wMonth, curtime.wDay, + curtime.wHour, curtime.wMinute, curtime.wSecond); + ShowDebugPopup(hContact,TranslateT("AVH Debug: GetOldStyleAvatarName"),fn); + return fn; +} + +void CreateOldStyleShortcut(HANDLE hContact, TCHAR *history_filename) +{ + TCHAR shortcut[MAX_PATH] = _T(""); + + GetOldStyleAvatarName(shortcut, hContact); + + mir_sntprintf(shortcut, MAX_REGS(shortcut), _T("%s.%s.lnk"), shortcut, + GetExtension(history_filename)); + + if (!CreateShortcut(history_filename, shortcut)) + { + ShowPopup(hContact, TranslateT("Avatar History: Unable to create shortcut"), shortcut); + } + else + { + ShowDebugPopup(hContact, TranslateT("AVH Debug: Shortcut created successfully"), shortcut); + } +} + + +BOOL CopyImageFile(TCHAR *old_file, TCHAR *new_file) +{ + TCHAR *ext = GetExtension(old_file); + mir_sntprintf(new_file, MAX_PATH, _T("%s.%s"), new_file, ext); + + BOOL ret = CopyFile(old_file, new_file, TRUE); + if (!ret) + ErrorExit(NULL,_T("CopyImageFile")); + return !ret; +} + +TCHAR * GetCachedAvatar(char *proto, TCHAR *hash) +{ + TCHAR *ret = NULL; + TCHAR file[1024] = _T(""); + TCHAR search[1024] = _T(""); + if (opts.log_keep_same_folder) + GetHistoryFolder(file); + else + GetProtocolFolder(file, proto); + + mir_sntprintf(search, MAX_REGS(search), _T("%s\\%s.*"), file, hash); + + WIN32_FIND_DATA finddata; + HANDLE hFind = FindFirstFile(search, &finddata); + if (hFind == INVALID_HANDLE_VALUE) + return NULL; + + do + { + size_t len = lstrlen(finddata.cFileName); + if (len > 4 + && (!lstrcmpi(&finddata.cFileName[len-4], _T(".png")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".bmp")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".gif")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".jpg")) + || !lstrcmpi(&finddata.cFileName[len-5], _T(".jpeg")))) + { + mir_sntprintf(file, MAX_REGS(file), _T("%s\\%s"), file, finddata.cFileName); + ret = mir_tstrdup(file); + break; + } + } while(FindNextFile(hFind, &finddata)); + FindClose(hFind); + + return ret; +} + +BOOL CreateShortcut(TCHAR *file, TCHAR *shortcut) +{ + IShellLink *psl = NULL; + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl); + if (SUCCEEDED(hr)) { + psl->SetPath(file); + + IPersistFile *ppf = NULL; + hr = psl->QueryInterface(IID_IPersistFile, (void **) &ppf); + if (SUCCEEDED(hr)) { + hr = ppf->Save(shortcut, TRUE); + ppf->Release(); + } + + psl->Release(); + } + + if (FAILED(hr)) + ErrorExit(NULL,_T("CreateShortcut")); + return SUCCEEDED(hr); +} + +BOOL ResolveShortcut(TCHAR *shortcut, TCHAR *file) +{ + IShellLink* psl = NULL; + + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl); + + if (SUCCEEDED(hr)) { + IPersistFile* ppf = NULL; + hr = psl->QueryInterface(IID_IPersistFile, (void **) &ppf); + + if (SUCCEEDED(hr)) { + hr = ppf->Load(shortcut, STGM_READ); + if (SUCCEEDED(hr)) { + hr = psl->Resolve(NULL, SLR_UPDATE); + if (SUCCEEDED(hr)) { + WIN32_FIND_DATA wfd; + hr = psl->GetPath(file, MAX_PATH, &wfd, SLGP_RAWPATH); + } + } + + ppf->Release(); + } + psl->Release(); + } + + if (FAILED(hr)) + ErrorExit(NULL,_T("CreateShortcut")); + return SUCCEEDED(hr); +} -- cgit v1.2.3