+++ /dev/null
-/*
-* DEL.C - del internal command.
-*
-*
-* History:
-*
-* 06/29/98 (Rob Lake rlake@cs.mun.ca)
-* rewrote del to support wildcards
-* added my name to the contributors
-*
-* 07/13/98 (Rob Lake)
-* fixed bug that caused del not to delete file with out
-* attribute. moved set, del, ren, and ver to there own files
-*
-* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
-* added config.h include
-*
-* 09-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
-* Fixed command line parsing bugs.
-*
-* 21-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
-* Started major rewrite using a new structure.
-*
-* 03-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
-* First working version.
-*
-* 30-Mar-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
-* Added quiet ("/Q"), wipe ("/W") and zap ("/Z") option.
-*
-* 06-Nov-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
-* Little fix to keep DEL quiet inside batch files.
-*
-* 28-Jan-2004 (Michael Fritscher <michael@fritscher.net>)
-* Added prompt ("/P"), yes ("/Y") and wipe("/W") option.
-*
-* 22-Jun-2005 (Brandon Turner <turnerb7@msu.edu>)
-* Added exclusive deletion "del * -abc.txt -text*.txt"
-*
-* 22-Jun-2005 (Brandon Turner <turnerb7@msu.edu>)
-* Implemented /A example "del /A:H /A:-R *.exe -ping.exe"
-*
-* 07-Aug-2005
-* Removed the exclusive deletion (see two comments above) because '-' is a valid file name character.
-* Optimized the recursive deletion in directories.
-* Preload some nice strings.
-*/
-
-#include <precomp.h>
-#include "resource.h"
-
-#ifdef INCLUDE_CMD_DEL
-
-
-enum
-{
- DEL_ATTRIBUTES = 0x001, /* /A */
- DEL_NOTHING = 0x004, /* /N */
- DEL_PROMPT = 0x008, /* /P */
- DEL_QUIET = 0x010, /* /Q */
- DEL_SUBDIR = 0x020, /* /S */
- DEL_TOTAL = 0x040, /* /T */
- DEL_WIPE = 0x080, /* /W */
- DEL_EMPTYDIR = 0x100, /* /X : not implemented */
- DEL_YES = 0x200, /* /Y */
- DEL_FORCE = 0x800 /* /F */
-};
-
-enum
-{
- ATTR_ARCHIVE = 0x001, /* /A:A */
- ATTR_HIDDEN = 0x002, /* /A:H */
- ATTR_SYSTEM = 0x004, /* /A:S */
- ATTR_READ_ONLY = 0x008, /* /A:R */
- ATTR_N_ARCHIVE = 0x010, /* /A:-A */
- ATTR_N_HIDDEN = 0x020, /* /A:-H */
- ATTR_N_SYSTEM = 0x040, /* /A:-S */
- ATTR_N_READ_ONLY = 0x080 /* /A:-R */
-};
-
-static TCHAR szDeleteWipe[RC_STRING_MAX_SIZE];
-static TCHAR szDelHelp2[RC_STRING_MAX_SIZE];
-static TCHAR szDelHelp3[RC_STRING_MAX_SIZE];
-static TCHAR szDelHelp4[RC_STRING_MAX_SIZE];
-static TCHAR szDelError5[RC_STRING_MAX_SIZE];
-static TCHAR szDelError6[RC_STRING_MAX_SIZE];
-static TCHAR szDelError7[RC_STRING_MAX_SIZE];
-static TCHAR CMDPath[MAX_PATH];
-
-static BOOLEAN StringsLoaded = FALSE;
-
-static VOID LoadStrings(VOID)
-{
- LoadString( CMD_ModuleHandle, STRING_DELETE_WIPE, szDeleteWipe, RC_STRING_MAX_SIZE);
- LoadString( CMD_ModuleHandle, STRING_DEL_HELP2, szDelHelp2, RC_STRING_MAX_SIZE);
- LoadString( CMD_ModuleHandle, STRING_DEL_HELP3, szDelHelp3, RC_STRING_MAX_SIZE);
- LoadString( CMD_ModuleHandle, STRING_DEL_HELP4, szDelHelp4, RC_STRING_MAX_SIZE);
- LoadString( CMD_ModuleHandle, STRING_DEL_ERROR5, szDelError5, RC_STRING_MAX_SIZE);
- LoadString( CMD_ModuleHandle, STRING_DEL_ERROR6, szDelError6, RC_STRING_MAX_SIZE);
- LoadString( CMD_ModuleHandle, STRING_DEL_ERROR7, szDelError7, RC_STRING_MAX_SIZE);
- GetModuleFileName(NULL, CMDPath, MAX_PATH);
- StringsLoaded = TRUE;
-}
-
-static BOOL
-RemoveFile (LPTSTR lpFileName, DWORD dwFlags, WIN32_FIND_DATA* f)
-{
- /*This function is called by CommandDelete and
- does the actual process of deleting the single
- file*/
- if(CheckCtrlBreak(BREAK_INPUT))
- return 1;
-
- /*check to see if it is read only and if this is done based on /A
- if it is done by file name, access is denied. However, if it is done
- using the /A switch you must un-read only the file and allow it to be
- deleted*/
- if((dwFlags & DEL_ATTRIBUTES) || (dwFlags & DEL_FORCE))
- {
- if(f->dwFileAttributes & FILE_ATTRIBUTE_READONLY)
- {
- /*setting file to normal, not saving old attrs first
- because the file is going to be deleted anyways
- so the only thing that matters is that it isnt
- read only.*/
- SetFileAttributes(lpFileName,FILE_ATTRIBUTE_NORMAL);
- }
- }
-
- if (dwFlags & DEL_WIPE)
- {
-
- HANDLE file;
- DWORD temp;
-#define BufferSize 65536
- BYTE buffer[BufferSize];
- LONGLONG i;
- LARGE_INTEGER FileSize;
-
- FileSize.u.HighPart = f->nFileSizeHigh;
- FileSize.u.LowPart = f->nFileSizeLow;
-
- for(i = 0; i < BufferSize; i++)
- {
- buffer[i]=rand() % 256;
- }
- file = CreateFile (lpFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);
- if (file != INVALID_HANDLE_VALUE)
- {
- for(i = 0; i < (FileSize.QuadPart - BufferSize); i += BufferSize)
- {
- WriteFile (file, buffer, BufferSize, &temp, NULL);
- ConOutPrintf (_T("%I64d%% %s\r"),(i * (LONGLONG)100)/FileSize.QuadPart,szDeleteWipe);
- }
- WriteFile (file, buffer, (DWORD)(FileSize.QuadPart - i), &temp, NULL);
- ConOutPrintf (_T("100%% %s\n"),szDeleteWipe);
- CloseHandle (file);
- }
- }
-
- return DeleteFile (lpFileName);
-}
-
-
-static DWORD
-DeleteFiles(LPTSTR FileName, DWORD* dwFlags, DWORD dwAttrFlags)
-{
- TCHAR szFullPath[MAX_PATH];
- TCHAR szFileName[MAX_PATH];
- LPTSTR pFilePart;
- HANDLE hFile;
- WIN32_FIND_DATA f;
- BOOL bExclusion;
- INT res;
- DWORD dwFiles = 0;
-
- _tcscpy(szFileName, FileName);
-
- if(_tcschr (szFileName, _T('*')) == NULL &&
- IsExistingDirectory (szFileName))
- {
- /* If it doesnt have a \ at the end already then on needs to be added */
- if(szFileName[_tcslen(szFileName) - 1] != _T('\\'))
- _tcscat (szFileName, _T("\\"));
- /* Add a wildcard after the \ */
- _tcscat (szFileName, _T("*"));
- }
-
- if(!_tcscmp (szFileName, _T("*")) ||
- !_tcscmp (szFileName, _T("*.*")) ||
- (szFileName[_tcslen(szFileName) - 2] == _T('\\') && szFileName[_tcslen(szFileName) - 1] == _T('*')))
- {
- /* well, the user wants to delete everything but if they didnt yes DEL_YES, DEL_QUIET, or DEL_PROMPT
- then we are going to want to make sure that in fact they want to do that. */
-
- if (!((*dwFlags & DEL_YES) || (*dwFlags & DEL_QUIET) || (*dwFlags & DEL_PROMPT)))
- {
- res = FilePromptYNA (szDelHelp2);
- if ((res == PROMPT_NO) || (res == PROMPT_BREAK))
- return 0x80000000;
- if(res == PROMPT_ALL)
- *dwFlags |= DEL_YES;
- }
- }
-
- GetFullPathName (szFileName,
- MAX_PATH,
- szFullPath,
- &pFilePart);
-
- hFile = FindFirstFile(szFullPath, &f);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- do
- {
- bExclusion = FALSE;
-
- /*if it is going to be excluded by - no need to check attrs*/
- if(*dwFlags & DEL_ATTRIBUTES && !bExclusion)
- {
-
- /*save if file attr check if user doesnt care about that attr anyways*/
- if(dwAttrFlags & ATTR_ARCHIVE && !(f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE))
- bExclusion = TRUE;
- if(dwAttrFlags & ATTR_HIDDEN && !(f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
- bExclusion = TRUE;
- if(dwAttrFlags & ATTR_SYSTEM && !(f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM))
- bExclusion = TRUE;
- if(dwAttrFlags & ATTR_READ_ONLY && !(f.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
- bExclusion = TRUE;
- if(dwAttrFlags & ATTR_N_ARCHIVE && (f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE))
- bExclusion = TRUE;
- if(dwAttrFlags & ATTR_N_HIDDEN && (f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
- bExclusion = TRUE;
- if(dwAttrFlags & ATTR_N_SYSTEM && (f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM))
- bExclusion = TRUE;
- if(dwAttrFlags & ATTR_N_READ_ONLY && (f.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
- bExclusion = TRUE;
- }
-
- if(bExclusion)
- continue;
-
- /* ignore directories */
- if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- continue;
-
-
- _tcscpy (pFilePart, f.cFileName);
-
- /* We cant delete ourselves */
- if(!_tcscmp (CMDPath,szFullPath))
- continue;
-
-
-#ifdef _DEBUG
- ConErrPrintf(_T("Full filename: %s\n"), szFullPath);
-#endif
-
- /* ask for deleting */
- if (*dwFlags & DEL_PROMPT)
- {
- ConErrPrintf(szDelError5, szFullPath);
-
- res = FilePromptYN (szDelError6);
-
- if ((res == PROMPT_NO) || (res == PROMPT_BREAK))
- {
- nErrorLevel = 0;
- continue;
- }
- }
-
- /*user cant ask it to be quiet and tell you what it did*/
- if (!(*dwFlags & DEL_QUIET) && !(*dwFlags & DEL_TOTAL))
- {
- ConErrPrintf(szDelError7, szFullPath);
- }
-
- /* delete the file */
- if(*dwFlags & DEL_NOTHING)
- continue;
-
- if(RemoveFile (szFullPath, *dwFlags, &f))
- dwFiles++;
- else
- {
- ErrorMessage (GetLastError(), _T(""));
-// FindClose(hFile);
-// return -1;
- }
- }
- while (FindNextFile (hFile, &f));
- FindClose (hFile);
- }
- return dwFiles;
-}
-
-
-static DWORD
-ProcessDirectory(LPTSTR FileName, DWORD* dwFlags, DWORD dwAttrFlags)
-{
- TCHAR szFullPath[MAX_PATH];
- LPTSTR pFilePart;
- LPTSTR pSearchPart;
- HANDLE hFile;
- WIN32_FIND_DATA f;
- DWORD dwFiles = 0;
-
- GetFullPathName (FileName,
- MAX_PATH,
- szFullPath,
- &pFilePart);
-
- dwFiles = DeleteFiles(szFullPath, dwFlags, dwAttrFlags);
- if (dwFiles & 0x80000000)
- return dwFiles;
-
- if (*dwFlags & DEL_SUBDIR)
- {
- /* Get just the file name */
- pSearchPart = _tcsrchr(FileName,_T('\\'));
- if(pSearchPart != NULL)
- pSearchPart++;
- else
- pSearchPart = FileName;
-
- /* Get the full path to the file */
- GetFullPathName (FileName,MAX_PATH,szFullPath,NULL);
-
- /* strip the filename off of it */
- pFilePart = _tcsrchr(szFullPath, _T('\\'));
- if (pFilePart == NULL)
- {
- pFilePart = szFullPath;
- }
- else
- {
- pFilePart++;
- }
-
- _tcscpy(pFilePart, _T("*"));
-
- hFile = FindFirstFile(szFullPath, &f);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- do
- {
- if (!(f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
- !_tcscmp(f.cFileName, _T(".")) ||
- !_tcscmp(f.cFileName, _T("..")))
- continue;
-
- _tcscpy(pFilePart, f.cFileName);
- _tcscat(pFilePart, _T("\\"));
- _tcscat(pFilePart, pSearchPart);
-
- dwFiles +=ProcessDirectory(szFullPath, dwFlags, dwAttrFlags);
- if (dwFiles & 0x80000000)
- {
- break;
- }
- }
- while (FindNextFile (hFile, &f));
- FindClose (hFile);
- }
- }
- return dwFiles;
-}
-
-
-
-INT CommandDelete (LPTSTR cmd, LPTSTR param)
-{
- /*cmd is the command that was given, in this case it will always be "del" or "delete"
- param is whatever is given after the command*/
-
- LPTSTR *arg = NULL;
- INT args;
- INT i;
- INT nEvalArgs = 0; /* nunber of evaluated arguments */
- DWORD dwFlags = 0;
- DWORD dwAttrFlags = 0;
- DWORD dwFiles = 0;
- LONG ch;
- TCHAR szOrginalArg[MAX_PATH];
-
- /*checks the first two chars of param to see if it is /?
- this however allows the following command to not show help
- "del frog.txt /?" */
-
- if (!StringsLoaded)
- {
- LoadStrings();
- }
-
- if (!_tcsncmp (param, _T("/?"), 2))
- {
- ConOutResPaging(TRUE,STRING_DEL_HELP1);
- return 0;
- }
-
- nErrorLevel = 0;
-
- arg = split (param, &args, FALSE);
-
- if (args == 0)
- {
- /* only command given */
- error_req_param_missing ();
- freep (arg);
- return 1;
- }
- /* check for options anywhere in command line */
- for (i = 0; i < args; i++)
- {
- if (*arg[i] == _T('/'))
- {
- /*found a command, but check to make sure it has something after it*/
- if (_tcslen (arg[i]) >= 2)
- {
- ch = _totupper (arg[i][1]);
- if (ch == _T('N'))
- {
- dwFlags |= DEL_NOTHING;
- }
- else if (ch == _T('P'))
- {
- dwFlags |= DEL_PROMPT;
- }
- else if (ch == _T('Q'))
- {
- dwFlags |= DEL_QUIET;
- }
- else if (ch == _T('F'))
- {
- dwFlags |= DEL_FORCE;
- }
- else if (ch == _T('S'))
- {
- dwFlags |= DEL_SUBDIR;
- }
- else if (ch == _T('T'))
- {
- dwFlags |= DEL_TOTAL;
- }
- else if (ch == _T('W'))
- {
- dwFlags |= DEL_WIPE;
- }
- else if (ch == _T('Y'))
- {
- dwFlags |= DEL_YES;
- }
- else if (ch == _T('A'))
- {
-
- dwFlags |= DEL_ATTRIBUTES;
- /*the proper syntax for /A has a min of 4 chars
- i.e. /A:R or /A:-H */
- if (_tcslen (arg[i]) < 4)
- {
- error_invalid_parameter_format(arg[i]);
- return 0;
- }
- ch = _totupper (arg[i][3]);
- if (_tcslen (arg[i]) == 4)
- {
- if(ch == _T('A'))
- {
- dwAttrFlags |= ATTR_ARCHIVE;
- }
- if(ch == _T('H'))
- {
- dwAttrFlags |= ATTR_HIDDEN;
- }
- if(ch == _T('S'))
- {
- dwAttrFlags |= ATTR_SYSTEM;
- }
- if(ch == _T('R'))
- {
- dwAttrFlags |= ATTR_READ_ONLY;
- }
- }
- if (_tcslen (arg[i]) == 5)
- {
- if(ch == _T('-'))
- {
- ch = _totupper (arg[i][4]);
- if(ch == _T('A'))
- {
- dwAttrFlags |= ATTR_N_ARCHIVE;
- }
- if(ch == _T('H'))
- {
- dwAttrFlags |= ATTR_N_HIDDEN;
- }
- if(ch == _T('S'))
- {
- dwAttrFlags |= ATTR_N_SYSTEM;
- }
- if(ch == _T('R'))
- {
- dwAttrFlags |= ATTR_N_READ_ONLY;
- }
- }
- }
- }
- }
-
- nEvalArgs++;
- }
- }
-
- /* there are only options on the command line --> error!!!
- there is the same number of args as there is flags, so none of the args were filenames*/
- if (args == nEvalArgs)
- {
- error_req_param_missing ();
- freep (arg);
- return 1;
- }
-
- /* keep quiet within batch files */
- if (bc != NULL)
- dwFlags |= DEL_QUIET;
-
- /* check for filenames anywhere in command line */
- for (i = 0; i < args && !(dwFiles & 0x80000000); i++)
- {
-
- /*this checks to see if it isnt a flag, if it isnt, we assume it is a file name*/
- if((*arg[i] == _T('/')) || (*arg[i] == _T('-')))
- continue;
-
- /* We want to make a copies of the argument */
- if(_tcslen(arg[i]) == 2 && arg[i][1] == _T(':'))
- {
- /* Check for C: D: ... */
- GetRootPath(arg[i],szOrginalArg,MAX_PATH);
- }
- else
- {
- _tcscpy(szOrginalArg,arg[i]);
- }
- dwFiles += ProcessDirectory(szOrginalArg, &dwFlags, dwAttrFlags);
-
- }
-
- freep (arg);
-
- /*Based on MS cmd, we only tell what files are being deleted when /S is used */
- if (dwFlags & DEL_TOTAL)
- {
- dwFiles &= 0x7fffffff;
- if (dwFiles < 2)
- {
- ConOutPrintf(szDelHelp3, dwFiles);
- }
- else
- {
- ConOutPrintf(szDelHelp4, dwFiles);
- }
- }
-
- return 0;
-}
-
-
-#endif