diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/PluginUpdater/src/DlgListNew.cpp | 976 | ||||
-rw-r--r-- | plugins/PluginUpdater/src/DlgUpdate.cpp | 1527 | ||||
-rw-r--r-- | plugins/PluginUpdater/src/Notifications.cpp | 546 |
3 files changed, 1524 insertions, 1525 deletions
diff --git a/plugins/PluginUpdater/src/DlgListNew.cpp b/plugins/PluginUpdater/src/DlgListNew.cpp index 4ef7d445b2..bd1e0c122d 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()) {
- EndDialog(hDlg, 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);
-
- EndDialog(hDlg, 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()) { + 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; }
\ No newline at end of file diff --git a/plugins/PluginUpdater/src/DlgUpdate.cpp b/plugins/PluginUpdater/src/DlgUpdate.cpp index c7f02157ce..711bfcd57b 100644 --- a/plugins/PluginUpdater/src/DlgUpdate.cpp +++ b/plugins/PluginUpdater/src/DlgUpdate.cpp @@ -1,765 +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()) {
- EndDialog(hDlg, 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);
- EndDialog(hDlg, 0);
- PostMessage(hDlg, WM_DESTROY, 0, 0); // why do we have to call this manually?
- 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()) { + 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; }
\ No newline at end of file diff --git a/plugins/PluginUpdater/src/Notifications.cpp b/plugins/PluginUpdater/src/Notifications.cpp index 06b308d673..d49c0d55b7 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))
- EndDialog(pmpd->hDialog, LOWORD(wParam));
- PUDeletePopup(hDlg);
- break;
-
- case IDNO:
- if (IsWindow(pmpd->hDialog))
- EndDialog(pmpd->hDialog, LOWORD(wParam));
- 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)) + 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; +} |