Forráskód Böngészése

ADD: WSL to virtual file system list

Alexander Koblov 2 éve
szülő
commit
92899fb35f

+ 5 - 5
src/doublecmd.lpi

@@ -40,7 +40,7 @@
           </Target>
           <SearchPaths>
             <IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
-            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash"/>
+            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl"/>
             <UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
             <SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
           </SearchPaths>
@@ -83,7 +83,7 @@
           </Target>
           <SearchPaths>
             <IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
-            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash"/>
+            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl"/>
             <UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
             <SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
           </SearchPaths>
@@ -122,7 +122,7 @@
           </Target>
           <SearchPaths>
             <IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
-            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash"/>
+            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl"/>
             <UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
             <SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
           </SearchPaths>
@@ -196,7 +196,7 @@ end;"/>
           </Target>
           <SearchPaths>
             <IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
-            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;..\components\DDetours\Source;filesources\gio\trash"/>
+            <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;..\components\DDetours\Source;filesources\gio\trash;filesources\winnet\wsl"/>
             <UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
             <SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
           </SearchPaths>
@@ -1977,7 +1977,7 @@ end;"/>
     </Target>
     <SearchPaths>
       <IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
-      <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash"/>
+      <OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl"/>
       <UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
       <SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
     </SearchPaths>

+ 2 - 52
src/filesources/winnet/uwinnetlistoperation.pas

@@ -20,9 +20,7 @@ type
   private
     procedure ShareEnum;
     procedure ShellEnum;
-    procedure LinuxEnum;
     procedure WorkgroupEnum;
-    function Linux: Boolean;
     function Connect: Boolean;
   public
     constructor Create(aFileSource: IFileSource; aPath: String); override;
@@ -36,17 +34,6 @@ uses
   StrUtils, DCStrUtils, uShowMsg, DCOSUtils, uOSUtils, uNetworkThread, uMyWindows,
   ShlObj, ComObj, DCConvertEncoding, uShellFolder, uShlObjAdditional;
 
-function TWinNetListOperation.Linux: Boolean;
-var
-  APath: String;
-begin
-  Result:= CheckWin32Version(10);
-  if Result then begin
-    APath:= LowerCase(Path);
-    Result:= StrBegins(APath, '\\wsl$\') or StrBegins(APath, '\\wsl.localhost\');
-  end;
-end;
-
 function TWinNetListOperation.Connect: Boolean;
 var
   dwResult: DWORD;
@@ -224,40 +211,6 @@ begin
   end;
 end;
 
-procedure TWinNetListOperation.LinuxEnum;
-var
-  AFile: TFile;
-  pchEaten: ULONG;
-  APath: UnicodeString;
-  NumIDs: LongWord = 0;
-  AFolder: IShellFolder;
-  dwAttributes: ULONG = 0;
-  EnumIDList: IEnumIDList;
-  DesktopFolder: IShellFolder;
-  PIDL, NetworkPIDL: PItemIDList;
-begin
-  try
-    OleCheckUTF8(SHGetDesktopFolder(DesktopFolder));
-    APath:= CeUtf8ToUtf16(ExcludeTrailingPathDelimiter(Path));
-    OleCheckUTF8(DeskTopFolder.ParseDisplayName(0, nil, PWideChar(APath), pchEaten, NetworkPIDL, dwAttributes));
-    OleCheckUTF8(DesktopFolder.BindToObject(NetworkPIDL, nil, IID_IShellFolder, Pointer(AFolder)));
-    OleCheckUTF8(AFolder.EnumObjects(0, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN, EnumIDList));
-
-    while EnumIDList.Next(1, PIDL, NumIDs) = S_OK do
-    begin
-      CheckOperationState;
-
-      aFile:= TWinNetFileSource.CreateFile(Path);
-      aFile.Attributes:= FILE_ATTRIBUTE_DIRECTORY;
-      AFile.FullPath:= GetDisplayName(AFolder, PIDL, SHGDN_FORPARSING or SHGDN_FORADDRESSBAR);
-
-      FFiles.Add(AFile);
-    end;
-  except
-    on E: Exception do msgError(Thread, E.Message);
-  end;
-end;
-
 constructor TWinNetListOperation.Create(aFileSource: IFileSource; aPath: String);
 begin
   FFiles := TFiles.Create(aPath);
@@ -273,15 +226,12 @@ begin
     // Shared directory
     if not IsNetworkPath(Path) then
     begin
-      if Linux or Connect then
+      if Connect then
         inherited MainExecute;
     end
     else begin
-      // Linux WSL
-      if Linux then
-        LinuxEnum
       // Workstation/Server
-      else if (IsPathAtRoot(Path) = False) and (Pos('\\', Path) = 1) then
+      if (IsPathAtRoot(Path) = False) and (Pos('\\', Path) = 1) then
         ShareEnum
       // Root/Domain/Workgroup
       else if not Samba1 then

+ 92 - 0
src/filesources/winnet/wsl/uwslfilesource.pas

@@ -0,0 +1,92 @@
+unit uWslFileSource;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, Dialogs,
+  uFileSource, uFileSourceOperation, uWinNetFileSource;
+
+type
+
+  { TWslFileSource }
+
+  TWslFileSource = class(TWinNetFileSource)
+  public
+    function GetParentDir(sPath : String): String; override;
+    function IsPathAtRoot(Path: String): Boolean; override;
+    function GetRootDir(sPath: String): String; override; overload;
+    function GetRootDir: String; override; overload;
+
+    class function Available: Boolean;
+    class function IsSupportedPath(const Path: String): Boolean; override;
+    class function GetMainIcon(out Path: String): Boolean; override;
+
+    function CreateListOperation(TargetPath: String): TFileSourceOperation; override;
+  end;
+
+implementation
+
+uses
+  LazUTF8, DCOSUtils, DCStrUtils, uMyWindows, uWslListOperation;
+
+{ TWslFileSource }
+
+function TWslFileSource.GetParentDir(sPath: String): String;
+begin
+  Result:= DCStrUtils.GetParentDir(sPath);
+end;
+
+function TWslFileSource.IsPathAtRoot(Path: String): Boolean;
+begin
+  Path:= IncludeTrailingBackslash(LowerCase(Path));
+  Result:= SameStr(Path, '\\wsl$\') or SameStr(Path, '\\wsl.localhost\');
+end;
+
+function TWslFileSource.GetRootDir(sPath: String): String;
+begin
+  if (Win32BuildNumber >= 22000) then
+    Result:= '\\wsl.localhost\'
+  else begin
+    Result:= '\\wsl$\';
+  end;
+end;
+
+function TWslFileSource.GetRootDir: String;
+begin
+  Result:= GetRootDir(EmptyStr);
+end;
+
+class function TWslFileSource.Available: Boolean;
+begin
+  Result:= GetServiceStatus('LxssManager') <> 0;
+end;
+
+class function TWslFileSource.IsSupportedPath(const Path: String): Boolean;
+var
+  APath: String;
+begin
+  APath:= IncludeTrailingBackslash(LowerCase(Path));
+  Result:= StrBegins(APath, '\\wsl$\') or StrBegins(APath, '\\wsl.localhost\');
+end;
+
+class function TWslFileSource.GetMainIcon(out Path: String): Boolean;
+begin
+  if IsWow64 then
+    Path:= '%SystemRoot%\Sysnative\wsl.exe'
+  else begin
+    Path:= '%SystemRoot%\System32\wsl.exe';
+  end;
+  Result:= True;
+end;
+
+function TWslFileSource.CreateListOperation(TargetPath: String): TFileSourceOperation;
+var
+  TargetFileSource: IFileSource;
+begin
+  TargetFileSource := Self;
+  Result:= TWslListOperation.Create(TargetFileSource, TargetPath);
+end;
+
+end.

+ 88 - 0
src/filesources/winnet/wsl/uwsllistoperation.pas

@@ -0,0 +1,88 @@
+unit uWslListOperation;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils,
+  uFileSystemListOperation,
+  uWinNetFileSource,
+  uFileSource;
+
+type
+
+  { TWslListOperation }
+
+  TWslListOperation = class(TFileSystemListOperation)
+  private
+    FWinNetFileSource: IWinNetFileSource;
+  private
+    procedure LinuxEnum;
+  public
+    constructor Create(aFileSource: IFileSource; aPath: String); override;
+    procedure MainExecute; override;
+  end;
+
+implementation
+
+uses
+  LazUTF8, uFile, Windows, uShowMsg, DCOSUtils, uMyWindows, ShlObj, ComObj,
+  DCConvertEncoding, uShellFolder, uShlObjAdditional;
+
+procedure TWslListOperation.LinuxEnum;
+var
+  AFile: TFile;
+  pchEaten: ULONG;
+  APath: UnicodeString;
+  NumIDs: LongWord = 0;
+  AFolder: IShellFolder;
+  dwAttributes: ULONG = 0;
+  EnumIDList: IEnumIDList;
+  DesktopFolder: IShellFolder;
+  PIDL, NetworkPIDL: PItemIDList;
+begin
+  try
+    OleCheckUTF8(SHGetDesktopFolder(DesktopFolder));
+    APath:= CeUtf8ToUtf16(ExcludeTrailingPathDelimiter(Path));
+    OleCheckUTF8(DeskTopFolder.ParseDisplayName(0, nil, PWideChar(APath), pchEaten, NetworkPIDL, dwAttributes));
+    OleCheckUTF8(DesktopFolder.BindToObject(NetworkPIDL, nil, IID_IShellFolder, Pointer(AFolder)));
+    OleCheckUTF8(AFolder.EnumObjects(0, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN, EnumIDList));
+
+    while EnumIDList.Next(1, PIDL, NumIDs) = S_OK do
+    begin
+      CheckOperationState;
+
+      aFile:= TWinNetFileSource.CreateFile(Path);
+      aFile.Attributes:= FILE_ATTRIBUTE_DIRECTORY;
+      AFile.FullPath:= GetDisplayName(AFolder, PIDL, SHGDN_FORPARSING or SHGDN_FORADDRESSBAR);
+
+      FFiles.Add(AFile);
+    end;
+  except
+    on E: Exception do msgError(Thread, E.Message);
+  end;
+end;
+
+constructor TWslListOperation.Create(aFileSource: IFileSource; aPath: String);
+begin
+  FFiles := TFiles.Create(aPath);
+  FWinNetFileSource := aFileSource as IWinNetFileSource;
+  inherited Create(aFileSource, aPath);
+end;
+
+procedure TWslListOperation.MainExecute;
+begin
+  FFiles.Clear;
+  with FWinNetFileSource do
+  begin
+    if IsNetworkPath(Path) then
+      LinuxEnum
+    else begin
+      inherited MainExecute;
+    end;
+  end;
+end;
+
+end.
+

+ 10 - 2
src/platform/uosforms.pas

@@ -3,7 +3,7 @@
     -------------------------------------------------------------------------
     This unit contains platform depended functions.
 
-    Copyright (C) 2006-2018 Alexander Koblov ([email protected])
+    Copyright (C) 2006-2022 Alexander Koblov ([email protected])
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -132,7 +132,7 @@ uses
   , uWinNetFileSource, uVfsModule, uMyWindows, DCStrUtils, uOleDragDrop
   , uDCReadRSVG, uFileSourceUtil, uGdiPlusJPEG, uListGetPreviewBitmap
   , Dialogs, Clipbrd, uDebug, JwaDbt, uThumbnailProvider, uShellFolder
-  , uRecycleBinFileSource, uDCReadHEIF, uDCReadWIC
+  , uRecycleBinFileSource, uWslFileSource, uDCReadHEIF, uDCReadWIC
     {$IFDEF LCLQT5}
     , qt5, qtwidgets, uDarkStyle
     {$ENDIF}
@@ -569,10 +569,18 @@ begin
     Screen.AddHandlerFormVisibleChanged(TScreenFormEvent(Handler), True);
   end;
 {$ENDIF}
+  // Register Windows Subsystem for Linux (WSL) file source
+  if CheckWin32Version(10) then
+  begin
+    RegisterVirtualFileSource('Linux', TWslFileSource, TWslFileSource.Available);
+  end;
   // Register network file source
   RegisterVirtualFileSource(rsVfsNetwork, TWinNetFileSource);
+  // Register recycle bin file source
   if CheckWin32Version(5, 1) then
+  begin
     RegisterVirtualFileSource(rsVfsRecycleBin, TRecycleBinFileSource);
+  end;
 
   // If run under administrator
   if (IsUserAdmin = dupAccept) then