reactos/reactos/base/shell/cmd/attrib.c
Hermès Bélusca-Maïto 1965b2bf85 [CMD]
Remove extra \r put by hand in some console output functions, so that we use there only \n.
But modify the ConWrite function so that, if we redirect output to something else than a console
(e.g. redirect to a file or to a serial console via ... > AUX), newline characters \n get converted
into \r\n automatically.

What you get, for instance, is: https://imageshack.com/a/img853/5834/l34.png

svn path=/trunk/; revision=59411
2013-07-02 23:07:15 +00:00

345 lines
9 KiB
C

/*
* 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 <magnus@greatlord.com>)
* 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 */