/************************* Workers ************************************/ static BOOL IsShutdownTypeEnabled(BYTE shutdownType) { BOOL bReturn = FALSE; switch (shutdownType) { case SDSDT_HIBERNATE: case SDSDT_STANDBY: bReturn = shutdownType == SDSDT_HIBERNATE ? IsPwrHibernateAllowed() : IsPwrSuspendAllowed() != 0; /* test privilege */ if (bReturn) { bReturn = WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE); if (bReturn) WinNT_SetPrivilege(SE_SHUTDOWN_NAME, FALSE); } break; case SDSDT_LOGOFF: { HKEY hKey; DWORD dwSetting, dwSize; /* NoLogOff is BINARY on Win9x/ME and DWORD on Win2000+ */ bReturn = TRUE; if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(dwSetting); if (RegQueryValueEx(hKey, _T("NoLogOff"), 0, NULL, (LPBYTE)&dwSetting, &dwSize) == ERROR_SUCCESS) if (dwSetting) bReturn = FALSE; RegCloseKey(hKey); } } break; case SDSDT_LOCKWORKSTATION: { HKEY hKey; DWORD dwSize, dwSetting; /* DisableLockWorkstation is DWORD on Win2000+ */ bReturn = TRUE; if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(dwSetting); if (!RegQueryValueEx(hKey, _T("DisableLockWorkstation"), 0, NULL, (LPBYTE)&dwSetting, &dwSize)) if (dwSetting) bReturn = FALSE; RegCloseKey(hKey); } } break; case SDSDT_CLOSERASCONNECTIONS: /* check if RAS installed/available */ bReturn = TRUE; break; case SDSDT_SETMIRANDAOFFLINE: case SDSDT_CLOSEMIRANDA: bReturn = TRUE; /* always possible */ break; case SDSDT_REBOOT: case SDSDT_SHUTDOWN: /* test privileges */ bReturn = WinNT_SetPrivilege(SE_SHUTDOWN_NAME, TRUE); if (bReturn) WinNT_SetPrivilege(SE_SHUTDOWN_NAME, FALSE); break; } return bReturn; }
bool HibernationEnabled() { #pragma warning (push, 4) #pragma warning( disable : 4800 ) BOOST_LOG_SEV(logger(), debug) << "IsPwrHibernateAllowed(): " << (bool)IsPwrHibernateAllowed(); BOOST_LOG_SEV(logger(), debug) << "IsPwrShutdownAllowed(): " << (bool)IsPwrShutdownAllowed(); BOOST_LOG_SEV(logger(), debug) << "IsPwrSuspendAllowed(): " << (bool)IsPwrSuspendAllowed(); #pragma warning (pop) SYSTEM_POWER_CAPABILITIES systemPowerCapabilities = {0}; if (!GetPwrCapabilities(&systemPowerCapabilities)) { DWORD last_error = GetLastError(); std::string msg = Utilities::MakeString() << "GetPwrCapabilities() failed. Reason: " << last_error; BOOST_LOG_SEV(logger(), error) << msg; return false; } #pragma warning (push, 4) #pragma warning( disable : 4800 ) BOOST_LOG_SEV(logger(), debug) << "systemPowerCapabilities.Hiberboot: " << (bool)systemPowerCapabilities.Hiberboot; #pragma warning (pop) return !!systemPowerCapabilities.Hiberboot; }
/* Main entry for program */ int wmain(int argc, WCHAR *argv[]) { DWORD error = ERROR_SUCCESS; struct CommandLineOptions opts; if (argc == 1) /* i.e. no commandline arguments given */ { PrintResourceString(IDS_USAGE); return EXIT_SUCCESS; } error = ParseArguments(&opts, argc, argv); if (error != ERROR_SUCCESS) { DisplayError(error); return EXIT_FAILURE; } /* If the user wants to abort a shutdown */ if (opts.abort) { /* First, the program has to determine if the shutdown/restart is local or remote. This is done since each one requires separate privileges. */ if (opts.remote_system == NULL) EnablePrivilege(SE_SHUTDOWN_NAME, TRUE); else EnablePrivilege(SE_REMOTE_SHUTDOWN_NAME, TRUE); /* Abort the delayed system shutdown specified. */ if (!AbortSystemShutdownW(opts.remote_system)) { PrintResourceString(IDS_ERROR_ABORT); DisplayError(GetLastError()); return EXIT_FAILURE; } else { return EXIT_SUCCESS; } } /* * If the user wants to hibernate the computer. Assume * that the user wants to wake the computer up from * hibernation and it should not force it on the system. */ if (opts.hibernate) { if (IsPwrHibernateAllowed()) { EnablePrivilege(SE_SHUTDOWN_NAME, TRUE); /* The shutdown utility cannot hibernate remote systems */ if (opts.remote_system != NULL) { return EXIT_FAILURE; } if (!SetSuspendState(TRUE, FALSE, FALSE)) { PrintResourceString(IDS_ERROR_HIBERNATE); DisplayError(GetLastError()); return EXIT_FAILURE; } else { PrintResourceString(IDS_ERROR_HIBERNATE_ENABLED); return EXIT_SUCCESS; } } else { return EXIT_FAILURE; } } /* Both shutdown and restart flags cannot both be true */ if (opts.shutdown && opts.restart) { PrintResourceString(IDS_ERROR_SHUTDOWN_REBOOT); return EXIT_FAILURE; } /* Ensure that the timout amount is not too high or a negative number */ if ((opts.shutdown_delay < 0) || (opts.shutdown_delay > MAX_TIMEOUT)) { PrintResourceString(IDS_ERROR_TIMEOUT, opts.shutdown_delay); return EXIT_FAILURE; } /* If the user wants a GUI environment */ if (opts.show_gui) { if (ShutdownGuiMain(opts)) return EXIT_SUCCESS; else return EXIT_FAILURE; } if (opts.logoff && (opts.remote_system == NULL)) { /* * NOTE: Sometimes, shutdown and logoff are used together. If the logoff * flag is used by itself, then simply logoff. But if used with shutdown, * then skip logging off of the computer and eventually go to the action * for shutdown. */ if (!opts.shutdown && !opts.restart) { EnablePrivilege(SE_SHUTDOWN_NAME, TRUE); if (ExitWindowsEx(EWX_LOGOFF, opts.reason)) { return EXIT_SUCCESS; } else { PrintResourceString(IDS_ERROR_LOGOFF); DisplayError(GetLastError()); return EXIT_FAILURE; } } } /* * Since both shutting down the system and restarting calls the exact same * function, all we need to know is if we wanted to restart or shutdown. */ if (opts.shutdown || opts.restart) { /* * First, the program has to determine if the shutdown/restart is local * or remote. This is done since each one requires separate privileges. */ if (opts.remote_system == NULL) { EnablePrivilege(SE_SHUTDOWN_NAME, TRUE); } else { /* TODO: Remote shutdown is not supported yet */ // EnablePrivilege(SE_REMOTE_SHUTDOWN_NAME, TRUE); return EXIT_SUCCESS; } /** ** HACK: When InitiateSystemShutdownExW will become really implemented, ** activate this line and delete the other... ** if(!InitiateSystemShutdownExW(opts.remote_system, opts.message, opts.shutdown_delay, opts.force, opts.restart, opts.reason)) ***/ if (!ExitWindowsEx((opts.shutdown ? EWX_SHUTDOWN : EWX_REBOOT) | (opts.force ? EWX_FORCE : 0), opts.reason)) { /* * If there is an error, give the proper output depending * on whether the user wanted to shutdown or restart. */ if (opts.restart) PrintResourceString(IDS_ERROR_RESTART); else PrintResourceString(IDS_ERROR_SHUTDOWN); DisplayError(GetLastError()); return EXIT_FAILURE; } else { return EXIT_SUCCESS; } } return EXIT_SUCCESS; }