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.

313 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. killfile.c
  5. Abstract:
  6. Performs a test of the file enumeration code.
  7. Author:
  8. Jim Schmidt (jimschm) 14-Jan-1998
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "pch.h"
  13. BOOL
  14. pKillEverything (
  15. PCTSTR Pattern,
  16. BOOL Root
  17. );
  18. UINT g_Dirs, g_Files;
  19. VOID
  20. HelpAndExit (
  21. VOID
  22. )
  23. {
  24. printf ("Command line syntax:\n\n"
  25. "kf [-sf|-sd|-s] [-l] <pattern>\n\n"
  26. "<pattern> Specifies pattern of file(s) or dir(s)\n"
  27. "\n"
  28. "Options:\n"
  29. "\n"
  30. "-sf Search all subdirs for matching files, then kill them\n"
  31. "-sd Search all subdirs for matching dirs, then kill them\n"
  32. "-s Kill all matches of <pattern> in any subdir\n"
  33. "-l List kill candidates; don't kill them\n"
  34. );
  35. exit(0);
  36. }
  37. HANDLE g_hHeap;
  38. HINSTANCE g_hInst;
  39. BOOL g_DeleteFile = TRUE;
  40. BOOL g_DeleteDir = FALSE;
  41. BOOL g_Recursive = FALSE;
  42. BOOL g_ListOnly = FALSE;
  43. INT
  44. __cdecl
  45. _tmain (
  46. INT argc,
  47. TCHAR *argv[]
  48. )
  49. {
  50. PCTSTR Pattern = NULL;
  51. PCTSTR FilePattern = NULL;
  52. INT i;
  53. DWORD d;
  54. BOOL DefaultOptions = TRUE;
  55. g_hHeap = GetProcessHeap();
  56. for (i = 1 ; i < argc ; i++) {
  57. if (argv[i][0] == TEXT('-') || argv[i][0] == TEXT('/')) {
  58. switch (_totlower (argv[i][1])) {
  59. case TEXT('s'):
  60. if (g_Recursive) {
  61. HelpAndExit();
  62. }
  63. g_Recursive = TRUE;
  64. switch (_totlower (argv[i][2])) {
  65. case TEXT('f'):
  66. g_DeleteFile = TRUE;
  67. g_DeleteDir = FALSE;
  68. DefaultOptions = FALSE;
  69. break;
  70. case TEXT('d'):
  71. g_DeleteFile = FALSE;
  72. g_DeleteDir = TRUE;
  73. DefaultOptions = FALSE;
  74. break;
  75. case 0:
  76. g_DeleteFile = TRUE;
  77. g_DeleteDir = TRUE;
  78. DefaultOptions = FALSE;
  79. break;
  80. default:
  81. HelpAndExit();
  82. }
  83. break;
  84. case TEXT('l'):
  85. g_ListOnly = TRUE;
  86. break;
  87. default:
  88. HelpAndExit();
  89. }
  90. }
  91. else if (Pattern) {
  92. HelpAndExit();
  93. }
  94. else {
  95. Pattern = argv[i];
  96. }
  97. }
  98. if (!Pattern || !Pattern[0]) {
  99. HelpAndExit();
  100. }
  101. d = GetFileAttributes (Pattern);
  102. if (d != INVALID_ATTRIBUTES && (d & FILE_ATTRIBUTE_DIRECTORY)) {
  103. if (DefaultOptions) {
  104. g_DeleteDir = TRUE;
  105. }
  106. }
  107. pKillEverything (Pattern, TRUE);
  108. printf ("\nFiles: %u Dirs: %u\n\n", g_Files, g_Dirs);
  109. return 0;
  110. }
  111. BOOL
  112. pKillPattern (
  113. PCTSTR Pattern
  114. )
  115. {
  116. FILE_ENUM e;
  117. TCHAR CurrentDir[MAX_TCHAR_PATH];
  118. GetCurrentDirectory (MAX_TCHAR_PATH, CurrentDir);
  119. if (EnumFirstFile (&e, CurrentDir, Pattern)) {
  120. do {
  121. if (e.Directory && !g_DeleteDir) {
  122. continue;
  123. }
  124. if (!e.Directory && !g_DeleteFile) {
  125. continue;
  126. }
  127. if (e.Directory) {
  128. g_Dirs++;
  129. } else {
  130. g_Files++;
  131. }
  132. if (g_ListOnly) {
  133. _tprintf (TEXT("%s\n"), e.FullPath);
  134. } else {
  135. SetCurrentDirectory (CurrentDir);
  136. SetFileAttributes (e.FullPath, FILE_ATTRIBUTE_NORMAL);
  137. if (e.Directory) {
  138. if (!RemoveCompleteDirectory (e.FullPath)) {
  139. _tprintf (TEXT("Can't kill directory %s, GLE=%u\n"), e.FullPath, GetLastError());
  140. }
  141. } else if (!DeleteFile (e.FullPath)) {
  142. _tprintf (TEXT("Can't kill %s, GLE=%u\n"), e.FullPath, GetLastError());
  143. }
  144. }
  145. } while (EnumNextFile (&e));
  146. }
  147. SetCurrentDirectory (CurrentDir);
  148. return TRUE;
  149. }
  150. BOOL
  151. pKillEverything (
  152. PCTSTR Pattern,
  153. BOOL Root
  154. )
  155. {
  156. TCHAR FilePattern[MAX_TCHAR_PATH];
  157. TCHAR SubPattern[MAX_TCHAR_PATH];
  158. TCHAR CurrentDir[MAX_TCHAR_PATH];
  159. PCTSTR p;
  160. PCTSTR q;
  161. PCTSTR NextPattern;
  162. FILE_ENUM e;
  163. DWORD d;
  164. TCHAR c = TEXT('\\');
  165. GetCurrentDirectory (MAX_TCHAR_PATH, CurrentDir);
  166. if (!Pattern || !Pattern[0]) {
  167. lstrcpy (FilePattern, TEXT("*.*"));
  168. NextPattern = NULL;
  169. } else {
  170. p = _tcschr (Pattern, TEXT('\\'));
  171. if (!p) {
  172. p = GetEndOfString (Pattern);
  173. } else {
  174. q = _tcschr (Pattern, TEXT(':'));
  175. if (q && p > q) {
  176. if (Root) {
  177. p++;
  178. c = 0;
  179. } else {
  180. _tprintf (TEXT("Pattern is bad: %s\n"), Pattern);
  181. return FALSE;
  182. }
  183. } else if (p == Pattern) {
  184. if (Root) {
  185. p++;
  186. c = 0;
  187. } else {
  188. _tprintf (TEXT("Pattern is bad: %s\n"), Pattern);
  189. return FALSE;
  190. }
  191. }
  192. }
  193. StringCopyAB (FilePattern, Pattern, p);
  194. if (*p) {
  195. NextPattern = p;
  196. if (*NextPattern == c) {
  197. NextPattern++;
  198. }
  199. } else {
  200. NextPattern = NULL;
  201. }
  202. }
  203. //
  204. // If NextPattern is NULL, then we must delete this pattern
  205. //
  206. if (!NextPattern) {
  207. if (g_Recursive) {
  208. wsprintf (SubPattern, TEXT("*.*\\%s"), Pattern);
  209. if (!pKillEverything (SubPattern, FALSE)) {
  210. return FALSE;
  211. }
  212. }
  213. pKillPattern (Pattern);
  214. }
  215. //
  216. // Otherwise we enumerate the files and dirs at this level,
  217. // and apply the rest of the pattern to the subdirs
  218. //
  219. else {
  220. d = GetFileAttributes (FilePattern);
  221. if (d != INVALID_ATTRIBUTES && (d & FILE_ATTRIBUTE_DIRECTORY)) {
  222. if (!SetCurrentDirectory (FilePattern)) {
  223. _tprintf (TEXT("Can't change dir to %s\n"), FilePattern);
  224. return FALSE;
  225. }
  226. if (!pKillEverything (NextPattern, FALSE)) {
  227. return FALSE;
  228. }
  229. } else if (EnumFirstFile (&e, TEXT("."), FilePattern)) {
  230. do {
  231. if (e.Directory) {
  232. SetCurrentDirectory (CurrentDir);
  233. if (SetCurrentDirectory (e.FileName)) {
  234. if (!pKillEverything (NextPattern, FALSE)) {
  235. AbortFileEnum (&e);
  236. return FALSE;
  237. }
  238. }
  239. }
  240. } while (EnumNextFile (&e));
  241. }
  242. }
  243. SetCurrentDirectory (CurrentDir);
  244. return TRUE;
  245. }