7
7
using Files . App . Utils . StorageItems ;
8
8
using Files . App . Helpers . StorageCache ;
9
9
using Files . App . Utils . Shell ;
10
- using Files . App . Storage . FtpStorage ;
11
10
using Files . App . ViewModels . Previews ;
12
11
using Files . Core . Services . SizeProvider ;
13
12
using Files . Shared . Cloud ;
14
13
using Files . Shared . EventArguments ;
15
14
using Files . Shared . Services ;
16
- using FluentFTP ;
17
15
using Microsoft . Extensions . Logging ;
18
16
using Microsoft . UI . Xaml . Data ;
19
17
using Microsoft . UI . Xaml . Media ;
20
18
using Microsoft . UI . Xaml . Media . Imaging ;
21
19
using System . Collections . Concurrent ;
22
20
using System . IO ;
23
- using System . Net ;
24
21
using System . Runtime . CompilerServices ;
25
22
using System . Runtime . InteropServices ;
26
- using System . Text ;
27
23
using System . Text . Json ;
28
24
using Vanara . Windows . Shell ;
29
25
using Windows . Foundation ;
@@ -144,20 +140,14 @@ public async Task SetWorkingDirectoryAsync(string? value)
144
140
145
141
WorkingDirectory = value ;
146
142
147
- string ? pathRoot ;
148
- if ( FtpHelpers . IsFtpPath ( WorkingDirectory ) )
149
- {
150
- var rootIndex = FtpHelpers . GetRootIndex ( WorkingDirectory ) ;
151
- pathRoot = rootIndex is - 1
152
- ? WorkingDirectory
153
- : WorkingDirectory . Substring ( 0 , rootIndex ) ;
154
- }
155
- else
143
+ string ? pathRoot = null ;
144
+ if ( ! FtpHelpers . IsFtpPath ( WorkingDirectory ) )
156
145
{
157
146
pathRoot = Path . GetPathRoot ( WorkingDirectory ) ;
158
147
}
159
148
160
149
GitDirectory = pathRoot is null ? null : GitHelpers . GetGitRepositoryPath ( WorkingDirectory , pathRoot ) ;
150
+
161
151
OnPropertyChanged ( nameof ( WorkingDirectory ) ) ;
162
152
}
163
153
@@ -1380,55 +1370,46 @@ private async Task RapidAddItemsToCollection(string? path, LibraryItem? library
1380
1370
var stopwatch = new Stopwatch ( ) ;
1381
1371
stopwatch . Start ( ) ;
1382
1372
1383
- if ( FtpHelpers . IsFtpPath ( path ) )
1384
- {
1385
- // Recycle bin and network are enumerated by the fulltrust process
1386
- PageTypeUpdated ? . Invoke ( this , new PageTypeUpdatedEventArgs ( ) { IsTypeCloudDrive = false } ) ;
1387
- await EnumerateItemsFromSpecialFolderAsync ( path ) ;
1388
- }
1389
- else
1373
+ var isRecycleBin = path . StartsWith ( Constants . UserEnvironmentPaths . RecycleBinPath , StringComparison . Ordinal ) ;
1374
+ var enumerated = await EnumerateItemsFromStandardFolderAsync ( path , addFilesCTS . Token , library ) ;
1375
+
1376
+ // Hide progressbar after enumeration
1377
+ IsLoadingItems = false ;
1378
+
1379
+ switch ( enumerated )
1390
1380
{
1391
- var isRecycleBin = path . StartsWith ( Constants . UserEnvironmentPaths . RecycleBinPath , StringComparison . Ordinal ) ;
1392
- var enumerated = await EnumerateItemsFromStandardFolderAsync ( path , addFilesCTS . Token , library ) ;
1381
+ // Enumerated with FindFirstFileExFromApp
1382
+ // Is folder synced to cloud storage?
1383
+ case 0 :
1384
+ currentStorageFolder ??= await FilesystemTasks . Wrap ( ( ) => StorageFileExtensions . DangerousGetFolderWithPathFromPathAsync ( path ) ) ;
1385
+ var syncStatus = await CheckCloudDriveSyncStatusAsync ( currentStorageFolder ? . Item ) ;
1386
+ PageTypeUpdated ? . Invoke ( this , new PageTypeUpdatedEventArgs ( )
1387
+ {
1388
+ IsTypeCloudDrive = syncStatus != CloudDriveSyncStatus . NotSynced && syncStatus != CloudDriveSyncStatus . Unknown ,
1389
+ IsTypeGitRepository = GitDirectory is not null
1390
+ } ) ;
1391
+ WatchForDirectoryChanges ( path , syncStatus ) ;
1392
+ if ( GitDirectory is not null )
1393
+ WatchForGitChanges ( ) ;
1394
+ break ;
1393
1395
1394
- // Hide progressbar after enumeration
1395
- IsLoadingItems = false ;
1396
+ // Enumerated with StorageFolder
1397
+ case 1 :
1398
+ PageTypeUpdated ? . Invoke ( this , new PageTypeUpdatedEventArgs ( ) { IsTypeCloudDrive = false , IsTypeRecycleBin = isRecycleBin } ) ;
1399
+ currentStorageFolder ??= await FilesystemTasks . Wrap ( ( ) => StorageFileExtensions . DangerousGetFolderWithPathFromPathAsync ( path ) ) ;
1400
+ WatchForStorageFolderChanges ( currentStorageFolder ? . Item ) ;
1401
+ break ;
1396
1402
1397
- switch ( enumerated )
1398
- {
1399
- // Enumerated with FindFirstFileExFromApp
1400
- // Is folder synced to cloud storage?
1401
- case 0 :
1402
- currentStorageFolder ??= await FilesystemTasks . Wrap ( ( ) => StorageFileExtensions . DangerousGetFolderWithPathFromPathAsync ( path ) ) ;
1403
- var syncStatus = await CheckCloudDriveSyncStatusAsync ( currentStorageFolder ? . Item ) ;
1404
- PageTypeUpdated ? . Invoke ( this , new PageTypeUpdatedEventArgs ( )
1405
- {
1406
- IsTypeCloudDrive = syncStatus != CloudDriveSyncStatus . NotSynced && syncStatus != CloudDriveSyncStatus . Unknown ,
1407
- IsTypeGitRepository = GitDirectory is not null
1408
- } ) ;
1409
- WatchForDirectoryChanges ( path , syncStatus ) ;
1410
- if ( GitDirectory is not null )
1411
- WatchForGitChanges ( ) ;
1412
- break ;
1413
-
1414
- // Enumerated with StorageFolder
1415
- case 1 :
1416
- PageTypeUpdated ? . Invoke ( this , new PageTypeUpdatedEventArgs ( ) { IsTypeCloudDrive = false , IsTypeRecycleBin = isRecycleBin } ) ;
1417
- currentStorageFolder ??= await FilesystemTasks . Wrap ( ( ) => StorageFileExtensions . DangerousGetFolderWithPathFromPathAsync ( path ) ) ;
1418
- WatchForStorageFolderChanges ( currentStorageFolder ? . Item ) ;
1419
- break ;
1420
-
1421
- // Watch for changes using FTP in Box Drive folder (#7428) and network drives (#5869)
1422
- case 2 :
1423
- PageTypeUpdated ? . Invoke ( this , new PageTypeUpdatedEventArgs ( ) { IsTypeCloudDrive = false } ) ;
1424
- WatchForWin32FolderChanges ( path ) ;
1425
- break ;
1426
-
1427
- // Enumeration failed
1428
- case - 1 :
1429
- default :
1430
- break ;
1431
- }
1403
+ // Watch for changes using Win32 in Box Drive folder (#7428) and network drives (#5869)
1404
+ case 2 :
1405
+ PageTypeUpdated ? . Invoke ( this , new PageTypeUpdatedEventArgs ( ) { IsTypeCloudDrive = false } ) ;
1406
+ WatchForWin32FolderChanges ( path ) ;
1407
+ break ;
1408
+
1409
+ // Enumeration failed
1410
+ case - 1 :
1411
+ default :
1412
+ break ;
1432
1413
}
1433
1414
1434
1415
await GetDefaultItemIcons ( folderSettings . GetIconSize ( ) ) ;
@@ -1455,99 +1436,6 @@ public void CloseWatcher()
1455
1436
watcherCTS = new CancellationTokenSource ( ) ;
1456
1437
}
1457
1438
1458
- public async Task EnumerateItemsFromSpecialFolderAsync ( string path )
1459
- {
1460
- var isFtp = FtpHelpers . IsFtpPath ( path ) ;
1461
-
1462
- CurrentFolder = new ListedItem ( null ! )
1463
- {
1464
- PrimaryItemAttribute = StorageItemTypes . Folder ,
1465
- ItemPropertiesInitialized = true ,
1466
- ItemNameRaw =
1467
- path . StartsWith ( Constants . UserEnvironmentPaths . RecycleBinPath , StringComparison . OrdinalIgnoreCase ) ? "RecycleBin" . GetLocalizedResource ( ) :
1468
- path . StartsWith ( Constants . UserEnvironmentPaths . NetworkFolderPath , StringComparison . OrdinalIgnoreCase ) ? "Network" . GetLocalizedResource ( ) :
1469
- path . StartsWith ( Constants . UserEnvironmentPaths . MyComputerPath , StringComparison . OrdinalIgnoreCase ) ? "ThisPC" . GetLocalizedResource ( ) :
1470
- isFtp ? "FTP" : "Unknown" ,
1471
- ItemDateModifiedReal = DateTimeOffset . Now , // Fake for now
1472
- ItemDateCreatedReal = DateTimeOffset . Now , // Fake for now
1473
- ItemType = "Folder" . GetLocalizedResource ( ) ,
1474
- FileImage = null ,
1475
- LoadFileIcon = false ,
1476
- ItemPath = path ,
1477
- FileSize = null ,
1478
- FileSizeBytes = 0
1479
- } ;
1480
-
1481
- if ( ! isFtp || ! FtpHelpers . VerifyFtpPath ( path ) )
1482
- return ;
1483
-
1484
- // TODO: Show invalid path dialog
1485
-
1486
- using var client = new AsyncFtpClient ( ) ;
1487
- client . Host = FtpHelpers . GetFtpHost ( path ) ;
1488
- client . Port = FtpHelpers . GetFtpPort ( path ) ;
1489
- client . Credentials = FtpManager . Credentials . Get ( client . Host , FtpManager . Anonymous ) ;
1490
-
1491
- static async Task < FtpProfile ? > WrappedAutoConnectFtpAsync ( AsyncFtpClient client )
1492
- {
1493
- try
1494
- {
1495
- return await client . AutoConnect ( ) ;
1496
- }
1497
- catch ( FtpAuthenticationException )
1498
- {
1499
- return null ;
1500
- }
1501
-
1502
- throw new InvalidOperationException ( ) ;
1503
- }
1504
-
1505
- await Task . Run ( async ( ) =>
1506
- {
1507
- try
1508
- {
1509
- if ( ! client . IsConnected && await WrappedAutoConnectFtpAsync ( client ) is null )
1510
- {
1511
- await dispatcherQueue . EnqueueOrInvokeAsync ( async ( ) =>
1512
- {
1513
- var credentialDialogViewModel = new CredentialDialogViewModel ( ) ;
1514
-
1515
- if ( await dialogService . ShowDialogAsync ( credentialDialogViewModel ) != DialogResult . Primary )
1516
- return ;
1517
-
1518
- // Can't do more than that to mitigate immutability of strings. Perhaps convert DisposableArray to SecureString immediately?
1519
- if ( ! credentialDialogViewModel . IsAnonymous )
1520
- client . Credentials = new NetworkCredential ( credentialDialogViewModel . UserName , Encoding . UTF8 . GetString ( credentialDialogViewModel . Password ) ) ;
1521
- } ) ;
1522
- }
1523
-
1524
- if ( ! client . IsConnected && await WrappedAutoConnectFtpAsync ( client ) is null )
1525
- throw new InvalidOperationException ( ) ;
1526
-
1527
- FtpManager . Credentials [ client . Host ] = client . Credentials ;
1528
-
1529
- var sampler = new IntervalSampler ( 500 ) ;
1530
- var list = await client . GetListing ( FtpHelpers . GetFtpPath ( path ) ) ;
1531
-
1532
- for ( var i = 0 ; i < list . Length ; i ++ )
1533
- {
1534
- filesAndFolders . Add ( new FtpItem ( list [ i ] , path ) ) ;
1535
-
1536
- if ( i == list . Length - 1 || sampler . CheckNow ( ) )
1537
- {
1538
- await OrderFilesAndFoldersAsync ( ) ;
1539
- await ApplyFilesAndFoldersChangesAsync ( ) ;
1540
- }
1541
- }
1542
- }
1543
- catch
1544
- {
1545
- // Network issue
1546
- FtpManager . Credentials . Remove ( client . Host ) ;
1547
- }
1548
- } ) ;
1549
- }
1550
-
1551
1439
public async Task < int > EnumerateItemsFromStandardFolderAsync ( string path , CancellationToken cancellationToken , LibraryItem ? library = null )
1552
1440
{
1553
1441
// Flag to use FindFirstFileExFromApp or StorageFolder enumeration - Use storage folder for Box Drive (#4629)
@@ -1557,7 +1445,8 @@ public async Task<int> EnumerateItemsFromStandardFolderAsync(string path, Cancel
1557
1445
! path . StartsWith ( @"\\?\" , StringComparison . Ordinal ) &&
1558
1446
! path . StartsWith ( @"\\SHELL\" , StringComparison . Ordinal ) &&
1559
1447
! isWslDistro ;
1560
- bool enumFromStorageFolder = isBoxFolder ;
1448
+ bool isFtp = FtpHelpers . IsFtpPath ( path ) ;
1449
+ bool enumFromStorageFolder = isBoxFolder || isFtp ;
1561
1450
1562
1451
BaseStorageFolder ? rootFolder = null ;
1563
1452
@@ -1585,7 +1474,7 @@ public async Task<int> EnumerateItemsFromStandardFolderAsync(string path, Cancel
1585
1474
}
1586
1475
else
1587
1476
{
1588
- var res = await FilesystemTasks . Wrap ( ( ) => StorageFileExtensions . DangerousGetFolderWithPathFromPathAsync ( path ) ) ;
1477
+ var res = await FilesystemTasks . Wrap ( ( ) => StorageFileExtensions . DangerousGetFolderWithPathFromPathAsync ( path , workingRoot , currentStorageFolder ) ) ;
1589
1478
if ( res )
1590
1479
{
1591
1480
currentStorageFolder = res . Result ;
@@ -1756,12 +1645,15 @@ await Task.Run(async () =>
1756
1645
}
1757
1646
}
1758
1647
1759
- private Task EnumFromStorageFolderAsync ( string path , BaseStorageFolder ? rootFolder , StorageFolderWithPath currentStorageFolder , CancellationToken cancellationToken )
1648
+ private async Task EnumFromStorageFolderAsync ( string path , BaseStorageFolder ? rootFolder , StorageFolderWithPath currentStorageFolder , CancellationToken cancellationToken )
1760
1649
{
1761
1650
if ( rootFolder is null )
1762
- return Task . CompletedTask ;
1651
+ return ;
1763
1652
1764
- return Task . Run ( async ( ) =>
1653
+ if ( rootFolder is IPasswordProtectedItem ppis )
1654
+ ppis . PasswordRequestedCallback = UIFilesystemHelpers . RequestPassword ;
1655
+
1656
+ await Task . Run ( async ( ) =>
1765
1657
{
1766
1658
List < ListedItem > finalList = await UniversalStorageEnumerator . ListEntries (
1767
1659
rootFolder ,
@@ -1782,6 +1674,9 @@ private Task EnumFromStorageFolderAsync(string path, BaseStorageFolder? rootFold
1782
1674
await OrderFilesAndFoldersAsync ( ) ;
1783
1675
await ApplyFilesAndFoldersChangesAsync ( ) ;
1784
1676
} , cancellationToken ) ;
1677
+
1678
+ if ( rootFolder is IPasswordProtectedItem ppiu )
1679
+ ppiu . PasswordRequestedCallback = null ;
1785
1680
}
1786
1681
1787
1682
private void CheckForSolutionFile ( )
0 commit comments