Example #1
0
static void IdleObject_Tick(IdleObject * obj)
{
	bool idle = false;
	int  idleType = 0, flags = 0;

	if (obj->useridlecheck && IdleObject_IsUserIdle(obj)) {
		idleType = 1; idle = true;
	}
	else if (IdleObject_IdleCheckSaver(obj) && IsScreenSaverRunning()) {
		idleType = 2; idle = true;
	}
	else if (IdleObject_IdleCheckFullScr(obj) && IsFullScreen()) {
		idleType = 5; idle = true;
	}
	else if (IdleObject_IdleCheckWorkstation(obj) && IsWorkstationLocked()) {
		idleType = 3; idle = true;
	}
	else if (IdleObject_IdleCheckTerminal(obj) && IsTerminalDisconnected()) {
		idleType = 4; idle = true;
	}

	if (IdleObject_IsPrivacy(obj))
		flags |= IDF_PRIVACY;

	if ( !IdleObject_IsIdle(obj) && idle) {
		IdleObject_SetIdle(obj);
		obj->idleType = idleType;
		NotifyEventHooks(hIdleEvent, 0, IDF_ISIDLE | flags);
	}
	if (IdleObject_IsIdle(obj) && !idle) {
		IdleObject_ClearIdle(obj);
		obj->idleType = 0;
		NotifyEventHooks(hIdleEvent, 0, flags);
}	}
Example #2
0
BOOL checkNotifyOptions()
{
	BOOL screenSaverIsRunning = IsScreenSaverRunning();
	if (screenSaverIsRunning && bScreenSaverRunning)
		return TRUE;

	BOOL workstationIsLocked = IsWorkstationLocked();
	if (workstationIsLocked && bWorkstationLocked)
		return TRUE;

	BOOL fullScreenMode = IsFullScreen() && !screenSaverIsRunning;
	if (fullScreenMode && bFullScreenMode)
		return TRUE;

	BOOL processesRunning = areThereProcessesRunning();
	if (processesRunning && bProcessesAreRunning)
		return TRUE;

	return (!fullScreenMode && !screenSaverIsRunning && !workstationIsLocked && !processesRunning && bWorkstationActive);
}
Example #3
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;
}
Example #4
0
unsigned __stdcall MessagePumpThread(void* param)
{
	if (param)
		SetEvent((HANDLE)param);

	MSG hwndMsg = { 0 };
	while (GetMessage(&hwndMsg, 0, 0, 0) > 0 && !bShutdown) {
		if (hwndMsg.hwnd != NULL && IsDialogMessage(hwndMsg.hwnd, &hwndMsg)) /* Wine fix. */
			continue;
		switch(hwndMsg.message) {
		case MUM_CREATEPOPUP:
			{
				bool enabled = true;
				int status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
				if (status >= ID_STATUS_OFFLINE && status <= ID_STATUS_OUTTOLUNCH && options.disable_status[status - ID_STATUS_OFFLINE])
					enabled = false;
				if ((options.disable_full_screen && IsFullScreen()) || IsWorkstationLocked())
					enabled = false;

				PopupData *pd = (PopupData*)hwndMsg.lParam;
				if (enabled && num_popups < MAX_POPUPS) {
					//HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("Popup"), WS_POPUP, 0, 0, 0, 0, GetDesktopWindow(), 0, hInst, (LPVOID)hwndMsg.lParam);
					HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("Popup"), WS_POPUP, 0, 0, 0, 0, 0, 0, hInst, (LPVOID)hwndMsg.lParam);
					num_popups++;
					if (hwndMsg.wParam) // set notifyer handle
						SendMessage(hwnd, PUM_SETNOTIFYH, hwndMsg.wParam, 0);
				}
				else if (pd) {
					mir_free(pd->pwzTitle);
					mir_free(pd->pwzText);
					mir_free(pd);
				}
			}
			break;

		case MUM_DELETEPOPUP:
			{
				HWND hwnd = (HWND)hwndMsg.lParam;
				if (IsWindow(hwnd)) {
					DestroyWindow(hwnd);
					num_popups--;
				}
			}
			break;

		case MUM_NMUPDATE:
			BroadcastMessage(PUM_UPDATENOTIFY, hwndMsg.wParam, 0);
			break;

		case MUM_NMREMOVE:
			BroadcastMessage(PUM_KILLNOTIFY, hwndMsg.wParam, 0);
			break;

		case MUM_NMAVATAR:
			RepositionWindows();
			break;

		default:
			TranslateMessage(&hwndMsg);
			DispatchMessage(&hwndMsg);
			break;
		}
	}

	DeinitWindowStack();
	num_popups = 0;
	return 0;
}