/*++ Copyright (c) 1997 Microsoft Corporation Module Name: killfile.c Abstract: Performs a test of the file enumeration code. Author: Jim Schmidt (jimschm) 14-Jan-1998 Revision History: --*/ #include "pch.h" BOOL pKillEverything ( PCTSTR Pattern, BOOL Root ); UINT g_Dirs, g_Files; VOID HelpAndExit ( VOID ) { printf ("Command line syntax:\n\n" "kf [-sf|-sd|-s] [-l] \n\n" " Specifies pattern of file(s) or dir(s)\n" "\n" "Options:\n" "\n" "-sf Search all subdirs for matching files, then kill them\n" "-sd Search all subdirs for matching dirs, then kill them\n" "-s Kill all matches of in any subdir\n" "-l List kill candidates; don't kill them\n" ); exit(0); } HANDLE g_hHeap; HINSTANCE g_hInst; BOOL g_DeleteFile = TRUE; BOOL g_DeleteDir = FALSE; BOOL g_Recursive = FALSE; BOOL g_ListOnly = FALSE; INT __cdecl _tmain ( INT argc, TCHAR *argv[] ) { PCTSTR Pattern = NULL; PCTSTR FilePattern = NULL; INT i; DWORD d; BOOL DefaultOptions = TRUE; g_hHeap = GetProcessHeap(); for (i = 1 ; i < argc ; i++) { if (argv[i][0] == TEXT('-') || argv[i][0] == TEXT('/')) { switch (_totlower (argv[i][1])) { case TEXT('s'): if (g_Recursive) { HelpAndExit(); } g_Recursive = TRUE; switch (_totlower (argv[i][2])) { case TEXT('f'): g_DeleteFile = TRUE; g_DeleteDir = FALSE; DefaultOptions = FALSE; break; case TEXT('d'): g_DeleteFile = FALSE; g_DeleteDir = TRUE; DefaultOptions = FALSE; break; case 0: g_DeleteFile = TRUE; g_DeleteDir = TRUE; DefaultOptions = FALSE; break; default: HelpAndExit(); } break; case TEXT('l'): g_ListOnly = TRUE; break; default: HelpAndExit(); } } else if (Pattern) { HelpAndExit(); } else { Pattern = argv[i]; } } if (!Pattern || !Pattern[0]) { HelpAndExit(); } d = GetFileAttributes (Pattern); if (d != INVALID_ATTRIBUTES && (d & FILE_ATTRIBUTE_DIRECTORY)) { if (DefaultOptions) { g_DeleteDir = TRUE; } } pKillEverything (Pattern, TRUE); printf ("\nFiles: %u Dirs: %u\n\n", g_Files, g_Dirs); return 0; } BOOL pKillPattern ( PCTSTR Pattern ) { FILE_ENUM e; TCHAR CurrentDir[MAX_TCHAR_PATH]; GetCurrentDirectory (MAX_TCHAR_PATH, CurrentDir); if (EnumFirstFile (&e, CurrentDir, Pattern)) { do { if (e.Directory && !g_DeleteDir) { continue; } if (!e.Directory && !g_DeleteFile) { continue; } if (e.Directory) { g_Dirs++; } else { g_Files++; } if (g_ListOnly) { _tprintf (TEXT("%s\n"), e.FullPath); } else { SetCurrentDirectory (CurrentDir); SetFileAttributes (e.FullPath, FILE_ATTRIBUTE_NORMAL); if (e.Directory) { if (!RemoveCompleteDirectory (e.FullPath)) { _tprintf (TEXT("Can't kill directory %s, GLE=%u\n"), e.FullPath, GetLastError()); } } else if (!DeleteFile (e.FullPath)) { _tprintf (TEXT("Can't kill %s, GLE=%u\n"), e.FullPath, GetLastError()); } } } while (EnumNextFile (&e)); } SetCurrentDirectory (CurrentDir); return TRUE; } BOOL pKillEverything ( PCTSTR Pattern, BOOL Root ) { TCHAR FilePattern[MAX_TCHAR_PATH]; TCHAR SubPattern[MAX_TCHAR_PATH]; TCHAR CurrentDir[MAX_TCHAR_PATH]; PCTSTR p; PCTSTR q; PCTSTR NextPattern; FILE_ENUM e; DWORD d; TCHAR c = TEXT('\\'); GetCurrentDirectory (MAX_TCHAR_PATH, CurrentDir); if (!Pattern || !Pattern[0]) { lstrcpy (FilePattern, TEXT("*.*")); NextPattern = NULL; } else { p = _tcschr (Pattern, TEXT('\\')); if (!p) { p = GetEndOfString (Pattern); } else { q = _tcschr (Pattern, TEXT(':')); if (q && p > q) { if (Root) { p++; c = 0; } else { _tprintf (TEXT("Pattern is bad: %s\n"), Pattern); return FALSE; } } else if (p == Pattern) { if (Root) { p++; c = 0; } else { _tprintf (TEXT("Pattern is bad: %s\n"), Pattern); return FALSE; } } } StringCopyAB (FilePattern, Pattern, p); if (*p) { NextPattern = p; if (*NextPattern == c) { NextPattern++; } } else { NextPattern = NULL; } } // // If NextPattern is NULL, then we must delete this pattern // if (!NextPattern) { if (g_Recursive) { wsprintf (SubPattern, TEXT("*.*\\%s"), Pattern); if (!pKillEverything (SubPattern, FALSE)) { return FALSE; } } pKillPattern (Pattern); } // // Otherwise we enumerate the files and dirs at this level, // and apply the rest of the pattern to the subdirs // else { d = GetFileAttributes (FilePattern); if (d != INVALID_ATTRIBUTES && (d & FILE_ATTRIBUTE_DIRECTORY)) { if (!SetCurrentDirectory (FilePattern)) { _tprintf (TEXT("Can't change dir to %s\n"), FilePattern); return FALSE; } if (!pKillEverything (NextPattern, FALSE)) { return FALSE; } } else if (EnumFirstFile (&e, TEXT("."), FilePattern)) { do { if (e.Directory) { SetCurrentDirectory (CurrentDir); if (SetCurrentDirectory (e.FileName)) { if (!pKillEverything (NextPattern, FALSE)) { AbortFileEnum (&e); return FALSE; } } } } while (EnumNextFile (&e)); } } SetCurrentDirectory (CurrentDir); return TRUE; }