Exemple #1
0
/*
 * New version notification dialog
 */
INT_PTR CALLBACK new_version_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	int i;
	HWND hNotes;
	char tmp[128], cmdline[] = APPLICATION_NAME " /W";
	static char* filepath = NULL;
	static int download_status = 0;
	STARTUPINFOA si;
	PROCESS_INFORMATION pi;
	HFONT hyperlink_font = NULL;
	EXT_DECL(exe_ext, NULL, __VA_GROUP__("*.exe"), __VA_GROUP__("Application"));

	switch (message) {
	case WM_INITDIALOG:
		download_status = 0;
		set_title_bar_icon(hDlg);
		center_dialog(hDlg);
		// Subclass the callback so that we can change the cursor
		original_wndproc = (WNDPROC)SetWindowLongPtr(hDlg, GWLP_WNDPROC, (LONG_PTR)subclass_callback);
		hNotes = GetDlgItem(hDlg, IDC_RELEASE_NOTES);
		SendMessage(hNotes, EM_AUTOURLDETECT, 1, 0);
		SendMessageA(hNotes, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update.release_notes);
		SendMessage(hNotes, EM_SETSEL, -1, -1);
		SendMessage(hNotes, EM_SETEVENTMASK, 0, ENM_LINK);
		safe_sprintf(tmp, sizeof(tmp), "Your version: %d.%d (Build %d)",
			application_version[0], application_version[1], application_version[2]);
		SetWindowTextU(GetDlgItem(hDlg, IDC_YOUR_VERSION), tmp);
		safe_sprintf(tmp, sizeof(tmp), "Latest version: %d.%d (Build %d)",
			update.version[0], update.version[1], update.version[2]);
		SetWindowTextU(GetDlgItem(hDlg, IDC_LATEST_VERSION), tmp);
		SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD_URL), update.download_url);
		SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000);
		if (update.download_url == NULL)
			EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), FALSE);
		break;
	case WM_CTLCOLORSTATIC:
		if ((HWND)lParam != GetDlgItem(hDlg, IDC_WEBSITE))
			return FALSE;
		// Change the font for the hyperlink
		SetBkMode((HDC)wParam, TRANSPARENT);
		CreateStaticFont((HDC)wParam, &hyperlink_font);
		SelectObject((HDC)wParam, hyperlink_font);
		SetTextColor((HDC)wParam, RGB(0,0,125));	// DARK_BLUE
		return (INT_PTR)CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDCLOSE:
		case IDCANCEL:
			if (download_status != 1) {
				safe_free(filepath);
				EndDialog(hDlg, LOWORD(wParam));
			}
			return (INT_PTR)TRUE;
		case IDC_WEBSITE:
			ShellExecuteA(hDlg, "open", APPLICATION_URL, NULL, NULL, SW_SHOWNORMAL);
			break;
		case IDC_DOWNLOAD:	// Also doubles as abort and launch function
			switch(download_status) {
			case 1:		// Abort
				download_status = 0;
				error_code = ERROR_SEVERITY_ERROR|ERROR_CANCELLED;
				break;
			case 2:		// Launch newer version and close this one
				Sleep(1000);	// Add a delay on account of antivirus scanners
				memset(&si, 0, sizeof(si));
				memset(&pi, 0, sizeof(pi));
				si.cb = sizeof(si);
				if (!CreateProcessU(filepath, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
					print_status(0, TRUE, "Failed to launch new application");
					dprintf("Failed to launch new application: %s\n", WindowsErrorString());
				} else {
					print_status(0, FALSE, "Launching new application...");
					PostMessage(hDlg, WM_COMMAND, (WPARAM)IDCLOSE, 0);
					PostMessage(hMainDialog, WM_CLOSE, 0, 0);
				}
				break;
			default:	// Download
				if (update.download_url == NULL) {
					print_status(0, TRUE, "Could not get download URL\n");
					break;
				}
				for (i=(int)strlen(update.download_url); (i>0)&&(update.download_url[i]!='/'); i--);
				exe_ext.filename = PathFindFileNameU(update.download_url);
				filepath = FileDialog(TRUE, app_dir, &exe_ext, OFN_NOCHANGEDIR);
				if (filepath == NULL) {
					print_status(0, TRUE, "Could not get save path\n");
					break;
				}
				DownloadFileThreaded(update.download_url, filepath, hDlg);
				break;
			}
			return (INT_PTR)TRUE;
		}
		break;
	case UM_DOWNLOAD_INIT:
		error_code = 0;
		download_status = 1;
		SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), "Abort");
		return (INT_PTR)TRUE;
	case UM_DOWNLOAD_EXIT:
		if (wParam) {
			SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), "Launch");
			download_status = 2;
		} else {
			SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), "Download");
			download_status = 0;
		}
		return (INT_PTR)TRUE;
	}
	return (INT_PTR)FALSE;
}
Exemple #2
0
// Run a console command, with optional redirection of stdout and stderr to our log
DWORD RunCommand(const char* cmd, const char* dir, BOOL log)
{
	DWORD ret, dwRead, dwAvail, dwPipeSize = 4096;
	STARTUPINFOA si = {0};
	PROCESS_INFORMATION pi = {0};
	HANDLE hOutputRead = INVALID_HANDLE_VALUE, hOutputWrite = INVALID_HANDLE_VALUE;
	HANDLE hDupOutputWrite = INVALID_HANDLE_VALUE;
	static char* output;

	si.cb = sizeof(si);
	if (log) {
		// NB: The size of a pipe is a suggestion, NOT an absolute guarantee
		// This means that you may get a pipe of 4K even if you requested 1K
		if (!CreatePipe(&hOutputRead, &hOutputWrite, NULL, dwPipeSize)) {
			ret = GetLastError();
			uprintf("Could not set commandline pipe: %s", WindowsErrorString());
			goto out;
		}
		// We need an inheritable pipe endpoint handle
		DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hDupOutputWrite,
			0L, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
		si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
		si.wShowWindow = SW_HIDE;
		si.hStdOutput = hDupOutputWrite;
		si.hStdError = hDupOutputWrite;
	}

	if (!CreateProcessU(NULL, cmd, NULL, NULL, TRUE,
		NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, dir, &si, &pi)) {
		ret = GetLastError();
		uprintf("Unable to launch command '%s': %s", cmd, WindowsErrorString());
		goto out;
	}

	if (log) {
		while (1) {
			// coverity[string_null]
			if (PeekNamedPipe(hOutputRead, NULL, dwPipeSize, NULL, &dwAvail, NULL)) {
				if (dwAvail != 0) {
					output = malloc(dwAvail + 1);
					if ((output != NULL) && (ReadFile(hOutputRead, output, dwAvail, &dwRead, NULL)) && (dwRead != 0)) {
						output[dwAvail] = 0;
						// coverity[tainted_string]
						uprintf(output);
					}
					free(output);
				}
			}
			if (WaitForSingleObject(pi.hProcess, 0) == WAIT_OBJECT_0)
				break;
			Sleep(100);
		};
	} else {
		WaitForSingleObject(pi.hProcess, INFINITE);
	}

	if (!GetExitCodeProcess(pi.hProcess, &ret))
		ret = GetLastError();
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

out:
	safe_closehandle(hDupOutputWrite);
	safe_closehandle(hOutputRead);
	return ret;
}