1
0
Эх сурвалжийг харах

Bug 1709: Crash on start while loading local file icons

https://winscp.net/tracker/1709

Source commit: 04612ed24571064b593ca3a05b3223429482580e
Martin Prikryl 7 жил өмнө
parent
commit
273e913a60

+ 2 - 0
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;

+ 23 - 8
source/packages/filemng/DirView.pas

@@ -41,7 +41,7 @@ uses
   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 @@ type
     PIDLRecycle: PItemIDList;
 
     FLastPath: TDictionary<string, string>;
+    FTimeoutShellIconRetrieval: Boolean;
 
     {Drag&Drop:}
     function GetDirColProperties: TDirViewColProperties;
@@ -236,6 +237,8 @@ type
     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 @@ type
     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 @@ begin
   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 @@ begin
             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 @@ begin
             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;

+ 7 - 0
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)
 {

+ 3 - 0
source/windows/WinConfiguration.h

@@ -448,6 +448,7 @@ private:
   UnicodeString FFileColors;
   int FRunsSinceLastTip;
   bool FLockedInterface;
+  bool FTimeoutShellIconRetrieval;
   int FDontDecryptPasswords;
   int FMasterPasswordSession;
   bool FMasterPasswordSessionAsked;
@@ -552,6 +553,7 @@ private:
   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 @@ public:
   __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 };
 };