ReactOS  0.4.13-dev-92-gf251225
attrib.c
Go to the documentation of this file.
1 /*
2  * ATTRIB.C - attrib internal command.
3  *
4  *
5  * History:
6  *
7  * 04-Dec-1998 Eric Kohl
8  * started
9  *
10  * 09-Dec-1998 Eric Kohl
11  * implementation works, except recursion ("attrib /s").
12  *
13  * 05-Jan-1999 Eric Kohl
14  * major rewrite.
15  * fixed recursion ("attrib /s").
16  * started directory support ("attrib /s /d").
17  * updated help text.
18  *
19  * 14-Jan-1999 Eric Kohl
20  * Unicode ready!
21  *
22  * 19-Jan-1999 Eric Kohl
23  * Redirection ready!
24  *
25  * 21-Jan-1999 Eric Kohl
26  * Added check for invalid filenames.
27  *
28  * 23-Jan-1999 Eric Kohl
29  * Added handling of multiple filenames.
30  *
31  * 02-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
32  * Remove all hardcoded strings in En.rc
33  */
34 
35 #include "precomp.h"
36 
37 #ifdef INCLUDE_CMD_ATTRIB
38 
39 static VOID
40 PrintAttribute (LPTSTR pszPath, LPTSTR pszFile, BOOL bRecurse)
41 {
42  WIN32_FIND_DATA findData;
43  HANDLE hFind;
44  TCHAR szFullName[MAX_PATH];
46 
47  /* prepare full file name buffer */
48  _tcscpy (szFullName, pszPath);
49  pszFileName = szFullName + _tcslen (szFullName);
50 
51  /* display all subdirectories */
52  if (bRecurse)
53  {
54  /* append file name */
55  _tcscpy (pszFileName, pszFile);
56 
57  hFind = FindFirstFile (szFullName, &findData);
58  if (hFind == INVALID_HANDLE_VALUE)
59  {
60  ErrorMessage (GetLastError (), pszFile);
61  return;
62  }
63 
64  do
65  {
66  if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
67  continue;
68 
69  if (!_tcscmp (findData.cFileName, _T(".")) ||
70  !_tcscmp (findData.cFileName, _T("..")))
71  continue;
72 
73  _tcscpy (pszFileName, findData.cFileName);
74  _tcscat (pszFileName, _T("\\"));
75  PrintAttribute (szFullName, pszFile, bRecurse);
76  }
77  while (FindNextFile (hFind, &findData));
78  FindClose (hFind);
79  }
80 
81  /* append file name */
82  _tcscpy (pszFileName, pszFile);
83 
84  /* display current directory */
85  hFind = FindFirstFile (szFullName, &findData);
86  if (hFind == INVALID_HANDLE_VALUE)
87  {
88  ErrorMessage (GetLastError (), pszFile);
89  return;
90  }
91 
92  do
93  {
94  if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
95  continue;
96 
97  _tcscpy (pszFileName, findData.cFileName);
98 
99  ConOutPrintf(_T("%c %c%c%c %s\n"),
100  (findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? _T('A') : _T(' '),
101  (findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? _T('S') : _T(' '),
102  (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? _T('H') : _T(' '),
103  (findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _T('R') : _T(' '),
104  szFullName);
105  }
106  while (FindNextFile(hFind, &findData));
107  FindClose(hFind);
108 }
109 
110 
111 static VOID
112 ChangeAttribute(LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask,
113  DWORD dwAttrib, BOOL bRecurse, BOOL bDirectories)
114 {
115  WIN32_FIND_DATA findData;
116  HANDLE hFind;
117  DWORD dwAttribute;
118  TCHAR szFullName[MAX_PATH];
120 
121 
122  /* prepare full file name buffer */
123  _tcscpy (szFullName, pszPath);
124  pszFileName = szFullName + _tcslen (szFullName);
125 
126  /* change all subdirectories */
127  if (bRecurse)
128  {
129  /* append file name */
130  _tcscpy (pszFileName, _T("*.*"));
131 
132  hFind = FindFirstFile (szFullName, &findData);
133  if (hFind == INVALID_HANDLE_VALUE)
134  {
135  ErrorMessage (GetLastError (), pszFile);
136  nErrorLevel = 1;
137  return;
138  }
139 
140  do
141  {
142  if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
143  {
144  if (!_tcscmp (findData.cFileName, _T(".")) ||
145  !_tcscmp (findData.cFileName, _T("..")))
146  continue;
147 
148  _tcscpy (pszFileName, findData.cFileName);
149  _tcscat (pszFileName, _T("\\"));
150 
151  ChangeAttribute (szFullName, pszFile, dwMask,
152  dwAttrib, bRecurse, bDirectories);
153  }
154  }
155  while (FindNextFile (hFind, &findData));
156  FindClose (hFind);
157  }
158 
159  /* append file name */
160  _tcscpy (pszFileName, pszFile);
161 
162  hFind = FindFirstFile (szFullName, &findData);
163  if (hFind == INVALID_HANDLE_VALUE)
164  {
165  ErrorMessage (GetLastError (), pszFile);
166  nErrorLevel = 1;
167  return;
168  }
169 
170  do
171  {
172  if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
173  continue;
174 
175  _tcscpy (pszFileName, findData.cFileName);
176 
177  dwAttribute = GetFileAttributes (szFullName);
178 
179  if (dwAttribute != 0xFFFFFFFF)
180  {
181  dwAttribute = (dwAttribute & ~dwMask) | dwAttrib;
182  SetFileAttributes (szFullName, dwAttribute);
183  }
184  }
185  while (FindNextFile (hFind, &findData));
186  FindClose (hFind);
187 }
188 
189 
191 {
192  LPTSTR *arg;
193  INT argc, i;
195  TCHAR szFileName [MAX_PATH];
196  BOOL bRecurse = FALSE;
197  BOOL bDirectories = FALSE;
198  DWORD dwAttrib = 0;
199  DWORD dwMask = 0;
200 
201  /* initialize strings */
202  szPath[0] = _T('\0');
203  szFileName[0] = _T('\0');
204 
205  /* print help */
206  if (!_tcsncmp (param, _T("/?"), 2))
207  {
209  return 0;
210  }
211 
212  nErrorLevel = 0;
213 
214  /* build parameter array */
215  arg = split (param, &argc, FALSE, FALSE);
216 
217  /* check for options */
218  for (i = 0; i < argc; i++)
219  {
220  if (_tcsicmp (arg[i], _T("/s")) == 0)
221  bRecurse = TRUE;
222  else if (_tcsicmp (arg[i], _T("/d")) == 0)
223  bDirectories = TRUE;
224  }
225 
226  /* create attributes and mask */
227  for (i = 0; i < argc; i++)
228  {
229  if (*arg[i] == _T('+'))
230  {
231  if (_tcslen (arg[i]) != 2)
232  {
234  freep (arg);
235  return -1;
236  }
237 
238  switch ((TCHAR)_totupper (arg[i][1]))
239  {
240  case _T('A'):
241  dwMask |= FILE_ATTRIBUTE_ARCHIVE;
242  dwAttrib |= FILE_ATTRIBUTE_ARCHIVE;
243  break;
244 
245  case _T('H'):
246  dwMask |= FILE_ATTRIBUTE_HIDDEN;
247  dwAttrib |= FILE_ATTRIBUTE_HIDDEN;
248  break;
249 
250  case _T('R'):
251  dwMask |= FILE_ATTRIBUTE_READONLY;
252  dwAttrib |= FILE_ATTRIBUTE_READONLY;
253  break;
254 
255  case _T('S'):
256  dwMask |= FILE_ATTRIBUTE_SYSTEM;
257  dwAttrib |= FILE_ATTRIBUTE_SYSTEM;
258  break;
259 
260  default:
262  freep (arg);
263  return -1;
264  }
265  }
266  else if (*arg[i] == _T('-'))
267  {
268  if (_tcslen (arg[i]) != 2)
269  {
271  freep (arg);
272  return -1;
273  }
274 
275  switch ((TCHAR)_totupper (arg[i][1]))
276  {
277  case _T('A'):
278  dwMask |= FILE_ATTRIBUTE_ARCHIVE;
279  dwAttrib &= ~FILE_ATTRIBUTE_ARCHIVE;
280  break;
281 
282  case _T('H'):
283  dwMask |= FILE_ATTRIBUTE_HIDDEN;
284  dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN;
285  break;
286 
287  case _T('R'):
288  dwMask |= FILE_ATTRIBUTE_READONLY;
289  dwAttrib &= ~FILE_ATTRIBUTE_READONLY;
290  break;
291 
292  case _T('S'):
293  dwMask |= FILE_ATTRIBUTE_SYSTEM;
294  dwAttrib &= ~FILE_ATTRIBUTE_SYSTEM;
295  break;
296 
297  default:
299  freep (arg);
300  return -1;
301  }
302  }
303  }
304 
305  if (argc == 0)
306  {
307  DWORD len;
308 
310  if (szPath[len-1] != _T('\\'))
311  {
312  szPath[len] = _T('\\');
313  szPath[len + 1] = 0;
314  }
315  _tcscpy (szFileName, _T("*.*"));
316  PrintAttribute (szPath, szFileName, bRecurse);
317  freep (arg);
318  return 0;
319  }
320 
321  /* get full file name */
322  for (i = 0; i < argc; i++)
323  {
324  if ((*arg[i] != _T('+')) && (*arg[i] != _T('-')) && (*arg[i] != _T('/')))
325  {
326  LPTSTR p;
328  p = _tcsrchr (szPath, _T('\\')) + 1;
329  _tcscpy (szFileName, p);
330  *p = _T('\0');
331 
332  if (dwMask == 0)
333  PrintAttribute (szPath, szFileName, bRecurse);
334  else
335  ChangeAttribute (szPath, szFileName, dwMask,
336  dwAttrib, bRecurse, bDirectories);
337  }
338  }
339 
340  freep (arg);
341  return 0;
342 }
343 
344 #endif /* INCLUDE_CMD_ATTRIB */
INT nErrorLevel
Definition: cmd.c:157
static int argc
Definition: ServiceArgs.c:12
#define TRUE
Definition: types.h:120
#define _tcsicmp
Definition: xmlstorage.h:205
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
VOID ErrorMessage(DWORD, LPTSTR,...)
Definition: error.c:26
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ConOutPrintf(szStr,...)
Definition: console.h:42
void * arg
Definition: msvc.h:12
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
#define _totupper
Definition: tchar.h:1509
int32_t INT
Definition: typedefs.h:56
CHAR * LPTSTR
Definition: xmlstorage.h:192
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
INT CommandAttrib(LPTSTR param)
Definition: attrib.c:190
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:41
#define GetCurrentDirectory
Definition: winbase.h:3619
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
static VOID freep(LPSTR *p)
Definition: cmdcons.c:98
smooth NULL
Definition: ftsmooth.c:416
VOID error_invalid_parameter_format(LPTSTR)
Definition: error.c:143
#define FindFirstFile
Definition: winbase.h:3596
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define SetFileAttributes
Definition: winbase.h:3723
#define FindNextFile
Definition: winbase.h:3602
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:26
static LPSTR * split(LPSTR s, LPINT args)
Definition: cmdcons.c:163
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
unsigned long DWORD
Definition: ntddk_ex.h:95
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
static VOID PrintAttribute(LPTSTR pszPath, LPTSTR pszFile, BOOL bRecurse)
Definition: attrib.c:40
GLenum GLsizei len
Definition: glext.h:6722
#define GetFullPathName
Definition: winbase.h:3635
#define GetFileAttributes
Definition: winbase.h:3629
LPCWSTR szPath
Definition: env.c:35
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
static VOID ChangeAttribute(LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask, DWORD dwAttrib, BOOL bRecurse, BOOL bDirectories)
Definition: attrib.c:112
_TCHAR * _tcsrchr(const _TCHAR *s, _XINT c)
Definition: tcsrchr.h:4
_TCHAR * _tcscat(_TCHAR *s, const _TCHAR *append)
Definition: tcscat.h:8
GLfloat GLfloat p
Definition: glext.h:8902
int _tcsncmp(const _TCHAR *s1, const _TCHAR *s2, size_t n)
Definition: tcsncmp.h:9
#define STRING_ATTRIB_HELP
Definition: resource.h:69
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502