Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
11 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. tree.c
  5. Abstract:
  6. Implements routines that do operations on entire trees
  7. Author:
  8. Jim Schmidt (jimschm) 08-Mar-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "pch.h"
  13. //
  14. // Includes
  15. //
  16. // None
  17. #define DBG_TREE "Tree"
  18. //
  19. // Strings
  20. //
  21. // None
  22. //
  23. // Constants
  24. //
  25. // None
  26. //
  27. // Macros
  28. //
  29. // None
  30. //
  31. // Types
  32. //
  33. // None
  34. //
  35. // Globals
  36. //
  37. // None
  38. //
  39. // Macro expansion list
  40. //
  41. // None
  42. //
  43. // Private function prototypes
  44. //
  45. // None
  46. //
  47. // Macro expansion definition
  48. //
  49. // None
  50. //
  51. // Code
  52. //
  53. BOOL
  54. FiRemoveAllFilesInDirA (
  55. IN PCSTR Dir
  56. )
  57. {
  58. FILETREE_ENUMA e;
  59. PCSTR pattern;
  60. BOOL result = TRUE;
  61. pattern = ObsBuildEncodedObjectStringExA (Dir, "*", FALSE);
  62. if (EnumFirstFileInTreeExA (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) {
  63. do {
  64. SetFileAttributesA (e.NativeFullName, FILE_ATTRIBUTE_NORMAL);
  65. if (!DeleteFileA (e.NativeFullName)) {
  66. AbortEnumFileInTreeA (&e);
  67. result = FALSE;
  68. break;
  69. }
  70. } while (EnumNextFileInTreeA (&e));
  71. }
  72. ObsFreeA (pattern);
  73. return result;
  74. }
  75. BOOL
  76. FiRemoveAllFilesInDirW (
  77. IN PCWSTR Dir
  78. )
  79. {
  80. FILETREE_ENUMW e;
  81. PCWSTR pattern;
  82. BOOL result = TRUE;
  83. pattern = ObsBuildEncodedObjectStringExW (Dir, L"*", FALSE);
  84. if (EnumFirstFileInTreeExW (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) {
  85. do {
  86. SetFileAttributesW (e.NativeFullName, FILE_ATTRIBUTE_NORMAL);
  87. if (!DeleteFileW (e.NativeFullName)) {
  88. AbortEnumFileInTreeW (&e);
  89. result = FALSE;
  90. break;
  91. }
  92. } while (EnumNextFileInTreeW (&e));
  93. }
  94. ObsFreeW (pattern);
  95. return result;
  96. }
  97. BOOL
  98. FiRemoveAllFilesInTreeExA (
  99. IN PCSTR Dir,
  100. IN BOOL RemoveRoot
  101. )
  102. {
  103. FILETREE_ENUMA e;
  104. PCSTR pattern;
  105. BOOL result = TRUE;
  106. PSTR encodedStr;
  107. PCSTR dirPattern;
  108. encodedStr = DuplicatePathStringA (Dir, TcharCountA (Dir));
  109. ObsEncodeStringExA (encodedStr, Dir, "^");
  110. dirPattern = JoinPathsA (encodedStr, "*");
  111. FreePathStringA (encodedStr);
  112. pattern = ObsBuildEncodedObjectStringExA (dirPattern, "*", FALSE);
  113. if (EnumFirstFileInTreeExA (&e, pattern, 0, TRUE, FALSE, FALSE, TRUE, FILEENUM_ALL_SUBLEVELS, FALSE, NULL)) {
  114. do {
  115. if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) {
  116. result = RemoveDirectoryA (e.NativeFullName);
  117. } else {
  118. SetFileAttributesA (e.NativeFullName, FILE_ATTRIBUTE_NORMAL);
  119. result = DeleteFileA (e.NativeFullName);
  120. }
  121. if (!result) {
  122. AbortEnumFileInTreeA (&e);
  123. break;
  124. }
  125. } while (EnumNextFileInTreeA (&e));
  126. }
  127. if (result) {
  128. if (RemoveRoot) {
  129. result = RemoveDirectoryA (Dir);
  130. }
  131. }
  132. ObsFreeA (pattern);
  133. FreePathStringA (dirPattern);
  134. return result;
  135. }
  136. BOOL
  137. FiRemoveAllFilesInTreeExW (
  138. IN PCWSTR Dir,
  139. IN BOOL RemoveRoot
  140. )
  141. {
  142. FILETREE_ENUMW e;
  143. PCWSTR pattern;
  144. BOOL result = TRUE;
  145. PWSTR encodedStr;
  146. PCWSTR dirPattern;
  147. encodedStr = DuplicatePathStringW (Dir, TcharCountW (Dir));
  148. ObsEncodeStringExW (encodedStr, Dir, L"^");
  149. dirPattern = JoinPathsW (encodedStr, L"*");
  150. FreePathStringW (encodedStr);
  151. pattern = ObsBuildEncodedObjectStringExW (dirPattern, L"*", FALSE);
  152. if (EnumFirstFileInTreeExW (&e, pattern, 0, TRUE, FALSE, FALSE, TRUE, FILEENUM_ALL_SUBLEVELS, FALSE, NULL)) {
  153. do {
  154. if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) {
  155. result = RemoveDirectoryW (e.NativeFullName);
  156. } else {
  157. SetFileAttributesW (e.NativeFullName, FILE_ATTRIBUTE_NORMAL);
  158. result = DeleteFileW (e.NativeFullName);
  159. }
  160. if (!result) {
  161. AbortEnumFileInTreeW (&e);
  162. break;
  163. }
  164. } while (EnumNextFileInTreeW (&e));
  165. }
  166. if (result) {
  167. if (RemoveRoot) {
  168. result = RemoveDirectoryW (Dir);
  169. }
  170. }
  171. ObsFreeW (pattern);
  172. FreePathStringW (dirPattern);
  173. return result;
  174. }
  175. BOOL
  176. FiCopyAllFilesInDirExA (
  177. IN PCSTR Source,
  178. IN PCSTR Dest,
  179. IN BOOL SkipExisting
  180. )
  181. {
  182. FILETREE_ENUMA e;
  183. PCSTR pattern;
  184. BOOL result = TRUE;
  185. PCSTR subPath;
  186. PCSTR destPath;
  187. BOOL fileResult;
  188. pattern = ObsBuildEncodedObjectStringExA (Source, "*", FALSE);
  189. if (EnumFirstFileInTreeExA (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) {
  190. do {
  191. subPath = e.NativeFullName;
  192. subPath = (PCSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes);
  193. destPath = JoinPathsA (Dest, subPath);
  194. SetFileAttributesA (destPath, FILE_ATTRIBUTE_NORMAL);
  195. fileResult = CopyFileA (e.NativeFullName, destPath, SkipExisting);
  196. if (fileResult) {
  197. fileResult = SetFileAttributesA (destPath, e.Attributes);
  198. }
  199. FreePathStringA (destPath);
  200. if (!fileResult) {
  201. if ((!SkipExisting) ||
  202. (GetLastError() != ERROR_FILE_EXISTS)) {
  203. result = FALSE;
  204. DEBUGMSGA ((DBG_WARNING, "Unable to copy %s", e.NativeFullName));
  205. }
  206. }
  207. } while (EnumNextFileInTreeA (&e));
  208. }
  209. ObsFreeA (pattern);
  210. return result;
  211. }
  212. BOOL
  213. FiCopyAllFilesInDirExW (
  214. IN PCWSTR Source,
  215. IN PCWSTR Dest,
  216. IN BOOL SkipExisting
  217. )
  218. {
  219. FILETREE_ENUMW e;
  220. PCWSTR pattern;
  221. BOOL result = TRUE;
  222. PCWSTR subPath;
  223. PCWSTR destPath;
  224. BOOL fileResult;
  225. pattern = ObsBuildEncodedObjectStringExW (Source, L"*", FALSE);
  226. if (EnumFirstFileInTreeExW (&e, pattern, 0, FALSE, FALSE, TRUE, TRUE, 1, FALSE, NULL)) {
  227. do {
  228. subPath = e.NativeFullName;
  229. subPath = (PCWSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes);
  230. destPath = JoinPathsW (Dest, subPath);
  231. SetFileAttributesW (destPath, FILE_ATTRIBUTE_NORMAL);
  232. fileResult = CopyFileW (e.NativeFullName, destPath, SkipExisting);
  233. if (fileResult) {
  234. fileResult = SetFileAttributesW (destPath, e.Attributes);
  235. }
  236. FreePathStringW (destPath);
  237. if (!fileResult) {
  238. if ((!SkipExisting) ||
  239. (GetLastError() != ERROR_FILE_EXISTS)) {
  240. result = FALSE;
  241. DEBUGMSGW ((DBG_WARNING, "Unable to copy %s", e.NativeFullName));
  242. }
  243. }
  244. } while (EnumNextFileInTreeW (&e));
  245. }
  246. ObsFreeW (pattern);
  247. return result;
  248. }
  249. BOOL
  250. FiCopyAllFilesInTreeExA (
  251. IN PCSTR Source,
  252. IN PCSTR Dest,
  253. IN BOOL SkipExisting
  254. )
  255. {
  256. FILETREE_ENUMA e;
  257. PCSTR pattern;
  258. BOOL result = TRUE;
  259. PCSTR dirPattern;
  260. PCSTR subPath;
  261. PCSTR destPath;
  262. BOOL fileResult;
  263. dirPattern = JoinPathsA (Source, "*");
  264. pattern = ObsBuildEncodedObjectStringExA (dirPattern, "*", FALSE);
  265. if (EnumFirstFileInTreeExA (
  266. &e,
  267. pattern,
  268. 0, // drive enum types
  269. TRUE, // enum containers
  270. TRUE, // containers first
  271. FALSE, // files first
  272. FALSE, // depth first
  273. FILEENUM_ALL_SUBLEVELS, // max sublevel
  274. FALSE, // use exclusions
  275. NULL // callback on error
  276. )) {
  277. do {
  278. subPath = e.NativeFullName;
  279. subPath = (PCSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes);
  280. destPath = JoinPathsA (Dest, subPath);
  281. if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) {
  282. fileResult = BfCreateDirectoryA (destPath);
  283. if (fileResult) {
  284. fileResult = SetFileAttributesA (destPath, e.Attributes);
  285. }
  286. } else {
  287. SetFileAttributesA (destPath, FILE_ATTRIBUTE_NORMAL);
  288. fileResult = CopyFileA (e.NativeFullName, destPath, SkipExisting);
  289. if (fileResult) {
  290. fileResult = SetFileAttributesA (destPath, e.Attributes);
  291. }
  292. }
  293. FreePathStringA (destPath);
  294. if (!fileResult) {
  295. if ((!SkipExisting) ||
  296. (GetLastError() != ERROR_FILE_EXISTS)) {
  297. result = FALSE;
  298. DEBUGMSGA ((DBG_WARNING, "Unable to copy %s", e.NativeFullName));
  299. }
  300. }
  301. } while (EnumNextFileInTreeA (&e));
  302. }
  303. ObsFreeA (pattern);
  304. FreePathStringA (dirPattern);
  305. return result;
  306. }
  307. BOOL
  308. FiCopyAllFilesInTreeExW (
  309. IN PCWSTR Source,
  310. IN PCWSTR Dest,
  311. IN BOOL SkipExisting
  312. )
  313. {
  314. FILETREE_ENUMW e;
  315. PCWSTR pattern;
  316. BOOL result = TRUE;
  317. PCWSTR dirPattern;
  318. PCWSTR subPath;
  319. PCWSTR destPath;
  320. BOOL fileResult;
  321. dirPattern = JoinPathsW (Source, L"*");
  322. pattern = ObsBuildEncodedObjectStringExW (dirPattern, L"*", FALSE);
  323. if (EnumFirstFileInTreeExW (
  324. &e,
  325. pattern,
  326. 0, // drive enum types
  327. TRUE, // enum containers
  328. TRUE, // containers first
  329. FALSE, // files first
  330. FALSE, // depth first
  331. FILEENUM_ALL_SUBLEVELS, // max sublevel
  332. FALSE, // use exclusions
  333. NULL // callback on error
  334. )) {
  335. do {
  336. subPath = e.NativeFullName;
  337. subPath = (PCWSTR) ((PBYTE) subPath + e.FileEnumInfo.PathPattern->ExactRootBytes);
  338. destPath = JoinPathsW (Dest, subPath);
  339. if (e.Attributes & FILE_ATTRIBUTE_DIRECTORY) {
  340. fileResult = BfCreateDirectoryW (destPath);
  341. if (fileResult) {
  342. fileResult = SetFileAttributesW (destPath, e.Attributes);
  343. }
  344. } else {
  345. SetFileAttributesW (destPath, FILE_ATTRIBUTE_NORMAL);
  346. fileResult = CopyFileW (e.NativeFullName, destPath, SkipExisting);
  347. if (fileResult) {
  348. fileResult = SetFileAttributesW (destPath, e.Attributes);
  349. }
  350. }
  351. FreePathStringW (destPath);
  352. if (!fileResult) {
  353. if ((!SkipExisting) ||
  354. (GetLastError() != ERROR_FILE_EXISTS)) {
  355. result = FALSE;
  356. DEBUGMSGW ((DBG_WARNING, "Unable to copy %s", e.NativeFullName));
  357. }
  358. }
  359. } while (EnumNextFileInTreeW (&e));
  360. }
  361. ObsFreeW (pattern);
  362. FreePathStringW (dirPattern);
  363. return result;
  364. }