diff options
author | George Hazan <george.hazan@gmail.com> | 2014-07-21 14:45:09 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2014-07-21 14:45:09 +0000 |
commit | d3ea6d2693b3e93c9dc62c75db2a9d5a67b9bce0 (patch) | |
tree | 3dac36054b2220c053243987a9978e17943471d7 /plugins/PluginUpdater/src | |
parent | 18bbf1ec823082a3635d7d2e4332c8ae972ce511 (diff) |
PostMessage should be used to send messages to another thread
git-svn-id: http://svn.miranda-ng.org/main/trunk@9904 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/PluginUpdater/src')
-rw-r--r-- | plugins/PluginUpdater/src/DlgListNew.cpp | 976 | ||||
-rw-r--r-- | plugins/PluginUpdater/src/DlgUpdate.cpp | 1526 | ||||
-rw-r--r-- | plugins/PluginUpdater/src/Notifications.cpp | 546 |
3 files changed, 1524 insertions, 1524 deletions
diff --git a/plugins/PluginUpdater/src/DlgListNew.cpp b/plugins/PluginUpdater/src/DlgListNew.cpp index bd1e0c122d..45cd3ddb64 100644 --- a/plugins/PluginUpdater/src/DlgListNew.cpp +++ b/plugins/PluginUpdater/src/DlgListNew.cpp @@ -1,489 +1,489 @@ -/* -Copyright (C) 2010 Mataes - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "common.h" - -static HWND hwndDialog; -HANDLE hListThread; - -static void SelectAll(HWND hDlg, bool bEnable) -{ - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES); - - for (int i=0; i < todo.getCount(); i++) { - ListView_SetCheckState(hwndList, i, bEnable); - todo[i].bEnabled = bEnable; - } -} - -static void ApplyDownloads(void *param) -{ - HWND hDlg = (HWND)param; - - ////////////////////////////////////////////////////////////////////////////////////// - // if we need to escalate priviledges, launch a atub - - if (!PrepareEscalation()) { - SendMessage(hDlg, WM_CLOSE, 0, 0); - return; - } - - ////////////////////////////////////////////////////////////////////////////////////// - // ok, let's unpack all zips - - AutoHandle pipe(hPipe); - HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES); - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - TCHAR tszBuff[2048], tszFileTemp[MAX_PATH], tszFileBack[MAX_PATH]; - - mir_sntprintf(tszFileBack, SIZEOF(tszFileBack), _T("%s\\Backups"), tszRoot); - SafeCreateDirectory(tszFileBack); - - mir_sntprintf(tszFileTemp, SIZEOF(tszFileTemp), _T("%s\\Temp"), tszRoot); - SafeCreateDirectory(tszFileTemp); - - HANDLE nlc = NULL; - for (int i=0; i < todo.getCount(); ++i) { - ListView_EnsureVisible(hwndList, i, FALSE); - if (!todo[i].bEnabled) { - ListView_SetItemText(hwndList, i, 2, TranslateT("Skipped.")); - continue; - } - - // download update - ListView_SetItemText(hwndList, i, 2, TranslateT("Downloading...")); - - FILEURL *pFileUrl = &todo[i].File; - if (!DownloadFile(pFileUrl, nlc)) { - ListView_SetItemText(hwndList, i, 2, TranslateT("Failed!")); - } - else - ListView_SetItemText(hwndList, i, 2, TranslateT("Succeeded.")); - } - Netlib_CloseHandle(nlc); - - if (todo.getCount() > 0) { - ShowPopup(0, LPGENT("Plugin Updater"), TranslateT("Download complete"), 2, 0); - - TCHAR *tszMirandaPath = Utils_ReplaceVarsT(_T("%miranda_path%")); - - for (int i = 0; i < todo.getCount(); i++) { - if (!todo[i].bEnabled) - continue; - - TCHAR tszBackFile[MAX_PATH]; - FILEINFO& p = todo[i]; - if (p.bDeleteOnly) { // we need only to backup the old file - TCHAR *ptszRelPath = p.tszNewName + _tcslen(tszMirandaPath) + 1; - mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, ptszRelPath); - BackupFile(p.tszNewName, tszBackFile); - continue; - } - - // if file name differs, we also need to backup the old file here - // otherwise it would be replaced by unzip - if ( _tcsicmp(p.tszOldName, p.tszNewName)) { - TCHAR tszSrcPath[MAX_PATH]; - mir_sntprintf(tszSrcPath, SIZEOF(tszSrcPath), _T("%s\\%s"), tszMirandaPath, p.tszOldName); - mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, p.tszOldName); - BackupFile(tszSrcPath, tszBackFile); - } - - if ( unzip(p.File.tszDiskPath, tszMirandaPath, tszFileBack,false)) - SafeDeleteFile(p.File.tszDiskPath); // remove .zip after successful update - } - } - - PopupDataText temp; - temp.Title = TranslateT("Plugin Updater"); - temp.Text = tszBuff; - lstrcpyn(tszBuff, TranslateT("Download complete. Do you want to go to plugins option page?"), SIZEOF(tszBuff)); - int rc = MessageBox(hDlg, temp.Text, temp.Title, MB_YESNO | MB_ICONQUESTION); - if (rc == IDYES) - CallFunctionAsync(OpenPluginOptions, 0); - - SendMessage(hDlg, WM_CLOSE, 0, 0); - return; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static WNDPROC oldWndProc = NULL; - -static LRESULT CALLBACK PluginListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_LBUTTONDOWN) { - LVHITTESTINFO hi; - hi.pt.x = LOWORD(lParam); hi.pt.y = HIWORD(lParam); - ListView_SubItemHitTest(hwnd, &hi); - if (hi.iSubItem == 1) { - LVITEM lvi = {0}; - lvi.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_GROUPID; - lvi.stateMask = -1; - lvi.iItem = hi.iItem; - if (ListView_GetItem(hwnd, &lvi) && lvi.iGroupId == 1) { - FILEINFO *info = (FILEINFO *)lvi.lParam; - - TCHAR tszFileName[MAX_PATH]; - _tcscpy(tszFileName, _tcsrchr(info->tszNewName, L'\\') + 1); - TCHAR *p = _tcschr(tszFileName, L'.'); *p = 0; - - TCHAR link[MAX_PATH]; - mir_sntprintf(link, MAX_PATH, _T("http://miranda-ng.org/p/%s"), tszFileName); - CallService(MS_UTILS_OPENURL, OUF_TCHAR, (LPARAM) link); - } - } - } - - return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam); -} - -static int ListDlg_Resize(HWND, LPARAM, UTILRESIZECONTROL *urc) -{ - switch (urc->wId) { - case IDC_SELNONE: - case IDOK: - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; - - case IDC_UPDATETEXT: - return RD_ANCHORX_CENTRE; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; -} - -INT_PTR CALLBACK DlgList(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES); - - switch (message) { - case WM_INITDIALOG: - hwndDialog = hDlg; - TranslateDialogDefault( hDlg ); - oldWndProc = (WNDPROC)SetWindowLongPtr(hwndList, GWLP_WNDPROC, (LONG_PTR)PluginListWndProc); - - SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon("plg_list", 1)); - SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon("plg_list")); - { - HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 4, 0); - ImageList_AddIconFromIconLib(hIml, "info"); - ListView_SetImageList(hwndList, hIml, LVSIL_SMALL); - - OSVERSIONINFO osver = { sizeof(osver) }; - if (GetVersionEx(&osver) && osver.dwMajorVersion >= 6) { - wchar_t szPath[MAX_PATH]; - GetModuleFileName(NULL, szPath, SIZEOF(szPath)); - TCHAR *ext = _tcsrchr(szPath, '.'); - if (ext != NULL) - *ext = '\0'; - _tcscat(szPath, _T(".test")); - HANDLE hFile = CreateFile(szPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) - // Running Windows Vista or later (major version >= 6). - Button_SetElevationRequiredState(GetDlgItem(hDlg, IDOK), !IsProcessElevated()); - else { - CloseHandle(hFile); - DeleteFile(szPath); - } - } - RECT r; - GetClientRect(hwndList, &r); - - /// - LVCOLUMN lvc = {0}; - lvc.mask = LVCF_WIDTH | LVCF_TEXT; - //lvc.fmt = LVCFMT_LEFT; - - lvc.pszText = TranslateT("Component Name"); - lvc.cx = 220; // width of column in pixels - ListView_InsertColumn(hwndList, 0, &lvc); - - lvc.pszText = L""; - lvc.cx = 32 - GetSystemMetrics(SM_CXVSCROLL); // width of column in pixels - ListView_InsertColumn(hwndList, 1, &lvc); - - lvc.pszText = TranslateT("State"); - lvc.cx = 100 - GetSystemMetrics(SM_CXVSCROLL); // width of column in pixels - ListView_InsertColumn(hwndList, 2, &lvc); - - /// - LVGROUP lvg; - lvg.cbSize = sizeof(LVGROUP); - lvg.mask = LVGF_HEADER | LVGF_GROUPID; - - lvg.pszHeader = TranslateT("Plugins"); - lvg.iGroupId = 1; - ListView_InsertGroup(hwndList, 0, &lvg); - - lvg.pszHeader = TranslateT("Icons"); - lvg.iGroupId = 2; - ListView_InsertGroup(hwndList, 0, &lvg); - - lvg.pszHeader = TranslateT("Languages"); - lvg.iGroupId = 3; - ListView_InsertGroup(hwndList, 0, &lvg); - - lvg.pszHeader = TranslateT("Other"); - lvg.iGroupId = 4; - ListView_InsertGroup(hwndList, 0, &lvg); - - ListView_EnableGroupView(hwndList, TRUE); - - /// - SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES | LVS_EX_CHECKBOXES | LVS_EX_LABELTIP); - ListView_DeleteAllItems(hwndList); - - /// - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)lParam; - for (int i = 0; i < todo.getCount(); ++i) { - LVITEM lvi = {0}; - lvi.mask = LVIF_PARAM | LVIF_GROUPID | LVIF_TEXT | LVIF_IMAGE; - - int groupId = 4; - if (_tcschr(todo[i].tszOldName, L'\\') != NULL) - groupId = (_tcsstr(todo[i].tszOldName, _T("Plugins")) != NULL) ? 1 : ((_tcsstr(todo[i].tszOldName, _T("Languages")) != NULL) ? 3 : 2); - - lvi.iItem = i; - lvi.lParam = (LPARAM)&todo[i]; - lvi.iGroupId = groupId; - lvi.iImage = -1; - lvi.pszText = todo[i].tszOldName; - int iRow = ListView_InsertItem(hwndList, &lvi); - - if (iRow != -1) { - lvi.iItem = iRow; - if (groupId == 1) { - lvi.mask = LVIF_IMAGE; - lvi.iSubItem = 1; - lvi.iImage = 0; - ListView_SetItem(hwndList, &lvi); - } - } - todo[i].bEnabled = false; - } - HWND hwOk = GetDlgItem(hDlg, IDOK); - EnableWindow(hwOk, false); - } - - // do this after filling list - enables 'ITEMCHANGED' below - SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam); - Utils_RestoreWindowPosition(hDlg, 0, MODNAME, "ListWindow"); - return TRUE; - - case WM_NOTIFY: - if (((LPNMHDR) lParam)->hwndFrom == hwndList) { - switch (((LPNMHDR) lParam)->code) { - case LVN_ITEMCHANGED: - if (GetWindowLongPtr(hDlg, GWLP_USERDATA)) { - NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam; - - LVITEM lvI = {0}; - lvI.iItem = nmlv->iItem; - lvI.iSubItem = 0; - lvI.mask = LVIF_PARAM; - ListView_GetItem(hwndList, &lvI); - - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - if ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK) { - todo[lvI.iItem].bEnabled = ListView_GetCheckState(hwndList, nmlv->iItem); - - bool enableOk = false; - for (int i=0; i < todo.getCount(); ++i) { - if (todo[i].bEnabled) { - enableOk = true; - break; - } - } - HWND hwOk = GetDlgItem(hDlg, IDOK); - EnableWindow(hwOk, enableOk ? TRUE : FALSE); - } - } - break; - } - } - break; - - case WM_COMMAND: - if (HIWORD( wParam ) == BN_CLICKED) { - switch(LOWORD(wParam)) { - case IDOK: - EnableWindow( GetDlgItem(hDlg, IDOK), FALSE); - EnableWindow( GetDlgItem(hDlg, IDC_SELNONE), FALSE); - - mir_forkthread(ApplyDownloads, hDlg); - return TRUE; - - case IDC_SELNONE: - SelectAll(hDlg, false); - break; - - case IDCANCEL: - DestroyWindow(hDlg); - return TRUE; - } - } - break; - - case WM_SIZE: // make the dlg resizeable - if (!IsIconic(hDlg)) { - UTILRESIZEDIALOG urd = { sizeof(urd) }; - urd.hInstance = hInst; - urd.hwndDlg = hDlg; - urd.lpTemplate = MAKEINTRESOURCEA(IDD_LIST); - urd.pfnResizer = ListDlg_Resize; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); - } - break; - - case WM_GETMINMAXINFO: - { - LPMINMAXINFO mmi = (LPMINMAXINFO)lParam; - - // The minimum width in points - mmi->ptMinTrackSize.x = 370; - // The minimum height in points - mmi->ptMinTrackSize.y = 300; - } - break; - - case WM_CLOSE: - DestroyWindow(hDlg); - break; - - case WM_DESTROY: - Utils_SaveWindowPosition(hDlg, NULL, MODNAME, "ListWindow"); - Skin_ReleaseIcon((HICON)SendMessage(hDlg, WM_SETICON, ICON_BIG, 0)); - Skin_ReleaseIcon((HICON)SendMessage(hDlg, WM_SETICON, ICON_SMALL, 0)); - hwndDialog = NULL; - delete (OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - SetWindowLongPtr(hDlg, GWLP_USERDATA, 0); - break; - } - - return FALSE; -} - -static void __stdcall LaunchListDialog(void *param) -{ - CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_LIST), GetDesktopWindow(), DlgList, (LPARAM)param); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// building file list in the separate thread - -static void GetList(void *) -{ - char szKey[64] = {0}; - - TCHAR tszTempPath[MAX_PATH]; - DWORD dwLen = GetTempPath(SIZEOF(tszTempPath), tszTempPath); - if (tszTempPath[dwLen-1] == '\\') - tszTempPath[dwLen-1] = 0; - - ptrT updateUrl( GetDefaultUrl()), baseUrl; - SERVLIST hashes(50, CompareHashes); - if (!ParseHashes(updateUrl, baseUrl, hashes)) { - hListThread = NULL; - return; - } - - FILELIST *UpdateFiles = new FILELIST(20); - TCHAR *dirname = Utils_ReplaceVarsT(_T("%miranda_path%")); - - for (int i=0; i < hashes.getCount(); i++) { - ServListEntry &hash = hashes[i]; - - TCHAR tszPath[MAX_PATH]; - mir_sntprintf(tszPath, SIZEOF(tszPath), _T("%s\\%s"), dirname, hash.m_name); - - if (GetFileAttributes(tszPath) != DWORD(-1)) - continue; - - FILEINFO *FileInfo = new FILEINFO; - FileInfo->bDeleteOnly = FALSE; - _tcscpy(FileInfo->tszOldName, hash.m_name); // copy the relative old name - _tcscpy(FileInfo->tszNewName, hash.m_name); - - TCHAR tszFileName[MAX_PATH]; - _tcscpy(tszFileName, _tcsrchr(tszPath, L'\\') + 1); - TCHAR *tp = _tcschr(tszFileName, L'.'); *tp = 0; - - TCHAR tszRelFileName[MAX_PATH]; - _tcscpy(tszRelFileName, hash.m_name); - tp = _tcsrchr(tszRelFileName, L'.'); if (tp) *tp = 0; - tp = _tcschr(tszRelFileName, L'\\'); if (tp) tp++; else tp = tszRelFileName; - _tcslwr(tp); - - mir_sntprintf(FileInfo->File.tszDiskPath, SIZEOF(FileInfo->File.tszDiskPath), _T("%s\\Temp\\%s.zip"), tszRoot, tszFileName); - mir_sntprintf(FileInfo->File.tszDownloadURL, SIZEOF(FileInfo->File.tszDownloadURL), _T("%s/%s.zip"), baseUrl, tszRelFileName); - for (tp = _tcschr(FileInfo->File.tszDownloadURL, '\\'); tp != 0; tp = _tcschr(tp, '\\')) - *tp++ = '/'; - FileInfo->File.CRCsum = hash.m_crc; - UpdateFiles->insert(FileInfo); - } - - mir_free(dirname); - - // Show dialog - if (UpdateFiles->getCount() == 0) { - if (!opts.bSilent) - ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("List is empty."), 2, 0); - delete UpdateFiles; - } - else CallFunctionAsync(LaunchListDialog, UpdateFiles); - - hListThread = NULL; -} - -void DoGetList(int iFlag) -{ - if (hListThread) - ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("List loading already started!"), 2, 0); - else if (hwndDialog) { - ShowWindow(hwndDialog, SW_SHOW); - SetForegroundWindow(hwndDialog); - SetFocus(hwndDialog); - } - else if (iFlag) - hListThread = mir_forkthread(GetList, 0); -} - -void UninitListNew() -{ - if (hwndDialog != NULL) - DestroyWindow(hwndDialog); -} - -INT_PTR ShowListCommand(WPARAM,LPARAM) -{ - opts.bSilent = false; - DoGetList(true); - return 0; -} - -void InitListNew() -{ - CreateServiceFunction(MODNAME"/ShowList", ShowListCommand); -} - -void UnloadListNew() -{ - if (hListThread) - hListThread = NULL; +/*
+Copyright (C) 2010 Mataes
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include "common.h"
+
+static HWND hwndDialog;
+HANDLE hListThread;
+
+static void SelectAll(HWND hDlg, bool bEnable)
+{
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES);
+
+ for (int i=0; i < todo.getCount(); i++) {
+ ListView_SetCheckState(hwndList, i, bEnable);
+ todo[i].bEnabled = bEnable;
+ }
+}
+
+static void ApplyDownloads(void *param)
+{
+ HWND hDlg = (HWND)param;
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // if we need to escalate priviledges, launch a atub
+
+ if (!PrepareEscalation()) {
+ PostMessage(hDlg, WM_CLOSE, 0, 0);
+ return;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // ok, let's unpack all zips
+
+ AutoHandle pipe(hPipe);
+ HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES);
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ TCHAR tszBuff[2048], tszFileTemp[MAX_PATH], tszFileBack[MAX_PATH];
+
+ mir_sntprintf(tszFileBack, SIZEOF(tszFileBack), _T("%s\\Backups"), tszRoot);
+ SafeCreateDirectory(tszFileBack);
+
+ mir_sntprintf(tszFileTemp, SIZEOF(tszFileTemp), _T("%s\\Temp"), tszRoot);
+ SafeCreateDirectory(tszFileTemp);
+
+ HANDLE nlc = NULL;
+ for (int i=0; i < todo.getCount(); ++i) {
+ ListView_EnsureVisible(hwndList, i, FALSE);
+ if (!todo[i].bEnabled) {
+ ListView_SetItemText(hwndList, i, 2, TranslateT("Skipped."));
+ continue;
+ }
+
+ // download update
+ ListView_SetItemText(hwndList, i, 2, TranslateT("Downloading..."));
+
+ FILEURL *pFileUrl = &todo[i].File;
+ if (!DownloadFile(pFileUrl, nlc)) {
+ ListView_SetItemText(hwndList, i, 2, TranslateT("Failed!"));
+ }
+ else
+ ListView_SetItemText(hwndList, i, 2, TranslateT("Succeeded."));
+ }
+ Netlib_CloseHandle(nlc);
+
+ if (todo.getCount() > 0) {
+ ShowPopup(0, LPGENT("Plugin Updater"), TranslateT("Download complete"), 2, 0);
+
+ TCHAR *tszMirandaPath = Utils_ReplaceVarsT(_T("%miranda_path%"));
+
+ for (int i = 0; i < todo.getCount(); i++) {
+ if (!todo[i].bEnabled)
+ continue;
+
+ TCHAR tszBackFile[MAX_PATH];
+ FILEINFO& p = todo[i];
+ if (p.bDeleteOnly) { // we need only to backup the old file
+ TCHAR *ptszRelPath = p.tszNewName + _tcslen(tszMirandaPath) + 1;
+ mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, ptszRelPath);
+ BackupFile(p.tszNewName, tszBackFile);
+ continue;
+ }
+
+ // if file name differs, we also need to backup the old file here
+ // otherwise it would be replaced by unzip
+ if ( _tcsicmp(p.tszOldName, p.tszNewName)) {
+ TCHAR tszSrcPath[MAX_PATH];
+ mir_sntprintf(tszSrcPath, SIZEOF(tszSrcPath), _T("%s\\%s"), tszMirandaPath, p.tszOldName);
+ mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, p.tszOldName);
+ BackupFile(tszSrcPath, tszBackFile);
+ }
+
+ if ( unzip(p.File.tszDiskPath, tszMirandaPath, tszFileBack,false))
+ SafeDeleteFile(p.File.tszDiskPath); // remove .zip after successful update
+ }
+ }
+
+ PopupDataText temp;
+ temp.Title = TranslateT("Plugin Updater");
+ temp.Text = tszBuff;
+ lstrcpyn(tszBuff, TranslateT("Download complete. Do you want to go to plugins option page?"), SIZEOF(tszBuff));
+ int rc = MessageBox(hDlg, temp.Text, temp.Title, MB_YESNO | MB_ICONQUESTION);
+ if (rc == IDYES)
+ CallFunctionAsync(OpenPluginOptions, 0);
+
+ PostMessage(hDlg, WM_CLOSE, 0, 0);
+ return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static WNDPROC oldWndProc = NULL;
+
+static LRESULT CALLBACK PluginListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_LBUTTONDOWN) {
+ LVHITTESTINFO hi;
+ hi.pt.x = LOWORD(lParam); hi.pt.y = HIWORD(lParam);
+ ListView_SubItemHitTest(hwnd, &hi);
+ if (hi.iSubItem == 1) {
+ LVITEM lvi = {0};
+ lvi.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_GROUPID;
+ lvi.stateMask = -1;
+ lvi.iItem = hi.iItem;
+ if (ListView_GetItem(hwnd, &lvi) && lvi.iGroupId == 1) {
+ FILEINFO *info = (FILEINFO *)lvi.lParam;
+
+ TCHAR tszFileName[MAX_PATH];
+ _tcscpy(tszFileName, _tcsrchr(info->tszNewName, L'\\') + 1);
+ TCHAR *p = _tcschr(tszFileName, L'.'); *p = 0;
+
+ TCHAR link[MAX_PATH];
+ mir_sntprintf(link, MAX_PATH, _T("http://miranda-ng.org/p/%s"), tszFileName);
+ CallService(MS_UTILS_OPENURL, OUF_TCHAR, (LPARAM) link);
+ }
+ }
+ }
+
+ return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam);
+}
+
+static int ListDlg_Resize(HWND, LPARAM, UTILRESIZECONTROL *urc)
+{
+ switch (urc->wId) {
+ case IDC_SELNONE:
+ case IDOK:
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
+
+ case IDC_UPDATETEXT:
+ return RD_ANCHORX_CENTRE;
+ }
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
+}
+
+INT_PTR CALLBACK DlgList(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES);
+
+ switch (message) {
+ case WM_INITDIALOG:
+ hwndDialog = hDlg;
+ TranslateDialogDefault( hDlg );
+ oldWndProc = (WNDPROC)SetWindowLongPtr(hwndList, GWLP_WNDPROC, (LONG_PTR)PluginListWndProc);
+
+ SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon("plg_list", 1));
+ SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon("plg_list"));
+ {
+ HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 4, 0);
+ ImageList_AddIconFromIconLib(hIml, "info");
+ ListView_SetImageList(hwndList, hIml, LVSIL_SMALL);
+
+ OSVERSIONINFO osver = { sizeof(osver) };
+ if (GetVersionEx(&osver) && osver.dwMajorVersion >= 6) {
+ wchar_t szPath[MAX_PATH];
+ GetModuleFileName(NULL, szPath, SIZEOF(szPath));
+ TCHAR *ext = _tcsrchr(szPath, '.');
+ if (ext != NULL)
+ *ext = '\0';
+ _tcscat(szPath, _T(".test"));
+ HANDLE hFile = CreateFile(szPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ // Running Windows Vista or later (major version >= 6).
+ Button_SetElevationRequiredState(GetDlgItem(hDlg, IDOK), !IsProcessElevated());
+ else {
+ CloseHandle(hFile);
+ DeleteFile(szPath);
+ }
+ }
+ RECT r;
+ GetClientRect(hwndList, &r);
+
+ ///
+ LVCOLUMN lvc = {0};
+ lvc.mask = LVCF_WIDTH | LVCF_TEXT;
+ //lvc.fmt = LVCFMT_LEFT;
+
+ lvc.pszText = TranslateT("Component Name");
+ lvc.cx = 220; // width of column in pixels
+ ListView_InsertColumn(hwndList, 0, &lvc);
+
+ lvc.pszText = L"";
+ lvc.cx = 32 - GetSystemMetrics(SM_CXVSCROLL); // width of column in pixels
+ ListView_InsertColumn(hwndList, 1, &lvc);
+
+ lvc.pszText = TranslateT("State");
+ lvc.cx = 100 - GetSystemMetrics(SM_CXVSCROLL); // width of column in pixels
+ ListView_InsertColumn(hwndList, 2, &lvc);
+
+ ///
+ LVGROUP lvg;
+ lvg.cbSize = sizeof(LVGROUP);
+ lvg.mask = LVGF_HEADER | LVGF_GROUPID;
+
+ lvg.pszHeader = TranslateT("Plugins");
+ lvg.iGroupId = 1;
+ ListView_InsertGroup(hwndList, 0, &lvg);
+
+ lvg.pszHeader = TranslateT("Icons");
+ lvg.iGroupId = 2;
+ ListView_InsertGroup(hwndList, 0, &lvg);
+
+ lvg.pszHeader = TranslateT("Languages");
+ lvg.iGroupId = 3;
+ ListView_InsertGroup(hwndList, 0, &lvg);
+
+ lvg.pszHeader = TranslateT("Other");
+ lvg.iGroupId = 4;
+ ListView_InsertGroup(hwndList, 0, &lvg);
+
+ ListView_EnableGroupView(hwndList, TRUE);
+
+ ///
+ SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES | LVS_EX_CHECKBOXES | LVS_EX_LABELTIP);
+ ListView_DeleteAllItems(hwndList);
+
+ ///
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)lParam;
+ for (int i = 0; i < todo.getCount(); ++i) {
+ LVITEM lvi = {0};
+ lvi.mask = LVIF_PARAM | LVIF_GROUPID | LVIF_TEXT | LVIF_IMAGE;
+
+ int groupId = 4;
+ if (_tcschr(todo[i].tszOldName, L'\\') != NULL)
+ groupId = (_tcsstr(todo[i].tszOldName, _T("Plugins")) != NULL) ? 1 : ((_tcsstr(todo[i].tszOldName, _T("Languages")) != NULL) ? 3 : 2);
+
+ lvi.iItem = i;
+ lvi.lParam = (LPARAM)&todo[i];
+ lvi.iGroupId = groupId;
+ lvi.iImage = -1;
+ lvi.pszText = todo[i].tszOldName;
+ int iRow = ListView_InsertItem(hwndList, &lvi);
+
+ if (iRow != -1) {
+ lvi.iItem = iRow;
+ if (groupId == 1) {
+ lvi.mask = LVIF_IMAGE;
+ lvi.iSubItem = 1;
+ lvi.iImage = 0;
+ ListView_SetItem(hwndList, &lvi);
+ }
+ }
+ todo[i].bEnabled = false;
+ }
+ HWND hwOk = GetDlgItem(hDlg, IDOK);
+ EnableWindow(hwOk, false);
+ }
+
+ // do this after filling list - enables 'ITEMCHANGED' below
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
+ Utils_RestoreWindowPosition(hDlg, 0, MODNAME, "ListWindow");
+ return TRUE;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR) lParam)->hwndFrom == hwndList) {
+ switch (((LPNMHDR) lParam)->code) {
+ case LVN_ITEMCHANGED:
+ if (GetWindowLongPtr(hDlg, GWLP_USERDATA)) {
+ NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam;
+
+ LVITEM lvI = {0};
+ lvI.iItem = nmlv->iItem;
+ lvI.iSubItem = 0;
+ lvI.mask = LVIF_PARAM;
+ ListView_GetItem(hwndList, &lvI);
+
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ if ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK) {
+ todo[lvI.iItem].bEnabled = ListView_GetCheckState(hwndList, nmlv->iItem);
+
+ bool enableOk = false;
+ for (int i=0; i < todo.getCount(); ++i) {
+ if (todo[i].bEnabled) {
+ enableOk = true;
+ break;
+ }
+ }
+ HWND hwOk = GetDlgItem(hDlg, IDOK);
+ EnableWindow(hwOk, enableOk ? TRUE : FALSE);
+ }
+ }
+ break;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ if (HIWORD( wParam ) == BN_CLICKED) {
+ switch(LOWORD(wParam)) {
+ case IDOK:
+ EnableWindow( GetDlgItem(hDlg, IDOK), FALSE);
+ EnableWindow( GetDlgItem(hDlg, IDC_SELNONE), FALSE);
+
+ mir_forkthread(ApplyDownloads, hDlg);
+ return TRUE;
+
+ case IDC_SELNONE:
+ SelectAll(hDlg, false);
+ break;
+
+ case IDCANCEL:
+ DestroyWindow(hDlg);
+ return TRUE;
+ }
+ }
+ break;
+
+ case WM_SIZE: // make the dlg resizeable
+ if (!IsIconic(hDlg)) {
+ UTILRESIZEDIALOG urd = { sizeof(urd) };
+ urd.hInstance = hInst;
+ urd.hwndDlg = hDlg;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_LIST);
+ urd.pfnResizer = ListDlg_Resize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+ }
+ break;
+
+ case WM_GETMINMAXINFO:
+ {
+ LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
+
+ // The minimum width in points
+ mmi->ptMinTrackSize.x = 370;
+ // The minimum height in points
+ mmi->ptMinTrackSize.y = 300;
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hDlg);
+ break;
+
+ case WM_DESTROY:
+ Utils_SaveWindowPosition(hDlg, NULL, MODNAME, "ListWindow");
+ Skin_ReleaseIcon((HICON)SendMessage(hDlg, WM_SETICON, ICON_BIG, 0));
+ Skin_ReleaseIcon((HICON)SendMessage(hDlg, WM_SETICON, ICON_SMALL, 0));
+ hwndDialog = NULL;
+ delete (OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, 0);
+ break;
+ }
+
+ return FALSE;
+}
+
+static void __stdcall LaunchListDialog(void *param)
+{
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_LIST), GetDesktopWindow(), DlgList, (LPARAM)param);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// building file list in the separate thread
+
+static void GetList(void *)
+{
+ char szKey[64] = {0};
+
+ TCHAR tszTempPath[MAX_PATH];
+ DWORD dwLen = GetTempPath(SIZEOF(tszTempPath), tszTempPath);
+ if (tszTempPath[dwLen-1] == '\\')
+ tszTempPath[dwLen-1] = 0;
+
+ ptrT updateUrl( GetDefaultUrl()), baseUrl;
+ SERVLIST hashes(50, CompareHashes);
+ if (!ParseHashes(updateUrl, baseUrl, hashes)) {
+ hListThread = NULL;
+ return;
+ }
+
+ FILELIST *UpdateFiles = new FILELIST(20);
+ TCHAR *dirname = Utils_ReplaceVarsT(_T("%miranda_path%"));
+
+ for (int i=0; i < hashes.getCount(); i++) {
+ ServListEntry &hash = hashes[i];
+
+ TCHAR tszPath[MAX_PATH];
+ mir_sntprintf(tszPath, SIZEOF(tszPath), _T("%s\\%s"), dirname, hash.m_name);
+
+ if (GetFileAttributes(tszPath) != DWORD(-1))
+ continue;
+
+ FILEINFO *FileInfo = new FILEINFO;
+ FileInfo->bDeleteOnly = FALSE;
+ _tcscpy(FileInfo->tszOldName, hash.m_name); // copy the relative old name
+ _tcscpy(FileInfo->tszNewName, hash.m_name);
+
+ TCHAR tszFileName[MAX_PATH];
+ _tcscpy(tszFileName, _tcsrchr(tszPath, L'\\') + 1);
+ TCHAR *tp = _tcschr(tszFileName, L'.'); *tp = 0;
+
+ TCHAR tszRelFileName[MAX_PATH];
+ _tcscpy(tszRelFileName, hash.m_name);
+ tp = _tcsrchr(tszRelFileName, L'.'); if (tp) *tp = 0;
+ tp = _tcschr(tszRelFileName, L'\\'); if (tp) tp++; else tp = tszRelFileName;
+ _tcslwr(tp);
+
+ mir_sntprintf(FileInfo->File.tszDiskPath, SIZEOF(FileInfo->File.tszDiskPath), _T("%s\\Temp\\%s.zip"), tszRoot, tszFileName);
+ mir_sntprintf(FileInfo->File.tszDownloadURL, SIZEOF(FileInfo->File.tszDownloadURL), _T("%s/%s.zip"), baseUrl, tszRelFileName);
+ for (tp = _tcschr(FileInfo->File.tszDownloadURL, '\\'); tp != 0; tp = _tcschr(tp, '\\'))
+ *tp++ = '/';
+ FileInfo->File.CRCsum = hash.m_crc;
+ UpdateFiles->insert(FileInfo);
+ }
+
+ mir_free(dirname);
+
+ // Show dialog
+ if (UpdateFiles->getCount() == 0) {
+ if (!opts.bSilent)
+ ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("List is empty."), 2, 0);
+ delete UpdateFiles;
+ }
+ else CallFunctionAsync(LaunchListDialog, UpdateFiles);
+
+ hListThread = NULL;
+}
+
+void DoGetList(int iFlag)
+{
+ if (hListThread)
+ ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("List loading already started!"), 2, 0);
+ else if (hwndDialog) {
+ ShowWindow(hwndDialog, SW_SHOW);
+ SetForegroundWindow(hwndDialog);
+ SetFocus(hwndDialog);
+ }
+ else if (iFlag)
+ hListThread = mir_forkthread(GetList, 0);
+}
+
+void UninitListNew()
+{
+ if (hwndDialog != NULL)
+ DestroyWindow(hwndDialog);
+}
+
+INT_PTR ShowListCommand(WPARAM,LPARAM)
+{
+ opts.bSilent = false;
+ DoGetList(true);
+ return 0;
+}
+
+void InitListNew()
+{
+ CreateServiceFunction(MODNAME"/ShowList", ShowListCommand);
+}
+
+void UnloadListNew()
+{
+ if (hListThread)
+ hListThread = NULL;
}
\ No newline at end of file diff --git a/plugins/PluginUpdater/src/DlgUpdate.cpp b/plugins/PluginUpdater/src/DlgUpdate.cpp index 711bfcd57b..258efd4389 100644 --- a/plugins/PluginUpdater/src/DlgUpdate.cpp +++ b/plugins/PluginUpdater/src/DlgUpdate.cpp @@ -1,764 +1,764 @@ -/* -Copyright (C) 2010 Mataes - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "common.h" - -#define UM_ERROR (WM_USER+1) - -static bool bShowDetails; -static HWND hwndDialog; -HANDLE hCheckThread; - -static void SelectAll(HWND hDlg, bool bEnable) -{ - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES); - - for (int i=0; i < todo.getCount(); i++) { - ListView_SetCheckState(hwndList, i, bEnable); - db_set_b(NULL, MODNAME "Files", StrToLower(_T2A(todo[i].tszOldName)), todo[i].bEnabled = bEnable); - } -} - -static void SetStringText(HWND hWnd, size_t i, TCHAR *ptszText) -{ - ListView_SetItemText(hWnd, i, 1, ptszText); -} - -static void ApplyUpdates(void *param) -{ - HWND hDlg = (HWND)param; - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - if (todo.getCount() == 0) { - return; - } - - // 1) If we need to escalate priviledges, launch a stub - if (!PrepareEscalation()) { - SendMessage(hDlg, WM_CLOSE, 0, 0); - return; - } - - AutoHandle pipe(hPipe); - HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES); - TCHAR tszFileTemp[MAX_PATH], tszFileBack[MAX_PATH]; - - mir_sntprintf(tszFileBack, SIZEOF(tszFileBack), _T("%s\\Backups"), tszRoot); - SafeCreateDirectory(tszFileBack); - - mir_sntprintf(tszFileTemp, SIZEOF(tszFileTemp), _T("%s\\Temp"), tszRoot); - SafeCreateDirectory(tszFileTemp); - - // 2) Download all plugins - HANDLE nlc = NULL; - for (int i=0; i < todo.getCount(); i++) { - ListView_EnsureVisible(hwndList, i, FALSE); - if (!todo[i].bEnabled) { - SetStringText(hwndList, i, TranslateT("Skipped.")); - } - else if (todo[i].bDeleteOnly) { - SetStringText(hwndList, i, TranslateT("Will be deleted!")); - } - else { - // download update - SetStringText(hwndList, i, TranslateT("Downloading...")); - - FILEURL *pFileUrl = &todo[i].File; - if (!DownloadFile(pFileUrl, nlc)) { - SetStringText(hwndList, i, TranslateT("Failed!")); - - // interrupt update as we require all components to be updated - Netlib_CloseHandle(nlc); - PostMessage(hDlg, UM_ERROR, 0, 0); - SkinPlaySound("updatefailed"); - return; - } - SetStringText(hwndList, i, TranslateT("Succeeded.")); - } - } - Netlib_CloseHandle(nlc); - - // 3) Unpack all zips - TCHAR *tszMirandaPath = Utils_ReplaceVarsT(_T("%miranda_path%")); - for (int i = 0; i < todo.getCount(); i++) { - if (todo[i].bEnabled) { - TCHAR tszBackFile[MAX_PATH]; - FILEINFO& p = todo[i]; - if (p.bDeleteOnly) { - // we need only to backup the old file - TCHAR *ptszRelPath = p.tszNewName + _tcslen(tszMirandaPath) + 1; - mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, ptszRelPath); - BackupFile(p.tszNewName, tszBackFile); - } - else { - // if file name differs, we also need to backup the old file here - // otherwise it would be replaced by unzip - if ( _tcsicmp(p.tszOldName, p.tszNewName)) { - TCHAR tszSrcPath[MAX_PATH]; - mir_sntprintf(tszSrcPath, SIZEOF(tszSrcPath), _T("%s\\%s"), tszMirandaPath, p.tszOldName); - mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, p.tszOldName); - BackupFile(tszSrcPath, tszBackFile); - } - - if ( unzip(p.File.tszDiskPath, tszMirandaPath, tszFileBack,true)) - SafeDeleteFile(p.File.tszDiskPath); // remove .zip after successful update - } - } - } - SkinPlaySound("updatecompleted"); - -#if MIRANDA_VER < 0x0A00 - // 4) Change title of clist - ptrT title = db_get_tsa(NULL, "CList", "TitleText"); - if (!_tcsicmp(title, _T("Miranda IM"))) - db_set_ts(NULL, "CList", "TitleText", _T("Miranda NG")); -#endif - - opts.bForceRedownload = false; - db_unset(NULL, MODNAME, "ForceRedownload"); - - db_set_b(NULL, MODNAME, "RestartCount", 5); - - // 5) Prepare Restart - int rc = MessageBox(hDlg, TranslateT("Update complete. Press Yes to restart Miranda now or No to postpone a restart until the exit."), TranslateT("Plugin Updater"), MB_YESNO | MB_ICONQUESTION); - SendMessage(hDlg, WM_CLOSE, 0, 0); - if (rc == IDYES) - CallFunctionAsync(RestartMe, 0); -} - -static void ResizeVert(HWND hDlg, int yy) -{ - RECT r = { 0, 0, 244, yy }; - MapDialogRect(hDlg, &r); - r.bottom += GetSystemMetrics(SM_CYSMCAPTION); - SetWindowPos(hDlg, 0, 0, 0, r.right, r.bottom, SWP_NOMOVE | SWP_NOZORDER); -} - -static INT_PTR CALLBACK DlgUpdate(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES); - - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hDlg); - SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); - SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon("check_update")); - SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon("check_update", 1)); - { - OSVERSIONINFO osver = { sizeof(osver) }; - if (GetVersionEx(&osver) && osver.dwMajorVersion >= 6) - { - wchar_t szPath[MAX_PATH]; - GetModuleFileName(NULL, szPath, SIZEOF(szPath)); - TCHAR *ext = _tcsrchr(szPath, '.'); - if (ext != NULL) - *ext = '\0'; - _tcscat(szPath, _T(".test")); - HANDLE hFile = CreateFile(szPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) - // Running Windows Vista or later (major version >= 6). - Button_SetElevationRequiredState(GetDlgItem(hDlg, IDOK), !IsProcessElevated()); - else - { - CloseHandle(hFile); - DeleteFile(szPath); - } - } - RECT r; - GetClientRect(hwndList, &r); - - LVCOLUMN lvc = {0}; - // Initialize the LVCOLUMN structure. - // The mask specifies that the format, width, text, and - // subitem members of the structure are valid. - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; - lvc.fmt = LVCFMT_LEFT; - - lvc.iSubItem = 0; - lvc.pszText = TranslateT("Component Name"); - lvc.cx = 220; // width of column in pixels - ListView_InsertColumn(hwndList, 0, &lvc); - - lvc.iSubItem = 1; - lvc.pszText = TranslateT("State"); - lvc.cx = 120 - GetSystemMetrics(SM_CXVSCROLL); // width of column in pixels - ListView_InsertColumn(hwndList, 1, &lvc); - - //enumerate plugins, fill in list - //bool one_enabled = false; - ListView_DeleteAllItems(hwndList); - - // Some code to create the list-view control. - // Initialize LVITEM members that are common to all items. - LVITEM lvI = {0}; - lvI.mask = LVIF_TEXT | LVIF_PARAM | LVIF_NORECOMPUTE;// | LVIF_IMAGE; - - bool enableOk = false; - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)lParam; - for (int i = 0; i < todo.getCount(); ++i) { - lvI.mask = LVIF_TEXT | LVIF_PARAM;// | LVIF_IMAGE; - lvI.iSubItem = 0; - lvI.lParam = (LPARAM)&todo[i]; - lvI.pszText = todo[i].tszOldName; - lvI.iItem = i; - ListView_InsertItem(hwndList, &lvI); - - // remember whether the user has decided not to update this component with this particular new version - todo[i].bEnabled = db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(todo[i].tszOldName)), true); - ListView_SetCheckState(hwndList, lvI.iItem, todo[i].bEnabled); - if (todo[i].bEnabled) - enableOk = true; - } - HWND hwOk = GetDlgItem(hDlg, IDOK); - EnableWindow(hwOk, enableOk); - } - - bShowDetails = false; - ResizeVert(hDlg, 60); - - // do this after filling list - enables 'ITEMCHANGED' below - SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam); - Utils_RestoreWindowPositionNoSize(hDlg, 0, MODNAME, "ConfirmWindow"); - return TRUE; - - case WM_NOTIFY: - if (((LPNMHDR) lParam)->hwndFrom == hwndList) { - switch (((LPNMHDR) lParam)->code) { - case LVN_ITEMCHANGED: - if (GetWindowLongPtr(hDlg, GWLP_USERDATA)) { - NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam; - - LVITEM lvI = {0}; - lvI.iItem = nmlv->iItem; - lvI.iSubItem = 0; - lvI.mask = LVIF_PARAM; - ListView_GetItem(hwndList, &lvI); - - OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - if ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK) { - todo[lvI.iItem].bEnabled = ListView_GetCheckState(hwndList, nmlv->iItem); - db_set_b(NULL, MODNAME "Files", StrToLower(_T2A(todo[lvI.iItem].tszOldName)), todo[lvI.iItem].bEnabled); - - bool enableOk = false; - for (int i=0; i < todo.getCount(); ++i) { - if (todo[i].bEnabled) { - enableOk = true; - break; - } - } - HWND hwOk = GetDlgItem(hDlg, IDOK); - EnableWindow(hwOk, enableOk ? TRUE : FALSE); - } - } - break; - } - } - break; - - case WM_COMMAND: - if (HIWORD( wParam ) == BN_CLICKED) { - switch(LOWORD(wParam)) { - case IDOK: - EnableWindow( GetDlgItem(hDlg, IDOK), FALSE); - EnableWindow( GetDlgItem(hDlg, IDC_SELALL), FALSE); - EnableWindow( GetDlgItem(hDlg, IDC_SELNONE), FALSE); - - mir_forkthread(ApplyUpdates, hDlg); - return TRUE; - - case IDC_DETAILS: - bShowDetails = !bShowDetails; - ResizeVert(hDlg, bShowDetails ? 242 : 60); - SetDlgItemText(hDlg, IDC_DETAILS, (bShowDetails ? TranslateT("<< Details") : TranslateT("Details >>"))); - break; - - case IDC_SELALL: - SelectAll(hDlg, true); - break; - - case IDC_SELNONE: - SelectAll(hDlg, false); - break; - - case IDCANCEL: - DestroyWindow(hDlg); - return TRUE; - } - } - break; - - case UM_ERROR: - MessageBox(hDlg, TranslateT("Update failed! One of the components wasn't downloaded correctly. Try it again later."), TranslateT("Plugin Updater"), MB_OK | MB_ICONERROR); - DestroyWindow(hDlg); - break; - - case WM_CLOSE: - DestroyWindow(hDlg); - break; - - case WM_DESTROY: - Skin_ReleaseIcon((HICON)SendMessage(hDlg, WM_SETICON, ICON_SMALL, 0)); - Utils_SaveWindowPosition(hDlg, NULL, MODNAME, "ConfirmWindow"); - hwndDialog = NULL; - opts.bSilent = true; - delete (OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - SetWindowLongPtr(hDlg, GWLP_USERDATA, 0); - #if MIRANDA_VER >= 0x0A00 - db_set_dw(NULL, MODNAME, "LastUpdate", time(NULL)); - #endif - mir_forkthread(InitTimer, (void*)0); - break; - } - - return FALSE; -} - -static LRESULT CALLBACK PopupDlgProcRestart(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_COMMAND: - case WM_CONTEXTMENU: - PUDeletePopup(hDlg); - - if (uMsg == WM_COMMAND) { - TCHAR tszText[200]; - mir_sntprintf(tszText, SIZEOF(tszText), _T("%s\n\n%s"), TranslateT("You need to restart your Miranda to apply installed updates."), TranslateT("Would you like to restart it now?")); - - if (MessageBox(hDlg, tszText, TranslateT("Plugin Updater"), MB_YESNO | MB_ICONQUESTION) == IDYES) - CallFunctionAsync(RestartMe, 0); - } - - return TRUE; - } - - return DefWindowProc(hDlg, uMsg, wParam, lParam); -} - -static void DlgUpdateSilent(void *lParam) -{ - OBJLIST<FILEINFO> &UpdateFiles = *(OBJLIST<FILEINFO> *)lParam; - if (UpdateFiles.getCount() == 0) { - delete &UpdateFiles; - return; - } - - // 1) If we need to escalate priviledges, launch a stub - if (!PrepareEscalation()) { - delete &UpdateFiles; - return; - } - - AutoHandle pipe(hPipe); - TCHAR tszFileTemp[MAX_PATH], tszFileBack[MAX_PATH]; - - mir_sntprintf(tszFileBack, SIZEOF(tszFileBack), _T("%s\\Backups"), tszRoot); - SafeCreateDirectory(tszFileBack); - - mir_sntprintf(tszFileTemp, SIZEOF(tszFileTemp), _T("%s\\Temp"), tszRoot); - SafeCreateDirectory(tszFileTemp); - - // 2) Download all plugins - HANDLE nlc = NULL; - // Count all updates that have been enabled - int count = 0; - for (int i = 0; i < UpdateFiles.getCount(); i++) { - if (db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(UpdateFiles[i].tszOldName)), 1) && !UpdateFiles[i].bDeleteOnly) { - // download update - FILEURL *pFileUrl = &UpdateFiles[i].File; - if (!DownloadFile(pFileUrl, nlc)) { - // interrupt update as we require all components to be updated - Netlib_CloseHandle(nlc); - SkinPlaySound("updatefailed"); - delete &UpdateFiles; - return; - } - count++; - } - - } - Netlib_CloseHandle(nlc); - - if (count == 0) { - delete &UpdateFiles; - return; - } - - // 3) Unpack all zips - TCHAR *tszMirandaPath = Utils_ReplaceVarsT(_T("%miranda_path%")); - for (int i = 0; i < UpdateFiles.getCount(); i++) { - if (db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(UpdateFiles[i].tszOldName)), 1)) { - TCHAR tszBackFile[MAX_PATH]; - FILEINFO& p = UpdateFiles[i]; - if (p.bDeleteOnly) { // we need only to backup the old file - TCHAR *ptszRelPath = p.tszNewName + _tcslen(tszMirandaPath) + 1; - mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, ptszRelPath); - BackupFile(p.tszNewName, tszBackFile); - } - else { - // if file name differs, we also need to backup the old file here - // otherwise it would be replaced by unzip - if (_tcsicmp(p.tszOldName, p.tszNewName)) { - TCHAR tszSrcPath[MAX_PATH]; - mir_sntprintf(tszSrcPath, SIZEOF(tszSrcPath), _T("%s\\%s"), tszMirandaPath, p.tszOldName); - mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, p.tszOldName); - BackupFile(tszSrcPath, tszBackFile); - } - - if (unzip(p.File.tszDiskPath, tszMirandaPath, tszFileBack, true)) - SafeDeleteFile(p.File.tszDiskPath); // remove .zip after successful update - } - } - } - delete &UpdateFiles; - SkinPlaySound("updatecompleted"); - -#if MIRANDA_VER < 0x0A00 - // 4) Change title of clist - ptrT title = db_get_tsa(NULL, "CList", "TitleText"); - if (!_tcsicmp(title, _T("Miranda IM"))) - db_set_ts(NULL, "CList", "TitleText", _T("Miranda NG")); -#endif - - opts.bForceRedownload = false; - db_unset(NULL, MODNAME, "ForceRedownload"); - - db_set_b(NULL, MODNAME, "RestartCount", 5); - db_set_b(NULL, MODNAME, "NeedRestart", 1); - - // 5) Prepare Restart - TCHAR tszTitle[100]; - mir_sntprintf(tszTitle, SIZEOF(tszTitle), TranslateT("%d component(s) was updated"), count); - - if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) { - POPUPDATAT_V2 pd = { 0 }; - pd.cbSize = sizeof(pd); - pd.lchContact = NULL; - pd.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); - pd.colorBack = pd.colorText = 0; - pd.iSeconds = -1; - pd.PluginWindowProc = PopupDlgProcRestart; - - lstrcpyn(pd.lptzText, TranslateT("You need to restart your Miranda to apply installed updates."), MAX_SECONDLINE); - lstrcpyn(pd.lptzContactName, tszTitle, MAX_CONTACTNAME); - - CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&pd, APF_NEWDATA); - } else { - bool notified = false; - - if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) { - MIRANDASYSTRAYNOTIFY err; - err.szProto = MODULEA; - err.cbSize = sizeof(err); - err.dwInfoFlags = NIIF_INTERN_UNICODE | NIIF_INFO; - err.tszInfoTitle = tszTitle; - err.tszInfo = TranslateT("You need to restart your Miranda to apply installed updates."); - err.uTimeout = 30000; - - notified = !CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM)&err); - } - - if (!notified) { - // Error, let's try to show MessageBox as last way to inform user about successful update - TCHAR tszText[200]; - mir_sntprintf(tszText, SIZEOF(tszText), _T("%s\n\n%s"), TranslateT("You need to restart your Miranda to apply installed updates."), TranslateT("Would you like to restart it now?")); - - if (MessageBox(NULL, tszText, tszTitle, MB_ICONINFORMATION | MB_YESNO) == IDYES) - CallFunctionAsync(RestartMe, 0); - } - } -} - -static void __stdcall LaunchDialog(void *param) -{ - if (opts.bSilentMode && opts.bSilent) - mir_forkthread(DlgUpdateSilent, param); - else - hwndDialog = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_UPDATE), GetDesktopWindow(), DlgUpdate, (LPARAM)param); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// building file list in the separate thread - -struct -{ - TCHAR *oldName, *newName; -} -static renameTable[] = -{ - { _T("svc_dbepp.dll"), _T("Plugins\\dbeditorpp.dll") }, - { _T("svc_crshdmp.dll"), _T("Plugins\\crashdumper.dll") }, - { _T("svc_vi.dll"), _T("Plugins\\versioninfo.dll") }, - { _T("crashrpt.dll"), _T("Plugins\\crashdumper.dll") }, - { _T("advsplashscreen.dll"), _T("Plugins\\splashscreen.dll") }, - { _T("import_sa.dll"), _T("Plugins\\import.dll") }, - { _T("newnr.dll"), _T("Plugins\\notesreminders.dll") }, - { _T("dbtool.exe"), _T("Plugins\\dbchecker.dll") }, - { _T("dbtool_sa.exe"), _T("Plugins\\dbchecker.dll") }, - { _T("bclist.dll"), _T("Plugins\\clist_blind.dll") }, - { _T("otr.dll"), _T("Plugins\\mirotr.dll") }, - { _T("ttnotify.dll"), _T("Plugins\\tooltipnotify.dll") }, - { _T("newstatusnotify.dll"), _T("Plugins\\newxstatusnotify.dll") }, - { _T("rss.dll"), _T("Plugins\\newsaggregator.dll") }, - { _T("dbx_3x.dll"), _T("Plugins\\dbx_mmap.dll") }, - - #if MIRANDA_VER >= 0x0A00 - { _T("dbx_mmap_sa.dll"), _T("Plugins\\dbx_mmap.dll") }, - { _T("dbx_tree.dll"), _T("Plugins\\dbx_mmap.dll") }, - { _T("rc4.dll"), NULL }, - { _T("athena.dll"), NULL }, - #endif - - { _T("proto_newsaggr.dll"), _T("Icons\\proto_newsaggregator.dll") }, - { _T("clienticons_*.dll"), _T("Icons\\fp_icons.dll") }, - { _T("fp_*.dll"), _T("Icons\\fp_icons.dll") }, - - { _T("langpack_*.txt"), _T("Languages\\*") }, - - { _T("clist_classic.dll"), NULL }, - { _T("chat.dll"), NULL }, - { _T("gender.dll"), NULL }, - { _T("srmm.dll"), NULL }, - { _T("extraicons.dll"), NULL }, - { _T("langman.dll"), NULL }, - { _T("metacontacts.dll"), NULL }, -}; - -static bool CheckFileRename(const TCHAR *ptszOldName, TCHAR *pNewName) -{ - for (int i = 0; i < SIZEOF(renameTable); i++) { - if (!wildcmpit(ptszOldName, renameTable[i].oldName)) - continue; - - TCHAR *ptszDest = renameTable[i].newName; - if (ptszDest == NULL) - *pNewName = 0; - else { - _tcsncpy_s(pNewName, MAX_PATH, ptszDest, _TRUNCATE); - size_t cbLen = _tcslen(ptszDest) - 1; - if (pNewName[cbLen] == '*') - _tcsncpy_s(pNewName + cbLen, MAX_PATH - cbLen, ptszOldName, _TRUNCATE); - } - return true; - } - - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static bool isValidExtension(const TCHAR *ptszFileName) -{ - const TCHAR *pExt = _tcsrchr(ptszFileName, '.'); - - return (pExt != NULL) && (!_tcsicmp(pExt, _T(".dll")) || !_tcsicmp(pExt, _T(".exe")) || !_tcsicmp(pExt, _T(".txt"))); -} - -static int ScanFolder(const TCHAR *tszFolder, size_t cbBaseLen, int level, const TCHAR *tszBaseUrl, SERVLIST& hashes, OBJLIST<FILEINFO> *UpdateFiles) -{ - int count = 0; - - // skip updater's own folder - if (!_tcsicmp(tszFolder, tszRoot)) - return count; - - TCHAR tszBuf[MAX_PATH]; - mir_sntprintf(tszBuf, SIZEOF(tszBuf), _T("%s\\*"), tszFolder); - - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(tszBuf, &ffd); - if (hFind == INVALID_HANDLE_VALUE) - return count; - - do { - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (_tcscmp(ffd.cFileName, _T(".")) && _tcscmp(ffd.cFileName, _T(".."))) { - // we need to skip profile folder - TCHAR tszProfilePath[MAX_PATH]; - CallService(MS_DB_GETPROFILEPATHT, SIZEOF(tszProfilePath), (LPARAM)tszProfilePath); - - mir_sntprintf(tszBuf, SIZEOF(tszBuf), _T("%s\\%s"), tszFolder, ffd.cFileName); - if (0 != _tcsicmp(tszBuf, tszProfilePath)) - count += ScanFolder(tszBuf, cbBaseLen, level+1, tszBaseUrl, hashes, UpdateFiles); - } - } - else if (isValidExtension(ffd.cFileName)) { - // calculate the current file's relative name and store it into tszNewName - TCHAR tszNewName[MAX_PATH]; - if (!CheckFileRename(ffd.cFileName, tszNewName)) { - if (level == 0) - _tcsncpy(tszNewName, ffd.cFileName, MAX_PATH); - else - mir_sntprintf(tszNewName, SIZEOF(tszNewName), _T("%s\\%s"), tszFolder+cbBaseLen, ffd.cFileName); - } - - bool bHasNewVersion = true; - TCHAR *ptszUrl; - int MyCRC = 0; - mir_sntprintf(tszBuf, SIZEOF(tszBuf), _T("%s\\%s"), tszFolder, ffd.cFileName); - - // this file is not marked for deletion - if (tszNewName[0]) { - TCHAR *pName = tszNewName; - ServListEntry *item = hashes.find((ServListEntry*)&pName); - if (item == NULL) { - TCHAR *p = _tcsrchr(tszNewName, '.'); - if (p[-1] != 'w' && p[-1] != 'W') - continue; - - int iPos = int(p - tszNewName)-1; - strdel(p-1, 1); - if ((item = hashes.find((ServListEntry*)&pName)) == NULL) - continue; - - strdel(tszNewName+iPos, 1); - } - - ptszUrl = item->m_name; - // No need to hash a file if we are forcing a redownload anyway - if (!opts.bForceRedownload) { - // try to hash the file - char szMyHash[33]; - __try { - CalculateModuleHash(tszBuf, szMyHash); - bHasNewVersion = strcmp(szMyHash, item->m_szHash) != 0; - } - __except(EXCEPTION_EXECUTE_HANDLER) { - ZeroMemory(szMyHash, 0); - // smth went wrong, reload a file from scratch - } - } - - MyCRC = item->m_crc; - } - else // file was marked for deletion, add it to the list anyway - ptszUrl = _T(""); - - // Compare versions - if (bHasNewVersion) { // Yeah, we've got new version. - FILEINFO *FileInfo = new FILEINFO; - _tcscpy(FileInfo->tszOldName, tszBuf+cbBaseLen); // copy the relative old name - if (tszNewName[0] == 0) { - FileInfo->bDeleteOnly = TRUE; - _tcscpy(FileInfo->tszNewName, tszBuf); // save the full old name for deletion - } - else { - FileInfo->bDeleteOnly = FALSE; - _tcsncpy(FileInfo->tszNewName, ptszUrl, SIZEOF(FileInfo->tszNewName)); - } - - _tcscpy(tszBuf, ptszUrl); - TCHAR *p = _tcsrchr(tszBuf, '.'); - if (p) *p = 0; - p = _tcsrchr(tszBuf, '\\'); - p = (p) ? p+1 : tszBuf; - _tcslwr(p); - - mir_sntprintf(FileInfo->File.tszDiskPath, SIZEOF(FileInfo->File.tszDiskPath), _T("%s\\Temp\\%s.zip"), tszRoot, p); - mir_sntprintf(FileInfo->File.tszDownloadURL, SIZEOF(FileInfo->File.tszDownloadURL), _T("%s/%s.zip"), tszBaseUrl, tszBuf); - for (p = _tcschr(FileInfo->File.tszDownloadURL, '\\'); p != 0; p = _tcschr(p, '\\')) - *p++ = '/'; - - FileInfo->File.CRCsum = MyCRC; - UpdateFiles->insert(FileInfo); - - if (!opts.bSilent || db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(FileInfo->tszNewName)), true)) - count++; - } // end compare versions - } - } - while (FindNextFile(hFind, &ffd) != 0); - - FindClose(hFind); - return count; -} - -static void CheckUpdates(void *) -{ - char szKey[64] = {0}; - - TCHAR tszTempPath[MAX_PATH]; - DWORD dwLen = GetTempPath(SIZEOF(tszTempPath), tszTempPath); - if (tszTempPath[dwLen-1] == '\\') - tszTempPath[dwLen-1] = 0; - - ptrT updateUrl(GetDefaultUrl()), baseUrl; - - SERVLIST hashes(50, CompareHashes); - bool success = ParseHashes(updateUrl, baseUrl, hashes); - if (success) { - FILELIST *UpdateFiles = new FILELIST(20); - VARST dirname( _T("%miranda_path%")); - int count = ScanFolder(dirname, lstrlen(dirname)+1, 0, baseUrl, hashes, UpdateFiles); - - // Show dialog - if (count == 0) { - if (!opts.bSilent) - ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("No updates found."), 2, 0); - delete UpdateFiles; - opts.bSilent = true; - } - else CallFunctionAsync(LaunchDialog, UpdateFiles); - } - else opts.bSilent = true; - - mir_forkthread(InitTimer, (void*)(success ? 0 : 2)); - - hashes.destroy(); - hCheckThread = NULL; -} - -void DoCheck() -{ - if (hCheckThread) - ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("Update checking already started!"), 2, 0); - else if (hwndDialog) { - ShowWindow(hwndDialog, SW_SHOW); - SetForegroundWindow(hwndDialog); - SetFocus(hwndDialog); - } else { - #if MIRANDA_VER >= 0x0A00 - db_set_dw(NULL, MODNAME, "LastUpdate", time(NULL)); - #endif - hCheckThread = mir_forkthread(CheckUpdates, 0); - } -} - -void UninitCheck() -{ - if (hwndDialog != NULL) - DestroyWindow(hwndDialog); -} - -INT_PTR MenuCommand(WPARAM,LPARAM) -{ - opts.bSilent = false; - DoCheck(); - return 0; -} - -void InitCheck() -{ - CreateServiceFunction(MODNAME"/CheckUpdates", MenuCommand); -} - -void UnloadCheck() -{ - if (hCheckThread) - hCheckThread = NULL; +/*
+Copyright (C) 2010 Mataes
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include "common.h"
+
+#define UM_ERROR (WM_USER+1)
+
+static bool bShowDetails;
+static HWND hwndDialog;
+HANDLE hCheckThread;
+
+static void SelectAll(HWND hDlg, bool bEnable)
+{
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES);
+
+ for (int i=0; i < todo.getCount(); i++) {
+ ListView_SetCheckState(hwndList, i, bEnable);
+ db_set_b(NULL, MODNAME "Files", StrToLower(_T2A(todo[i].tszOldName)), todo[i].bEnabled = bEnable);
+ }
+}
+
+static void SetStringText(HWND hWnd, size_t i, TCHAR *ptszText)
+{
+ ListView_SetItemText(hWnd, i, 1, ptszText);
+}
+
+static void ApplyUpdates(void *param)
+{
+ HWND hDlg = (HWND)param;
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ if (todo.getCount() == 0) {
+ return;
+ }
+
+ // 1) If we need to escalate priviledges, launch a stub
+ if (!PrepareEscalation()) {
+ PostMessage(hDlg, WM_CLOSE, 0, 0);
+ return;
+ }
+
+ AutoHandle pipe(hPipe);
+ HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES);
+ TCHAR tszFileTemp[MAX_PATH], tszFileBack[MAX_PATH];
+
+ mir_sntprintf(tszFileBack, SIZEOF(tszFileBack), _T("%s\\Backups"), tszRoot);
+ SafeCreateDirectory(tszFileBack);
+
+ mir_sntprintf(tszFileTemp, SIZEOF(tszFileTemp), _T("%s\\Temp"), tszRoot);
+ SafeCreateDirectory(tszFileTemp);
+
+ // 2) Download all plugins
+ HANDLE nlc = NULL;
+ for (int i=0; i < todo.getCount(); i++) {
+ ListView_EnsureVisible(hwndList, i, FALSE);
+ if (!todo[i].bEnabled) {
+ SetStringText(hwndList, i, TranslateT("Skipped."));
+ }
+ else if (todo[i].bDeleteOnly) {
+ SetStringText(hwndList, i, TranslateT("Will be deleted!"));
+ }
+ else {
+ // download update
+ SetStringText(hwndList, i, TranslateT("Downloading..."));
+
+ FILEURL *pFileUrl = &todo[i].File;
+ if (!DownloadFile(pFileUrl, nlc)) {
+ SetStringText(hwndList, i, TranslateT("Failed!"));
+
+ // interrupt update as we require all components to be updated
+ Netlib_CloseHandle(nlc);
+ PostMessage(hDlg, UM_ERROR, 0, 0);
+ SkinPlaySound("updatefailed");
+ return;
+ }
+ SetStringText(hwndList, i, TranslateT("Succeeded."));
+ }
+ }
+ Netlib_CloseHandle(nlc);
+
+ // 3) Unpack all zips
+ TCHAR *tszMirandaPath = Utils_ReplaceVarsT(_T("%miranda_path%"));
+ for (int i = 0; i < todo.getCount(); i++) {
+ if (todo[i].bEnabled) {
+ TCHAR tszBackFile[MAX_PATH];
+ FILEINFO& p = todo[i];
+ if (p.bDeleteOnly) {
+ // we need only to backup the old file
+ TCHAR *ptszRelPath = p.tszNewName + _tcslen(tszMirandaPath) + 1;
+ mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, ptszRelPath);
+ BackupFile(p.tszNewName, tszBackFile);
+ }
+ else {
+ // if file name differs, we also need to backup the old file here
+ // otherwise it would be replaced by unzip
+ if ( _tcsicmp(p.tszOldName, p.tszNewName)) {
+ TCHAR tszSrcPath[MAX_PATH];
+ mir_sntprintf(tszSrcPath, SIZEOF(tszSrcPath), _T("%s\\%s"), tszMirandaPath, p.tszOldName);
+ mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, p.tszOldName);
+ BackupFile(tszSrcPath, tszBackFile);
+ }
+
+ if ( unzip(p.File.tszDiskPath, tszMirandaPath, tszFileBack,true))
+ SafeDeleteFile(p.File.tszDiskPath); // remove .zip after successful update
+ }
+ }
+ }
+ SkinPlaySound("updatecompleted");
+
+#if MIRANDA_VER < 0x0A00
+ // 4) Change title of clist
+ ptrT title = db_get_tsa(NULL, "CList", "TitleText");
+ if (!_tcsicmp(title, _T("Miranda IM")))
+ db_set_ts(NULL, "CList", "TitleText", _T("Miranda NG"));
+#endif
+
+ opts.bForceRedownload = false;
+ db_unset(NULL, MODNAME, "ForceRedownload");
+
+ db_set_b(NULL, MODNAME, "RestartCount", 5);
+
+ // 5) Prepare Restart
+ int rc = MessageBox(hDlg, TranslateT("Update complete. Press Yes to restart Miranda now or No to postpone a restart until the exit."), TranslateT("Plugin Updater"), MB_YESNO | MB_ICONQUESTION);
+ PostMessage(hDlg, WM_CLOSE, 0, 0);
+ if (rc == IDYES)
+ CallFunctionAsync(RestartMe, 0);
+}
+
+static void ResizeVert(HWND hDlg, int yy)
+{
+ RECT r = { 0, 0, 244, yy };
+ MapDialogRect(hDlg, &r);
+ r.bottom += GetSystemMetrics(SM_CYSMCAPTION);
+ SetWindowPos(hDlg, 0, 0, 0, r.right, r.bottom, SWP_NOMOVE | SWP_NOZORDER);
+}
+
+static INT_PTR CALLBACK DlgUpdate(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HWND hwndList = GetDlgItem(hDlg, IDC_LIST_UPDATES);
+
+ switch (message) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hDlg);
+ SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES);
+ SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon("check_update"));
+ SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon("check_update", 1));
+ {
+ OSVERSIONINFO osver = { sizeof(osver) };
+ if (GetVersionEx(&osver) && osver.dwMajorVersion >= 6)
+ {
+ wchar_t szPath[MAX_PATH];
+ GetModuleFileName(NULL, szPath, SIZEOF(szPath));
+ TCHAR *ext = _tcsrchr(szPath, '.');
+ if (ext != NULL)
+ *ext = '\0';
+ _tcscat(szPath, _T(".test"));
+ HANDLE hFile = CreateFile(szPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ // Running Windows Vista or later (major version >= 6).
+ Button_SetElevationRequiredState(GetDlgItem(hDlg, IDOK), !IsProcessElevated());
+ else
+ {
+ CloseHandle(hFile);
+ DeleteFile(szPath);
+ }
+ }
+ RECT r;
+ GetClientRect(hwndList, &r);
+
+ LVCOLUMN lvc = {0};
+ // Initialize the LVCOLUMN structure.
+ // The mask specifies that the format, width, text, and
+ // subitem members of the structure are valid.
+ lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
+ lvc.fmt = LVCFMT_LEFT;
+
+ lvc.iSubItem = 0;
+ lvc.pszText = TranslateT("Component Name");
+ lvc.cx = 220; // width of column in pixels
+ ListView_InsertColumn(hwndList, 0, &lvc);
+
+ lvc.iSubItem = 1;
+ lvc.pszText = TranslateT("State");
+ lvc.cx = 120 - GetSystemMetrics(SM_CXVSCROLL); // width of column in pixels
+ ListView_InsertColumn(hwndList, 1, &lvc);
+
+ //enumerate plugins, fill in list
+ //bool one_enabled = false;
+ ListView_DeleteAllItems(hwndList);
+
+ // Some code to create the list-view control.
+ // Initialize LVITEM members that are common to all items.
+ LVITEM lvI = {0};
+ lvI.mask = LVIF_TEXT | LVIF_PARAM | LVIF_NORECOMPUTE;// | LVIF_IMAGE;
+
+ bool enableOk = false;
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)lParam;
+ for (int i = 0; i < todo.getCount(); ++i) {
+ lvI.mask = LVIF_TEXT | LVIF_PARAM;// | LVIF_IMAGE;
+ lvI.iSubItem = 0;
+ lvI.lParam = (LPARAM)&todo[i];
+ lvI.pszText = todo[i].tszOldName;
+ lvI.iItem = i;
+ ListView_InsertItem(hwndList, &lvI);
+
+ // remember whether the user has decided not to update this component with this particular new version
+ todo[i].bEnabled = db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(todo[i].tszOldName)), true);
+ ListView_SetCheckState(hwndList, lvI.iItem, todo[i].bEnabled);
+ if (todo[i].bEnabled)
+ enableOk = true;
+ }
+ HWND hwOk = GetDlgItem(hDlg, IDOK);
+ EnableWindow(hwOk, enableOk);
+ }
+
+ bShowDetails = false;
+ ResizeVert(hDlg, 60);
+
+ // do this after filling list - enables 'ITEMCHANGED' below
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
+ Utils_RestoreWindowPositionNoSize(hDlg, 0, MODNAME, "ConfirmWindow");
+ return TRUE;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR) lParam)->hwndFrom == hwndList) {
+ switch (((LPNMHDR) lParam)->code) {
+ case LVN_ITEMCHANGED:
+ if (GetWindowLongPtr(hDlg, GWLP_USERDATA)) {
+ NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam;
+
+ LVITEM lvI = {0};
+ lvI.iItem = nmlv->iItem;
+ lvI.iSubItem = 0;
+ lvI.mask = LVIF_PARAM;
+ ListView_GetItem(hwndList, &lvI);
+
+ OBJLIST<FILEINFO> &todo = *(OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ if ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK) {
+ todo[lvI.iItem].bEnabled = ListView_GetCheckState(hwndList, nmlv->iItem);
+ db_set_b(NULL, MODNAME "Files", StrToLower(_T2A(todo[lvI.iItem].tszOldName)), todo[lvI.iItem].bEnabled);
+
+ bool enableOk = false;
+ for (int i=0; i < todo.getCount(); ++i) {
+ if (todo[i].bEnabled) {
+ enableOk = true;
+ break;
+ }
+ }
+ HWND hwOk = GetDlgItem(hDlg, IDOK);
+ EnableWindow(hwOk, enableOk ? TRUE : FALSE);
+ }
+ }
+ break;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ if (HIWORD( wParam ) == BN_CLICKED) {
+ switch(LOWORD(wParam)) {
+ case IDOK:
+ EnableWindow( GetDlgItem(hDlg, IDOK), FALSE);
+ EnableWindow( GetDlgItem(hDlg, IDC_SELALL), FALSE);
+ EnableWindow( GetDlgItem(hDlg, IDC_SELNONE), FALSE);
+
+ mir_forkthread(ApplyUpdates, hDlg);
+ return TRUE;
+
+ case IDC_DETAILS:
+ bShowDetails = !bShowDetails;
+ ResizeVert(hDlg, bShowDetails ? 242 : 60);
+ SetDlgItemText(hDlg, IDC_DETAILS, (bShowDetails ? TranslateT("<< Details") : TranslateT("Details >>")));
+ break;
+
+ case IDC_SELALL:
+ SelectAll(hDlg, true);
+ break;
+
+ case IDC_SELNONE:
+ SelectAll(hDlg, false);
+ break;
+
+ case IDCANCEL:
+ DestroyWindow(hDlg);
+ return TRUE;
+ }
+ }
+ break;
+
+ case UM_ERROR:
+ MessageBox(hDlg, TranslateT("Update failed! One of the components wasn't downloaded correctly. Try it again later."), TranslateT("Plugin Updater"), MB_OK | MB_ICONERROR);
+ DestroyWindow(hDlg);
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hDlg);
+ break;
+
+ case WM_DESTROY:
+ Skin_ReleaseIcon((HICON)SendMessage(hDlg, WM_SETICON, ICON_SMALL, 0));
+ Utils_SaveWindowPosition(hDlg, NULL, MODNAME, "ConfirmWindow");
+ hwndDialog = NULL;
+ opts.bSilent = true;
+ delete (OBJLIST<FILEINFO> *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, 0);
+ #if MIRANDA_VER >= 0x0A00
+ db_set_dw(NULL, MODNAME, "LastUpdate", time(NULL));
+ #endif
+ mir_forkthread(InitTimer, (void*)0);
+ break;
+ }
+
+ return FALSE;
+}
+
+static LRESULT CALLBACK PopupDlgProcRestart(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_COMMAND:
+ case WM_CONTEXTMENU:
+ PUDeletePopup(hDlg);
+
+ if (uMsg == WM_COMMAND) {
+ TCHAR tszText[200];
+ mir_sntprintf(tszText, SIZEOF(tszText), _T("%s\n\n%s"), TranslateT("You need to restart your Miranda to apply installed updates."), TranslateT("Would you like to restart it now?"));
+
+ if (MessageBox(hDlg, tszText, TranslateT("Plugin Updater"), MB_YESNO | MB_ICONQUESTION) == IDYES)
+ CallFunctionAsync(RestartMe, 0);
+ }
+
+ return TRUE;
+ }
+
+ return DefWindowProc(hDlg, uMsg, wParam, lParam);
+}
+
+static void DlgUpdateSilent(void *lParam)
+{
+ OBJLIST<FILEINFO> &UpdateFiles = *(OBJLIST<FILEINFO> *)lParam;
+ if (UpdateFiles.getCount() == 0) {
+ delete &UpdateFiles;
+ return;
+ }
+
+ // 1) If we need to escalate priviledges, launch a stub
+ if (!PrepareEscalation()) {
+ delete &UpdateFiles;
+ return;
+ }
+
+ AutoHandle pipe(hPipe);
+ TCHAR tszFileTemp[MAX_PATH], tszFileBack[MAX_PATH];
+
+ mir_sntprintf(tszFileBack, SIZEOF(tszFileBack), _T("%s\\Backups"), tszRoot);
+ SafeCreateDirectory(tszFileBack);
+
+ mir_sntprintf(tszFileTemp, SIZEOF(tszFileTemp), _T("%s\\Temp"), tszRoot);
+ SafeCreateDirectory(tszFileTemp);
+
+ // 2) Download all plugins
+ HANDLE nlc = NULL;
+ // Count all updates that have been enabled
+ int count = 0;
+ for (int i = 0; i < UpdateFiles.getCount(); i++) {
+ if (db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(UpdateFiles[i].tszOldName)), 1) && !UpdateFiles[i].bDeleteOnly) {
+ // download update
+ FILEURL *pFileUrl = &UpdateFiles[i].File;
+ if (!DownloadFile(pFileUrl, nlc)) {
+ // interrupt update as we require all components to be updated
+ Netlib_CloseHandle(nlc);
+ SkinPlaySound("updatefailed");
+ delete &UpdateFiles;
+ return;
+ }
+ count++;
+ }
+
+ }
+ Netlib_CloseHandle(nlc);
+
+ if (count == 0) {
+ delete &UpdateFiles;
+ return;
+ }
+
+ // 3) Unpack all zips
+ TCHAR *tszMirandaPath = Utils_ReplaceVarsT(_T("%miranda_path%"));
+ for (int i = 0; i < UpdateFiles.getCount(); i++) {
+ if (db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(UpdateFiles[i].tszOldName)), 1)) {
+ TCHAR tszBackFile[MAX_PATH];
+ FILEINFO& p = UpdateFiles[i];
+ if (p.bDeleteOnly) { // we need only to backup the old file
+ TCHAR *ptszRelPath = p.tszNewName + _tcslen(tszMirandaPath) + 1;
+ mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, ptszRelPath);
+ BackupFile(p.tszNewName, tszBackFile);
+ }
+ else {
+ // if file name differs, we also need to backup the old file here
+ // otherwise it would be replaced by unzip
+ if (_tcsicmp(p.tszOldName, p.tszNewName)) {
+ TCHAR tszSrcPath[MAX_PATH];
+ mir_sntprintf(tszSrcPath, SIZEOF(tszSrcPath), _T("%s\\%s"), tszMirandaPath, p.tszOldName);
+ mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), tszFileBack, p.tszOldName);
+ BackupFile(tszSrcPath, tszBackFile);
+ }
+
+ if (unzip(p.File.tszDiskPath, tszMirandaPath, tszFileBack, true))
+ SafeDeleteFile(p.File.tszDiskPath); // remove .zip after successful update
+ }
+ }
+ }
+ delete &UpdateFiles;
+ SkinPlaySound("updatecompleted");
+
+#if MIRANDA_VER < 0x0A00
+ // 4) Change title of clist
+ ptrT title = db_get_tsa(NULL, "CList", "TitleText");
+ if (!_tcsicmp(title, _T("Miranda IM")))
+ db_set_ts(NULL, "CList", "TitleText", _T("Miranda NG"));
+#endif
+
+ opts.bForceRedownload = false;
+ db_unset(NULL, MODNAME, "ForceRedownload");
+
+ db_set_b(NULL, MODNAME, "RestartCount", 5);
+ db_set_b(NULL, MODNAME, "NeedRestart", 1);
+
+ // 5) Prepare Restart
+ TCHAR tszTitle[100];
+ mir_sntprintf(tszTitle, SIZEOF(tszTitle), TranslateT("%d component(s) was updated"), count);
+
+ if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) {
+ POPUPDATAT_V2 pd = { 0 };
+ pd.cbSize = sizeof(pd);
+ pd.lchContact = NULL;
+ pd.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ pd.colorBack = pd.colorText = 0;
+ pd.iSeconds = -1;
+ pd.PluginWindowProc = PopupDlgProcRestart;
+
+ lstrcpyn(pd.lptzText, TranslateT("You need to restart your Miranda to apply installed updates."), MAX_SECONDLINE);
+ lstrcpyn(pd.lptzContactName, tszTitle, MAX_CONTACTNAME);
+
+ CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&pd, APF_NEWDATA);
+ } else {
+ bool notified = false;
+
+ if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) {
+ MIRANDASYSTRAYNOTIFY err;
+ err.szProto = MODULEA;
+ err.cbSize = sizeof(err);
+ err.dwInfoFlags = NIIF_INTERN_UNICODE | NIIF_INFO;
+ err.tszInfoTitle = tszTitle;
+ err.tszInfo = TranslateT("You need to restart your Miranda to apply installed updates.");
+ err.uTimeout = 30000;
+
+ notified = !CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM)&err);
+ }
+
+ if (!notified) {
+ // Error, let's try to show MessageBox as last way to inform user about successful update
+ TCHAR tszText[200];
+ mir_sntprintf(tszText, SIZEOF(tszText), _T("%s\n\n%s"), TranslateT("You need to restart your Miranda to apply installed updates."), TranslateT("Would you like to restart it now?"));
+
+ if (MessageBox(NULL, tszText, tszTitle, MB_ICONINFORMATION | MB_YESNO) == IDYES)
+ CallFunctionAsync(RestartMe, 0);
+ }
+ }
+}
+
+static void __stdcall LaunchDialog(void *param)
+{
+ if (opts.bSilentMode && opts.bSilent)
+ mir_forkthread(DlgUpdateSilent, param);
+ else
+ hwndDialog = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_UPDATE), GetDesktopWindow(), DlgUpdate, (LPARAM)param);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// building file list in the separate thread
+
+struct
+{
+ TCHAR *oldName, *newName;
+}
+static renameTable[] =
+{
+ { _T("svc_dbepp.dll"), _T("Plugins\\dbeditorpp.dll") },
+ { _T("svc_crshdmp.dll"), _T("Plugins\\crashdumper.dll") },
+ { _T("svc_vi.dll"), _T("Plugins\\versioninfo.dll") },
+ { _T("crashrpt.dll"), _T("Plugins\\crashdumper.dll") },
+ { _T("advsplashscreen.dll"), _T("Plugins\\splashscreen.dll") },
+ { _T("import_sa.dll"), _T("Plugins\\import.dll") },
+ { _T("newnr.dll"), _T("Plugins\\notesreminders.dll") },
+ { _T("dbtool.exe"), _T("Plugins\\dbchecker.dll") },
+ { _T("dbtool_sa.exe"), _T("Plugins\\dbchecker.dll") },
+ { _T("bclist.dll"), _T("Plugins\\clist_blind.dll") },
+ { _T("otr.dll"), _T("Plugins\\mirotr.dll") },
+ { _T("ttnotify.dll"), _T("Plugins\\tooltipnotify.dll") },
+ { _T("newstatusnotify.dll"), _T("Plugins\\newxstatusnotify.dll") },
+ { _T("rss.dll"), _T("Plugins\\newsaggregator.dll") },
+ { _T("dbx_3x.dll"), _T("Plugins\\dbx_mmap.dll") },
+
+ #if MIRANDA_VER >= 0x0A00
+ { _T("dbx_mmap_sa.dll"), _T("Plugins\\dbx_mmap.dll") },
+ { _T("dbx_tree.dll"), _T("Plugins\\dbx_mmap.dll") },
+ { _T("rc4.dll"), NULL },
+ { _T("athena.dll"), NULL },
+ #endif
+
+ { _T("proto_newsaggr.dll"), _T("Icons\\proto_newsaggregator.dll") },
+ { _T("clienticons_*.dll"), _T("Icons\\fp_icons.dll") },
+ { _T("fp_*.dll"), _T("Icons\\fp_icons.dll") },
+
+ { _T("langpack_*.txt"), _T("Languages\\*") },
+
+ { _T("clist_classic.dll"), NULL },
+ { _T("chat.dll"), NULL },
+ { _T("gender.dll"), NULL },
+ { _T("srmm.dll"), NULL },
+ { _T("extraicons.dll"), NULL },
+ { _T("langman.dll"), NULL },
+ { _T("metacontacts.dll"), NULL },
+};
+
+static bool CheckFileRename(const TCHAR *ptszOldName, TCHAR *pNewName)
+{
+ for (int i = 0; i < SIZEOF(renameTable); i++) {
+ if (!wildcmpit(ptszOldName, renameTable[i].oldName))
+ continue;
+
+ TCHAR *ptszDest = renameTable[i].newName;
+ if (ptszDest == NULL)
+ *pNewName = 0;
+ else {
+ _tcsncpy_s(pNewName, MAX_PATH, ptszDest, _TRUNCATE);
+ size_t cbLen = _tcslen(ptszDest) - 1;
+ if (pNewName[cbLen] == '*')
+ _tcsncpy_s(pNewName + cbLen, MAX_PATH - cbLen, ptszOldName, _TRUNCATE);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static bool isValidExtension(const TCHAR *ptszFileName)
+{
+ const TCHAR *pExt = _tcsrchr(ptszFileName, '.');
+
+ return (pExt != NULL) && (!_tcsicmp(pExt, _T(".dll")) || !_tcsicmp(pExt, _T(".exe")) || !_tcsicmp(pExt, _T(".txt")));
+}
+
+static int ScanFolder(const TCHAR *tszFolder, size_t cbBaseLen, int level, const TCHAR *tszBaseUrl, SERVLIST& hashes, OBJLIST<FILEINFO> *UpdateFiles)
+{
+ int count = 0;
+
+ // skip updater's own folder
+ if (!_tcsicmp(tszFolder, tszRoot))
+ return count;
+
+ TCHAR tszBuf[MAX_PATH];
+ mir_sntprintf(tszBuf, SIZEOF(tszBuf), _T("%s\\*"), tszFolder);
+
+ WIN32_FIND_DATA ffd;
+ HANDLE hFind = FindFirstFile(tszBuf, &ffd);
+ if (hFind == INVALID_HANDLE_VALUE)
+ return count;
+
+ do {
+ if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if (_tcscmp(ffd.cFileName, _T(".")) && _tcscmp(ffd.cFileName, _T(".."))) {
+ // we need to skip profile folder
+ TCHAR tszProfilePath[MAX_PATH];
+ CallService(MS_DB_GETPROFILEPATHT, SIZEOF(tszProfilePath), (LPARAM)tszProfilePath);
+
+ mir_sntprintf(tszBuf, SIZEOF(tszBuf), _T("%s\\%s"), tszFolder, ffd.cFileName);
+ if (0 != _tcsicmp(tszBuf, tszProfilePath))
+ count += ScanFolder(tszBuf, cbBaseLen, level+1, tszBaseUrl, hashes, UpdateFiles);
+ }
+ }
+ else if (isValidExtension(ffd.cFileName)) {
+ // calculate the current file's relative name and store it into tszNewName
+ TCHAR tszNewName[MAX_PATH];
+ if (!CheckFileRename(ffd.cFileName, tszNewName)) {
+ if (level == 0)
+ _tcsncpy(tszNewName, ffd.cFileName, MAX_PATH);
+ else
+ mir_sntprintf(tszNewName, SIZEOF(tszNewName), _T("%s\\%s"), tszFolder+cbBaseLen, ffd.cFileName);
+ }
+
+ bool bHasNewVersion = true;
+ TCHAR *ptszUrl;
+ int MyCRC = 0;
+ mir_sntprintf(tszBuf, SIZEOF(tszBuf), _T("%s\\%s"), tszFolder, ffd.cFileName);
+
+ // this file is not marked for deletion
+ if (tszNewName[0]) {
+ TCHAR *pName = tszNewName;
+ ServListEntry *item = hashes.find((ServListEntry*)&pName);
+ if (item == NULL) {
+ TCHAR *p = _tcsrchr(tszNewName, '.');
+ if (p[-1] != 'w' && p[-1] != 'W')
+ continue;
+
+ int iPos = int(p - tszNewName)-1;
+ strdel(p-1, 1);
+ if ((item = hashes.find((ServListEntry*)&pName)) == NULL)
+ continue;
+
+ strdel(tszNewName+iPos, 1);
+ }
+
+ ptszUrl = item->m_name;
+ // No need to hash a file if we are forcing a redownload anyway
+ if (!opts.bForceRedownload) {
+ // try to hash the file
+ char szMyHash[33];
+ __try {
+ CalculateModuleHash(tszBuf, szMyHash);
+ bHasNewVersion = strcmp(szMyHash, item->m_szHash) != 0;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER) {
+ ZeroMemory(szMyHash, 0);
+ // smth went wrong, reload a file from scratch
+ }
+ }
+
+ MyCRC = item->m_crc;
+ }
+ else // file was marked for deletion, add it to the list anyway
+ ptszUrl = _T("");
+
+ // Compare versions
+ if (bHasNewVersion) { // Yeah, we've got new version.
+ FILEINFO *FileInfo = new FILEINFO;
+ _tcscpy(FileInfo->tszOldName, tszBuf+cbBaseLen); // copy the relative old name
+ if (tszNewName[0] == 0) {
+ FileInfo->bDeleteOnly = TRUE;
+ _tcscpy(FileInfo->tszNewName, tszBuf); // save the full old name for deletion
+ }
+ else {
+ FileInfo->bDeleteOnly = FALSE;
+ _tcsncpy(FileInfo->tszNewName, ptszUrl, SIZEOF(FileInfo->tszNewName));
+ }
+
+ _tcscpy(tszBuf, ptszUrl);
+ TCHAR *p = _tcsrchr(tszBuf, '.');
+ if (p) *p = 0;
+ p = _tcsrchr(tszBuf, '\\');
+ p = (p) ? p+1 : tszBuf;
+ _tcslwr(p);
+
+ mir_sntprintf(FileInfo->File.tszDiskPath, SIZEOF(FileInfo->File.tszDiskPath), _T("%s\\Temp\\%s.zip"), tszRoot, p);
+ mir_sntprintf(FileInfo->File.tszDownloadURL, SIZEOF(FileInfo->File.tszDownloadURL), _T("%s/%s.zip"), tszBaseUrl, tszBuf);
+ for (p = _tcschr(FileInfo->File.tszDownloadURL, '\\'); p != 0; p = _tcschr(p, '\\'))
+ *p++ = '/';
+
+ FileInfo->File.CRCsum = MyCRC;
+ UpdateFiles->insert(FileInfo);
+
+ if (!opts.bSilent || db_get_b(NULL, MODNAME "Files", StrToLower(_T2A(FileInfo->tszNewName)), true))
+ count++;
+ } // end compare versions
+ }
+ }
+ while (FindNextFile(hFind, &ffd) != 0);
+
+ FindClose(hFind);
+ return count;
+}
+
+static void CheckUpdates(void *)
+{
+ char szKey[64] = {0};
+
+ TCHAR tszTempPath[MAX_PATH];
+ DWORD dwLen = GetTempPath(SIZEOF(tszTempPath), tszTempPath);
+ if (tszTempPath[dwLen-1] == '\\')
+ tszTempPath[dwLen-1] = 0;
+
+ ptrT updateUrl(GetDefaultUrl()), baseUrl;
+
+ SERVLIST hashes(50, CompareHashes);
+ bool success = ParseHashes(updateUrl, baseUrl, hashes);
+ if (success) {
+ FILELIST *UpdateFiles = new FILELIST(20);
+ VARST dirname( _T("%miranda_path%"));
+ int count = ScanFolder(dirname, lstrlen(dirname)+1, 0, baseUrl, hashes, UpdateFiles);
+
+ // Show dialog
+ if (count == 0) {
+ if (!opts.bSilent)
+ ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("No updates found."), 2, 0);
+ delete UpdateFiles;
+ opts.bSilent = true;
+ }
+ else CallFunctionAsync(LaunchDialog, UpdateFiles);
+ }
+ else opts.bSilent = true;
+
+ mir_forkthread(InitTimer, (void*)(success ? 0 : 2));
+
+ hashes.destroy();
+ hCheckThread = NULL;
+}
+
+void DoCheck()
+{
+ if (hCheckThread)
+ ShowPopup(0, LPGENT("Plugin Updater"), LPGENT("Update checking already started!"), 2, 0);
+ else if (hwndDialog) {
+ ShowWindow(hwndDialog, SW_SHOW);
+ SetForegroundWindow(hwndDialog);
+ SetFocus(hwndDialog);
+ } else {
+ #if MIRANDA_VER >= 0x0A00
+ db_set_dw(NULL, MODNAME, "LastUpdate", time(NULL));
+ #endif
+ hCheckThread = mir_forkthread(CheckUpdates, 0);
+ }
+}
+
+void UninitCheck()
+{
+ if (hwndDialog != NULL)
+ DestroyWindow(hwndDialog);
+}
+
+INT_PTR MenuCommand(WPARAM,LPARAM)
+{
+ opts.bSilent = false;
+ DoCheck();
+ return 0;
+}
+
+void InitCheck()
+{
+ CreateServiceFunction(MODNAME"/CheckUpdates", MenuCommand);
+}
+
+void UnloadCheck()
+{
+ if (hCheckThread)
+ hCheckThread = NULL;
}
\ No newline at end of file diff --git a/plugins/PluginUpdater/src/Notifications.cpp b/plugins/PluginUpdater/src/Notifications.cpp index d49c0d55b7..4a9108a5e8 100644 --- a/plugins/PluginUpdater/src/Notifications.cpp +++ b/plugins/PluginUpdater/src/Notifications.cpp @@ -1,273 +1,273 @@ -/* -Copyright (C) 2010 Mataes - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "common.h" - -HANDLE hPipe = NULL; - -void PopupAction(HWND hWnd, BYTE action) -{ - switch (action) { - case PCA_CLOSEPOPUP: - break; - case PCA_DONOTHING: - return; - } - PUDeletePopup(hWnd); -} - -static LRESULT CALLBACK PopupDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case UM_POPUPACTION: - if (HIWORD(wParam) == BN_CLICKED) { - LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg); - if (pmpd) { - switch (LOWORD(wParam)) { - case IDYES: - if (IsWindow(pmpd->hDialog)) - SendMessage(pmpd->hDialog, WM_CLOSE, 0, 0); - PUDeletePopup(hDlg); - break; - - case IDNO: - if (IsWindow(pmpd->hDialog)) - SendMessage(pmpd->hDialog, WM_CLOSE, 0, 0); - PUDeletePopup(hDlg); - break; - } - } - } - break; - - case UM_FREEPLUGINDATA: - { - LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg); - if (pmpd > 0) - mir_free(pmpd); - return TRUE; //TRUE or FALSE is the same, it gets ignored. - } - break; - } - - return DefWindowProc(hDlg, uMsg, wParam, lParam); -} - -static LRESULT CALLBACK PopupDlgProc2(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_COMMAND: - PopupAction(hDlg, PopupOptions.LeftClickAction); - break; - - case WM_CONTEXTMENU: - PopupAction(hDlg, PopupOptions.RightClickAction); - break; - - case UM_FREEPLUGINDATA: - { - LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg); - if (pmpd > 0) - mir_free(pmpd); - return TRUE; //TRUE or FALSE is the same, it gets ignored. - } - break; - } - - return DefWindowProc(hDlg, uMsg, wParam, lParam); -} - -static void MakePopupAction(POPUPACTION &pa, int id) -{ - pa.cbSize = sizeof(POPUPACTION); - pa.flags = PAF_ENABLED; - pa.wParam = MAKEWORD(id, BN_CLICKED); - pa.lParam = 0; - switch (id) { - case IDYES: - pa.lchIcon = Skin_GetIcon("btn_ok"); - strncpy_s(pa.lpzTitle, MODNAME"/Yes", MAX_ACTIONTITLE); - break; - - case IDNO: - pa.lchIcon = Skin_GetIcon("btn_cancel"); - strncpy_s(pa.lpzTitle, MODNAME"/No", MAX_ACTIONTITLE); - break; - } -} - -void ShowPopup(HWND hDlg, LPCTSTR ptszTitle, LPCTSTR ptszText, int Number, int ActType, bool NoMessageBox) -{ - if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) { - LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)mir_alloc(sizeof(MSGPOPUPDATA)); - if (!pmpd) - return; - - POPUPDATAT_V2 pd = { 0 }; - pd.cbSize = sizeof(pd); - pd.lchContact = NULL; //(HANDLE)wParam; - pd.lchIcon = LoadSkinnedIcon(PopupsList[Number].Icon); - pd.PluginWindowProc = (Number == 0 && ActType != 0) ? PopupDlgProc : PopupDlgProc2; - pd.PluginData = pmpd; - pd.iSeconds = (Number == 0) ? -1 : PopupOptions.Timeout; - pd.hNotification = NULL; - pd.lpActions = pmpd->pa; - - lstrcpyn(pd.lptzText, TranslateTS(ptszText), MAX_SECONDLINE); - lstrcpyn(pd.lptzContactName, TranslateTS(ptszTitle), MAX_CONTACTNAME); - - switch (PopupOptions.DefColors) { - case byCOLOR_WINDOWS: - pd.colorBack = GetSysColor(COLOR_BTNFACE); - pd.colorText = GetSysColor(COLOR_WINDOWTEXT); - break; - case byCOLOR_OWN: - pd.colorBack = PopupsList[Number].colorBack; - pd.colorText = PopupsList[Number].colorText; - break; - case byCOLOR_POPUP: - pd.colorBack = pd.colorText = 0; - break; - } - - pmpd->hDialog = hDlg; - - if (ActType == 1) { - MakePopupAction(pmpd->pa[pd.actionCount++], IDYES); - MakePopupAction(pmpd->pa[pd.actionCount++], IDNO); - } - - CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&pd, APF_NEWDATA); - } else if (!NoMessageBox) { - char setting[100]; - mir_snprintf(setting, SIZEOF(setting), "Popups%dM", Number); - if (db_get_b(NULL, MODNAME, setting, DEFAULT_MESSAGE_ENABLED)) { - int iMsgType; - switch( Number ) { - case 1: iMsgType = MB_ICONSTOP; break; - case 2: iMsgType = MB_ICONINFORMATION; break; - case 3: iMsgType = MB_ICONQUESTION; break; - case 4: return; - default: iMsgType = 0; - } - MessageBox(hDlg, TranslateTS(ptszText), TranslateTS(ptszTitle), iMsgType); - } - } -} - -INT_PTR CALLBACK DlgDownload(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_INITDIALOG: - SetWindowText(GetDlgItem(hDlg, IDC_LABEL), tszDialogMsg); - SetWindowLongPtr(GetDlgItem(hDlg, IDC_PB), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hDlg, IDC_PB), GWL_STYLE) | PBS_MARQUEE); - SendMessage(GetDlgItem(hDlg, IDC_PB), PBM_SETMARQUEE, 1, 50); - return TRUE; - } - return FALSE; -} - -INT_PTR CALLBACK DlgDownloadPop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - PopupDataText *temp = (PopupDataText*)lParam; - ShowPopup(hDlg, temp->Title, temp->Text, 3, 0); - return TRUE; - } - return FALSE; -} - -bool PrepareEscalation() -{ - // First try to create a file near Miranda32.exe - TCHAR szPath[MAX_PATH]; - GetModuleFileName(NULL, szPath, SIZEOF(szPath)); - TCHAR *ext = _tcsrchr(szPath, '.'); - if (ext != NULL) - *ext = '\0'; - _tcscat(szPath, _T(".test")); - HANDLE hFile = CreateFile(szPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) { - // we are admins or UAC is disable, cool - CloseHandle(hFile); - DeleteFile(szPath); - return true; - } - - // Check the current process's "run as administrator" status. - if ( IsRunAsAdmin()) - return true; - - // Elevate the process. Create a pipe for a stub first - TCHAR tszPipeName[MAX_PATH]; - mir_sntprintf(tszPipeName, MAX_PATH, _T("\\\\.\\pipe\\Miranda_Pu_%d"), GetCurrentProcessId()); - hPipe = CreateNamedPipe(tszPipeName, PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); - if (hPipe == INVALID_HANDLE_VALUE) { - hPipe = NULL; - return false; - } - - TCHAR cmdLine[100], *p; - GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)); - if ((p = _tcsrchr(szPath, '\\')) != 0) - _tcscpy(p+1, _T("pu_stub.exe")); - mir_sntprintf(cmdLine, SIZEOF(cmdLine), _T("%d"), GetCurrentProcessId()); - - // Launch a stub - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.lpVerb = L"runas"; - sei.lpFile = szPath; - sei.lpParameters = cmdLine; - sei.hwnd = NULL; - sei.nShow = SW_NORMAL; - if (ShellExecuteEx(&sei)) { - if (hPipe != NULL) - ConnectNamedPipe(hPipe, NULL); - return true; - } - - DWORD dwError = GetLastError(); - if (dwError == ERROR_CANCELLED) - { - // The user refused to allow privileges elevation. - // Do nothing ... - } - return false; -} - -int ImageList_AddIconFromIconLib(HIMAGELIST hIml, const char *name) -{ - HICON icon = Skin_GetIconByHandle(Skin_GetIconHandle(name)); - int res = ImageList_AddIcon(hIml, icon); - Skin_ReleaseIcon(icon); - return res; -} - -INT_PTR CALLBACK DlgMsgPop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - PopupDataText *temp = (PopupDataText*)lParam; - ShowPopup(hDlg, temp->Title, temp->Text, 0, 1); - return TRUE; - } - ShowWindow(hDlg, SW_HIDE); - return FALSE; -} +/*
+Copyright (C) 2010 Mataes
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include "common.h"
+
+HANDLE hPipe = NULL;
+
+void PopupAction(HWND hWnd, BYTE action)
+{
+ switch (action) {
+ case PCA_CLOSEPOPUP:
+ break;
+ case PCA_DONOTHING:
+ return;
+ }
+ PUDeletePopup(hWnd);
+}
+
+static LRESULT CALLBACK PopupDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case UM_POPUPACTION:
+ if (HIWORD(wParam) == BN_CLICKED) {
+ LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg);
+ if (pmpd) {
+ switch (LOWORD(wParam)) {
+ case IDYES:
+ if (IsWindow(pmpd->hDialog))
+ PostMessage(pmpd->hDialog, WM_CLOSE, 0, 0);
+ PUDeletePopup(hDlg);
+ break;
+
+ case IDNO:
+ if (IsWindow(pmpd->hDialog))
+ PostMessage(pmpd->hDialog, WM_CLOSE, 0, 0);
+ PUDeletePopup(hDlg);
+ break;
+ }
+ }
+ }
+ break;
+
+ case UM_FREEPLUGINDATA:
+ {
+ LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg);
+ if (pmpd > 0)
+ mir_free(pmpd);
+ return TRUE; //TRUE or FALSE is the same, it gets ignored.
+ }
+ break;
+ }
+
+ return DefWindowProc(hDlg, uMsg, wParam, lParam);
+}
+
+static LRESULT CALLBACK PopupDlgProc2(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_COMMAND:
+ PopupAction(hDlg, PopupOptions.LeftClickAction);
+ break;
+
+ case WM_CONTEXTMENU:
+ PopupAction(hDlg, PopupOptions.RightClickAction);
+ break;
+
+ case UM_FREEPLUGINDATA:
+ {
+ LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg);
+ if (pmpd > 0)
+ mir_free(pmpd);
+ return TRUE; //TRUE or FALSE is the same, it gets ignored.
+ }
+ break;
+ }
+
+ return DefWindowProc(hDlg, uMsg, wParam, lParam);
+}
+
+static void MakePopupAction(POPUPACTION &pa, int id)
+{
+ pa.cbSize = sizeof(POPUPACTION);
+ pa.flags = PAF_ENABLED;
+ pa.wParam = MAKEWORD(id, BN_CLICKED);
+ pa.lParam = 0;
+ switch (id) {
+ case IDYES:
+ pa.lchIcon = Skin_GetIcon("btn_ok");
+ strncpy_s(pa.lpzTitle, MODNAME"/Yes", MAX_ACTIONTITLE);
+ break;
+
+ case IDNO:
+ pa.lchIcon = Skin_GetIcon("btn_cancel");
+ strncpy_s(pa.lpzTitle, MODNAME"/No", MAX_ACTIONTITLE);
+ break;
+ }
+}
+
+void ShowPopup(HWND hDlg, LPCTSTR ptszTitle, LPCTSTR ptszText, int Number, int ActType, bool NoMessageBox)
+{
+ if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) {
+ LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)mir_alloc(sizeof(MSGPOPUPDATA));
+ if (!pmpd)
+ return;
+
+ POPUPDATAT_V2 pd = { 0 };
+ pd.cbSize = sizeof(pd);
+ pd.lchContact = NULL; //(HANDLE)wParam;
+ pd.lchIcon = LoadSkinnedIcon(PopupsList[Number].Icon);
+ pd.PluginWindowProc = (Number == 0 && ActType != 0) ? PopupDlgProc : PopupDlgProc2;
+ pd.PluginData = pmpd;
+ pd.iSeconds = (Number == 0) ? -1 : PopupOptions.Timeout;
+ pd.hNotification = NULL;
+ pd.lpActions = pmpd->pa;
+
+ lstrcpyn(pd.lptzText, TranslateTS(ptszText), MAX_SECONDLINE);
+ lstrcpyn(pd.lptzContactName, TranslateTS(ptszTitle), MAX_CONTACTNAME);
+
+ switch (PopupOptions.DefColors) {
+ case byCOLOR_WINDOWS:
+ pd.colorBack = GetSysColor(COLOR_BTNFACE);
+ pd.colorText = GetSysColor(COLOR_WINDOWTEXT);
+ break;
+ case byCOLOR_OWN:
+ pd.colorBack = PopupsList[Number].colorBack;
+ pd.colorText = PopupsList[Number].colorText;
+ break;
+ case byCOLOR_POPUP:
+ pd.colorBack = pd.colorText = 0;
+ break;
+ }
+
+ pmpd->hDialog = hDlg;
+
+ if (ActType == 1) {
+ MakePopupAction(pmpd->pa[pd.actionCount++], IDYES);
+ MakePopupAction(pmpd->pa[pd.actionCount++], IDNO);
+ }
+
+ CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&pd, APF_NEWDATA);
+ } else if (!NoMessageBox) {
+ char setting[100];
+ mir_snprintf(setting, SIZEOF(setting), "Popups%dM", Number);
+ if (db_get_b(NULL, MODNAME, setting, DEFAULT_MESSAGE_ENABLED)) {
+ int iMsgType;
+ switch( Number ) {
+ case 1: iMsgType = MB_ICONSTOP; break;
+ case 2: iMsgType = MB_ICONINFORMATION; break;
+ case 3: iMsgType = MB_ICONQUESTION; break;
+ case 4: return;
+ default: iMsgType = 0;
+ }
+ MessageBox(hDlg, TranslateTS(ptszText), TranslateTS(ptszTitle), iMsgType);
+ }
+ }
+}
+
+INT_PTR CALLBACK DlgDownload(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+ case WM_INITDIALOG:
+ SetWindowText(GetDlgItem(hDlg, IDC_LABEL), tszDialogMsg);
+ SetWindowLongPtr(GetDlgItem(hDlg, IDC_PB), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hDlg, IDC_PB), GWL_STYLE) | PBS_MARQUEE);
+ SendMessage(GetDlgItem(hDlg, IDC_PB), PBM_SETMARQUEE, 1, 50);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK DlgDownloadPop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ PopupDataText *temp = (PopupDataText*)lParam;
+ ShowPopup(hDlg, temp->Title, temp->Text, 3, 0);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool PrepareEscalation()
+{
+ // First try to create a file near Miranda32.exe
+ TCHAR szPath[MAX_PATH];
+ GetModuleFileName(NULL, szPath, SIZEOF(szPath));
+ TCHAR *ext = _tcsrchr(szPath, '.');
+ if (ext != NULL)
+ *ext = '\0';
+ _tcscat(szPath, _T(".test"));
+ HANDLE hFile = CreateFile(szPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile != INVALID_HANDLE_VALUE) {
+ // we are admins or UAC is disable, cool
+ CloseHandle(hFile);
+ DeleteFile(szPath);
+ return true;
+ }
+
+ // Check the current process's "run as administrator" status.
+ if ( IsRunAsAdmin())
+ return true;
+
+ // Elevate the process. Create a pipe for a stub first
+ TCHAR tszPipeName[MAX_PATH];
+ mir_sntprintf(tszPipeName, MAX_PATH, _T("\\\\.\\pipe\\Miranda_Pu_%d"), GetCurrentProcessId());
+ hPipe = CreateNamedPipe(tszPipeName, PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
+ if (hPipe == INVALID_HANDLE_VALUE) {
+ hPipe = NULL;
+ return false;
+ }
+
+ TCHAR cmdLine[100], *p;
+ GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath));
+ if ((p = _tcsrchr(szPath, '\\')) != 0)
+ _tcscpy(p+1, _T("pu_stub.exe"));
+ mir_sntprintf(cmdLine, SIZEOF(cmdLine), _T("%d"), GetCurrentProcessId());
+
+ // Launch a stub
+ SHELLEXECUTEINFO sei = { sizeof(sei) };
+ sei.lpVerb = L"runas";
+ sei.lpFile = szPath;
+ sei.lpParameters = cmdLine;
+ sei.hwnd = NULL;
+ sei.nShow = SW_NORMAL;
+ if (ShellExecuteEx(&sei)) {
+ if (hPipe != NULL)
+ ConnectNamedPipe(hPipe, NULL);
+ return true;
+ }
+
+ DWORD dwError = GetLastError();
+ if (dwError == ERROR_CANCELLED)
+ {
+ // The user refused to allow privileges elevation.
+ // Do nothing ...
+ }
+ return false;
+}
+
+int ImageList_AddIconFromIconLib(HIMAGELIST hIml, const char *name)
+{
+ HICON icon = Skin_GetIconByHandle(Skin_GetIconHandle(name));
+ int res = ImageList_AddIcon(hIml, icon);
+ Skin_ReleaseIcon(icon);
+ return res;
+}
+
+INT_PTR CALLBACK DlgMsgPop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ PopupDataText *temp = (PopupDataText*)lParam;
+ ShowPopup(hDlg, temp->Title, temp->Text, 0, 1);
+ return TRUE;
+ }
+ ShowWindow(hDlg, SW_HIDE);
+ return FALSE;
+}
|