/* 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 "stdafx.h" bool ProtocolEnabled(const char *proto) { return Proto_GetAccount(proto)->IsEnabled(); } bool ContactEnabled(MCONTACT hContact, char *setting, int def) { if (hContact == NULL) return false; char *proto = Proto_GetBaseAccountName(hContact); if (!ProtocolEnabled(proto)) return false; BYTE globpref = g_plugin.getByte(setting, def); BYTE userpref = g_plugin.getByte(hContact, 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(wchar_t *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] = '_'; } } } wchar_t* GetExtension(wchar_t *file) { if (file == nullptr) return L""; wchar_t *ext = wcsrchr(file, '.'); if (ext != nullptr) ext++; else ext = L""; return ext; } wchar_t* GetHistoryFolder(wchar_t *fn) { if (fn == nullptr) return nullptr; FoldersGetCustomPathW(hFolder, fn, MAX_PATH, basedir); CreateDirectoryTreeW(fn); return fn; } wchar_t* GetProtocolFolder(wchar_t *fn, char *proto) { GetHistoryFolder(fn); if (proto == nullptr) proto = Translate("Unknown protocol"); mir_snwprintf(fn, MAX_PATH, L"%s\\%S", fn, proto); CreateDirectoryTreeW(fn); return fn; } wchar_t* GetContactFolder(wchar_t *fn, MCONTACT hContact) { char *proto = Proto_GetBaseAccountName(hContact); GetProtocolFolder(fn, proto); wchar_t uin[MAX_PATH]; ptrW id(Contact_GetInfo(CNF_UNIQUEID, hContact, proto)); wcsncpy_s(uin, (id == NULL) ? TranslateT("Unknown UIN") : id, _TRUNCATE); ConvertToFilename(uin, MAX_PATH); //added so that weather id's like "yw/CI0000" work mir_snwprintf(fn, MAX_PATH, L"%s\\%s", fn, uin); CreateDirectoryTreeW(fn); #ifdef DBGPOPUPS wchar_t log[1024]; mir_snwprintf(log, L"Path: %s\nProto: %S\nUIN: %s", fn, proto, uin); ShowPopup(hContact, L"AVH Debug: GetContactFolder", log); #endif return fn; } wchar_t* GetOldStyleAvatarName(wchar_t *fn, MCONTACT hContact) { GetContactFolder(fn, hContact); SYSTEMTIME curtime; GetLocalTime(&curtime); mir_snwprintf(fn, MAX_PATH, L"%s\\%04d-%02d-%02d %02dh%02dm%02ds", fn, curtime.wYear, curtime.wMonth, curtime.wDay, curtime.wHour, curtime.wMinute, curtime.wSecond); ShowDebugPopup(hContact, L"AVH Debug: GetOldStyleAvatarName", fn); return fn; } void CreateOldStyleShortcut(MCONTACT hContact, wchar_t *history_filename) { wchar_t shortcut[MAX_PATH] = L""; GetOldStyleAvatarName(shortcut, hContact); mir_snwprintf(shortcut, L"%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, L"AVH Debug: Shortcut created successfully", shortcut); } BOOL CopyImageFile(wchar_t *old_file, wchar_t *new_file) { wchar_t *ext = GetExtension(old_file); mir_snwprintf(new_file, MAX_PATH, L"%s.%s", new_file, ext); return !CopyFile(old_file, new_file, TRUE); } wchar_t* GetCachedAvatar(char *proto, wchar_t *hash) { wchar_t *ret = nullptr; wchar_t file[1024] = L""; wchar_t search[1024] = L""; if (opts.log_keep_same_folder) GetHistoryFolder(file); else GetProtocolFolder(file, proto); mir_snwprintf(search, L"%s\\%s.*", file, hash); WIN32_FIND_DATA finddata; HANDLE hFind = FindFirstFile(search, &finddata); if (hFind == INVALID_HANDLE_VALUE) return nullptr; do { size_t len = mir_wstrlen(finddata.cFileName); if (len > 4 && (!mir_wstrcmpi(&finddata.cFileName[len - 4], L".png") || !mir_wstrcmpi(&finddata.cFileName[len - 4], L".bmp") || !mir_wstrcmpi(&finddata.cFileName[len - 4], L".gif") || !mir_wstrcmpi(&finddata.cFileName[len - 4], L".jpg") || !mir_wstrcmpi(&finddata.cFileName[len - 5], L".jpeg"))) { mir_snwprintf(file, L"%s\\%s", file, finddata.cFileName); ret = mir_wstrdup(file); break; } } while (FindNextFile(hFind, &finddata)); FindClose(hFind); return ret; } BOOL CreateShortcut(wchar_t *file, wchar_t *shortcut) { IShellLink *psl = nullptr; HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl); if (SUCCEEDED(hr)) { psl->SetPath(file); IPersistFile *ppf = nullptr; hr = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hr)) { hr = ppf->Save(shortcut, TRUE); ppf->Release(); } psl->Release(); } return SUCCEEDED(hr); } BOOL ResolveShortcut(wchar_t *shortcut, wchar_t *file) { IShellLink* psl = nullptr; HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl); if (SUCCEEDED(hr)) { IPersistFile* ppf = nullptr; hr = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hr)) { hr = ppf->Load(shortcut, STGM_READ); if (SUCCEEDED(hr)) { hr = psl->Resolve(nullptr, SLR_UPDATE); if (SUCCEEDED(hr)) { WIN32_FIND_DATA wfd; hr = psl->GetPath(file, MAX_PATH, &wfd, SLGP_RAWPATH); } } ppf->Release(); } psl->Release(); } return SUCCEEDED(hr); }