From 5cd5598ea97aa20d6b143a7f1c45169fe9895bdd Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Wed, 22 Apr 2020 20:47:00 +0200 Subject: [PATCH] [ZIPFLDR_APITEST] Add test enumerating over zip folder's parent Disable tests for unimplemented features --- .../rostests/apitests/zipfldr/CMakeLists.txt | 1 + .../rostests/apitests/zipfldr/EnumObjects.cpp | 30 ++- .../apitests/zipfldr/EnumParentDir.cpp | 218 ++++++++++++++++++ .../rostests/apitests/zipfldr/IDataObject.cpp | 22 +- modules/rostests/apitests/zipfldr/precomp.h | 4 +- modules/rostests/apitests/zipfldr/testlist.c | 2 + 6 files changed, 260 insertions(+), 17 deletions(-) create mode 100644 modules/rostests/apitests/zipfldr/EnumParentDir.cpp diff --git a/modules/rostests/apitests/zipfldr/CMakeLists.txt b/modules/rostests/apitests/zipfldr/CMakeLists.txt index 20a7abf8dc8..a53bbfd1bfd 100644 --- a/modules/rostests/apitests/zipfldr/CMakeLists.txt +++ b/modules/rostests/apitests/zipfldr/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl) list(APPEND SOURCE EnumObjects.cpp + EnumParentDir.cpp IDataObject.cpp precomp.h resource.h) diff --git a/modules/rostests/apitests/zipfldr/EnumObjects.cpp b/modules/rostests/apitests/zipfldr/EnumObjects.cpp index a7c1749c481..66bc90e182e 100644 --- a/modules/rostests/apitests/zipfldr/EnumObjects.cpp +++ b/modules/rostests/apitests/zipfldr/EnumObjects.cpp @@ -9,17 +9,19 @@ static bool g_bOldZipfldr = false; -#define ok_displayname(pFolder, pidl, Flags, Name) ok_displayname_(__FILE__, __LINE__, pFolder, pidl, Flags, Name) -static void ok_displayname_(const char* file, int line, IShellFolder* pFolder, PCUITEMID_CHILD pidl, SHGDNF Flags, LPCWSTR Name) +void ok_displayname_(const char* file, int line, IShellFolder* pFolder, PCUITEMID_CHILD pidl, SHGDNF Flags, LPCWSTR Name) { STRRET NameRet; HRESULT hr; - ok_hr_(file, line, (hr = pFolder->GetDisplayNameOf(pidl, Flags, &NameRet)), S_OK); + + hr = pFolder->GetDisplayNameOf(pidl, Flags, &NameRet); + ok_hr_(file, line, hr, S_OK); if (!SUCCEEDED(hr)) return; WCHAR DisplayName[MAX_PATH]; - ok_hr_(file, line, (hr = StrRetToBufW(&NameRet, pidl, DisplayName, ARRAYSIZE(DisplayName))), S_OK); + hr = StrRetToBufW(&NameRet, pidl, DisplayName, RTL_NUMBER_OF(DisplayName)); + ok_hr_(file, line, hr, S_OK); if (!SUCCEEDED(hr)) return; @@ -61,8 +63,8 @@ static void test_EnumObjects_Files(const WCHAR* Filename, IShellFolder* pFolder) if (celtFetched != 1) break; - LPCWSTR ExpectedName = totalFetched < ARRAYSIZE(ExpectedFiles) ? ExpectedFiles[totalFetched].Name : L""; - SFGAOF ExpectedAttributes = totalFetched < ARRAYSIZE(ExpectedFiles) ? ExpectedFiles[totalFetched].Attributes : 0xdeaddead; + LPCWSTR ExpectedName = totalFetched < RTL_NUMBER_OF(ExpectedFiles) ? ExpectedFiles[totalFetched].Name : L""; + SFGAOF ExpectedAttributes = totalFetched < RTL_NUMBER_OF(ExpectedFiles) ? ExpectedFiles[totalFetched].Attributes : 0xdeaddead; totalFetched++; @@ -117,7 +119,7 @@ static void test_EnumObjects_Files(const WCHAR* Filename, IShellFolder* pFolder) ReleaseStgMedium(&medium); } while (true); - ok_int(totalFetched, ARRAYSIZE(ExpectedFiles)); + ok_int(totalFetched, RTL_NUMBER_OF(ExpectedFiles)); ok_hr(hr, S_FALSE); } @@ -163,9 +165,9 @@ static void test_EnumObjects_Folders(const WCHAR* Filename, IShellFolder* pFolde if (celtFetched != 1) break; - LPCWSTR ExpectedName = totalFetched < ARRAYSIZE(ExpectedFolders) ? ExpectedFolders[totalFetched].Name : L""; - SFGAOF ExpectedAttributes = totalFetched < ARRAYSIZE(ExpectedFolders) ? ExpectedFolders[totalFetched].Attributes : 0xdeaddead; - LPCWSTR* ExtraFiles = totalFetched < ARRAYSIZE(ExpectedExtraFiles) ? ExpectedExtraFiles[totalFetched] : ExpectedExtraFiles[0]; + LPCWSTR ExpectedName = totalFetched < RTL_NUMBER_OF(ExpectedFolders) ? ExpectedFolders[totalFetched].Name : L""; + SFGAOF ExpectedAttributes = totalFetched < RTL_NUMBER_OF(ExpectedFolders) ? ExpectedFolders[totalFetched].Attributes : 0xdeaddead; + LPCWSTR* ExtraFiles = totalFetched < RTL_NUMBER_OF(ExpectedExtraFiles) ? ExpectedExtraFiles[totalFetched] : ExpectedExtraFiles[0]; totalFetched++; @@ -216,7 +218,7 @@ static void test_EnumObjects_Folders(const WCHAR* Filename, IShellFolder* pFolde ReleaseStgMedium(&medium); } while (true); - ok_int(totalFetched, ARRAYSIZE(ExpectedFolders)); + ok_int(totalFetched, RTL_NUMBER_OF(ExpectedFolders)); ok_hr(hr, S_FALSE); } @@ -252,6 +254,9 @@ static void test_EnumObjects(const WCHAR* Filename) START_TEST(EnumObjects) { + skip("Code in zipfldr not implemented yet\n"); + return; + HRESULT hr = CoInitialize(NULL); ok_hr(hr, S_OK); @@ -259,8 +264,9 @@ START_TEST(EnumObjects) return; WCHAR ZipTestFile[MAX_PATH]; - if (!extract_resource(ZipTestFile, MAKEINTRESOURCEW(IDR_ZIP_TEST_ENUM))) + if (!extract_resource(ZipTestFile, MAKEINTRESOURCEW(IDR_ZIP_TEST_ENUM), NULL)) return; test_EnumObjects(ZipTestFile); DeleteFileW(ZipTestFile); + CoUninitialize(); } diff --git a/modules/rostests/apitests/zipfldr/EnumParentDir.cpp b/modules/rostests/apitests/zipfldr/EnumParentDir.cpp new file mode 100644 index 00000000000..8eec80e3436 --- /dev/null +++ b/modules/rostests/apitests/zipfldr/EnumParentDir.cpp @@ -0,0 +1,218 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Test the result of enumerating over a folder with a zip in it + * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) + */ + +#include "precomp.h" + +struct FileInfo +{ + LPCWSTR Name; + SFGAOF Attributes; + bool Found; +}; + +int zipfldr_loaded() +{ + return GetModuleHandleA("zipfldr.dll") ? TRUE : FALSE; +} + +void FindExpectedFile(FileInfo* Array, size_t len, IShellFolder* pFolder, PCUITEMID_CHILD pidl, LPCWSTR& ExpectedName, SFGAOF& ExpectedAttributes) +{ + ExpectedName = L""; + ExpectedAttributes = (SFGAOF)~0; + + STRRET NameRet; + HRESULT hr; + + hr = pFolder->GetDisplayNameOf(pidl, SHGDN_NORMAL, &NameRet); + ok_hr(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + WCHAR DisplayName[MAX_PATH]; + hr = StrRetToBufW(&NameRet, pidl, DisplayName, RTL_NUMBER_OF(DisplayName)); + ok_hr(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + for (size_t n = 0; n < len; ++n) + { + if (!wcsicmp(Array[n].Name, DisplayName) && !Array[n].Found) + { + Array[n].Found = true; + ExpectedName = Array[n].Name; + ExpectedAttributes = Array[n].Attributes; + return; + } + } +} + +static void test_EnumDirFiles(const WCHAR* TestFolder) +{ + CComPtr spFolder; + if (!InitializeShellFolder(TestFolder, spFolder)) + return; + + CComPtr spEnum; + ok_int(zipfldr_loaded(), FALSE); + HRESULT hr = spFolder->EnumObjects(NULL, SHCONTF_NONFOLDERS, &spEnum); + ok_hr(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + ok_int(zipfldr_loaded(), FALSE); + + SFGAOF BaseAttributes = SFGAO_FILESYSTEM; + FileInfo ExpectedFiles[] = { + { L"test.txt", BaseAttributes, false }, + }; + + ULONG totalFetched = 0; + do + { + CComHeapPtr child; + ULONG celtFetched = 0; + hr = spEnum->Next(1, &child, &celtFetched); + if (hr != S_OK) + break; + ok_int(celtFetched, 1); + if (celtFetched != 1) + break; + + LPCWSTR ExpectedName; + SFGAOF ExpectedAttributes; + FindExpectedFile(ExpectedFiles, RTL_NUMBER_OF(ExpectedFiles), spFolder, child, ExpectedName, ExpectedAttributes); + + totalFetched++; + + ok_displayname(spFolder, child, SHGDN_NORMAL, ExpectedName); + + SFGAOF Attributes = SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER; + hr = spFolder->GetAttributesOf(1, &child, &Attributes); + /* Just keep the ones we are interested in */ + Attributes &= (SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | SFGAO_STORAGEANCESTOR); + ok_hr(hr, S_OK); + ok_hex(Attributes, ExpectedAttributes); + } while (true); + + ok_int(totalFetched, RTL_NUMBER_OF(ExpectedFiles)); + ok_hr(hr, S_FALSE); + ok_int(zipfldr_loaded(), FALSE); +} + +static void test_EnumDirDirs(const WCHAR* TestFolder) +{ + CComPtr spFolder; + if (!InitializeShellFolder(TestFolder, spFolder)) + return; + + CComPtr spEnum; + ok_int(zipfldr_loaded(), FALSE); + HRESULT hr = spFolder->EnumObjects(NULL, SHCONTF_FOLDERS, &spEnum); + ok_hr(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + ok_int(zipfldr_loaded(), FALSE); + + SFGAOF BaseAttributes = SFGAO_FILESYSTEM | SFGAO_FOLDER; + FileInfo ExpectedFiles[] = { + { L"TMP0.zip", BaseAttributes, false}, + { L"ASUBFLD", BaseAttributes | SFGAO_FILESYSANCESTOR | SFGAO_STORAGEANCESTOR, false }, + }; + + bool bFoundZipfldr = false; + + ULONG totalFetched = 0; + do + { + CComHeapPtr child; + ULONG celtFetched = 0; + ok_int(zipfldr_loaded(), bFoundZipfldr ? TRUE : FALSE); + hr = spEnum->Next(1, &child, &celtFetched); + if (hr != S_OK) + break; + ok_int(celtFetched, 1); + if (celtFetched != 1) + break; + + ok_int(zipfldr_loaded(), bFoundZipfldr ? TRUE : FALSE); + + LPCWSTR ExpectedName; + SFGAOF ExpectedAttributes; + FindExpectedFile(ExpectedFiles, RTL_NUMBER_OF(ExpectedFiles), spFolder, child, ExpectedName, ExpectedAttributes); + + totalFetched++; + + ok_displayname(spFolder, child, SHGDN_NORMAL, ExpectedName); + trace("Current: %S\n", ExpectedName); + + SFGAOF Attributes = SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER; + hr = spFolder->GetAttributesOf(1, &child, &Attributes); + if ((ExpectedAttributes & SFGAO_FILESYSANCESTOR)) + { + ok_int(zipfldr_loaded(), bFoundZipfldr ? TRUE : FALSE); + } + else + { + ok_int(zipfldr_loaded(), TRUE); + bFoundZipfldr = true; + } + /* Just keep the ones we are interested in */ + Attributes &= (SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | SFGAO_STORAGEANCESTOR); + ok_hr(hr, S_OK); + ok_hex(Attributes, ExpectedAttributes); + } while (true); + + ok_int(totalFetched, RTL_NUMBER_OF(ExpectedFiles)); + ok_hr(hr, S_FALSE); +} + + +START_TEST(EnumParentDir) +{ + HRESULT hr = CoInitialize(NULL); + + ok_hr(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + WCHAR TestFolder[MAX_PATH], TestFile[MAX_PATH], SubFolder[MAX_PATH]; + GetTempPathW(_countof(TestFolder), TestFolder); + PathAppendW(TestFolder, L"ZipDir"); + PathAddBackslashW(TestFolder); + + CreateDirectoryW(TestFolder, NULL); + + WCHAR ZipTestFile[MAX_PATH]; + if (!extract_resource(ZipTestFile, MAKEINTRESOURCEW(IDR_ZIP_TEST_FILE), TestFolder)) + { + RemoveDirectoryW(TestFolder); + return; + } + + StringCchPrintfW(TestFile, _countof(TestFile), L"%stest.txt", TestFolder); + + HANDLE hFile = CreateFileW(TestFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL); + + ok(hFile != INVALID_HANDLE_VALUE, "Error creating %S\n", TestFile); + if (hFile != INVALID_HANDLE_VALUE) + { + StringCchPrintfW(SubFolder, _countof(SubFolder), L"%sASUBFLD", TestFolder); + + CreateDirectoryW(SubFolder, NULL); + + test_EnumDirFiles(TestFolder); + test_EnumDirDirs(TestFolder); + + RemoveDirectoryW(SubFolder); + + CloseHandle(hFile); + } + + DeleteFileW(ZipTestFile); + RemoveDirectoryW(TestFolder); + CoUninitialize(); +} diff --git a/modules/rostests/apitests/zipfldr/IDataObject.cpp b/modules/rostests/apitests/zipfldr/IDataObject.cpp index ac2a7dfe4bc..b27730f6f50 100644 --- a/modules/rostests/apitests/zipfldr/IDataObject.cpp +++ b/modules/rostests/apitests/zipfldr/IDataObject.cpp @@ -36,11 +36,21 @@ static BOOL write_raw_file(const WCHAR* FileName, const void* Data, DWORD Size) return Success && (dwWritten == Size); } -BOOL extract_resource(WCHAR* Filename, LPCWSTR ResourceName) +BOOL extract_resource(WCHAR* Filename, LPCWSTR ResourceName, WCHAR* ParentFolder) { WCHAR workdir[MAX_PATH]; - GetTempPathW(_countof(workdir), workdir); - StringCchPrintfW(Filename, MAX_PATH, L"%sTMP%u.zip", workdir, GetTickCount() & 0xffff); + UINT TickMask = 0xffff; + if (!ParentFolder) + { + GetTempPathW(_countof(workdir), workdir); + ParentFolder = workdir; + } + else + { + // Fixed filename + TickMask = 0; + } + StringCchPrintfW(Filename, MAX_PATH, L"%sTMP%u.zip", ParentFolder, GetTickCount() & TickMask); HMODULE hMod = GetModuleHandleW(NULL); HRSRC hRsrc = FindResourceW(hMod, ResourceName, MAKEINTRESOURCEW(RT_RCDATA)); @@ -554,6 +564,9 @@ static void test_DataObject(const WCHAR* Filename) START_TEST(IDataObject) { + skip("Code in zipfldr not implemented yet\n"); + return; + HRESULT hr = CoInitialize(NULL); ok_hr(hr, S_OK); @@ -561,8 +574,9 @@ START_TEST(IDataObject) return; WCHAR ZipTestFile[MAX_PATH]; - if (!extract_resource(ZipTestFile, MAKEINTRESOURCEW(IDR_ZIP_TEST_FILE))) + if (!extract_resource(ZipTestFile, MAKEINTRESOURCEW(IDR_ZIP_TEST_FILE), NULL)) return; test_DataObject(ZipTestFile); DeleteFileW(ZipTestFile); + CoUninitialize(); } diff --git a/modules/rostests/apitests/zipfldr/precomp.h b/modules/rostests/apitests/zipfldr/precomp.h index 6af5f674709..62a683bb604 100644 --- a/modules/rostests/apitests/zipfldr/precomp.h +++ b/modules/rostests/apitests/zipfldr/precomp.h @@ -21,12 +21,14 @@ #include "resource.h" -BOOL extract_resource(WCHAR* Filename, LPCWSTR ResourceName); +BOOL extract_resource(WCHAR* Filename, LPCWSTR ResourceName, WCHAR* ParentFolder); #define InitializeShellFolder(Filename, pFolder) InitializeShellFolder_(__FILE__, __LINE__, Filename, pFolder) bool InitializeShellFolder_(const char* file, int line, const WCHAR* Filename, CComPtr& spFolder); #define IsFormatAdvertised(pDataObj, cfFormat, tymed) IsFormatAdvertised_(__FILE__, __LINE__, pDataObj, cfFormat, tymed) bool IsFormatAdvertised_(const char* file, int line, IDataObject* pDataObj, CLIPFORMAT cfFormat, TYMED tymed); +#define ok_displayname(pFolder, pidl, Flags, Name) ok_displayname_(__FILE__, __LINE__, pFolder, pidl, Flags, Name) +void ok_displayname_(const char* file, int line, IShellFolder* pFolder, PCUITEMID_CHILD pidl, SHGDNF Flags, LPCWSTR Name); #endif /* _ZIPFLDR_APITEST_PRECOMP_H_ */ diff --git a/modules/rostests/apitests/zipfldr/testlist.c b/modules/rostests/apitests/zipfldr/testlist.c index ecd1bb9d700..5f67cf4af85 100644 --- a/modules/rostests/apitests/zipfldr/testlist.c +++ b/modules/rostests/apitests/zipfldr/testlist.c @@ -2,11 +2,13 @@ #include extern void func_EnumObjects(void); +extern void func_EnumParentDir(void); extern void func_IDataObject(void); const struct test winetest_testlist[] = { { "EnumObjects", func_EnumObjects }, + { "EnumParentDir", func_EnumParentDir }, { "IDataObject", func_IDataObject }, { 0, 0 } };