浏览代码

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->NaturalOrderNumericalSorting = WinConfiguration->NaturalOrderNumericalSorting;
 
 
+  LocalDirView->TimeoutShellIconRetrieval = WinConfiguration->TimeoutShellIconRetrieval;
+
   if (LocalDirView->RowSelect != WinConfiguration->FullRowSelect)
   if (LocalDirView->RowSelect != WinConfiguration->FullRowSelect)
   {
   {
     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,
   Windows, ShlObj, ComCtrls, CompThread, CustomDirView, ListExt,
   ExtCtrls, Graphics, FileOperator, DiscMon, Classes, DirViewColProperties,
   ExtCtrls, Graphics, FileOperator, DiscMon, Classes, DirViewColProperties,
   DragDrop, Messages, ListViewColProperties, CommCtrl, DragDropFilesEx,
   DragDrop, Messages, ListViewColProperties, CommCtrl, DragDropFilesEx,
-  FileCtrl, SysUtils, BaseUtils, Controls, CustomDriveView;
+  FileCtrl, SysUtils, BaseUtils, Controls, CustomDriveView, Winapi.ShellAPI;
 
 
 {$I ResStrings.pas }
 {$I ResStrings.pas }
 
 
@@ -168,6 +168,7 @@ type
     PIDLRecycle: PItemIDList;
     PIDLRecycle: PItemIDList;
 
 
     FLastPath: array[TDriveLetter] of string;
     FLastPath: array[TDriveLetter] of string;
+    FTimeoutShellIconRetrieval: Boolean;
 
 
     {Drag&Drop:}
     {Drag&Drop:}
     function GetDirColProperties: TDirViewColProperties;
     function GetDirColProperties: TDirViewColProperties;
@@ -238,6 +239,8 @@ type
     procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY;
     procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY;
     procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
     procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
     procedure Load(DoFocusSomething: Boolean); override;
     procedure Load(DoFocusSomething: Boolean); override;
+    function GetFileInfo(pszPath: LPCWSTR; dwFileAttributes: DWORD; var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD_PTR;
+
     function HiddenCount: Integer; override;
     function HiddenCount: Integer; override;
     function FilteredCount: Integer; override;
     function FilteredCount: Integer; override;
 
 
@@ -313,6 +316,7 @@ type
     procedure ReloadDirectory; override;
     procedure ReloadDirectory; override;
     procedure ExecuteDrive(Drive: TDriveLetter);
     procedure ExecuteDrive(Drive: TDriveLetter);
     property HomeDirectory: string read GetHomeDirectory write FHomeDirectory;
     property HomeDirectory: string read GetHomeDirectory write FHomeDirectory;
+    property TimeoutShellIconRetrieval: Boolean read FTimeoutShellIconRetrieval write FTimeoutShellIconRetrieval;
 
 
   published
   published
     property DirColProperties: TDirViewColProperties read GetDirColProperties write SetDirColProperties;
     property DirColProperties: TDirViewColProperties read GetDirColProperties write SetDirColProperties;
@@ -408,7 +412,7 @@ implementation
 uses
 uses
   DriveView, OperationWithTimeout,
   DriveView, OperationWithTimeout,
   PIDL, Forms, Dialogs,
   PIDL, Forms, Dialogs,
-  ShellAPI, ComObj,
+  ComObj,
   ActiveX, ImgList,
   ActiveX, ImgList,
   ShellDialogs, IEDriveInfo,
   ShellDialogs, IEDriveInfo,
   FileChanges, Math, PasTools, StrUtils, Types, UITypes;
   FileChanges, Math, PasTools, StrUtils, Types, UITypes;
@@ -1598,6 +1602,19 @@ begin
   end;
   end;
 end; {GetAttrString}
 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);
 procedure TDirView.GetDisplayData(Item: TListItem; FetchIcon: Boolean);
 var
 var
   FileInfo: TShFileInfo;
   FileInfo: TShFileInfo;
@@ -1716,10 +1733,9 @@ begin
             begin
             begin
               // Files with PIDL are typically .exe files.
               // Files with PIDL are typically .exe files.
               // It may take long to retrieve an icon from exe file.
               // It may take long to retrieve an icon from exe file.
-              if SHGetFileInfoWithTimeout(
+              if GetFileInfo(
                    PChar(PIDL), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo),
                    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
               begin
                 FileInfo.szTypeName[0] := #0;
                 FileInfo.szTypeName[0] := #0;
                 FileInfo.iIcon := DefaultExeIcon;
                 FileInfo.iIcon := DefaultExeIcon;
@@ -1727,9 +1743,8 @@ begin
             end
             end
               else
               else
             begin
             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;
             end;
 
 
             TypeName := FileInfo.szTypeName;
             TypeName := FileInfo.szTypeName;

+ 7 - 0
source/windows/WinConfiguration.cpp

@@ -573,6 +573,7 @@ void __fastcall TWinConfiguration::Default()
   FLockedInterface = false;
   FLockedInterface = false;
 
 
   HonorDrivePolicy = true;
   HonorDrivePolicy = true;
+  TimeoutShellIconRetrieval = false;
 
 
   FEditor.Font.FontName = DefaultFixedWidthFontName;
   FEditor.Font.FontName = DefaultFixedWidthFontName;
   FEditor.Font.FontSize = DefaultFixedWidthFontSize;
   FEditor.Font.FontSize = DefaultFixedWidthFontSize;
@@ -971,6 +972,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool & SessionList)
     KEYEX(String, FExtensionsDeleted, L"ExtensionsDeleted"); \
     KEYEX(String, FExtensionsDeleted, L"ExtensionsDeleted"); \
     KEYEX(String, FExtensionsOrder, L"ExtensionsOrder"); \
     KEYEX(String, FExtensionsOrder, L"ExtensionsOrder"); \
     KEY(Bool,  TimeoutShellOperations); \
     KEY(Bool,  TimeoutShellOperations); \
+    KEY(Bool,     TimeoutShellIconRetrieval); \
   ); \
   ); \
   BLOCK(L"Interface\\Editor", CANCREATE, \
   BLOCK(L"Interface\\Editor", CANCREATE, \
     KEYEX(String,   Editor.Font.FontName, L"FontName2"); \
     KEYEX(String,   Editor.Font.FontName, L"FontName2"); \
@@ -2545,6 +2547,11 @@ void __fastcall TWinConfiguration::SetTimeoutShellOperations(bool value)
   ::TimeoutShellOperations = value;
   ::TimeoutShellOperations = value;
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
+void __fastcall TWinConfiguration::SetTimeoutShellIconRetrieval(bool value)
+{
+  SET_CONFIG_PROPERTY(TimeoutShellIconRetrieval);
+}
+//---------------------------------------------------------------------------
 TStringList * __fastcall TWinConfiguration::LoadJumpList(
 TStringList * __fastcall TWinConfiguration::LoadJumpList(
   THierarchicalStorage * Storage, UnicodeString Name)
   THierarchicalStorage * Storage, UnicodeString Name)
 {
 {

+ 3 - 0
source/windows/WinConfiguration.h

@@ -432,6 +432,7 @@ private:
   TDateTime FTipsShown;
   TDateTime FTipsShown;
   int FRunsSinceLastTip;
   int FRunsSinceLastTip;
   bool FLockedInterface;
   bool FLockedInterface;
+  bool FTimeoutShellIconRetrieval;
   int FDontDecryptPasswords;
   int FDontDecryptPasswords;
   int FMasterPasswordSession;
   int FMasterPasswordSession;
   bool FMasterPasswordSessionAsked;
   bool FMasterPasswordSessionAsked;
@@ -537,6 +538,7 @@ private:
   void __fastcall SetLockedInterface(bool value);
   void __fastcall SetLockedInterface(bool value);
   bool __fastcall GetTimeoutShellOperations();
   bool __fastcall GetTimeoutShellOperations();
   void __fastcall SetTimeoutShellOperations(bool value);
   void __fastcall SetTimeoutShellOperations(bool value);
+  void __fastcall SetTimeoutShellIconRetrieval(bool value);
   int __fastcall GetLocaleCompletenessTreshold();
   int __fastcall GetLocaleCompletenessTreshold();
 
 
   bool __fastcall GetDDExtInstalled();
   bool __fastcall GetDDExtInstalled();
@@ -717,6 +719,7 @@ public:
   __property TStrings * CustomCommandOptions = { read = GetCustomCommandOptions, write = SetCustomCommandOptions };
   __property TStrings * CustomCommandOptions = { read = GetCustomCommandOptions, write = SetCustomCommandOptions };
   __property bool LockedInterface = { read = FLockedInterface, write = SetLockedInterface };
   __property bool LockedInterface = { read = FLockedInterface, write = SetLockedInterface };
   __property bool TimeoutShellOperations = { read = GetTimeoutShellOperations, write = SetTimeoutShellOperations };
   __property bool TimeoutShellOperations = { read = GetTimeoutShellOperations, write = SetTimeoutShellOperations };
+  __property bool TimeoutShellIconRetrieval = { read = FTimeoutShellIconRetrieval, write = SetTimeoutShellIconRetrieval };
   __property LCID DefaultLocale = { read = FDefaultLocale };
   __property LCID DefaultLocale = { read = FDefaultLocale };
   __property int LocaleCompletenessTreshold = { read = GetLocaleCompletenessTreshold };
   __property int LocaleCompletenessTreshold = { read = GetLocaleCompletenessTreshold };
 };
 };