From ef09f963dd2e1e12f7e64b1688e2a9d0ad4c886c Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Mon, 27 Jun 2005 18:46:07 +0000 Subject: [PATCH] Brandon Turner Implemented /A example "del /A:H /A:-R *.exe -ping.exe" svn path=/trunk/; revision=16305 --- reactos/subsys/system/cmd/En.rc | 17 ++-- reactos/subsys/system/cmd/del.c | 144 +++++++++++++++++++++++++++++--- 2 files changed, 145 insertions(+), 16 deletions(-) diff --git a/reactos/subsys/system/cmd/En.rc b/reactos/subsys/system/cmd/En.rc index befe66c32d6..268bde5f605 100644 --- a/reactos/subsys/system/cmd/En.rc +++ b/reactos/subsys/system/cmd/En.rc @@ -137,17 +137,24 @@ Type DATE without parameters to display the current date setting and\n\ a prompt for a new one. Press ENTER to keep the same date." STRING_DEL_HELP1, "Deletes one or more files.\n\n\ -DEL [/N /P /T /Q /W /Y /Z] file ...\n\ -DELETE [/N /P /T /Q /W /Y /Z] file ...\n\ -ERASE [/N /P /T /Q /W /Y /Z] file ...\n\n\ - file Specifies the file(s) to delete.\n\n\ +DEL [/N /P /T /Q /W /Y /Z /A[[:]attributes]] file ...\n\ +DELETE [/N /P /T /Q /W /Y /Z /A[[:]attributes]] file ...\n\ +ERASE [/N /P /T /Q /W /Y /Z /A[[:]attributes]] file ...\n\n\ + file Specifies the file(s) to delete.\n\n\ /N Nothing.\n\ /P Prompt. Ask before deleting each file.\n\ /T Total. Display total number of deleted files and freed disk space.\n\ /Q Quiet.\n\ /W Wipe. Overwrite the file with random numbers before deleting it.\n\ /Y Yes. Kill even *.* without asking.\n\ - /Z Zap. Delete hidden, read-only and system files.\n" + /Z Zap. Delete hidden, read-only and system files.\n\ + /A Select files to be deleted based on attributes.\n\ + attributes\n\ + R Read Only files\n\ + S System files\n\ + A Archiveable files\n\ + H Hidden Files\n\ + - prefix meaning not\n" STRING_DEL_HELP2, "All files in the directory will be deleted!\nAre you sure (Y/N)?" STRING_DEL_HELP3, " %lu file deleted\n" diff --git a/reactos/subsys/system/cmd/del.c b/reactos/subsys/system/cmd/del.c index 2dbcc41a5d7..6f2b71ac161 100644 --- a/reactos/subsys/system/cmd/del.c +++ b/reactos/subsys/system/cmd/del.c @@ -35,6 +35,9 @@ * * 22-Jun-2005 (Brandon Turner ) * Added exclusive deletion "del * -abc.txt -text*.txt" + * + * 22-Jun-2005 (Brandon Turner ) + * Implemented /A example "del /A:H /A:-R *.exe -ping.exe" */ #include "precomp.h" @@ -45,7 +48,7 @@ enum { - DEL_ATTRIBUTES = 0x001, /* /A : not implemented */ + DEL_ATTRIBUTES = 0x001, /* /A */ DEL_ERROR = 0x002, /* /E : not implemented */ DEL_NOTHING = 0x004, /* /N */ DEL_PROMPT = 0x008, /* /P */ @@ -58,6 +61,18 @@ enum DEL_ZAP = 0x400 /* /Z */ }; +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 BOOL @@ -99,6 +114,25 @@ RemoveFile (LPTSTR lpFileName, DWORD dwFlags) ConOutPrintf (_T("100%% %s\n"),szMsg); CloseHandle (file); } + /*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)) + { + HANDLE hFile; + WIN32_FIND_DATA f2; + hFile = FindFirstFile(lpFileName, &f2); + if(f2.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); + } + + } return DeleteFile (lpFileName); } @@ -120,6 +154,7 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param) INT res; INT nEvalArgs = 0; /* nunber of evaluated arguments */ DWORD dwFlags = 0; + DWORD dwAttrFlags = 0; DWORD dwFiles = 0; HANDLE hFile; HANDLE hFileExcl; @@ -183,12 +218,67 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param) { dwFlags |= DEL_ZAP; } + 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) @@ -246,17 +336,18 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param) #endif hFile = FindFirstFile (szFullPath, &f); - if (hFile == INVALID_HANDLE_VALUE) - { - error_file_not_found (); - freep (arg); - return 0; - } do { + if (hFile == INVALID_HANDLE_VALUE) + { + error_file_not_found (); + freep (arg); + return 0; + } + /*bExclusion is the check varible to see if it has a match and it needs to be set to false before each loop, as it hasnt been matched yet*/ bExclusion = 0; @@ -264,8 +355,8 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param) /*loop through each of the arguments*/ for (ii = 0; ii < args; ii++) { - /*check to see if it is a exclusion tag*/ - if(_tcschr (arg[ii], _T('-'))) + /*check to see if it is a exclusion tag but not a ':' (used in ATTR)*/ + if(_tcschr (arg[ii], _T('-')) && _tcschr (arg[ii], _T(':')) == NULL) { /*remove the - from the front to get the real name*/ _tcscpy (exfileName , arg[ii]); @@ -284,7 +375,38 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param) while (FindNextFile (hFileExcl, &f2)); } } - + + /*if it is going to be excluded by - no need to check attrs*/ + if(dwFlags & DEL_ATTRIBUTES && bExclusion == 0) + { + + /*save if file attr check if user doesnt care about that attr anyways*/ + if(dwAttrFlags & ATTR_ARCHIVE) + {if(!(f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)) + bExclusion = 1;} + if(dwAttrFlags & ATTR_HIDDEN) + {if(!(f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + bExclusion = 1;} + if(dwAttrFlags & ATTR_SYSTEM) + {if(!(f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) + bExclusion = 1;} + if(dwAttrFlags & ATTR_READ_ONLY) + {if(!(f.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + bExclusion = 1;} + if(dwAttrFlags & ATTR_N_ARCHIVE) + {if(f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) + bExclusion = 1;} + if(dwAttrFlags & ATTR_N_HIDDEN) + {if(f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + bExclusion = 1;} + if(dwAttrFlags & ATTR_N_SYSTEM) + {if(f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) + bExclusion = 1;} + if(dwAttrFlags & ATTR_N_READ_ONLY) + {if(f.dwFileAttributes & FILE_ATTRIBUTE_READONLY) + bExclusion = 1;} + } + if(!bExclusion) { /* ignore ".", ".." and directories */