Left base folder: S:\winscp553source_orig Right base folder: S:\winscp553source --- source\core\Exceptions.h 2014-04-14 11:46:18.000000000 +0200 +++ source\core\Exceptions.h 2014-04-25 20:19:44.000000000 +0200 @@ -10,13 +10,13 @@ bool __fastcall ShouldDisplayException(Exception * E); bool __fastcall ExceptionMessage(Exception * E, UnicodeString & Message); bool __fastcall ExceptionMessageFormatted(Exception * E, UnicodeString & Message); UnicodeString __fastcall LastSysErrorMessage(); TStrings * __fastcall ExceptionToMoreMessages(Exception * E); //--------------------------------------------------------------------------- -enum TOnceDoneOperation { odoIdle, odoDisconnect, odoShutDown }; +enum TOnceDoneOperation { odoIdle, odoDisconnect, odoShutDown, odoHibernate }; //--------------------------------------------------------------------------- class ExtException : public Sysutils::Exception { public: __fastcall ExtException(Exception* E); __fastcall ExtException(Exception* E, UnicodeString Msg, UnicodeString HelpKeyword = L""); --- source\forms\CustomScpExplorer.dfm 2014-04-14 11:26:44.000000000 +0200 +++ source\forms\CustomScpExplorer.dfm 2014-04-25 20:13:02.000000000 +0200 @@ -278,12 +278,16 @@ RadioItem = True end object TBXItem225: TTBXItem Action = NonVisualDataModule.QueueDisconnectOnceEmptyAction RadioItem = True end + object TBXItem227: TTBXItem + Action = NonVisualDataModule.QueueHibernateOnceEmptyAction + RadioItem = True + end object TBXItem226: TTBXItem Action = NonVisualDataModule.QueueShutDownOnceEmptyAction RadioItem = True end end object TBXItem208: TTBXItem --- source\forms\CustomScpExplorer.h 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\CustomScpExplorer.h 2014-04-25 20:13:00.000000000 +0200 @@ -82,12 +82,13 @@ TTBXItem *TBXItem194; TTBXItem *TBXItem195; TTBXSubmenuItem *TBXSubmenuItem27; TTBXItem *TBXItem211; TTBXItem *TBXItem225; TTBXItem *TBXItem226; + TTBXItem *TBXItem227; TTabSheet *TabSheet1; TThemePageControl *SessionsPageControl; TPathLabel *QueueLabel; TTBXSeparatorItem *TBXSeparatorItem57; TTBXItem *QueueDeleteAllDoneQueueToolbarItem; void __fastcall RemoteDirViewContextPopup(TObject *Sender, --- source\forms\NonVisual.cpp 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\NonVisual.cpp 2014-04-25 20:11:38.000000000 +0200 @@ -469,12 +469,13 @@ #undef QUEUEACTION UPDEX1(QueueCycleOnceEmptyAction, ScpExplorer->AllowQueueOperation(qoOnceEmpty), QueueCycleOnceEmptyAction->ImageIndex = CurrentQueueOnceEmptyAction()->ImageIndex; QueueCycleOnceEmptyAction->Checked = !QueueIdleOnceEmptyAction->Checked) UPD(QueueIdleOnceEmptyAction, ScpExplorer->AllowQueueOperation(qoOnceEmpty)) UPD(QueueDisconnectOnceEmptyAction, ScpExplorer->AllowQueueOperation(qoOnceEmpty)) + UPD(QueueHibernateOnceEmptyAction, ScpExplorer->AllowQueueOperation(qoOnceEmpty)) UPD(QueueShutDownOnceEmptyAction, ScpExplorer->AllowQueueOperation(qoOnceEmpty)) UPDCOMP(CommanderPreferencesBand) UPDACT(QueueToolbarAction, ((TAction *)Action)->Enabled = ScpExplorer->ComponentVisible[fcQueueView]; ((TAction *)Action)->Checked = ScpExplorer->ComponentVisible[fcQueueToolbar]) ; @@ -773,12 +774,13 @@ QUEUEACTION(HideWhenEmpty) QUEUEACTION(Hide) #undef QUEUEACTION EXE(QueueCycleOnceEmptyAction, CycleQueueOnceEmptyAction()); EXE(QueueIdleOnceEmptyAction, SetQueueOnceEmptyAction(QueueIdleOnceEmptyAction)) EXE(QueueDisconnectOnceEmptyAction, SetQueueOnceEmptyAction(QueueDisconnectOnceEmptyAction)) + EXE(QueueHibernateOnceEmptyAction, SetQueueOnceEmptyAction(QueueHibernateOnceEmptyAction)) EXE(QueueShutDownOnceEmptyAction, SetQueueOnceEmptyAction(QueueShutDownOnceEmptyAction)) EXECOMP(QueueToolbar); EXE(QueueItemSpeedAction, ) ; } @@ -1588,12 +1590,16 @@ QueueDisconnectOnceEmptyAction->Checked = true; } else if (Current == QueueDisconnectOnceEmptyAction) { QueueShutDownOnceEmptyAction->Checked = true; } + else if (Current == QueueHibernateOnceEmptyAction) + { + QueueHibernateOnceEmptyAction->Checked = true; + } else if (Current == QueueShutDownOnceEmptyAction) { QueueIdleOnceEmptyAction->Checked = true; } else { @@ -1608,12 +1614,16 @@ { Result = QueueIdleOnceEmptyAction; } else if (QueueDisconnectOnceEmptyAction->Checked) { Result = QueueDisconnectOnceEmptyAction; + } + else if (QueueHibernateOnceEmptyAction->Checked) + { + Result = QueueHibernateOnceEmptyAction; } else if (QueueShutDownOnceEmptyAction->Checked) { Result = QueueShutDownOnceEmptyAction; } else @@ -1631,12 +1641,16 @@ { Result = odoIdle; } else if (Current == QueueDisconnectOnceEmptyAction) { Result = odoDisconnect; + } + else if (Current == QueueHibernateOnceEmptyAction) + { + Result = odoHibernate; } else if (Current == QueueShutDownOnceEmptyAction) { Result = odoShutDown; } else --- source\forms\NonVisual.dfm 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\NonVisual.dfm 2014-04-25 20:16:50.000000000 +0200 @@ -1859,12 +1859,20 @@ Category = 'Queue' Caption = '&Shut Down' HelpKeyword = 'ui_queue' Hint = 'Shut down the computer once the queue is empty' ImageIndex = 93 end + object QueueHibernateOnceEmptyAction: TAction + Tag = 12 + Category = 'Queue' + Caption = '&Hibernate' + HelpKeyword = 'ui_queue' + Hint = 'Hibernate the computer once the queue is empty' + ImageIndex = 93 + end object QueueIdleOnceEmptyAction: TAction Tag = 12 Category = 'Queue' Caption = '&Stay Idle' Checked = True HelpKeyword = 'ui_queue' --- source\forms\NonVisual.h 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\NonVisual.h 2014-04-25 20:16:24.000000000 +0200 @@ -487,12 +487,13 @@ TAction *CurrentDeleteAlternativeAction; TAction *CurrentEditWithAction; TAction *LocalFilterAction; TAction *RemoteFilterAction; TTBXItem *TBXItem26; TTBXItem *TBXItem27; + TAction *QueueHibernateOnceEmptyAction; TAction *QueueShutDownOnceEmptyAction; TAction *QueueIdleOnceEmptyAction; TTBXSubmenuItem *TBXSubmenuItem3; TTBXItem *TBXItem28; TTBXItem *TBXItem29; TAction *QueueCycleOnceEmptyAction; --- source\forms\Progress.cpp 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\Progress.cpp 2014-04-25 20:19:24.000000000 +0200 @@ -487,12 +487,16 @@ break; case odoShutDown: Index = 2; break; + case odoHibernate: + Index = 3; + break; + default: assert(false); } OnceDoneOperationCombo->ItemIndex = Index; OnceDoneOperationComboSelect(NULL); } @@ -579,17 +583,21 @@ break; case 2: FOnceDoneOperation = odoShutDown; break; + case 3: + FOnceDoneOperation = odoHibernate; + break; + default: assert(false); } } //--------------------------------------------------------------------------- void __fastcall TProgressForm::OnceDoneOperationComboCloseUp(TObject * /*Sender*/) { CancelButton->SetFocus(); } //--------------------------------------------------------------------------- #pragma warn -8080 --- source\forms\Progress.dfm 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\Progress.dfm 2014-04-25 20:21:48.000000000 +0200 @@ -270,15 +270,16 @@ TabOrder = 5 OnCloseUp = OnceDoneOperationComboCloseUp OnSelect = OnceDoneOperationComboSelect Items.Strings = ( 'Stay idle' 'Disconnect' + 'Hibernate' 'Shut down') end object UpdateTimer: TTimer Enabled = False OnTimer = UpdateTimerTimer Left = 336 Top = 168 end end --- source\forms\ScpCommander.dfm 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\ScpCommander.dfm 2014-04-25 20:14:38.000000000 +0200 @@ -544,12 +544,16 @@ RadioItem = True end object TBXItem223: TTBXItem Action = NonVisualDataModule.QueueDisconnectOnceEmptyAction RadioItem = True end + object TBXItem250: TTBXItem + Action = NonVisualDataModule.QueueHibernateOnceEmptyAction + RadioItem = True + end object TBXItem224: TTBXItem Action = NonVisualDataModule.QueueShutDownOnceEmptyAction RadioItem = True end end object TBXItem81: TTBXItem --- source\forms\ScpCommander.h 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\ScpCommander.h 2014-04-25 20:14:28.000000000 +0200 @@ -347,12 +347,13 @@ TTBXItem *TBXItem220; TTBXItem *TBXItem221; TTBXSubmenuItem *TBXSubmenuItem8; TTBXItem *TBXItem222; TTBXItem *TBXItem223; TTBXItem *TBXItem224; + TTBXItem *TBXItem250; TTBXItem *TBXItem210; TTBXItem *TBXItem228; TTBXItem *TBXItem229; TTBXSeparatorItem *TBXSeparatorItem53; TTBXItem *TBXItem230; TTBXSubmenuItem *TBXSubmenuItem231; --- source\forms\ScpExplorer.dfm 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\ScpExplorer.dfm 2014-04-25 20:15:28.000000000 +0200 @@ -362,12 +362,16 @@ RadioItem = True end object TBXItem223: TTBXItem Action = NonVisualDataModule.QueueDisconnectOnceEmptyAction RadioItem = True end + object TBXItem250: TTBXItem + Action = NonVisualDataModule.QueueHibernateOnceEmptyAction + RadioItem = True + end object TBXItem224: TTBXItem Action = NonVisualDataModule.QueueShutDownOnceEmptyAction RadioItem = True end end object TBXItem81: TTBXItem --- source\forms\ScpExplorer.h 2014-04-14 11:46:18.000000000 +0200 +++ source\forms\ScpExplorer.h 2014-04-25 20:15:40.000000000 +0200 @@ -277,12 +277,13 @@ TTBXComboBoxItem *QueueSpeedComboBoxItem; TTBXItem *TBXItem138; TTBXSubmenuItem *TBXSubmenuItem8; TTBXItem *TBXItem222; TTBXItem *TBXItem223; TTBXItem *TBXItem224; + TTBXItem *TBXItem250; TTBXItem *TBXItem3; TTBXItem *TBXItem139; TTBXSeparatorItem *TBXSeparatorItem53; TTBXItem *TBXItem230; TTBXSubmenuItem *TBXSubmenuItem231; TTBXSeparatorItem *TBXSeparatorItem24; --- source\windows\Tools.cpp 2014-04-14 11:46:18.000000000 +0200 +++ source\windows\Tools.cpp 2014-04-26 06:58:22.000000000 +0200 @@ -853,32 +853,50 @@ } } return (Result > 0); } //--------------------------------------------------------------------------- -void __fastcall ShutDownWindows() +void __fastcall ShutDownWindows(BOOL Hibernate) { HANDLE Token; TOKEN_PRIVILEGES Priv; // Get a token for this process. Win32Check(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token)); // Get the LUID for the shutdown privilege. + // http://stackoverflow.com/questions/959589/is-there-any-win32-api-to-trigger-the-hibernate-or-suspend-mode-in-windows + // --> You need the SE_SHUTDOWN_NAME privilege too! Win32Check(LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &Priv.Privileges[0].Luid)); Priv.PrivilegeCount = 1; // one privilege to set Priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get the shutdown privilege for this process. Win32Check(AdjustTokenPrivileges(Token, FALSE, &Priv, 0, (PTOKEN_PRIVILEGES)NULL, 0)); - // Shut down the system and force all applications to close. - Win32Check(ExitWindowsEx(EWX_SHUTDOWN | EWX_POWEROFF, - SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)); + if ( Hibernate ) { + /* +http://msdn.microsoft.com/en-us/library/windows/desktop/aa373201(v=vs.85).aspx + +Hibernate [in] + If this parameter is TRUE, the system hibernates. If the parameter is FALSE, the system is suspended. +ForceCritical [in] + This parameter has no effect. + Windows Server 2003 and Windows XP: If this parameter is TRUE, the system suspends operation immediately; if it is FALSE, the system broadcasts a PBT_APMQUERYSUSPEND event to each application to request permission to suspend operation. +DisableWakeEvent [in] + If this parameter is TRUE, the system disables all wake events. If the parameter is FALSE, any system wake events remain enabled. + */ + Win32Check(SetSuspendState(TRUE, FALSE, FALSE)); + } + else { + // Shut down the system and force all applications to close. + Win32Check(ExitWindowsEx(EWX_SHUTDOWN | EWX_POWEROFF, + SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)); + } } //--------------------------------------------------------------------------- void __fastcall EditSelectBaseName(HWND Edit) { UnicodeString Text; Text.SetLength(GetWindowTextLength(Edit) + 1); --- source\windows\Tools.h 2014-04-14 11:46:18.000000000 +0200 +++ source\windows\Tools.h 2014-04-26 06:55:50.000000000 +0200 @@ -49,13 +49,14 @@ bool __fastcall SaveDialog(UnicodeString Title, UnicodeString Filter, UnicodeString DefaultExt, UnicodeString & FileName); bool __fastcall AutodetectProxyUrl(UnicodeString & Proxy); bool __fastcall IsWin64(); void __fastcall CopyToClipboard(UnicodeString Text); void __fastcall CopyToClipboard(TStrings * Strings); -void __fastcall ShutDownWindows(); +void __fastcall ShutDownWindows(BOOL Hibernate = FALSE); +void __fastcall HibernateWindows() { ShutDownWindows(TRUE); } void __fastcall EditSelectBaseName(HWND Edit); void __fastcall VerifyKey(UnicodeString FileName); void __fastcall VerifyKeyIncludingVersion(UnicodeString FileName, TSshProt SshProt); TStrings * __fastcall GetUnwrappedMemoLines(TMemo * Memo); //--------------------------------------------------------------------------- #define IUNKNOWN \ --- source\windows\UserInterface.cpp 2014-04-14 11:46:18.000000000 +0200 +++ source\windows\UserInterface.cpp 2014-04-25 20:19:26.000000000 +0200 @@ -194,12 +194,16 @@ break; case odoShutDown: ShutDownWindows(); break; + case odoHibernate: + HibernateWindows(); + break; + default: assert(false); } } else if (Result == qaRetry) {