From 273e913a60e2bbdc322ca8690399792d7fc9811f Mon Sep 17 00:00:00 2001 From: Martin Prikryl Date: Thu, 29 Nov 2018 14:05:09 +0000 Subject: [PATCH] Bug 1709: Crash on start while loading local file icons https://winscp.net/tracker/1709 Source commit: 04612ed24571064b593ca3a05b3223429482580e --- source/forms/ScpCommander.cpp | 2 ++ source/packages/filemng/DirView.pas | 31 +++++++++++++++++++++-------- source/windows/WinConfiguration.cpp | 7 +++++++ source/windows/WinConfiguration.h | 3 +++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/source/forms/ScpCommander.cpp b/source/forms/ScpCommander.cpp index a0e5a4be9..b8b7be05f 100644 --- a/source/forms/ScpCommander.cpp +++ b/source/forms/ScpCommander.cpp @@ -575,6 +575,8 @@ void __fastcall TScpCommanderForm::ConfigurationChanged() LocalDirView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting; LocalDriveView->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting; + LocalDirView->TimeoutShellIconRetrieval = WinConfiguration->TimeoutShellIconRetrieval; + if (LocalDirView->RowSelect != WinConfiguration->FullRowSelect) { LocalDirView->RowSelect = WinConfiguration->FullRowSelect; diff --git a/source/packages/filemng/DirView.pas b/source/packages/filemng/DirView.pas index 56977e42e..877580f05 100644 --- a/source/packages/filemng/DirView.pas +++ b/source/packages/filemng/DirView.pas @@ -41,7 +41,7 @@ interface Windows, ShlObj, ComCtrls, CompThread, CustomDirView, ListExt, ExtCtrls, Graphics, FileOperator, DiscMon, Classes, DirViewColProperties, DragDrop, Messages, ListViewColProperties, CommCtrl, DragDropFilesEx, - FileCtrl, SysUtils, BaseUtils, Controls, CustomDriveView, System.Generics.Collections; + FileCtrl, SysUtils, BaseUtils, Controls, CustomDriveView, System.Generics.Collections, Winapi.ShellAPI; {$I ResStrings.pas } @@ -166,6 +166,7 @@ TDirView = class(TCustomDirView) PIDLRecycle: PItemIDList; FLastPath: TDictionary; + FTimeoutShellIconRetrieval: Boolean; {Drag&Drop:} function GetDirColProperties: TDirViewColProperties; @@ -236,6 +237,8 @@ TDirView = class(TCustomDirView) procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY; procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND; procedure Load(DoFocusSomething: Boolean); override; + function GetFileInfo(pszPath: LPCWSTR; dwFileAttributes: DWORD; var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD_PTR; + function HiddenCount: Integer; override; function FilteredCount: Integer; override; @@ -310,6 +313,7 @@ TDirView = class(TCustomDirView) procedure ReloadDirectory; override; procedure ExecuteDrive(Drive: string); property HomeDirectory: string read GetHomeDirectory write FHomeDirectory; + property TimeoutShellIconRetrieval: Boolean read FTimeoutShellIconRetrieval write FTimeoutShellIconRetrieval; published property DirColProperties: TDirViewColProperties read GetDirColProperties write SetDirColProperties; @@ -411,7 +415,7 @@ implementation uses DriveView, OperationWithTimeout, PIDL, Forms, Dialogs, - ShellAPI, ComObj, + ComObj, ActiveX, ImgList, ShellDialogs, IEDriveInfo, FileChanges, Math, PasTools, StrUtils, Types, UITypes; @@ -1749,6 +1753,19 @@ function TDirView.GetAttrString(Attr: Integer): string; end; end; {GetAttrString} +function TDirView.GetFileInfo( + pszPath: LPCWSTR; dwFileAttributes: DWORD; var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD_PTR; +begin + if TimeoutShellIconRetrieval then + begin + Result := SHGetFileInfoWithTimeout(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags,MSecsPerSec div 4); + end + else + begin + Result := SHGetFileInfo(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags); + end; +end; + procedure TDirView.GetDisplayData(Item: TListItem; FetchIcon: Boolean); var FileInfo: TShFileInfo; @@ -1867,10 +1884,9 @@ procedure TDirView.GetDisplayData(Item: TListItem; FetchIcon: Boolean); begin // Files with PIDL are typically .exe files. // It may take long to retrieve an icon from exe file. - if SHGetFileInfoWithTimeout( + if GetFileInfo( PChar(PIDL), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), - SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_PIDL, - MSecsPerSec div 4) = 0 then + SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_PIDL) = 0 then begin FileInfo.szTypeName[0] := #0; FileInfo.iIcon := DefaultExeIcon; @@ -1878,9 +1894,8 @@ procedure TDirView.GetDisplayData(Item: TListItem; FetchIcon: Boolean); end else begin - SHGetFileInfoWithTimeout(PChar(FileIconForName), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), - SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX, - MSecsPerSec div 4); + GetFileInfo(PChar(FileIconForName), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), + SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX); end; TypeName := FileInfo.szTypeName; diff --git a/source/windows/WinConfiguration.cpp b/source/windows/WinConfiguration.cpp index 9c1091279..3e190f9a6 100644 --- a/source/windows/WinConfiguration.cpp +++ b/source/windows/WinConfiguration.cpp @@ -619,6 +619,7 @@ void __fastcall TWinConfiguration::Default() HonorDrivePolicy = true; TimeoutShellOperations = true; + TimeoutShellIconRetrieval = false; FEditor.Font.FontName = DefaultFixedWidthFontName; FEditor.Font.FontSize = DefaultFixedWidthFontSize; @@ -1016,6 +1017,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool & SessionList) KEYEX(String, FExtensionsOrder, L"ExtensionsOrder"); \ KEYEX(String, FExtensionsShortCuts, L"ExtensionsShortCuts"); \ KEY(Bool, TimeoutShellOperations); \ + KEY(Bool, TimeoutShellIconRetrieval); \ ); \ BLOCK(L"Interface\\Editor", CANCREATE, \ KEYEX(String, Editor.Font.FontName, L"FontName2"); \ @@ -2605,6 +2607,11 @@ void __fastcall TWinConfiguration::SetTimeoutShellOperations(bool value) ::TimeoutShellOperations = value; } //--------------------------------------------------------------------------- +void __fastcall TWinConfiguration::SetTimeoutShellIconRetrieval(bool value) +{ + SET_CONFIG_PROPERTY(TimeoutShellIconRetrieval); +} +//--------------------------------------------------------------------------- TStringList * __fastcall TWinConfiguration::LoadJumpList( THierarchicalStorage * Storage, UnicodeString Name) { diff --git a/source/windows/WinConfiguration.h b/source/windows/WinConfiguration.h index 8c5a84d83..25d4c00bd 100644 --- a/source/windows/WinConfiguration.h +++ b/source/windows/WinConfiguration.h @@ -448,6 +448,7 @@ class TWinConfiguration : public TCustomWinConfiguration UnicodeString FFileColors; int FRunsSinceLastTip; bool FLockedInterface; + bool FTimeoutShellIconRetrieval; int FDontDecryptPasswords; int FMasterPasswordSession; bool FMasterPasswordSessionAsked; @@ -552,6 +553,7 @@ class TWinConfiguration : public TCustomWinConfiguration void __fastcall SetLockedInterface(bool value); bool __fastcall GetTimeoutShellOperations(); void __fastcall SetTimeoutShellOperations(bool value); + void __fastcall SetTimeoutShellIconRetrieval(bool value); int __fastcall GetLocaleCompletenessTreshold(); bool __fastcall GetDDExtInstalled(); @@ -731,6 +733,7 @@ class TWinConfiguration : public TCustomWinConfiguration __property TStrings * CustomCommandOptions = { read = GetCustomCommandOptions, write = SetCustomCommandOptions }; __property bool LockedInterface = { read = FLockedInterface, write = SetLockedInterface }; __property bool TimeoutShellOperations = { read = GetTimeoutShellOperations, write = SetTimeoutShellOperations }; + __property bool TimeoutShellIconRetrieval = { read = FTimeoutShellIconRetrieval, write = SetTimeoutShellIconRetrieval }; __property LCID DefaultLocale = { read = FDefaultLocale }; __property int LocaleCompletenessTreshold = { read = GetLocaleCompletenessTreshold }; };