/*++ Copyright (c) 1999 Microsoft Corporation Module Name: tree.c Abstract: Implements routines that do operations on entire trees Author: Jim Schmidt (jimschm) 08-Mar-2000 Revision History: --*/ #include "pch.h" // // Includes // // None #define DBG_TREE "Tree" // // Strings // // None // // Constants // // None // // Macros // // None // // Types // // None // // Globals // // None // // Macro expansion list // // None // // Private function prototypes // // None // // Macro expansion definition // // None // // Code // BOOL FiRemoveAllFilesInDirA ( IN PCSTR Dir ) { FILETREE_ENUMA e; PCSTR pattern; BOOL result = TRUE; pattern = ObsBuildEncodedObjectStringExA (Dir, "*", FALSE); if (EnumFirstFileInTreeExA (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) { do { SetFileAttributesA (e.NativeFullName, FILE_ATTRIBUTE_NORMAL); if (!DeleteFileA (e.NativeFullName)) { AbortEnumFileInTreeA (&e); result = FALSE; break; } } while (EnumNextFileInTreeA (&e)); } ObsFreeA (pattern); return result; } BOOL FiRemoveAllFilesInDirW ( IN PCWSTR Dir ) { FILETREE_ENUMW e; PCWSTR pattern; BOOL result = TRUE; pattern = ObsBuildEncodedObjectStringExW (Dir, L"*", FALSE); if (EnumFirstFileInTreeExW (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) { do { SetFileAttributesW (e.NativeFullName, FILE_ATTRIBUTE_NORMAL); if (!DeleteFileW (e.NativeFullName)) { AbortEnumFileInTreeW (&e); result = FALSE; break; } } while (EnumNextFileInTreeW (&e)); } ObsFreeW (pattern); return result; } BOOL FiRemoveAllFilesInTreeExA ( IN PCSTR Dir, IN BOOL RemoveRoot ) { FILETREE_ENUMA e; PCSTR pattern; BOOL result = TRUE; PSTR encodedStr; PCSTR dirPattern; encodedStr = DuplicatePathStringA (Dir, TcharCountA (Dir)); ObsEncodeStringExA (encodedStr, Dir, "^"); dirPattern = JoinPathsA (encodedStr, "*"); FreePathStringA (encodedStr); pattern = ObsBuildEncodedObjectStringExA (dirPattern, "*", FALSE); if (EnumFirstFileInTreeExA (&e, pattern, 0, TRUE, FALSE, FALSE, TRUE, FILEENUM_ALL_SUBLEVELS, FALSE, NULL)) { do { if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) { result = RemoveDirectoryA (e.NativeFullName); } else { SetFileAttributesA (e.NativeFullName, FILE_ATTRIBUTE_NORMAL); result = DeleteFileA (e.NativeFullName); } if (!result) { AbortEnumFileInTreeA (&e); break; } } while (EnumNextFileInTreeA (&e)); } if (result) { if (RemoveRoot) { result = RemoveDirectoryA (Dir); } } ObsFreeA (pattern); FreePathStringA (dirPattern); return result; } BOOL FiRemoveAllFilesInTreeExW ( IN PCWSTR Dir, IN BOOL RemoveRoot ) { FILETREE_ENUMW e; PCWSTR pattern; BOOL result = TRUE; PWSTR encodedStr; PCWSTR dirPattern; encodedStr = DuplicatePathStringW (Dir, TcharCountW (Dir)); ObsEncodeStringExW (encodedStr, Dir, L"^"); dirPattern = JoinPathsW (encodedStr, L"*"); FreePathStringW (encodedStr); pattern = ObsBuildEncodedObjectStringExW (dirPattern, L"*", FALSE); if (EnumFirstFileInTreeExW (&e, pattern, 0, TRUE, FALSE, FALSE, TRUE, FILEENUM_ALL_SUBLEVELS, FALSE, NULL)) { do { if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) { result = RemoveDirectoryW (e.NativeFullName); } else { SetFileAttributesW (e.NativeFullName, FILE_ATTRIBUTE_NORMAL); result = DeleteFileW (e.NativeFullName); } if (!result) { AbortEnumFileInTreeW (&e); break; } } while (EnumNextFileInTreeW (&e)); } if (result) { if (RemoveRoot) { result = RemoveDirectoryW (Dir); } } ObsFreeW (pattern); FreePathStringW (dirPattern); return result; } BOOL FiCopyAllFilesInDirExA ( IN PCSTR Source, IN PCSTR Dest, IN BOOL SkipExisting ) { FILETREE_ENUMA e; PCSTR pattern; BOOL result = TRUE; PCSTR subPath; PCSTR destPath; BOOL fileResult; pattern = ObsBuildEncodedObjectStringExA (Source, "*", FALSE); if (EnumFirstFileInTreeExA (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) { do { subPath = e.NativeFullName; subPath = (PCSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes); destPath = JoinPathsA (Dest, subPath); SetFileAttributesA (destPath, FILE_ATTRIBUTE_NORMAL); fileResult = CopyFileA (e.NativeFullName, destPath, SkipExisting); if (fileResult) { fileResult = SetFileAttributesA (destPath, e.Attributes); } FreePathStringA (destPath); if (!fileResult) { if ((!SkipExisting) || (GetLastError() != ERROR_FILE_EXISTS)) { result = FALSE; DEBUGMSGA ((DBG_WARNING, "Unable to copy %s", e.NativeFullName)); } } } while (EnumNextFileInTreeA (&e)); } ObsFreeA (pattern); return result; } BOOL FiCopyAllFilesInDirExW ( IN PCWSTR Source, IN PCWSTR Dest, IN BOOL SkipExisting ) { FILETREE_ENUMW e; PCWSTR pattern; BOOL result = TRUE; PCWSTR subPath; PCWSTR destPath; BOOL fileResult; pattern = ObsBuildEncodedObjectStringExW (Source, L"*", FALSE); if (EnumFirstFileInTreeExW (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) { do { subPath = e.NativeFullName; subPath = (PCWSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes); destPath = JoinPathsW (Dest, subPath); SetFileAttributesW (destPath, FILE_ATTRIBUTE_NORMAL); fileResult = CopyFileW (e.NativeFullName, destPath, SkipExisting); if (fileResult) { fileResult = SetFileAttributesW (destPath, e.Attributes); } FreePathStringW (destPath); if (!fileResult) { if ((!SkipExisting) || (GetLastError() != ERROR_FILE_EXISTS)) { result = FALSE; DEBUGMSGW ((DBG_WARNING, "Unable to copy %s", e.NativeFullName)); } } } while (EnumNextFileInTreeW (&e)); } ObsFreeW (pattern); return result; } BOOL FiCopyAllFilesInTreeExA ( IN PCSTR Source, IN PCSTR Dest, IN BOOL SkipExisting ) { FILETREE_ENUMA e; PCSTR pattern; BOOL result = TRUE; PCSTR dirPattern; PCSTR subPath; PCSTR destPath; BOOL fileResult; dirPattern = JoinPathsA (Source, "*"); pattern = ObsBuildEncodedObjectStringExA (dirPattern, "*", FALSE); if (EnumFirstFileInTreeExA ( &e, pattern, 0, // drive enum types TRUE, // enum containers TRUE, // containers first FALSE, // files first FALSE, // depth first FILEENUM_ALL_SUBLEVELS, // max sublevel FALSE, // use exclusions NULL // callback on error )) { do { subPath = e.NativeFullName; subPath = (PCSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes); destPath = JoinPathsA (Dest, subPath); if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) { fileResult = BfCreateDirectoryA (destPath); if (fileResult) { fileResult = SetFileAttributesA (destPath, e.Attributes); } } else { SetFileAttributesA (destPath, FILE_ATTRIBUTE_NORMAL); fileResult = CopyFileA (e.NativeFullName, destPath, SkipExisting); if (fileResult) { fileResult = SetFileAttributesA (destPath, e.Attributes); } } FreePathStringA (destPath); if (!fileResult) { if ((!SkipExisting) || (GetLastError() != ERROR_FILE_EXISTS)) { result = FALSE; DEBUGMSGA ((DBG_WARNING, "Unable to copy %s", e.NativeFullName)); } } } while (EnumNextFileInTreeA (&e)); } ObsFreeA (pattern); FreePathStringA (dirPattern); return result; } BOOL FiCopyAllFilesInTreeExW ( IN PCWSTR Source, IN PCWSTR Dest, IN BOOL SkipExisting ) { FILETREE_ENUMW e; PCWSTR pattern; BOOL result = TRUE; PCWSTR dirPattern; PCWSTR subPath; PCWSTR destPath; BOOL fileResult; dirPattern = JoinPathsW (Source, L"*"); pattern = ObsBuildEncodedObjectStringExW (dirPattern, L"*", FALSE); if (EnumFirstFileInTreeExW ( &e, pattern, 0, // drive enum types TRUE, // enum containers TRUE, // containers first FALSE, // files first FALSE, // depth first FILEENUM_ALL_SUBLEVELS, // max sublevel FALSE, // use exclusions NULL // callback on error )) { do { subPath = e.NativeFullName; subPath = (PCWSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes); destPath = JoinPathsW (Dest, subPath); if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) { fileResult = BfCreateDirectoryW (destPath); if (fileResult) { fileResult = SetFileAttributesW (destPath, e.Attributes); } } else { SetFileAttributesW (destPath, FILE_ATTRIBUTE_NORMAL); fileResult = CopyFileW (e.NativeFullName, destPath, SkipExisting); if (fileResult) { fileResult = SetFileAttributesW (destPath, e.Attributes); } } FreePathStringW (destPath); if (!fileResult) { if ((!SkipExisting) || (GetLastError() != ERROR_FILE_EXISTS)) { result = FALSE; DEBUGMSGW ((DBG_WARNING, "Unable to copy %s", e.NativeFullName)); } } } while (EnumNextFileInTreeW (&e)); } ObsFreeW (pattern); FreePathStringW (dirPattern); return result; }