/* * ATTRIB.C - attrib internal command. * * * History: * * 04-Dec-1998 Eric Kohl * started * * 09-Dec-1998 Eric Kohl * implementation works, except recursion ("attrib /s"). * * 05-Jan-1999 Eric Kohl * major rewrite. * fixed recursion ("attrib /s"). * started directory support ("attrib /s /d"). * updated help text. * * 14-Jan-1999 Eric Kohl * Unicode ready! * * 19-Jan-1999 Eric Kohl * Redirection ready! * * 21-Jan-1999 Eric Kohl * Added check for invalid filenames. * * 23-Jan-1999 Eric Kohl * Added handling of multiple filenames. * * 02-Apr-2005 (Magnus Olsen ) * Remove all hardcoded strings in En.rc */ #include "precomp.h" #ifdef INCLUDE_CMD_ATTRIB static VOID PrintAttribute (LPTSTR pszPath, LPTSTR pszFile, BOOL bRecurse) { WIN32_FIND_DATA findData; HANDLE hFind; TCHAR szFullName[MAX_PATH]; LPTSTR pszFileName; /* prepare full file name buffer */ _tcscpy (szFullName, pszPath); pszFileName = szFullName + _tcslen (szFullName); /* display all subdirectories */ if (bRecurse) { /* append file name */ _tcscpy (pszFileName, pszFile); hFind = FindFirstFile (szFullName, &findData); if (hFind == INVALID_HANDLE_VALUE) { ErrorMessage (GetLastError (), pszFile); return; } do { if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue; if (!_tcscmp (findData.cFileName, _T(".")) || !_tcscmp (findData.cFileName, _T(".."))) continue; _tcscpy (pszFileName, findData.cFileName); _tcscat (pszFileName, _T("\\")); PrintAttribute (szFullName, pszFile, bRecurse); } while (FindNextFile (hFind, &findData)); FindClose (hFind); } /* append file name */ _tcscpy (pszFileName, pszFile); /* display current directory */ hFind = FindFirstFile (szFullName, &findData); if (hFind == INVALID_HANDLE_VALUE) { ErrorMessage (GetLastError (), pszFile); return; } do { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; _tcscpy (pszFileName, findData.cFileName); ConOutPrintf(_T("%c %c%c%c %s\n"), (findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? _T('A') : _T(' '), (findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? _T('S') : _T(' '), (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? _T('H') : _T(' '), (findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _T('R') : _T(' '), szFullName); } while (FindNextFile(hFind, &findData)); FindClose(hFind); } static VOID ChangeAttribute(LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask, DWORD dwAttrib, BOOL bRecurse, BOOL bDirectories) { WIN32_FIND_DATA findData; HANDLE hFind; DWORD dwAttribute; TCHAR szFullName[MAX_PATH]; LPTSTR pszFileName; /* prepare full file name buffer */ _tcscpy (szFullName, pszPath); pszFileName = szFullName + _tcslen (szFullName); /* change all subdirectories */ if (bRecurse) { /* append file name */ _tcscpy (pszFileName, _T("*.*")); hFind = FindFirstFile (szFullName, &findData); if (hFind == INVALID_HANDLE_VALUE) { ErrorMessage (GetLastError (), pszFile); nErrorLevel = 1; return; } do { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (!_tcscmp (findData.cFileName, _T(".")) || !_tcscmp (findData.cFileName, _T(".."))) continue; _tcscpy (pszFileName, findData.cFileName); _tcscat (pszFileName, _T("\\")); ChangeAttribute (szFullName, pszFile, dwMask, dwAttrib, bRecurse, bDirectories); } } while (FindNextFile (hFind, &findData)); FindClose (hFind); } /* append file name */ _tcscpy (pszFileName, pszFile); hFind = FindFirstFile (szFullName, &findData); if (hFind == INVALID_HANDLE_VALUE) { ErrorMessage (GetLastError (), pszFile); nErrorLevel = 1; return; } do { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; _tcscpy (pszFileName, findData.cFileName); dwAttribute = GetFileAttributes (szFullName); if (dwAttribute != 0xFFFFFFFF) { dwAttribute = (dwAttribute & ~dwMask) | dwAttrib; SetFileAttributes (szFullName, dwAttribute); } } while (FindNextFile (hFind, &findData)); FindClose (hFind); } INT CommandAttrib (LPTSTR param) { LPTSTR *arg; INT argc, i; TCHAR szPath[MAX_PATH]; TCHAR szFileName [MAX_PATH]; BOOL bRecurse = FALSE; BOOL bDirectories = FALSE; DWORD dwAttrib = 0; DWORD dwMask = 0; /* initialize strings */ szPath[0] = _T('\0'); szFileName[0] = _T('\0'); /* print help */ if (!_tcsncmp (param, _T("/?"), 2)) { ConOutResPaging(TRUE,STRING_ATTRIB_HELP); return 0; } nErrorLevel = 0; /* build parameter array */ arg = split (param, &argc, FALSE, FALSE); /* check for options */ for (i = 0; i < argc; i++) { if (_tcsicmp (arg[i], _T("/s")) == 0) bRecurse = TRUE; else if (_tcsicmp (arg[i], _T("/d")) == 0) bDirectories = TRUE; } /* create attributes and mask */ for (i = 0; i < argc; i++) { if (*arg[i] == _T('+')) { if (_tcslen (arg[i]) != 2) { error_invalid_parameter_format (arg[i]); freep (arg); return -1; } switch ((TCHAR)_totupper (arg[i][1])) { case _T('A'): dwMask |= FILE_ATTRIBUTE_ARCHIVE; dwAttrib |= FILE_ATTRIBUTE_ARCHIVE; break; case _T('H'): dwMask |= FILE_ATTRIBUTE_HIDDEN; dwAttrib |= FILE_ATTRIBUTE_HIDDEN; break; case _T('R'): dwMask |= FILE_ATTRIBUTE_READONLY; dwAttrib |= FILE_ATTRIBUTE_READONLY; break; case _T('S'): dwMask |= FILE_ATTRIBUTE_SYSTEM; dwAttrib |= FILE_ATTRIBUTE_SYSTEM; break; default: error_invalid_parameter_format (arg[i]); freep (arg); return -1; } } else if (*arg[i] == _T('-')) { if (_tcslen (arg[i]) != 2) { error_invalid_parameter_format (arg[i]); freep (arg); return -1; } switch ((TCHAR)_totupper (arg[i][1])) { case _T('A'): dwMask |= FILE_ATTRIBUTE_ARCHIVE; dwAttrib &= ~FILE_ATTRIBUTE_ARCHIVE; break; case _T('H'): dwMask |= FILE_ATTRIBUTE_HIDDEN; dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN; break; case _T('R'): dwMask |= FILE_ATTRIBUTE_READONLY; dwAttrib &= ~FILE_ATTRIBUTE_READONLY; break; case _T('S'): dwMask |= FILE_ATTRIBUTE_SYSTEM; dwAttrib &= ~FILE_ATTRIBUTE_SYSTEM; break; default: error_invalid_parameter_format (arg[i]); freep (arg); return -1; } } } if (argc == 0) { DWORD len; len = GetCurrentDirectory (MAX_PATH, szPath); if (szPath[len-1] != _T('\\')) { szPath[len] = _T('\\'); szPath[len + 1] = 0; } _tcscpy (szFileName, _T("*.*")); PrintAttribute (szPath, szFileName, bRecurse); freep (arg); return 0; } /* get full file name */ for (i = 0; i < argc; i++) { if ((*arg[i] != _T('+')) && (*arg[i] != _T('-')) && (*arg[i] != _T('/'))) { LPTSTR p; GetFullPathName (arg[i], MAX_PATH, szPath, NULL); p = _tcsrchr (szPath, _T('\\')) + 1; _tcscpy (szFileName, p); *p = _T('\0'); if (dwMask == 0) PrintAttribute (szPath, szFileName, bRecurse); else ChangeAttribute (szPath, szFileName, dwMask, dwAttrib, bRecurse, bDirectories); } } freep (arg); return 0; } #endif /* INCLUDE_CMD_ATTRIB */