1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Test the result of enumerating over a folder with a zip in it 5 * COPYRIGHT: Copyright 2020-2023 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 struct FileInfo 11 { 12 LPCWSTR Name; 13 SFGAOF Attributes; 14 bool Found; 15 }; 16 17 int zipfldr_loaded() 18 { 19 return GetModuleHandleA("zipfldr.dll") ? TRUE : FALSE; 20 } 21 22 void FindExpectedFile(FileInfo* Array, size_t len, IShellFolder* pFolder, PCUITEMID_CHILD pidl, LPCWSTR& ExpectedName, SFGAOF& ExpectedAttributes) 23 { 24 ExpectedName = L"<WRONG FILE>"; 25 ExpectedAttributes = (SFGAOF)~0; 26 27 STRRET NameRet; 28 HRESULT hr; 29 30 hr = pFolder->GetDisplayNameOf(pidl, SHGDN_NORMAL, &NameRet); 31 ok_hr(hr, S_OK); 32 if (!SUCCEEDED(hr)) 33 return; 34 35 WCHAR DisplayName[MAX_PATH]; 36 hr = StrRetToBufW(&NameRet, pidl, DisplayName, RTL_NUMBER_OF(DisplayName)); 37 ok_hr(hr, S_OK); 38 if (!SUCCEEDED(hr)) 39 return; 40 41 for (size_t n = 0; n < len; ++n) 42 { 43 if (!wcsicmp(Array[n].Name, DisplayName) && !Array[n].Found) 44 { 45 Array[n].Found = true; 46 ExpectedName = Array[n].Name; 47 ExpectedAttributes = Array[n].Attributes; 48 return; 49 } 50 } 51 } 52 53 const SFGAOF BaseFileAttributes = SFGAO_FILESYSTEM; 54 const SFGAOF BaseFolderAttributes = SFGAO_FILESYSTEM | SFGAO_FOLDER; 55 FileInfo ExpectedFiles[] = { 56 { L"test.txt", BaseFileAttributes, false }, 57 { L"TMP0.zip", BaseFileAttributes, false}, // 2k3 Shows this as a file, newer shows this as a folder 58 { L"ASUBFLD", BaseFolderAttributes | SFGAO_FILESYSANCESTOR | SFGAO_STORAGEANCESTOR, false }, 59 }; 60 BOOL FoundZipfldr = FALSE; 61 62 static void 63 test_EnumDirFiles(const WCHAR *TestFolder, BOOL EnumFolders) 64 { 65 CComPtr<IShellFolder> spFolder; 66 if (!InitializeShellFolder(TestFolder, spFolder)) 67 return; 68 69 CComPtr<IEnumIDList> spEnum; 70 ok_int(zipfldr_loaded(), FoundZipfldr); 71 HRESULT hr = spFolder->EnumObjects(NULL, EnumFolders ? SHCONTF_FOLDERS : SHCONTF_NONFOLDERS, &spEnum); 72 ok_hr(hr, S_OK); 73 if (!SUCCEEDED(hr)) 74 return; 75 ok_int(zipfldr_loaded(), FoundZipfldr); 76 77 do 78 { 79 CComHeapPtr<ITEMID_CHILD> child; 80 ULONG celtFetched = 0; 81 ok_int(zipfldr_loaded(), FoundZipfldr); 82 hr = spEnum->Next(1, &child, &celtFetched); 83 ok_int(zipfldr_loaded(), FoundZipfldr); 84 if (hr != S_OK) 85 break; 86 ok_int(celtFetched, 1); 87 if (celtFetched != 1) 88 break; 89 90 LPCWSTR ExpectedName; 91 SFGAOF ExpectedAttributes; 92 FindExpectedFile(ExpectedFiles, RTL_NUMBER_OF(ExpectedFiles), spFolder, child, ExpectedName, ExpectedAttributes); 93 94 ok_int(zipfldr_loaded(), FoundZipfldr); 95 ok_displayname(spFolder, child, SHGDN_NORMAL, ExpectedName); 96 ok_int(zipfldr_loaded(), FoundZipfldr); 97 98 SFGAOF Attributes = SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER; 99 hr = spFolder->GetAttributesOf(1, &child, &Attributes); 100 101 if (!wcsicmp(ExpectedName, L"TMP0.zip")) 102 { 103 // We allow both .zip files being a 'file' (2k3) or a 'folder' (win10) 104 if (Attributes & SFGAO_FOLDER) 105 ExpectedAttributes |= SFGAO_FOLDER; 106 // Only at this point (after calling GetAttributesOf) it will load zipfldr 107 FoundZipfldr = TRUE; 108 trace("Found zip (%S)\n", ExpectedName); 109 } 110 ok_int(zipfldr_loaded(), FoundZipfldr); 111 112 /* Just keep the ones we are interested in */ 113 Attributes &= (SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | SFGAO_STORAGEANCESTOR); 114 ok_hr(hr, S_OK); 115 ok_hex(Attributes, ExpectedAttributes); 116 } while (true); 117 118 ok_hr(hr, S_FALSE); 119 ok_int(zipfldr_loaded(), FoundZipfldr); 120 } 121 122 123 START_TEST(EnumParentDir) 124 { 125 HRESULT hr = CoInitialize(NULL); 126 127 ok_hr(hr, S_OK); 128 if (!SUCCEEDED(hr)) 129 return; 130 131 ok_int(zipfldr_loaded(), FALSE); 132 133 WCHAR TestFolder[MAX_PATH], TestFile[MAX_PATH], SubFolder[MAX_PATH]; 134 GetTempPathW(_countof(TestFolder), TestFolder); 135 PathAppendW(TestFolder, L"ZipDir"); 136 PathAddBackslashW(TestFolder); 137 138 CreateDirectoryW(TestFolder, NULL); 139 140 WCHAR ZipTestFile[MAX_PATH]; 141 if (!extract_resource(ZipTestFile, MAKEINTRESOURCEW(IDR_ZIP_TEST_FILE), TestFolder)) 142 { 143 RemoveDirectoryW(TestFolder); 144 return; 145 } 146 147 StringCchPrintfW(TestFile, _countof(TestFile), L"%stest.txt", TestFolder); 148 149 HANDLE hFile = CreateFileW(TestFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL); 150 151 ok(hFile != INVALID_HANDLE_VALUE, "Error creating %S\n", TestFile); 152 if (hFile != INVALID_HANDLE_VALUE) 153 { 154 StringCchPrintfW(SubFolder, _countof(SubFolder), L"%sASUBFLD", TestFolder); 155 156 CreateDirectoryW(SubFolder, NULL); 157 158 winetest_push_context("Files"); 159 test_EnumDirFiles(TestFolder, FALSE); 160 winetest_pop_context(); 161 winetest_push_context("Folders"); 162 test_EnumDirFiles(TestFolder, TRUE); 163 winetest_pop_context(); 164 165 for (size_t n = 0; n < RTL_NUMBER_OF(ExpectedFiles); ++n) 166 { 167 ok(ExpectedFiles[n].Found, "Did not find %S\n", ExpectedFiles[n].Name); 168 } 169 170 RemoveDirectoryW(SubFolder); 171 172 CloseHandle(hFile); 173 } 174 175 DeleteFileW(ZipTestFile); 176 RemoveDirectoryW(TestFolder); 177 CoUninitialize(); 178 } 179