diff --git a/src/CaCommon/WixString.h b/src/CaCommon/WixString.h index eec47c7..f3408c4 100644 --- a/src/CaCommon/WixString.h +++ b/src/CaCommon/WixString.h @@ -37,18 +37,12 @@ class CWixString CWixString(CWixString&& other) noexcept { - _dwCapacity = other._dwCapacity; - _pTokenContext = other._pTokenContext; - _szObfuscated = other._szObfuscated; - _pS = other.Detach(); + MoveFrom(other); } CWixString& operator=(CWixString&& other) noexcept { - _dwCapacity = other._dwCapacity; - _pTokenContext = other._pTokenContext; - _szObfuscated = other._szObfuscated; - _pS = other.Detach(); + MoveFrom(other); return *this; } @@ -64,6 +58,22 @@ class CWixString return *this; } + void MoveFrom(CWixString& from) noexcept + { + if (this != &from) + { + Release(); + _dwCapacity = from._dwCapacity; + _pTokenContext = from._pTokenContext; + _szObfuscated = from._szObfuscated; + _pS = from._pS; + + from._pS = nullptr; + from._szObfuscated = nullptr; + from.Release(); + } + } + WCHAR& operator[](size_t i) { static WCHAR errChr = NULL; diff --git a/src/PanelSwCustomActions/FileEntry.cpp b/src/PanelSwCustomActions/FileEntry.cpp index d60ec25..5f7d2d2 100644 --- a/src/PanelSwCustomActions/FileEntry.cpp +++ b/src/PanelSwCustomActions/FileEntry.cpp @@ -109,6 +109,23 @@ CFileEntry::CFileEntry(const WIN32_FIND_DATA& findData, LPCWSTR szBasePath) } } +void CFileEntry::Release() noexcept +{ + _dwFileAttributes = INVALID_FILE_ATTRIBUTES; + _ftLastAccessTime.dwLowDateTime = 0; + _ftLastAccessTime.dwHighDateTime = 0; + _ftCreationTime.dwLowDateTime = 0; + _ftCreationTime.dwHighDateTime = 0; + _ftLastWriteTime.dwLowDateTime = 0; + _ftLastWriteTime.dwHighDateTime = 0; + + _ulFileSize.QuadPart = 0; + _dwReserved0 = 0; + _szPath.Release(); + _szFileName.Release(); + _szParentPath.Release(); +} + CFileEntry::CFileEntry(const CFileEntry& other) { HRESULT hr = S_OK; @@ -138,15 +155,7 @@ CFileEntry::CFileEntry(const CFileEntry& other) CFileEntry::CFileEntry(CFileEntry&& other) noexcept { - _szPath.Attach(other._szPath.Detach()); - _szParentPath.Attach(other._szParentPath.Detach()); - _szFileName.Attach(other._szFileName.Detach()); - _dwFileAttributes = other._dwFileAttributes; - _ftCreationTime = other._ftCreationTime; - _ftLastAccessTime = other._ftLastAccessTime; - _ftLastWriteTime = other._ftLastWriteTime; - _ulFileSize = other._ulFileSize; - _dwReserved0 = other._dwReserved0; + MoveFrom(other); } CFileEntry& CFileEntry::operator=(CFileEntry& other) @@ -180,18 +189,28 @@ CFileEntry& CFileEntry::operator=(CFileEntry& other) CFileEntry& CFileEntry::operator=(CFileEntry&& other) noexcept { - _szPath.Attach(other._szPath.Detach()); - _szParentPath.Attach(other._szParentPath.Detach()); - _szFileName.Attach(other._szFileName.Detach()); - _dwFileAttributes = other._dwFileAttributes; - _ftCreationTime = other._ftCreationTime; - _ftLastAccessTime = other._ftLastAccessTime; - _ftLastWriteTime = other._ftLastWriteTime; - _ulFileSize = other._ulFileSize; - _dwReserved0 = other._dwReserved0; + MoveFrom(other); return *this; } +void CFileEntry::MoveFrom(CFileEntry& other) noexcept +{ + if (this != &other) + { + Release(); + _szPath.MoveFrom(other._szPath); + _szParentPath.MoveFrom(other._szParentPath); + _szFileName.MoveFrom(other._szFileName); + _dwFileAttributes = other._dwFileAttributes; + _ftCreationTime = other._ftCreationTime; + _ftLastAccessTime = other._ftLastAccessTime; + _ftLastWriteTime = other._ftLastWriteTime; + _ulFileSize = other._ulFileSize; + _dwReserved0 = other._dwReserved0; + other.Release(); + } +} + DWORD CFileEntry::Attributes() const { return _dwFileAttributes; diff --git a/src/PanelSwCustomActions/FileEntry.h b/src/PanelSwCustomActions/FileEntry.h index 16b3b7a..1578179 100644 --- a/src/PanelSwCustomActions/FileEntry.h +++ b/src/PanelSwCustomActions/FileEntry.h @@ -15,6 +15,9 @@ class CFileEntry CFileEntry& operator=(CFileEntry& other); CFileEntry& operator=(CFileEntry&& other) noexcept; + void Release() noexcept; + void MoveFrom(CFileEntry& other) noexcept; + // Attribute tests DWORD Attributes() const; bool IsValid() const; diff --git a/src/PanelSwCustomActions/FileIterator.cpp b/src/PanelSwCustomActions/FileIterator.cpp index 71e5926..40ebdc8 100644 --- a/src/PanelSwCustomActions/FileIterator.cpp +++ b/src/PanelSwCustomActions/FileIterator.cpp @@ -32,6 +32,8 @@ CFileEntry CFileIterator::Find(LPCWSTR szBasePath, LPCWSTR szPattern, bool bRecu Release(); DWORD dwAttributes = INVALID_FILE_ATTRIBUTES; CWixString szBasePattern; + bool bSkip = true; + CFileEntry entry = CFileEntry::InvalidFileEntry(); _hrStatus = _szBasePath.Copy(szBasePath); ExitOnFailure(_hrStatus, "Failed to copy string"); @@ -45,7 +47,7 @@ CFileEntry CFileIterator::Find(LPCWSTR szBasePath, LPCWSTR szPattern, bool bRecu _hrStatus = _szPattern.Copy(szPattern); ExitOnFailure(_hrStatus, "Failed to copy string"); } - + _bRecursive = bRecursive; _bIncludeSelf = bIncludeSelf; @@ -62,7 +64,12 @@ CFileEntry CFileIterator::Find(LPCWSTR szBasePath, LPCWSTR szPattern, bool bRecu ExitOnWin32Error(dwError, _hrStatus, "Failed to find files in '%ls'", szBasePath); } - return ProcessFindData(); + entry = ProcessFindData(&bSkip); + if (bSkip) + { + return Next(); + } + return entry; LExit: return CFileEntry::InvalidFileEntry(); @@ -70,73 +77,87 @@ CFileEntry CFileIterator::Find(LPCWSTR szBasePath, LPCWSTR szPattern, bool bRecu CFileEntry CFileIterator::Next() { - // Sub dir is enumerating? - if (_pCurrSubDir) + CFileEntry entry = CFileEntry::InvalidFileEntry(); + + while (true) { - HRESULT hrSubDir = S_OK; - // First entry of the subdir? - if (_pCurrSubDir->_szBasePath.IsNullOrEmpty()) + bool bSkip = false; + + // Sub dir is enumerating? + if (_pCurrSubDir) { - CWixString szSubDirPath; + HRESULT hrSubDir = S_OK; + // First entry of the subdir? + if (_pCurrSubDir->_szBasePath.IsNullOrEmpty()) + { + CWixString szSubDirPath; - _hrStatus = szSubDirPath.AppnedFormat(L"%ls\\%ls", (LPCWSTR)_szBasePath, _findData.cFileName); - ExitOnFailure(_hrStatus, "Failed to format fodler path"); + _hrStatus = szSubDirPath.AppnedFormat(L"%ls\\%ls", (LPCWSTR)_szBasePath, _findData.cFileName); + ExitOnFailure(_hrStatus, "Failed to format fodler path"); - CFileEntry entry = _pCurrSubDir->Find((LPCWSTR)szSubDirPath, _szPattern, _bRecursive, false); - hrSubDir = _pCurrSubDir->Status(); - if (SUCCEEDED(hrSubDir)) + CFileEntry entry = _pCurrSubDir->Find((LPCWSTR)szSubDirPath, _szPattern, _bRecursive, false); + hrSubDir = _pCurrSubDir->Status(); + if (SUCCEEDED(hrSubDir)) + { + return entry; + } + } + else { - return entry; + CFileEntry entry = _pCurrSubDir->Next(); + hrSubDir = _pCurrSubDir->Status(); + if (SUCCEEDED(hrSubDir)) + { + return entry; + } } - } - else - { - CFileEntry entry = _pCurrSubDir->Next(); - hrSubDir = _pCurrSubDir->Status(); - if (SUCCEEDED(hrSubDir)) + + delete _pCurrSubDir; + _pCurrSubDir = nullptr; + + // Bad failure + if (hrSubDir != E_NOMOREFILES) { - return entry; + _hrStatus = hrSubDir; + ExitOnFailure(_hrStatus, "Failed to enumerate entries in %ls\\%ls", (LPCWSTR)_szBasePath, _findData.cFileName); } } - delete _pCurrSubDir; - _pCurrSubDir = nullptr; - - // Bad failure - if (hrSubDir != E_NOMOREFILES) + if (!::FindNextFile(_hFind, &_findData)) { - _hrStatus = hrSubDir; - ExitOnFailure(_hrStatus, "Failed to enumerate entries in %ls\\%ls", (LPCWSTR)_szBasePath, _findData.cFileName); + _hrStatus = HRESULT_FROM_WIN32(::GetLastError()); + if (_hrStatus == E_NOMOREFILES) + { + return CFileEntry::InvalidFileEntry(); + } + + ExitOnFailure(_hrStatus, "Failed to find next entry in %ls", (LPCWSTR)_szBasePath); } - } - if (!::FindNextFile(_hFind, &_findData)) - { - _hrStatus = HRESULT_FROM_WIN32(::GetLastError()); - if (_hrStatus == E_NOMOREFILES) + entry = ProcessFindData(&bSkip); + if (!bSkip) { - return CFileEntry::InvalidFileEntry(); + return entry; } - - ExitOnFailure(_hrStatus, "Failed to find next entry in %ls", (LPCWSTR)_szBasePath); } - return ProcessFindData(); - LExit: return CFileEntry::InvalidFileEntry(); } -CFileEntry CFileIterator::ProcessFindData() +CFileEntry CFileIterator::ProcessFindData(bool* pbSkip) { + *pbSkip = false; + if (_bIncludeSelf && (wcscmp(_findData.cFileName, L".") == 0)) { CFileEntry entry(_findData, (LPCWSTR)_szBasePath); - return ProcessEntry(entry); + return ProcessEntry(entry, pbSkip); } if ((wcscmp(_findData.cFileName, L".") == 0) || (wcscmp(_findData.cFileName, L"..") == 0)) { - return Next(); + *pbSkip = true; + return CFileEntry::InvalidFileEntry(); } // File? @@ -145,11 +166,12 @@ CFileEntry CFileIterator::ProcessFindData() // Skip files that don't match the wildcard pattern if (_szPattern.IsNullOrEmpty() || !::PathMatchSpec(_findData.cFileName, _szPattern)) { - return Next(); + *pbSkip = true; + return CFileEntry::InvalidFileEntry(); } CFileEntry entry(_findData, (LPCWSTR)_szBasePath); - return ProcessEntry(entry); + return ProcessEntry(entry, pbSkip); } // Skip symlink folders if (CFileEntry::IsSymlink(_findData.dwFileAttributes, _findData.dwReserved0)) @@ -157,12 +179,13 @@ CFileEntry CFileIterator::ProcessFindData() // Skip files that don't match the wildcard pattern if (_szPattern.IsNullOrEmpty() || !::PathMatchSpec(_findData.cFileName, _szPattern)) { - return Next(); + *pbSkip = true; + return CFileEntry::InvalidFileEntry(); } WcaLog(LOGLEVEL::LOGMSG_STANDARD, "Skipping files under symbolic link folder '%ls\\%ls'", (LPCWSTR)_szBasePath, _findData.cFileName); CFileEntry entry(_findData, (LPCWSTR)_szBasePath); - return ProcessEntry(entry); + return ProcessEntry(entry, pbSkip); } // Skip mount folders if (CFileEntry::IsMountPoint(_findData.dwFileAttributes, _findData.dwReserved0)) @@ -170,12 +193,13 @@ CFileEntry CFileIterator::ProcessFindData() // Skip files that don't match the wildcard pattern if (_szPattern.IsNullOrEmpty() || !::PathMatchSpec(_findData.cFileName, _szPattern)) { - return Next(); + *pbSkip = true; + return CFileEntry::InvalidFileEntry(); } WcaLog(LOGLEVEL::LOGMSG_STANDARD, "Skipping files under mount point folder '%ls\\%ls'", (LPCWSTR)_szBasePath, _findData.cFileName); CFileEntry entry(_findData, (LPCWSTR)_szBasePath); - return ProcessEntry(entry); + return ProcessEntry(entry, pbSkip); } // Return the subfolder name too? @@ -189,16 +213,17 @@ CFileEntry CFileIterator::ProcessFindData() } CFileEntry entry(_findData, (LPCWSTR)_szBasePath); - return ProcessEntry(entry); + return ProcessEntry(entry, pbSkip); } - return Next(); + *pbSkip = true; + return CFileEntry::InvalidFileEntry(); LExit: return CFileEntry::InvalidFileEntry(); } -CFileEntry CFileIterator::ProcessEntry(CFileEntry entry) +CFileEntry CFileIterator::ProcessEntry(CFileEntry entry, bool* pbSkip) { if (entry.IsValid()) { @@ -212,7 +237,8 @@ CFileEntry CFileIterator::ProcessEntry(CFileEntry entry) delete _pCurrSubDir; _pCurrSubDir = nullptr; - return Next(); + *pbSkip = true; + return CFileEntry::InvalidFileEntry(); } if (FAILED(_pCurrSubDir->Status())) diff --git a/src/PanelSwCustomActions/FileIterator.h b/src/PanelSwCustomActions/FileIterator.h index a94d742..ecd7b32 100644 --- a/src/PanelSwCustomActions/FileIterator.h +++ b/src/PanelSwCustomActions/FileIterator.h @@ -22,8 +22,8 @@ class CFileIterator private: CFileEntry Find(LPCWSTR szBasePath, LPCWSTR szPattern, bool bRecursive, bool bIncludeSelf); - CFileEntry ProcessFindData(); - CFileEntry ProcessEntry(CFileEntry entry); + CFileEntry ProcessFindData(bool * pbSkip); + CFileEntry ProcessEntry(CFileEntry entry, bool* pbSkip); HANDLE _hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA _findData = {}; diff --git a/src/TidyBuild.custom.props b/src/TidyBuild.custom.props index e3b65ae..4911ece 100644 --- a/src/TidyBuild.custom.props +++ b/src/TidyBuild.custom.props @@ -2,7 +2,7 @@ - 3.23.0 + 3.23.1 $(FullVersion).$(GITHUB_RUN_NUMBER) PanelSwWixExtension Panel::Software