bool CScheduler::ShutDownComputer() { int ShutdownSuccess = 0; // Try 2000/XP way first ShutdownSuccess = InitiateSystemShutdownEx( NULL,_T("Shareaza Scheduled Shutdown\n\nA system shutdown was scheduled using Shareaza. The system will now shut down."), 30, FALSE, FALSE, SHTDN_REASON_FLAG_USER_DEFINED ); // Fall back to 9x way if this does not work if ( !ShutdownSuccess && GetLastError() != ERROR_SHUTDOWN_IN_PROGRESS ) { UINT ShutdownFlags = EWX_POWEROFF; DWORD dReason; dReason = ( SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED ); ShutdownSuccess = ExitWindowsEx( ShutdownFlags, dReason ); } return (ShutdownSuccess != 0); }
bool reboot() { HANDLE token; TOKEN_PRIVILEGES new_privileges; LUID luid; if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) { if (LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid)) { new_privileges.PrivilegeCount = 1; new_privileges.Privileges[0].Luid = luid; new_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(token, FALSE, &new_privileges, 0, NULL, NULL); } CloseHandle(token); } #pragma warning(suppress: 28159) return (InitiateSystemShutdownEx(NULL, NULL, 0, FALSE, TRUE, REASON_PLANNED_FLAG | REASON_HWINSTALL) == TRUE); }
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; }
UINT CPackage::executePostCmd( UINT uCommandTimeOut) { CLog *pLog = getOcsLogger(); CExecCommand cmProcess; CString csBuffer; HANDLE hToken; TOKEN_PRIVILEGES tkp; // check if there is post command to execute if (m_csPostCmd.IsEmpty()) { pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => No post execution command provided for package <%s>"), m_csID); return TRUE; } // Check if post command is REBOOT if (m_csPostCmd == OCS_DOWNLOAD_POST_CMD_REBOOT) { pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing post execution command <%s> for package <%s>"), m_csPostCmd, m_csID); // Request ability to restart computer if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Reboot privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } if (!LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Reboot privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Reboot privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } // Initiate a planned restart to perform application installation. if (!InitiateSystemShutdownEx( NULL, _T( "OCS Inventory NG must REBOOT your system after package setup"), uCommandTimeOut, TRUE, TRUE, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to initiate System Reboot after package <%s> execution: %s"), m_csID, LookupError( GetLastError())); return FALSE; } return TRUE; } // Check if post command is SHUTDOWN if (m_csPostCmd == OCS_DOWNLOAD_POST_CMD_SHUTDOWN) { pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing post execution command <%s> for package <%s>"), m_csPostCmd, m_csID); // Request ability to shutdown computer if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Shutdown privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } if (!LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Shutdown privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Shutdown privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } // Initiate a planned shutdown to perform application installation. if (!InitiateSystemShutdownEx( NULL, _T( "OCS Inventory NG must SHUTDOWN your system after package setup"), uCommandTimeOut, TRUE, FALSE, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to initiate System Shutdown after package <%s> execution: %s"), m_csID, LookupError( GetLastError())); return FALSE; } return TRUE; } // Execute default post command pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing post execution command <%s> for package <%s>"), m_csPostCmd, m_csID); // Set command time out in milliseconds cmProcess.setTimeout( uCommandTimeOut * 60 * 1000); // Execute command and wait only for main process to terminate switch (cmProcess.execWait( m_csPostCmd, m_csPath)) { case EXEC_ERROR_START_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to execute post execution command <%s> for package <%s> (%s)"), m_csPostCmd, m_csID, cmProcess.getOutput()); setDone( ERR_EXECUTE); return FALSE; case EXEC_ERROR_WAIT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to get post execution command <%s> result code for package <%s> (%s)"), m_csPostCmd, m_csID, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_NO_EXIT_CODE; return FALSE; case EXEC_ERROR_TIMEOUT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Post execution command <%s> execution reached timeout (%s)"), m_csPostCmd, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_TIMEOUT; return FALSE; default: pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> post execution command successfully executed. Command exit code is <%d>"), m_csID, cmProcess.getExitValue()); if (cmProcess.getExitValue() != 0) // Command result code is not a success csBuffer.Format( _T( "%s%d"), ERR_EXIT_CODE, cmProcess.getExitValue()); else csBuffer = CODE_SUCCESS; break; } return TRUE; }
MI_Result ScheduleRestart( _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Uint32 dwError = ERROR_SUCCESS; HANDLE hToken; MI_Boolean bRevertToSelf = MI_FALSE; Intlstr intlstr = Intlstr_Null; MI_Result result = MI_RESULT_OK; if (cimErrorDetails == NULL) { return MI_RESULT_INVALID_PARAMETER; } *cimErrorDetails = NULL; // Explicitly set *cimErrorDetails to NULL as _Outptr_ requires setting this at least once. DSC_EventWriteMessageScheduleReboot(); GetResourceString(ID_LCMHELPER_SHUTDOWN_MESSAGE, &intlstr); if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &hToken)) { if (GetLastError() == ERROR_NO_TOKEN) { SetLastError(ERROR_SUCCESS); if (!ImpersonateSelf(SecurityImpersonation)) { return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); } if (!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &hToken)) { RevertToSelf(); return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); } bRevertToSelf = MI_TRUE; } else { return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); } } result = EnableShutdownPrivilege(hToken, cimErrorDetails); if (result != MI_RESULT_OK) { if (bRevertToSelf) { RevertToSelf(); } return result; } #ifdef _PREFAST_ #pragma prefast (push) #pragma prefast (disable: 28159) //This is needed to reconfigure windows server to finish configuring the system by DSC. #endif /* _PREFAST_ */ dwError = InitiateSystemShutdownEx(NULL, (MI_Char*)intlstr.str, DSC_REBOOT_GRACEPERIOD, TRUE, TRUE, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED); #ifdef _PREFAST_ #pragma prefast (pop) #endif /* _PREFAST_ */ if (bRevertToSelf) { RevertToSelf(); } if (intlstr.str ) { Intlstr_Free(intlstr); } if (!dwError) { return GetCimWin32Error(GetLastError(), cimErrorDetails, ID_LCMHELPER_SHUTDOWN_FAILED); } return MI_RESULT_OK; }