浏览代码

Bug 1709: Crash on start while loading local file icons

https://winscp.net/tracker/1709
(cherry picked from commit 273e913a60e2bbdc322ca8690399792d7fc9811f)

# Conflicts:
#	source/packages/filemng/DirView.pas
#	source/windows/WinConfiguration.cpp

Source commit: 87c1eaf9b7984f9791cbe273785ade0e5db1cd73
Martin Prikryl 7 年之前
父节点
当前提交
0ce5afd2e4

+ 2 - 0
source/forms/ScpCommander.cpp

@@ -569,6 +569,8 @@ void __fastcall TScpCommanderForm::ConfigurationChanged()
 
   LocalDirView->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;
+  FileCtrl, SysUtils, BaseUtils, Controls, CustomDriveView, Winapi.ShellAPI;
 
 {$I ResStrings.pas }
 
@@ -168,6 +168,7 @@ type
     PIDLRecycle: PItemIDList;
 
     FLastPath: array[TDriveLetter] of string;
+    FTimeoutShellIconRetrieval: Boolean;
 
     {Drag&Drop:}
     function GetDirColProperties: TDirViewColProperties;
@@ -238,6 +239,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;
 
@@ -313,6 +316,7 @@ type
     procedure ReloadDirectory; override;
     procedure ExecuteDrive(Drive: TDriveLetter);
     property HomeDirectory: string read GetHomeDirectory write FHomeDirectory;
+    property TimeoutShellIconRetrieval: Boolean read FTimeoutShellIconRetrieval write FTimeoutShellIconRetrieval;
 
   published
     property DirColProperties: TDirViewColProperties read GetDirColProperties write SetDirColProperties;
@@ -408,7 +412,7 @@ implementation
 uses
   DriveView, OperationWithTimeout,
   PIDL, Forms, Dialogs,
-  ShellAPI, ComObj,
+  ComObj,
   ActiveX, ImgList,
   ShellDialogs, IEDriveInfo,
   FileChanges, Math, PasTools, StrUtils, Types, UITypes;
@@ -1598,6 +1602,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;
@@ -1716,10 +1733,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;
@@ -1727,9 +1743,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

@@ -573,6 +573,7 @@ void __fastcall TWinConfiguration::Default()
   FLockedInterface = false;
 
   HonorDrivePolicy = true;
+  TimeoutShellIconRetrieval = false;
 
   FEditor.Font.FontName = DefaultFixedWidthFontName;
   FEditor.Font.FontSize = DefaultFixedWidthFontSize;
@@ -971,6 +972,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool & SessionList)
     KEYEX(String, FExtensionsDeleted, L"ExtensionsDeleted"); \
     KEYEX(String, FExtensionsOrder, L"ExtensionsOrder"); \
     KEY(Bool,  TimeoutShellOperations); \
+    KEY(Bool,     TimeoutShellIconRetrieval); \
   ); \
   BLOCK(L"Interface\\Editor", CANCREATE, \
     KEYEX(String,   Editor.Font.FontName, L"FontName2"); \
@@ -2545,6 +2547,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

@@ -432,6 +432,7 @@ private:
   TDateTime FTipsShown;
   int FRunsSinceLastTip;
   bool FLockedInterface;
+  bool FTimeoutShellIconRetrieval;
   int FDontDecryptPasswords;
   int FMasterPasswordSession;
   bool FMasterPasswordSessionAsked;
@@ -537,6 +538,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();
@@ -717,6 +719,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 };
 };