Ejemplo n.º 1
0
INT_PTR ServiceShutdown(WPARAM wParam, LPARAM lParam)
{
	/* passing 0 as wParam is only to be used internally, undocumented */
	if (!wParam) wParam = db_get_b(NULL, "AutoShutdown", "ShutdownType", SETTING_SHUTDOWNTYPE_DEFAULT);
	if (!IsShutdownTypeEnabled((BYTE)wParam)) return 1; /* does shutdownType range check */
	if ((BOOL)lParam && hwndShutdownDlg != NULL) return 2;

	/* ask others if allowed */
	if (NotifyEventHooks(hEventOkToShutdown, wParam, lParam)) {
		OutputDebugStringA("automatic shutdown denied by event hook\n"); /* all ascii */
		return 3;
	}
	/* tell others */
	NotifyEventHooks(hEventShutdown, wParam, lParam);
	/* show dialog */
	if (lParam && db_get_b(NULL, "AutoShutdown", "ShowConfirmDlg", SETTING_SHOWCONFIRMDLG_DEFAULT))
		if (CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SHUTDOWNNOW), NULL, ShutdownDlgProc, (BYTE)wParam) != NULL)
			return 0;
	/* show error */

	DWORD dwErrCode = ShutdownNow((BYTE)wParam);
	if (dwErrCode != ERROR_SUCCESS) {
		char *pszErr = GetWinErrorDescription(dwErrCode);
		ShowInfoMessage(NIIF_ERROR, Translate("Automatic Shutdown Error"), Translate("Inititiating the shutdown process failed!\nReason: %s"), (pszErr != NULL) ? pszErr : Translate("Unknown"));
		if (pszErr != NULL)
			LocalFree(pszErr);
		return 4;
	}

	return 0;
}
Ejemplo n.º 2
0
std::string I_ConsoleInput (void)
{
	// denis - todo - implement this properly!!!
    static char     text[1024] = {0};
    static char     buffer[1024] = {0};
    unsigned int    len = strlen(buffer);

    if (ShutdownNow())
        return "quit";

	while(kbhit() && len < sizeof(text))
	{
		char ch = (char)getch();

		// input the character
		if(ch == '\b' && len)
		{
			buffer[--len] = 0;
			// john - backspace hack
			fwrite(&ch, 1, 1, stdout);
			ch = ' ';
			fwrite(&ch, 1, 1, stdout);
			ch = '\b';
		}
		else
			buffer[len++] = ch;
		buffer[len] = 0;

		// recalculate length
		len = strlen(buffer);

		// echo character back to user
		fwrite(&ch, 1, 1, stdout);
		fflush(stdout);
	}

	if(len && buffer[len - 1] == '\n' || buffer[len - 1] == '\r')
	{
		// echo newline back to user
		char ch = '\n';
		fwrite(&ch, 1, 1, stdout);
		fflush(stdout);

		strcpy(text, buffer);
		text[len-1] = 0; // rip off the /n and terminate
		buffer[0] = 0;
		len = 0;

		return text;
	}

	return "";
}
Ejemplo n.º 3
0
static INT_PTR CALLBACK ShutdownDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	BYTE shutdownType = (BYTE)GetWindowLongPtr(hwndDlg, DWLP_USER);
	WORD countdown = (WORD)GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA);

	switch (msg) {
	case WM_INITDIALOG:
		hwndShutdownDlg = hwndDlg;
		SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
		TranslateDialogDefault(hwndDlg);

		if (lParam == SDSDT_SHUTDOWN || lParam == SDSDT_REBOOT || lParam == SDSDT_LOGOFF)
			ShowWindow(GetDlgItem(hwndDlg, IDC_TEXT_UNSAVEDWARNING), SW_SHOW);
		SendDlgItemMessage(hwndDlg, IDC_ICON_HEADER, STM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon("AutoShutdown_Header"));
		{
			HFONT hBoldFont;
			LOGFONT lf;
			if (GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_GETFONT, 0, 0), sizeof(lf), &lf)) {
				lf.lfWeight = FW_BOLD;
				hBoldFont = CreateFontIndirect(&lf);
			}
			else hBoldFont = NULL;
			SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_SETFONT, (WPARAM)hBoldFont, FALSE);
			SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, (LONG_PTR)hBoldFont);
		}
		{
			countdown = db_get_w(NULL, "AutoShutdown", "ConfirmDlgCountdown", SETTING_CONFIRMDLGCOUNTDOWN_DEFAULT);
			if (countdown < 3)
				countdown = SETTING_CONFIRMDLGCOUNTDOWN_DEFAULT;
			SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, countdown);
			SendMessage(hwndDlg, M_UPDATE_COUNTDOWN, 0, countdown);
		}
		SkinPlaySound("AutoShutdown_Countdown");
		if (!SetTimer(hwndDlg, 1, 1000, NULL))
			PostMessage(hwndDlg, M_START_SHUTDOWN, 0, 0);

		Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AutoShutdown", "ConfirmDlg_");

		/* disallow foreground window changes (WinMe/2000+) */
		SetForegroundWindow(hwndDlg);
		LockSetForegroundWindow(LSFW_LOCK);

		SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDCANCEL), TRUE);
		return FALSE; /* focus set on cancel */

	case WM_DESTROY:
		{
			hwndShutdownDlg = NULL;
			ShowWindow(hwndDlg, SW_HIDE);
			/* reallow foreground window changes (WinMe/2000+) */
			LockSetForegroundWindow(LSFW_UNLOCK);
			Utils_SaveWindowPosition(hwndDlg, NULL, "AutoShutdown", "ConfirmDlg_");
			HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_GETFONT, 0, 0);
			SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_SETFONT, 0, FALSE); /* no return value */
			if (hFont != NULL) DeleteObject(hFont);
		}
		return TRUE;

	case M_START_SHUTDOWN:
		if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BUTTON_SHUTDOWNNOW))) {
			EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_SHUTDOWNNOW), FALSE);
			ShowWindow(hwndDlg, SW_HIDE);  /* get rid of the dialog immediately */
			DWORD dwErrCode = ShutdownNow(shutdownType);
			if (dwErrCode != ERROR_SUCCESS) {
				char *pszErr = GetWinErrorDescription(dwErrCode);
				ShowInfoMessage(NIIF_ERROR, Translate("Automatic Shutdown Error"), Translate("The shutdown process failed!\nReason: %s"), (pszErr != NULL) ? pszErr : Translate("Unknown"));
				if (pszErr != NULL) LocalFree(pszErr);
			}
			DestroyWindow(hwndDlg);
		}
		return TRUE;

	case WM_TIMER:
		if (countdown) {
			--countdown;
			SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, countdown);
			if (countdown == 27 || countdown == 24 || countdown == 21 || countdown == 19 ||
				countdown == 17 || countdown == 15 || countdown == 13 || countdown == 11 ||
				countdown <= 10)
				SkinPlaySound("AutoShutdown_Countdown");
		}
		else KillTimer(hwndDlg, wParam);  /* countdown finished */
		PostMessage(hwndDlg, M_UPDATE_COUNTDOWN, 0, countdown);
		return TRUE;

	case M_UPDATE_COUNTDOWN:  /* lParam=(WORD)countdown */
		{
			TCHAR szText[256];
			mir_sntprintf(szText, TranslateTS(desc[shutdownType - 1]), lParam);
			SetDlgItemText(hwndDlg, IDC_TEXT_HEADER, szText);
			/* countdown finished */
			if (!lParam)
				PostMessage(hwndDlg, M_START_SHUTDOWN, 0, 0);
		}
		return TRUE;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_BUTTON_SHUTDOWNNOW:
			KillTimer(hwndDlg, 1);
			SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, 0);
			SendMessage(hwndDlg, M_UPDATE_COUNTDOWN, 0, (LONG)0);
			PostMessage(hwndDlg, M_START_SHUTDOWN, 0, 0);
			return TRUE;
		case IDCANCEL: /* WM_CLOSE */
			if (countdown) {
				KillTimer(hwndDlg, 1);
				DestroyWindow(hwndDlg);
			}
			return TRUE;
		}
		break;
	}
	return FALSE;
}
Ejemplo n.º 4
0
static DWORD ShutdownNow(BYTE shutdownType)
{
	DWORD dwErrCode = ERROR_SUCCESS;
	switch (shutdownType) {
	case SDSDT_CLOSEMIRANDA:
		if (!Miranda_Terminated()) {
			/* waiting for short until ready (but not too long...) */
			DWORD dwLastTickCount = GetTickCount();
			while (!CallService(MS_SYSTEM_OKTOEXIT, 0, 0)) {
				/* infinite loop protection (max 5 sec) */
				if (GetTickCount() - dwLastTickCount >= 5000) { /* wraparound works */
					OutputDebugStringA("Timeout (5 sec)\n"); /* tell others, all ascii */
					break;
				}
				SleepEx(1000, TRUE);
				if (Miranda_Terminated()) break; /* someone else did it */
				OutputDebugStringA("Not ready to exit. Waiting...\n"); /* tell others, all ascii */
			}
			/* shutdown service must be called from main thread anyway */
			if (!DestroyWindow(pcli->hwndContactList))
				dwErrCode = GetLastError();
		}
		break;

	case SDSDT_SETMIRANDAOFFLINE:
		/* set global status mode to offline (is remembered by Miranda on exit) */
		CallService(MS_CLIST_SETSTATUSMODE, (WPARAM)ID_STATUS_OFFLINE, 0);
		break;

	case SDSDT_STANDBY:
	case SDSDT_HIBERNATE:
		WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE);
		if (!SetSystemPowerState(shutdownType == SDSDT_STANDBY, TRUE))
			dwErrCode = GetLastError();
		WinNT_SetPrivilege(SE_SHUTDOWN_NAME, FALSE);
		break;

	case SDSDT_LOCKWORKSTATION:
		if (!IsWorkstationLocked())
			dwErrCode = GetLastError();
		break;

	case SDSDT_CLOSERASCONNECTIONS:
		ShutdownNow(SDSDT_SETMIRANDAOFFLINE); /* set Miranda offline */
		/* hang up all ras connections */
		{
			DWORD dwRetries;
			RASCONNSTATUS rcs;
			DWORD dw, dwLastTickCount;

			DWORD dwConnSize = sizeof(RASCONN);
			DWORD dwConnItems = 0;
			RASCONN *paConn = (RASCONN*)mir_alloc(dwConnSize);
			dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
			if (paConn != NULL) {
				for (dwRetries = 5; dwRetries != 0; dwRetries--) { /* prevent infinite loop (rare) */
					memset(paConn, 0, dwConnSize);
					paConn[0].dwSize = sizeof(RASCONN);
					dwErrCode = RasEnumConnections(paConn, &dwConnSize, &dwConnItems);
					if (dwErrCode != ERROR_BUFFER_TOO_SMALL) break;
					RASCONN *paConnBuf = (RASCONN*)mir_realloc(paConn, dwConnSize);
					if (paConnBuf == NULL) {
						mir_free(paConn);
						paConn = NULL;
						dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
						break;
					}
					paConn = paConnBuf;
				}
				if (dwErrCode == ERROR_SUCCESS || dwErrCode == ERROR_BUFFER_TOO_SMALL) {
					for (dw = 0; dw < dwConnItems; ++dw) {
						if (dwErrCode) {
							if (RasHangUp(paConn[dw].hrasconn))
								paConn[dw].hrasconn = NULL; /* do not wait for on error */
						}
						else {
							dwErrCode = RasHangUp(paConn[dw].hrasconn);
							if (!dwErrCode) paConn[dw].hrasconn = NULL; /* do not wait for on error */
						}
					}
					/* RAS does not allow to quit directly after HangUp (see docs) */
					dwLastTickCount = GetTickCount();
					memset(&rcs, 0, sizeof(RASCONNSTATUS));
					rcs.dwSize = sizeof(RASCONNSTATUS);
					for (dw = 0; dw < dwConnItems; ++dw) {
						if (paConn[dw].hrasconn != NULL) {
							while (RasGetConnectStatus(paConn[dw].hrasconn, &rcs) != ERROR_INVALID_HANDLE) {
								Sleep(0); /* give rest of time silce to other threads with equal priority */
								/* infinite loop protection (3000ms defined in docs) */
								dwRetries = GetTickCount();
								if (dwRetries - dwLastTickCount > 3000)
									break; /* wraparound works */
							}
						}
					}
				}
				mir_free(paConn); /* does NULL check */
			}
		}
		/* set Miranda to offline again, to remain offline with reconnection plugins */
		ShutdownNow(SDSDT_SETMIRANDAOFFLINE);
		break;

	case SDSDT_REBOOT:
	case SDSDT_SHUTDOWN:
		if (GetSystemMetrics(SM_SHUTTINGDOWN)) { /* Win2000+, 0 on error */
			dwErrCode = ERROR_SHUTDOWN_IN_PROGRESS;
			break;
		}
		/* WinNT4/2000/XP */
		{
			WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE);

			/* does not send out WM_ENDSESSION messages, so we do it manually to
			* give the applications the chance to save their data */
			WinNT_SetPrivilege(SE_TCB_NAME, TRUE); /* for BSM_ALLDESKTOPS */
			BroadcastEndSession(BSM_APPLICATIONS | BSM_ALLDESKTOPS, ENDSESSION_CLOSEAPP); /* app should close itself */
			WinNT_SetPrivilege(SE_TCB_NAME, FALSE);

			if (!InitiateSystemShutdownEx(NULL, TranslateT("AutoShutdown"), 0, TRUE, shutdownType == SDSDT_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED))
				dwErrCode = GetLastError();

			/* cleanly close Miranda */
			if (!dwErrCode) ShutdownNow(SDSDT_CLOSEMIRANDA);
			break;
		}
		/* fall through for Win9x */
	case SDSDT_LOGOFF:
		{
			UINT flags;
			switch (shutdownType) {
			case SDSDT_LOGOFF: flags = EWX_LOGOFF; break;
			case SDSDT_REBOOT: flags = EWX_REBOOT; break;
			default:           flags = EWX_SHUTDOWN | EWX_POWEROFF;
			}
			if (shutdownType == SDSDT_LOGOFF && !IsWorkstationLocked())
				flags |= EWX_FORCEIFHUNG; /* only considered for WM_ENDSESSION messages */
			else
				flags |= EWX_FORCE; /* must be used when workstation locked */

			if (flags & EWX_FORCE) {
				/* EWX_FORCE does not send out WM_ENDSESSION messages, so we do it
				* manually to give the applications the chance to save their data */
				BroadcastEndSession(BSM_APPLICATIONS, (shutdownType == SDSDT_LOGOFF) ? ENDSESSION_LOGOFF : 0);

				/* Windows Me/98/95 (msdn): Because of the design of the shell,
				* calling ExitWindowsEx with EWX_FORCE fails to completely log off
				* the user (the system terminates the applications and displays the
				* Enter Windows Password dialog box, however, the user's desktop remains.)
				* To log off the user forcibly, terminate the Explorer process before calling
				* ExitWindowsEx with EWX_LOGOFF and EWX_FORCE. */
			}
			if (!ExitWindowsEx(flags, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED))
				dwErrCode = GetLastError();
			/* cleanly close Miranda */
			if (!dwErrCode)
				ShutdownNow(SDSDT_CLOSEMIRANDA);
		}
		break;
	}
	return dwErrCode;
}