mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Bug 2083: Workaround for an apparent bug in Windows 11 that prevents WinSCP from stopping Windows going to the sleep mode during transfers
https://winscp.net/tracker/2083
(cherry picked from commit 4b38960069)
# Conflicts:
# source/windows/GUITools.cpp
Source commit: fcc260c91f8d3671c66cef13a8843514c39e9773
This commit is contained in:
@@ -13,6 +13,7 @@ USEFORM("forms\ScpExplorer.cpp", ScpExplorerForm);
|
||||
#include <VCLCommon.h>
|
||||
#include <Setup.h>
|
||||
#include <PuttyTools.h>
|
||||
#include <GUITools.h>
|
||||
//---------------------------------------------------------------------------
|
||||
WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
||||
{
|
||||
@@ -53,6 +54,7 @@ WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
||||
}
|
||||
__finally
|
||||
{
|
||||
GUIFinalize();
|
||||
FinalizeSystemSettings();
|
||||
FinalizeWinHelp();
|
||||
CoreFinalize();
|
||||
|
||||
@@ -3021,6 +3021,11 @@ bool __fastcall IsWin10Build(unsigned int BuildNumber)
|
||||
(OSVersionInfo.dwBuildNumber >= BuildNumber));
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool IsWin11()
|
||||
{
|
||||
return IsWin10Build(22000);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall IsWine()
|
||||
{
|
||||
HMODULE NtDll = GetModuleHandle(L"ntdll.dll");
|
||||
|
||||
@@ -141,6 +141,7 @@ bool __fastcall IsWin7();
|
||||
bool __fastcall IsWin8();
|
||||
bool __fastcall IsWin10();
|
||||
bool __fastcall IsWin10Build(unsigned int BuildNumber);
|
||||
bool IsWin11();
|
||||
bool __fastcall IsWine();
|
||||
bool __fastcall IsUWP();
|
||||
UnicodeString GetPackageName();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Common.h"
|
||||
#include "FileOperationProgress.h"
|
||||
#include "CoreMain.h"
|
||||
#include "Interface.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#define TRANSFER_BUF_SIZE 32768
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -310,7 +311,7 @@ void __fastcall TFileOperationProgressType::Progress()
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TFileOperationProgressType::DoProgress()
|
||||
{
|
||||
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
|
||||
SystemRequired();
|
||||
FOnProgress(*this);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -49,6 +49,7 @@ void __fastcall BusyEnd(void * Token);
|
||||
const unsigned int GUIUpdateInterval = 100;
|
||||
void __fastcall SetNoGUI();
|
||||
bool __fastcall ProcessGUI(bool Force = false);
|
||||
void SystemRequired();
|
||||
UnicodeString __fastcall AppNameString();
|
||||
UnicodeString __fastcall SshVersionString();
|
||||
void __fastcall CopyToClipboard(UnicodeString Text);
|
||||
|
||||
@@ -2144,3 +2144,90 @@ bool CanShowTimeEstimate(TDateTime StartTime)
|
||||
{
|
||||
return (SecondsBetween(StartTime, Now()) >= 3);
|
||||
}
|
||||
class TSystemRequiredThread : public TSignalThread
|
||||
{
|
||||
public:
|
||||
TSystemRequiredThread();
|
||||
void Required();
|
||||
protected:
|
||||
virtual bool __fastcall WaitForEvent();
|
||||
virtual void __fastcall ProcessEvent();
|
||||
private:
|
||||
bool FRequired;
|
||||
TDateTime FLastRequired;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
std::unique_ptr<TCriticalSection> SystemRequiredThreadSection(TraceInitPtr(new TCriticalSection()));
|
||||
TSystemRequiredThread * SystemRequiredThread = NULL;
|
||||
//---------------------------------------------------------------------------
|
||||
TSystemRequiredThread::TSystemRequiredThread() :
|
||||
TSignalThread(true), FRequired(false)
|
||||
{
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void TSystemRequiredThread::Required()
|
||||
{
|
||||
// guarded in SystemRequired()
|
||||
FLastRequired = Now();
|
||||
TriggerEvent();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TSystemRequiredThread::WaitForEvent()
|
||||
{
|
||||
const int ExpireInterval = 5000;
|
||||
bool Result = (TSignalThread::WaitForEvent(ExpireInterval) > 0);
|
||||
if (!Result && !FTerminated)
|
||||
{
|
||||
TGuard Guard(SystemRequiredThreadSection.get());
|
||||
if (!FTerminated && FRequired &&
|
||||
(MilliSecondsBetween(Now(), FLastRequired) > ExpireInterval))
|
||||
{
|
||||
SetThreadExecutionState(ES_CONTINUOUS);
|
||||
FLastRequired = TDateTime();
|
||||
FRequired = false;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSystemRequiredThread::ProcessEvent()
|
||||
{
|
||||
TGuard Guard(SystemRequiredThreadSection.get());
|
||||
if (!FRequired &&
|
||||
(FLastRequired != TDateTime()))
|
||||
{
|
||||
SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
|
||||
FRequired = true;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void SystemRequired()
|
||||
{
|
||||
if (IsWin11())
|
||||
{
|
||||
TGuard Guard(SystemRequiredThreadSection.get());
|
||||
if (SystemRequiredThread == NULL)
|
||||
{
|
||||
SystemRequiredThread = new TSystemRequiredThread();
|
||||
SystemRequiredThread->Start();
|
||||
}
|
||||
SystemRequiredThread->Required();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void GUIFinalize()
|
||||
{
|
||||
TSystemRequiredThread * Thread;
|
||||
{
|
||||
TGuard Guard(SystemRequiredThreadSection.get());
|
||||
Thread = SystemRequiredThread;
|
||||
SystemRequiredThread = NULL;
|
||||
}
|
||||
Thread->Terminate();
|
||||
Thread->WaitFor();
|
||||
delete Thread;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ class TSessionData;
|
||||
//---------------------------------------------------------------------------
|
||||
typedef void __fastcall (__closure* TProcessMessagesEvent)();
|
||||
//---------------------------------------------------------------------------
|
||||
void GUIFinalize();
|
||||
bool __fastcall FindFile(UnicodeString & Path);
|
||||
bool __fastcall FindTool(const UnicodeString & Name, UnicodeString & Path);
|
||||
void __fastcall ExecuteTool(const UnicodeString & Name);
|
||||
|
||||
Reference in New Issue
Block a user