HRESULT CFsFolderStat::Enumerate() { if (Progress) { RINOK(Progress->SetCompleted(NULL)); } Path.Add_PathSepar(); const unsigned len = Path.Len(); CEnumerator enumerator; enumerator.SetDirPrefix(Path); CFileInfo fi; while (enumerator.Next(fi)) { if (fi.IsDir()) { Path.DeleteFrom(len); Path += fi.Name; RINOK(Enumerate()); NumFolders++; } else { NumFiles++; Size += fi.Size; } } return S_OK; }
static HRESULT CopyFolder( CCopyState &state, const FString &srcPath, // without TAIL separator const FString &destPath) // without TAIL separator { RINOK(state.CallProgress()); if (IsDestChild(srcPath, destPath)) { RINOK(SendMessageError(state.Callback, state.MoveMode ? "can not copy folder onto itself" : "can not move folder onto itself" , destPath)); return E_ABORT; } if (state.MoveMode) { if (state.MoveFile_Sys(srcPath, destPath)) return S_OK; // MSDN: MoveFile() fails for dirs on different volumes. } if (!CreateComplexDir(destPath)) { RINOK(SendMessageError(state.Callback, "can not create folder", destPath)); return E_ABORT; } CEnumerator enumerator; enumerator.SetDirPrefix(CombinePath(srcPath, FString())); for (;;) { NFind::CFileInfo fi; bool found; if (!enumerator.Next(fi, found)) { SendLastErrorMessage(state.Callback, srcPath); return S_OK; } if (!found) break; const FString srcPath2 = CombinePath(srcPath, fi.Name); const FString destPath2 = CombinePath(destPath, fi.Name); if (fi.IsDir()) { RINOK(CopyFolder(state, srcPath2, destPath2)) } else { RINOK(CopyFile_Ask(state, srcPath2, fi, destPath2)); } } if (state.MoveMode) { if (!RemoveDir(srcPath)) { RINOK(SendMessageError(state.Callback, "can not remove folder", srcPath)); return E_ABORT; } } return S_OK; }
HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix) { unsigned startIndex = Folders.Size(); { CEnumerator enumerator; enumerator.SetDirPrefix(_path + relPrefix); CDirItem fi; fi.FolderStat_Defined = false; fi.NumFolders = 0; fi.NumFiles = 0; fi.Parent = dirItem; while (enumerator.Next(fi)) { if (fi.IsDir()) { fi.Size = 0; if (_flatMode) Folders.Add(relPrefix + fi.Name + FCHAR_PATH_SEPARATOR); } else { /* fi.PackSize_Defined = true; if (!MyGetCompressedFileSizeW(_path + relPrefix + fi.Name, fi.PackSize)) fi.PackSize = fi.Size; */ } #ifndef UNDER_CE fi.Reparse.Free(); fi.PackSize_Defined = false; #ifdef FS_SHOW_LINKS_INFO fi.FileInfo_Defined = false; fi.FileInfo_WasRequested = false; fi.FileIndex = 0; fi.NumLinks = 0; #endif fi.PackSize = fi.Size; if (fi.HasReparsePoint()) { fi.FileInfo_WasRequested = true; BY_HANDLE_FILE_INFORMATION info; NIO::GetReparseData(_path + relPrefix + fi.Name, fi.Reparse, &info); fi.NumLinks = info.nNumberOfLinks; fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; fi.FileInfo_Defined = true; } #endif /* unsigned fileIndex = */ Files.Add(fi); #if defined(_WIN32) && !defined(UNDER_CE) /* if (_scanAltStreams) { CStreamEnumerator enumerator(_path + relPrefix + fi.Name); CStreamInfo si; for (;;) { bool found; if (!enumerator.Next(si, found)) { // if (GetLastError() == ERROR_ACCESS_DENIED) // break; // return E_FAIL; break; } if (!found) break; if (si.IsMainStream()) continue; CAltStream ss; ss.Parent = fileIndex; ss.Name = si.GetReducedName(); ss.Size = si.Size; ss.PackSize_Defined = false; ss.PackSize = si.Size; Streams.Add(ss); } } */ #endif } } if (!_flatMode) return S_OK; unsigned endIndex = Folders.Size(); for (unsigned i = startIndex; i < endIndex; i++) LoadSubItems(i, Folders[i]); return S_OK; }