11// Copyright (c) Files Community
22// Licensed under the MIT License.
33
4- using System . Runtime . CompilerServices ;
54using Windows . Win32 ;
65using Windows . Win32 . Foundation ;
76using Windows . Win32 . System . SystemServices ;
109namespace Files . App . Storage
1110{
1211 [ DebuggerDisplay ( "{" + nameof ( ToString ) + "()}" ) ]
13- public sealed class WindowsFolder : WindowsStorable , IChildFolder
12+ public unsafe sealed class WindowsFolder : WindowsStorable , IChildFolder
1413 {
15- public WindowsFolder ( ComPtr < IShellItem > nativeObject )
14+ public WindowsFolder ( IShellItem * ptr )
1615 {
17- ThisPtr = nativeObject ;
18- }
19-
20- public unsafe WindowsFolder ( IShellItem * nativeObject )
21- {
22- ComPtr < IShellItem > ptr = default ;
23- ptr . Attach ( nativeObject ) ;
2416 ThisPtr = ptr ;
2517 }
2618
27- public unsafe WindowsFolder ( Guid folderId )
19+ public WindowsFolder ( Guid folderId )
2820 {
29- ComPtr < IShellItem > pItem = default ;
21+ IShellItem * pItem = default ;
3022
31- HRESULT hr = PInvoke . SHGetKnownFolderItem ( & folderId , KNOWN_FOLDER_FLAG . KF_FLAG_DEFAULT , HANDLE . Null , IID . IID_IShellItem , ( void * * ) pItem . GetAddressOf ( ) ) ;
23+ HRESULT hr = PInvoke . SHGetKnownFolderItem ( & folderId , KNOWN_FOLDER_FLAG . KF_FLAG_DEFAULT , HANDLE . Null , IID . IID_IShellItem , ( void * * ) & pItem ) ;
3224 if ( hr . Failed )
3325 {
3426 fixed ( char * pszShellPath = $ "Shell:::{ folderId : B} ")
35- hr = PInvoke . SHCreateItemFromParsingName ( pszShellPath , null , IID . IID_IShellItem , ( void * * ) pItem . GetAddressOf ( ) ) ;
27+ hr = PInvoke . SHCreateItemFromParsingName ( pszShellPath , null , IID . IID_IShellItem , ( void * * ) & pItem ) ;
3628
3729 // Invalid FOLDERID; this should never happen.
3830 hr . ThrowOnFailure ( ) ;
@@ -43,47 +35,35 @@ public unsafe WindowsFolder(Guid folderId)
4335
4436 public IAsyncEnumerable < IStorableChild > GetItemsAsync ( StorableType type = StorableType . All , CancellationToken cancellationToken = default )
4537 {
46- return GetItems ( ) . ToAsyncEnumerable ( ) ;
38+ ComPtr < IEnumShellItems > pEnumShellItems = default ;
39+ HRESULT hr = ThisPtr ->BindToHandler ( null , BHID . BHID_EnumItems , IID . IID_IEnumShellItems , ( void * * ) pEnumShellItems . GetAddressOf ( ) ) ;
40+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
41+ return Enumerable . Empty < IStorableChild > ( ) . ToAsyncEnumerable ( ) ;
4742
48- unsafe IEnumerable < IStorableChild > GetItems ( )
43+ List < IStorableChild > items = [ ] ;
44+ IShellItem * pShellItem = default ;
45+ while ( pEnumShellItems . Get ( ) ->Next ( 1 , & pShellItem ) . Succeeded && pShellItem is not null )
4946 {
50- ComPtr < IEnumShellItems > pEnumShellItems = default ;
51- GetEnumerator ( ) ;
47+ cancellationToken . ThrowIfCancellationRequested ( ) ;
5248
53- ComPtr < IShellItem > pShellItem = default ;
54- while ( GetNext ( ) && ! pShellItem . IsNull )
55- {
56- cancellationToken . ThrowIfCancellationRequested ( ) ;
57- var isFolder = pShellItem . HasShellAttributes ( SFGAO_FLAGS . SFGAO_FOLDER ) ;
49+ var isFolder = pShellItem ->GetAttributes ( SFGAO_FLAGS . SFGAO_FOLDER , out var returnedAttributes ) . Succeeded &&
50+ returnedAttributes == SFGAO_FLAGS . SFGAO_FOLDER ;
5851
59- if ( type is StorableType . File && ! isFolder )
60- {
61- yield return new WindowsFile ( pShellItem ) ;
62- }
63- else if ( type is StorableType . Folder && isFolder )
64- {
65- yield return new WindowsFolder ( pShellItem ) ;
66- }
67- else
68- {
69- continue ;
70- }
52+ if ( type is StorableType . File && ! isFolder )
53+ {
54+ items . Add ( new WindowsFile ( pShellItem ) ) ;
7155 }
72-
73- yield break ;
74-
75- unsafe void GetEnumerator ( )
56+ else if ( type is StorableType . Folder && isFolder )
7657 {
77- HRESULT hr = ThisPtr . Get ( ) ->BindToHandler ( null , BHID . BHID_EnumItems , IID . IID_IEnumShellItems , ( void * * ) pEnumShellItems . GetAddressOf ( ) ) ;
78- hr . ThrowIfFailedOnDebug ( ) ;
58+ items . Add ( new WindowsFolder ( pShellItem ) ) ;
7959 }
80-
81- unsafe bool GetNext ( )
60+ else
8261 {
83- HRESULT hr = pEnumShellItems . Get ( ) ->Next ( 1 , pShellItem . GetAddressOf ( ) ) ;
84- return hr . ThrowIfFailedOnDebug ( ) == HRESULT . S_OK ;
62+ continue ;
8563 }
8664 }
65+
66+ return items . ToAsyncEnumerable ( ) ;
8767 }
8868 }
8969}
0 commit comments