Index: base/applications/shutdown/CMakeLists.txt =================================================================== --- base/applications/shutdown/CMakeLists.txt (revision 57260) +++ base/applications/shutdown/CMakeLists.txt (working copy) @@ -9,6 +9,6 @@ add_executable(shutdown ${SOURCE}) set_module_type(shutdown win32cui) -add_importlibs(shutdown advapi32 user32 msvcrt kernel32) +add_importlibs(shutdown advapi32 user32 msvcrt powrprof kernel32) add_pch(shutdown precomp.h) add_cd_file(TARGET shutdown DESTINATION reactos/system32 FOR all) Index: base/applications/shutdown/lang/bg-BG.rc =================================================================== --- base/applications/shutdown/lang/bg-BG.rc (revision 57260) +++ base/applications/shutdown/lang/bg-BG.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\tНасилване на работещите приложения да се затворят без предупреждение\n\ \t\t\tАко не сте задали други ключове, тази възможност\n\ \t\t\tще доведе до изход от потребителя" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/de-DE.rc =================================================================== --- base/applications/shutdown/lang/de-DE.rc (revision 57260) +++ base/applications/shutdown/lang/de-DE.rc (working copy) @@ -16,4 +16,14 @@ -f\t\t\tLaufende Anwendungen ohne Warnung schließen\n\ \t\t\tWenn Sie keine weiteren Parameter angegeben haben,\n\ \t\t\tmeldet Sie diese Option auch ab" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/el-GR.rc =================================================================== --- base/applications/shutdown/lang/el-GR.rc (revision 57260) +++ base/applications/shutdown/lang/el-GR.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\tΕξαναγκάζει τις τρέχουσες εφαρμογές να κλείσουν χωρίς προειδοποίηση\n\ \t\t\tΑν δε δηλώσατε κάποια άλλη παράμετρο, αυτή η επιλογή\n\ \t\t\tθα κάνει την αποσύνδεση" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/en-US.rc =================================================================== --- base/applications/shutdown/lang/en-US.rc (revision 57260) +++ base/applications/shutdown/lang/en-US.rc (working copy) @@ -1,14 +1,35 @@ -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US STRINGTABLE DISCARDABLE BEGIN - -IDS_USAGE, "Usage: shutdown [-?] [-l | -s | -r] [-f]\n\n\ - No arguments or -?\tDisplay this message\n\ - -l\t\t\tLog off\n\ - -s\t\t\tShutdown the computer\n\ - -r\t\t\tShutdown and restart the computer\n\ - -f\t\t\tForces running applications to close without warnings\n\ - \t\t\tIf you did not specify any other parameter, this option\n\ - \t\t\twill also log off" +IDS_USAGE, "Usage: shutdown [-?] [-i | -l | -s | -r | -g | -a | -p | -h | -e] [-f]\n\ +\t[-m \\\\computer][-t xxx][-d [p|u]xx:yy [-c ""comment""]]\n\n\ +\tNo arguments or -?\tDisplay this message.\n\ +\t-a\t\t\tCancel delayed shutdown.\n\ +\t-c ""comment""\t\tComment on reason for shutdown.\n\ +\t-d\t\t\tReason code [p|u:]xx:yy.\n\ +\t-e\t\t\tDocuments reason for shutdown.\n\ +\t-f\t\t\tForces running applications to close without\n\ +\t\t\t\twarnings. If you did not specify any other\n\ +\t\t\t\tparameter, this option will also log off.\n\ +\t-h\t\t\tHibernate the local computer.\n\ +\t-i\t\t\tShows the GUI version of the shutdown utility.\n\ +\t-l\t\t\tLog off (Limited to the local system only).\n\ +\t-m \\\\computer\t\tTarget remote systems (UNC/IP address).\n\ +\t-p \t\t\tShuts down the local computer with no\n\ +\t\t\t\twarning/time-out.\n\ +\t-r \t\t\tRestart the computer.\n\ +\t-s\t\t\tShutdown the computer.\n\ +\t-t xxx\t\t\tSets the time-out period to xxx seconds before shutting\n\ +\t\t\t\tdown." +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/es-ES.rc =================================================================== --- base/applications/shutdown/lang/es-ES.rc (revision 57260) +++ base/applications/shutdown/lang/es-ES.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\tObliga las aplicaciones en curso de ejecución a apagarse sin advertencias\n\ \t\t\tSi no especifica algún otro parámetro, esta opción\n\ \t\t\tprovocará también una desconexión" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/fr-FR.rc =================================================================== --- base/applications/shutdown/lang/fr-FR.rc (revision 57260) +++ base/applications/shutdown/lang/fr-FR.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\tForce les applications en cours de fonctionnement à se fermer sans avertissements\n\ \t\t\tSi vous ne spécifiez aucun autre paramètre, cette option\n\ \t\t\tprovoquera aussi une déconnexion" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/it-IT.rc =================================================================== --- base/applications/shutdown/lang/it-IT.rc (revision 57260) +++ base/applications/shutdown/lang/it-IT.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\tArresta le applicazioni senza nessun avviso\n\ \t\t\tSe non viene specificato nessun altro parametro verrà\n\ \t\t\tchiusa la sessione" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/ja-JP.rc =================================================================== --- base/applications/shutdown/lang/ja-JP.rc (revision 57260) +++ base/applications/shutdown/lang/ja-JP.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\t実行中のアプリケーションを警告なしに閉じます\n\ \t\t\t他のパラメータを指定しない場合、ログオフn\n\ \t\t\tします" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/ko-KR.rc =================================================================== --- base/applications/shutdown/lang/ko-KR.rc (revision 57260) +++ base/applications/shutdown/lang/ko-KR.rc (working copy) @@ -14,4 +14,14 @@ -f\t\t\t프로세스 강제종료\n\ \t\t\t아무 파라미터도 입력하지 않으시면,\n\ \t\t\t로그오프 될 것입니다" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/lt-LT.rc =================================================================== --- base/applications/shutdown/lang/lt-LT.rc (revision 57260) +++ base/applications/shutdown/lang/lt-LT.rc (working copy) @@ -13,4 +13,14 @@ -f\t\t\tPriverstinai užverti visas paleistas programas\n\ \t\t\tJeigu nenurodyti jokie kiti parametrai, taip pat\n\ \t\t\tbus įvykdytas atsijungimas" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/nl-NL.rc =================================================================== --- base/applications/shutdown/lang/nl-NL.rc (revision 57260) +++ base/applications/shutdown/lang/nl-NL.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\tProgrammas zonder waarschuwing afsluiten\n\ \t\t\tAls u geen andere optie hebt geselecteerd, dan zal deze functie\n\ \t\t\tu ook doen afmelden" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/no-NO.rc =================================================================== --- base/applications/shutdown/lang/no-NO.rc (revision 57260) +++ base/applications/shutdown/lang/no-NO.rc (working copy) @@ -11,4 +11,14 @@ -f\t\t\tTvinger alle programmer til å avsluttes, og dersom\n\ \t\t\tdet ikke er spesifisert andre parametere vil\n\ \t\t\tbrukeren også logges ut." +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/pl-PL.rc =================================================================== --- base/applications/shutdown/lang/pl-PL.rc (revision 57260) +++ base/applications/shutdown/lang/pl-PL.rc (working copy) @@ -19,4 +19,14 @@ -f\t\t\tZamknięcie wszystkich działających aplikacji, bez ostrzeżenia\n\ \t\t\tBez podania innego parametru, ta opcja domyślnie wyloguje \n\ \t\t\tobecnego użytkownika" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/pt-BR.rc =================================================================== --- base/applications/shutdown/lang/pt-BR.rc (revision 57260) +++ base/applications/shutdown/lang/pt-BR.rc (working copy) @@ -13,4 +13,14 @@ -f\t\t\tForçar o fechamento dos aplicativos em execução sem avisar os usuários\n\ \t\t\tSe você não especificar outro parâmetro, esta opção\n\ \t\t\ttambém fará logoff" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/ro-RO.rc =================================================================== --- base/applications/shutdown/lang/ro-RO.rc (revision 57260) +++ base/applications/shutdown/lang/ro-RO.rc (working copy) @@ -21,4 +21,14 @@ \t\tDacă nu ați specificat nici un alt parametru, această\n\ \t\topțiune are în mod implicit stabilită închiderea\n\ \tsesiunii curente." +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/ru-RU.rc =================================================================== --- base/applications/shutdown/lang/ru-RU.rc (revision 57260) +++ base/applications/shutdown/lang/ru-RU.rc (working copy) @@ -14,4 +14,14 @@ \t\t\tпредупреждения\n\ \t\t\tЕсли вы не указали другие параметры, то эта опция\n\ \t\t\tприведет к завершению сеанса." +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/sk-SK.rc =================================================================== --- base/applications/shutdown/lang/sk-SK.rc (revision 57260) +++ base/applications/shutdown/lang/sk-SK.rc (working copy) @@ -20,4 +20,14 @@ -f\t\t\tDonúti spustené programy aby sa vypli bez upozornení.\n\ \t\t\tAk nebol zadaný žiadny iný parameter, tak aj odhlási\n\ \t\t\tpoužívateľa." +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/sv-SE.rc =================================================================== --- base/applications/shutdown/lang/sv-SE.rc (revision 57260) +++ base/applications/shutdown/lang/sv-SE.rc (working copy) @@ -18,4 +18,14 @@ -f\t\tGör att program som körs avslutas utan att användare meddelas.\n\ \t\tOm du inte angav någon annan parameter till detta kommandot\n\ \t\tkommer användaren dessutom att loggas ut." +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/uk-UA.rc =================================================================== --- base/applications/shutdown/lang/uk-UA.rc (revision 57260) +++ base/applications/shutdown/lang/uk-UA.rc (working copy) @@ -19,4 +19,14 @@ -f\t\t\tПримусове закриття запущених додатків без попереджень\n\ \t\t\tЯкщо ви не вказали інший параметр, то ця опція також\n\ \t\t\tзавершить сеанс" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/zh-CN.rc =================================================================== --- base/applications/shutdown/lang/zh-CN.rc (revision 57260) +++ base/applications/shutdown/lang/zh-CN.rc (working copy) @@ -15,4 +15,14 @@ -f\t\t\t毫无警告地强行关闭正在运行的程序\n\ \t\t\t如果您没有指定其他任何参数,这个选项\n\ \t\t\t也会引起注销" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/lang/zh-TW.rc =================================================================== --- base/applications/shutdown/lang/zh-TW.rc (revision 57260) +++ base/applications/shutdown/lang/zh-TW.rc (working copy) @@ -15,4 +15,14 @@ -f\t\t\t無警告地強制關閉正在執行的程式\n\ \t\t\t如果您沒有指定其他任何參數,這個選項\n\ \t\t\t也會引致登出" +IDS_ERROR_SHUTDOWN_REBOOT, "ERROR: Unable to Shutdown and restart at the same time.\n" +IDS_ERROR_TIMEOUT, "ERROR: Timeout value of %u is out of bounds (0-315360000).\n" +IDS_ERROR_ABORT, "ERROR: Unable to abort the shutdown the system.\n" +IDS_ERROR_LOGOFF, "ERROR: Unable to logoff the system.\n" +IDS_ERROR_SHUTDOWN, "ERROR: Unable to shutdown the system.\n" +IDS_ERROR_RESTART, "ERROR: Unable to restart the system.\n" +IDS_ERROR_MAX_COMMENT_LENGTH, "ERROR: Comment length exceeds maximum character limit.\n" +IDS_ERROR_HIBERNATE, "ERROR: Unable to send system into hibernation mode.\n" +IDS_ERROR_HIBERNATE_LOCAL, "ERROR: Hibernation mode can not be started remotely.\n" +IDS_ERROR_HIBERNATE_ENABLED, "ERROR: Hibernation mode is not enabled.\n" END Index: base/applications/shutdown/misc.c =================================================================== --- base/applications/shutdown/misc.c (revision 57260) +++ base/applications/shutdown/misc.c (working copy) @@ -1,63 +1,124 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS shutdown/logoff utility + * FILE: base/application/shutdown/misc.c + * PURPOSE: Misc. functions used for the shutdown utility + */ #include "precomp.h" -static INT -LengthOfStrResource(IN HINSTANCE hInst, - IN UINT uID) +REASON shutdownReason[] = { + {_T("U"), 0, 0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER}, /* Other (Unplanned) */ + {_T("E"), 0, 0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER}, /* Other (Unplanned) */ + {_T("EP"), 0, 0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED}, /* Other (Planned) */ + {_T("U"), 0, 5, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_HUNG}, /* Other Failure: System Unresponsive */ + {_T("E"), 1, 1, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_MAINTENANCE}, /* Hardware: Maintainance (Unplanned) */ + {_T("EP"), 1, 1, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED}, /* Hardware: Maintainance (Planned) */ + {_T("E"), 1, 2, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_INSTALLATION}, /* Hardware: Installation (Unplanned) */ + {_T("EP"), 1, 2, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED}, /* Hardware: Installation (Planned) */ + {_T("P"), 2, 3, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Upgrade (Planned) */ + {_T("E"), 2, 4, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG}, /* Operating System: Reconfiguration (Unplanned) */ + {_T("EP"), 2, 4, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Reconfiguration (Planned) */ + {_T("P"), 2, 16, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Service pack (Planned) */ + {_T("U"), 2, 17, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_HOTFIX}, /* Operating System: Hotfix (Unplanned) */ + {_T("P"), 2, 17, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_HOTFIX | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Hotfix (Planned) */ + {_T("U"), 2, 18, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX}, /* Operating System: Security fix (Unplanned) */ + {_T("P"), 2, 18, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Security fix (Planned) */ + {_T("E"), 4, 1, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE}, /* Application: Maintenance (Unplanned) */ + {_T("EP"), 4, 1, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED}, /* Application: Maintenance (Planned) */ + {_T("EP"), 4, 2, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED}, /* Application: Installation (Planned) */ + {_T("E"), 4, 5, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_HUNG}, /* Application: Unresponsive */ + {_T("E"), 4, 6, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_UNSTABLE}, /* Application: Unstable */ + {_T("U"), 5, 15, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_BLUESCREEN}, /* System Failure: Stop Error */ + {_T("E"), 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY}, /* Security Issue */ + {_T("U"), 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY}, /* Security Issue */ + {_T("EP"), 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY | SHTDN_REASON_FLAG_PLANNED}, /* Security Issue (Planned) */ + {_T("E"), 5, 20, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY}, /* Loss of Network Connectivity (Unplanned) */ + {_T("U"), 6, 11, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_CORDUNPLUGGED}, /* Power Failure: Cord Unplugged */ + {_T("U"), 6, 12, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_ENVIRONMENT}, /* Power Failure: Environment */ + {_T("P"), 7, 0, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_ENVIRONMENT} /* Legacy API shutdown (Planned) */ +}; + +/* This command helps to work around the fact that the shutdown utility has +different upper limits for the comment flag since each version of Windows seems +to have different limit sizes. */ +BOOL CheckCommentLength(LPSTR comment) { - HRSRC hrSrc; - HGLOBAL hRes; - LPWSTR lpName, lpStr; + DWORD finalLength = 0; + size_t strLength = 0; + DWORD osVersion = 0; + DWORD osMajorVersion = 0; + DWORD osMinorVersion = 0; + + /* Grabs the version of the current Operating System. */ + osVersion = GetVersion(); + + osMajorVersion = (DWORD)(LOBYTE(LOWORD(osVersion))); + osMinorVersion = (DWORD)(HIBYTE(LOWORD(osVersion))); + + /* Checks to make sure that the proper length is being used based + upon the version of Windows currently being used. */ + /* TODO: Update this list to include all major versions of Windows if needed. */ + if(((osMajorVersion == 5)&&(osMinorVersion == 1))|| + ((osMajorVersion == 5)&&(osMinorVersion == 2))) + finalLength = 127; /* Windows XP/2003 */ + else if(((osMajorVersion == 6)&&(osMinorVersion == 0))|| + ((osMajorVersion == 6)&&(osMinorVersion == 1))) + finalLength = 512; /* Windows Vista/7/2008 */ + + /* Grabs the length of the comment string. */ + strLength = _tcslen(comment); + + /* Compares the size of the string to make sure it fits with the current + version of Windows. */ + if(*comment <= finalLength) + return TRUE; + else + return FALSE; + + return TRUE; +} - if (hInst == NULL) - { - return -1; - } +/* Parses the reason code to a usable format that will specify why the user wants to +shut the computer down. Although this is used for both client and server environments, +use of a reason code is more important in a server environment since servers are supposed +to be on all the time for easier access. */ +DWORD ParseReasonCode(LPTSTR code) +{ + /* If no reason code is specified, use "Other (Unplanned)" as the default option. */ + if(code == NULL) + return SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER; + + /* TODO: Add parsing code here */ + return SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER; +} - /* There are always blocks of 16 strings */ - lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1); +/* Writes the last error as both text and error code to the console. */ +void DisplayLastError(void) +{ + int errorCode = GetLastError(); + LPTSTR lpMsgBuf = NULL; + DWORD errLength; /* error message length */ + LPTSTR resMsg; /* for error message in OEM symbols */ - /* Find the string table block */ - if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) && - (hRes = LoadResource(hInst, hrSrc)) && - (lpStr = (WCHAR*) LockResource(hRes))) - { - UINT x; + /* Grabs the length of the error message */ + errLength = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + errorCode, + LANG_USER_DEFAULT, + (LPTSTR) &lpMsgBuf, + 0, + NULL) + 1; - /* Find the string we're looking for */ - uID &= 0xF; /* position in the block, same as % 16 */ - for (x = 0; x < uID; x++) - { - lpStr += (*lpStr) + 1; - } + /* Gets the error message ready for output */ + resMsg = (LPTSTR)LocalAlloc(LPTR, errLength * sizeof(TCHAR)); + CharToOemBuff(lpMsgBuf, resMsg, errLength); - /* Found the string */ - return (int)(*lpStr); - } - return -1; + /* Prints out the error message to the user */ + _ftprintf(stderr, resMsg); + _ftprintf(stderr, _T("Error code: %d\n"), errorCode); + + LocalFree(lpMsgBuf); + LocalFree(resMsg); } -INT -AllocAndLoadString(OUT LPTSTR *lpTarget, - IN HINSTANCE hInst, - IN UINT uID) -{ - INT ln; - - ln = LengthOfStrResource(hInst, - uID); - if (ln++ > 0) - { - (*lpTarget) = (LPTSTR)LocalAlloc(LMEM_FIXED, - ln * sizeof(TCHAR)); - if ((*lpTarget) != NULL) - { - INT Ret; - if (!(Ret = LoadString(hInst, uID, *lpTarget, ln))) - { - LocalFree((HLOCAL)(*lpTarget)); - } - return Ret; - } - } - return 0; -} Index: base/applications/shutdown/precomp.h =================================================================== --- base/applications/shutdown/precomp.h (revision 57260) +++ base/applications/shutdown/precomp.h (working copy) @@ -3,14 +3,29 @@ #include #include +#include #include #include -#include //shutdown codes +#include #include "resource.h" -// misc.c -INT AllocAndLoadString(OUT LPTSTR *lpTarget, - IN HINSTANCE hInst, - IN UINT uID); +#define MAX_MESSAGE_SIZE 512 +#define MAX_MAJOR_CODE 256 +#define MAX_MINOR_CODE 65536 +#define MAX_TIMEOUT 315360000 +#define MAX_BUFFER_SIZE 5024 +/* misc.c */ +BOOL CheckCommentLength(LPSTR); +DWORD ParseReasonCode(LPTSTR); +void DisplayLastError(void); + +/* Reason Code List */ +typedef struct _REASON { + LPTSTR prefix; + int major; + int minor; + DWORD code; +} REASON, *PREASON; + #endif Index: base/applications/shutdown/resource.h =================================================================== --- base/applications/shutdown/resource.h (revision 57260) +++ base/applications/shutdown/resource.h (working copy) @@ -1 +1,11 @@ -#define IDS_USAGE 1000 +#define IDS_USAGE 1 +#define IDS_ERROR_SHUTDOWN_REBOOT 2 +#define IDS_ERROR_TIMEOUT 3 +#define IDS_ERROR_ABORT 4 +#define IDS_ERROR_LOGOFF 5 +#define IDS_ERROR_RESTART 6 +#define IDS_ERROR_SHUTDOWN 7 +#define IDS_ERROR_MAX_COMMENT_LENGTH 8 +#define IDS_ERROR_HIBERNATE 9 +#define IDS_ERROR_HIBERNATE_LOCAL 10 +#define IDS_ERROR_HIBERNATE_ENABLED 11 \ No newline at end of file Index: base/applications/shutdown/shutdown.c =================================================================== --- base/applications/shutdown/shutdown.c (revision 57260) +++ base/applications/shutdown/shutdown.c (working copy) @@ -7,86 +7,127 @@ #include "precomp.h" -// Print information about which commandline arguments the program accepts. -static void PrintUsage() { - LPTSTR lpUsage = NULL; - DWORD errLength; // error message length - LPTSTR resMsg; // for error message in OEM symbols +/* This takes strings from a resource stringtable and outputs it to +the command prompt. */ +VOID PrintResourceString(INT resID, ...) +{ + TCHAR tmpBuffer[MAX_BUFFER_SIZE]; + va_list arg_ptr; - if( AllocAndLoadString( &lpUsage, - GetModuleHandle(NULL), - IDS_USAGE ) ) - { - errLength = strlen(lpUsage) + 1; - resMsg = (LPTSTR)LocalAlloc(LPTR, errLength * sizeof(TCHAR)); - CharToOemBuff(lpUsage, resMsg, errLength); - - _putts( resMsg ); - - LocalFree(lpUsage); - LocalFree(resMsg); - } + va_start(arg_ptr, resID); + LoadString(GetModuleHandle(NULL), resID, tmpBuffer, MAX_BUFFER_SIZE); + _vtprintf(tmpBuffer, arg_ptr); + va_end(arg_ptr); } +/* Used to determine how to shutdown the system. */ struct CommandLineOptions { - BOOL abort; // Not used yet + BOOL abort; BOOL force; BOOL logoff; BOOL restart; BOOL shutdown; -}; - -struct ExitOptions { - // This flag is used to distinguish between a user-initiated LOGOFF (which has value 0) - // and an underdetermined situation because user didn't give an argument to start Exit. - BOOL shouldExit; - // flags is the type of shutdown to do - EWX_LOGOFF, EWX_REBOOT, EWX_POWEROFF, etc.. - UINT flags; - // reason is the System Shutdown Reason code. F.instance SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED. + BOOL document_reason; + BOOL hibernate; + DWORD shutdown_delay; + LPTSTR remote_system; + LPTSTR message; DWORD reason; + BOOL show_gui; }; -// Takes the commandline arguments, and creates a struct which matches the arguments supplied. +/* Takes the commandline arguments, and creates a struct which matches the arguments supplied. */ static struct CommandLineOptions ParseArguments(int argc, TCHAR *argv[]) { struct CommandLineOptions opts; - int i; + int index; - // Reset all flags in struct + /* Reset all flags in struct */ opts.abort = FALSE; opts.force = FALSE; opts.logoff = FALSE; opts.restart = FALSE; opts.shutdown = FALSE; + opts.document_reason = FALSE; + opts.hibernate = FALSE; + opts.shutdown_delay = 30; + opts.remote_system = NULL; + opts.reason = ParseReasonCode(NULL); /* NOTE: NEVER use 0 here since it can delay the shutdown. */ + opts.message = NULL; + opts.show_gui = FALSE; - for (i = 1; i < argc; i++) + for (index = 1; index < argc; index++) { - if (argv[i][0] == '-' || argv[i][0] == '/') + if (argv[index][0] == '-' || argv[index][0] == '/') { - switch(argv[i][1]) { - case '?': - PrintUsage(); - exit(0); - case 'f': - case 'F': + switch(_totlower(argv[index][1])) { + case '?': /* Help */ + PrintResourceString(IDS_USAGE); + exit(EXIT_SUCCESS); + break; + case 'a': /* Cancel delayed shutdown */ + opts.abort = TRUE; + break; + case 'c': /* Comment on reason for shutdown */ + if(CheckCommentLength(argv[index+1])) + { + if(index+1 <= argc) + opts.message = argv[index+1]; + else + exit(EXIT_FAILURE); + index++; + } + else + { + PrintResourceString(IDS_ERROR_MAX_COMMENT_LENGTH); + exit(EXIT_FAILURE); + } + break; + case 'd': /* Reason code [p|u:]xx:yy */ + if(index+1 <= argc) + opts.reason = ParseReasonCode(argv[index+1]); + else + exit(EXIT_FAILURE); + index++; + break; + case 'e': /* Documents reason for shutdown */ + /* TODO: Determine what this flag does exactly. */ + opts.document_reason = TRUE; + break; + case 'f': /* Force shutdown without warning */ opts.force = TRUE; break; - case 'l': - case 'L': + case 'h': /* Hibernate the local computer */ + opts.hibernate = TRUE; + break; + case 'i': /* Shows GUI version of the tool */ + opts.show_gui = TRUE; + break; + case 'l': /* Logoff the current user */ opts.logoff = TRUE; break; - case 'r': - case 'R': + case 'm': /* Target remote systems (UNC name/IP address) */ + opts.remote_system = argv[index+1]; + break; + case 'p': /* Turn off local computer with no warning/time-out */ + opts.force = TRUE; + opts.shutdown_delay = 0; + break; + case 'r': /* Restart computer */ opts.restart = TRUE; break; - case 's': - case 'S': + case 's': /* Shutdown */ opts.shutdown = TRUE; break; + case 't': /* Shutdown delay */ + opts.shutdown_delay = _tstoi(argv[index+1]); + if(opts.shutdown_delay > 0) + opts.force = TRUE; + break; default: - // Unknown arguments will exit program. - PrintUsage(); - exit(0); + /* Unknown arguments will exit the program. */ + PrintResourceString(IDS_USAGE); + exit(EXIT_SUCCESS); break; } } @@ -95,93 +136,31 @@ return opts; } -// Converts the commandline arguments to flags used to shutdown computer -static struct ExitOptions ParseCommandLineOptionsToExitOptions(struct CommandLineOptions opts) +void EnablePrivileges(LPCTSTR flag) { - struct ExitOptions exitOpts; - exitOpts.shouldExit = TRUE; - - // Sets ONE of the exit type flags - if (opts.logoff) - exitOpts.flags = EWX_LOGOFF; - else if (opts.restart) - exitOpts.flags = EWX_REBOOT; - else if(opts.shutdown) - exitOpts.flags = EWX_POWEROFF; - else - { - exitOpts.flags = 0; - exitOpts.shouldExit = FALSE; - } - - // Sets additional flags - if (opts.force) - { - exitOpts.flags = exitOpts.flags | EWX_FORCE; - - // This makes sure that we log off, also if there is only the "-f" option specified. - // The Windows shutdown utility does it the same way. - exitOpts.shouldExit = TRUE; - } - - // Reason for shutdown - // Hardcoded to "Other (Planned)" - exitOpts.reason = SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED; - - return exitOpts; -} - -// Writes the last error as both text and error code to the console. -void DisplayLastError() -{ - int errorCode = GetLastError(); - LPTSTR lpMsgBuf = NULL; - DWORD errLength; // error message length - LPTSTR resMsg; // for error message in OEM symbols - - // Display the error message to the user - errLength = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - errorCode, - LANG_USER_DEFAULT, - (LPTSTR) &lpMsgBuf, - 0, - NULL) + 1; - - resMsg = (LPTSTR)LocalAlloc(LPTR, errLength * sizeof(TCHAR)); - CharToOemBuff(lpMsgBuf, resMsg, errLength); - - _ftprintf(stderr, resMsg); - _ftprintf(stderr, _T("Error code: %d\n"), errorCode); - - LocalFree(lpMsgBuf); - LocalFree(resMsg); -} - -void EnableShutdownPrivileges() -{ HANDLE token; TOKEN_PRIVILEGES privs; - // Check to see if the choosen action is allowed by the user. Everyone can call LogOff, but only privilieged users can shutdown/restart etc. + /* Check to see if the choosen action is allowed by the user. Everyone can + call LogOff, but only privilieged users can shutdown/restart etc. */ if (! OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) { DisplayLastError(); - exit(1); + exit(EXIT_FAILURE); } - // Get LUID (Locally Unique Identifier) for the privilege we need + /* Grabs the LUID (Locally Unique Identifier) for the privilege we need. */ if (!LookupPrivilegeValue( - NULL, // system - NULL is localsystem - SE_SHUTDOWN_NAME, // name of the privilege - &privs.Privileges[0].Luid) // output + NULL, /* system - NULL is localsystem */ + flag, /* name of the privilege */ + &privs.Privileges[0].Luid) /* output */ ) { DisplayLastError(); - exit(1); + exit(EXIT_FAILURE); } - // and give our current process (i.e. shutdown.exe) the privilege to shutdown the machine. + /* Gives the current process (i.e. shutdown.exe) the privilege to shutdown + the machine if the current user has permission to. */ privs.PrivilegeCount = 1; privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges( @@ -189,42 +168,157 @@ FALSE, &privs, 0, - (PTOKEN_PRIVILEGES)NULL, // previous state. Set to NULL, we don't care about previous state. + (PTOKEN_PRIVILEGES)NULL, /* The previous state. Set to NULL, we don't + care about previous state. */ NULL - ) == 0) // return value 0 means failure + ) == 0) /* return value 0 means failure */ { DisplayLastError(); - exit(1); + exit(EXIT_FAILURE); } } - // Main entry for program + /* Main entry for program */ int _tmain(int argc, TCHAR *argv[]) { struct CommandLineOptions opts; - struct ExitOptions exitOpts; - if (argc == 1) // i.e. no commandline arguments given + if (argc == 1) /* i.e. no commandline arguments given */ { - PrintUsage(); - exit(0); + PrintResourceString(IDS_USAGE); + return EXIT_SUCCESS; } opts = ParseArguments(argc, argv); - exitOpts = ParseCommandLineOptionsToExitOptions(opts); + + /* 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) + EnablePrivileges(SE_SHUTDOWN_NAME); + else + EnablePrivileges(SE_REMOTE_SHUTDOWN_NAME); + + /* Abort the delayed system shutdown specified. */ + if(AbortSystemShutdown(opts.remote_system) == 0) + { + PrintResourceString(IDS_ERROR_ABORT); + DisplayLastError(); + 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() == TRUE) + { + EnablePrivileges(SE_SHUTDOWN_NAME); + + if(opts.remote_system != NULL) + { + return EXIT_FAILURE; + } + + if(SetSuspendState(TRUE, FALSE, FALSE) == 0) + { + PrintResourceString(IDS_ERROR_HIBERNATE); + DisplayLastError(); + 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) + { + //opts = GraphicMain(opts); + exit(EXIT_SUCCESS); + } + + /* 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.logoff) + { + if((!opts.shutdown)&&(!opts.restart)) + { + EnablePrivileges(SE_SHUTDOWN_NAME); - // Perform the shutdown/restart etc. action - if (exitOpts.shouldExit) + if(ExitWindowsEx(EWX_LOGOFF, opts.reason)) + exit(EXIT_SUCCESS); + else + { + PrintResourceString(IDS_ERROR_LOGOFF); + DisplayLastError(); + exit(EXIT_FAILURE); + } + } + } + + /* Since both shutting down the system and restarting calls the exact + same funciton, all we need to know is if we wanted to restart or shutdown. */ + if((opts.shutdown)||(opts.restart)) { - EnableShutdownPrivileges(); - - if (!ExitWindowsEx(exitOpts.flags, exitOpts.reason)) + /* 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) + EnablePrivileges(SE_SHUTDOWN_NAME); + else + EnablePrivileges(SE_REMOTE_SHUTDOWN_NAME); + + if(!InitiateSystemShutdownEx(opts.remote_system, + (LPTSTR)opts.message, + opts.shutdown_delay, + opts.force, + opts.restart, + opts.reason)) { + /* If there is an error, give the proper output depending on if + the user wanted to shutdown or restart. */ + if(opts.restart) + PrintResourceString(IDS_ERROR_RESTART); + else + PrintResourceString(IDS_ERROR_SHUTDOWN); + DisplayLastError(); - exit(1); + exit(EXIT_FAILURE); } + else + exit(EXIT_SUCCESS); } + return 0; } -// EOF +/* EOF */ Index: base/applications/shutdown/shutdown.rc =================================================================== --- base/applications/shutdown/shutdown.rc (revision 57260) +++ base/applications/shutdown/shutdown.rc (working copy) @@ -1,6 +1,3 @@ -#include -#include "resource.h" - #define REACTOS_STR_FILE_DESCRIPTION "ReactOS Shutdown Utility\0" #define REACTOS_STR_INTERNAL_NAME "shutdown\0" #define REACTOS_STR_ORIGINAL_FILENAME "shutdown.exe\0"