2 * ATTRIB.C - attrib internal command.
7 * 04-Dec-1998 Eric Kohl
10 * 09-Dec-1998 Eric Kohl
11 * implementation works, except recursion ("attrib /s").
13 * 05-Jan-1999 Eric Kohl
15 * fixed recursion ("attrib /s").
16 * started directory support ("attrib /s /d").
19 * 14-Jan-1999 Eric Kohl
22 * 19-Jan-1999 Eric Kohl
25 * 21-Jan-1999 Eric Kohl
26 * Added check for invalid filenames.
28 * 23-Jan-1999 Eric Kohl
29 * Added handling of multiple filenames.
31 * 02-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
32 * Remove all hardcoded strings in En.rc
37 #ifdef INCLUDE_CMD_ATTRIB
40 PrintAttribute (LPTSTR pszPath
, LPTSTR pszFile
, BOOL bRecurse
)
42 WIN32_FIND_DATA findData
;
44 TCHAR szFullName
[MAX_PATH
];
47 /* prepare full file name buffer */
48 _tcscpy (szFullName
, pszPath
);
49 pszFileName
= szFullName
+ _tcslen (szFullName
);
51 /* display all subdirectories */
54 /* append file name */
55 _tcscpy (pszFileName
, pszFile
);
57 hFind
= FindFirstFile (szFullName
, &findData
);
58 if (hFind
== INVALID_HANDLE_VALUE
)
60 ErrorMessage (GetLastError (), pszFile
);
66 if (!(findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
69 if (!_tcscmp (findData
.cFileName
, _T(".")) ||
70 !_tcscmp (findData
.cFileName
, _T("..")))
73 _tcscpy (pszFileName
, findData
.cFileName
);
74 _tcscat (pszFileName
, _T("\\"));
75 PrintAttribute (szFullName
, pszFile
, bRecurse
);
77 while (FindNextFile (hFind
, &findData
));
81 /* append file name */
82 _tcscpy (pszFileName
, pszFile
);
84 /* display current directory */
85 hFind
= FindFirstFile (szFullName
, &findData
);
86 if (hFind
== INVALID_HANDLE_VALUE
)
88 ErrorMessage (GetLastError (), pszFile
);
94 if (findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
97 _tcscpy (pszFileName
, findData
.cFileName
);
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(' '),
106 while (FindNextFile(hFind
, &findData
));
112 ChangeAttribute(LPTSTR pszPath
, LPTSTR pszFile
, DWORD dwMask
,
113 DWORD dwAttrib
, BOOL bRecurse
, BOOL bDirectories
)
115 WIN32_FIND_DATA findData
;
118 TCHAR szFullName
[MAX_PATH
];
122 /* prepare full file name buffer */
123 _tcscpy (szFullName
, pszPath
);
124 pszFileName
= szFullName
+ _tcslen (szFullName
);
126 /* change all subdirectories */
129 /* append file name */
130 _tcscpy (pszFileName
, _T("*.*"));
132 hFind
= FindFirstFile (szFullName
, &findData
);
133 if (hFind
== INVALID_HANDLE_VALUE
)
135 ErrorMessage (GetLastError (), pszFile
);
142 if (findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
144 if (!_tcscmp (findData
.cFileName
, _T(".")) ||
145 !_tcscmp (findData
.cFileName
, _T("..")))
148 _tcscpy (pszFileName
, findData
.cFileName
);
149 _tcscat (pszFileName
, _T("\\"));
151 ChangeAttribute (szFullName
, pszFile
, dwMask
,
152 dwAttrib
, bRecurse
, bDirectories
);
155 while (FindNextFile (hFind
, &findData
));
159 /* append file name */
160 _tcscpy (pszFileName
, pszFile
);
162 hFind
= FindFirstFile (szFullName
, &findData
);
163 if (hFind
== INVALID_HANDLE_VALUE
)
165 ErrorMessage (GetLastError (), pszFile
);
172 if (findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
175 _tcscpy (pszFileName
, findData
.cFileName
);
177 dwAttribute
= GetFileAttributes (szFullName
);
179 if (dwAttribute
!= 0xFFFFFFFF)
181 dwAttribute
= (dwAttribute
& ~dwMask
) | dwAttrib
;
182 SetFileAttributes (szFullName
, dwAttribute
);
185 while (FindNextFile (hFind
, &findData
));
190 INT
CommandAttrib (LPTSTR param
)
194 TCHAR szPath
[MAX_PATH
];
195 TCHAR szFileName
[MAX_PATH
];
196 BOOL bRecurse
= FALSE
;
197 BOOL bDirectories
= FALSE
;
201 /* initialize strings */
202 szPath
[0] = _T('\0');
203 szFileName
[0] = _T('\0');
206 if (!_tcsncmp (param
, _T("/?"), 2))
208 ConOutResPaging(TRUE
,STRING_ATTRIB_HELP
);
214 /* build parameter array */
215 arg
= split (param
, &argc
, FALSE
, FALSE
);
217 /* check for options */
218 for (i
= 0; i
< argc
; i
++)
220 if (_tcsicmp (arg
[i
], _T("/s")) == 0)
222 else if (_tcsicmp (arg
[i
], _T("/d")) == 0)
226 /* create attributes and mask */
227 for (i
= 0; i
< argc
; i
++)
229 if (*arg
[i
] == _T('+'))
231 if (_tcslen (arg
[i
]) != 2)
233 error_invalid_parameter_format (arg
[i
]);
238 switch ((TCHAR
)_totupper (arg
[i
][1]))
241 dwMask
|= FILE_ATTRIBUTE_ARCHIVE
;
242 dwAttrib
|= FILE_ATTRIBUTE_ARCHIVE
;
246 dwMask
|= FILE_ATTRIBUTE_HIDDEN
;
247 dwAttrib
|= FILE_ATTRIBUTE_HIDDEN
;
251 dwMask
|= FILE_ATTRIBUTE_READONLY
;
252 dwAttrib
|= FILE_ATTRIBUTE_READONLY
;
256 dwMask
|= FILE_ATTRIBUTE_SYSTEM
;
257 dwAttrib
|= FILE_ATTRIBUTE_SYSTEM
;
261 error_invalid_parameter_format (arg
[i
]);
266 else if (*arg
[i
] == _T('-'))
268 if (_tcslen (arg
[i
]) != 2)
270 error_invalid_parameter_format (arg
[i
]);
275 switch ((TCHAR
)_totupper (arg
[i
][1]))
278 dwMask
|= FILE_ATTRIBUTE_ARCHIVE
;
279 dwAttrib
&= ~FILE_ATTRIBUTE_ARCHIVE
;
283 dwMask
|= FILE_ATTRIBUTE_HIDDEN
;
284 dwAttrib
&= ~FILE_ATTRIBUTE_HIDDEN
;
288 dwMask
|= FILE_ATTRIBUTE_READONLY
;
289 dwAttrib
&= ~FILE_ATTRIBUTE_READONLY
;
293 dwMask
|= FILE_ATTRIBUTE_SYSTEM
;
294 dwAttrib
&= ~FILE_ATTRIBUTE_SYSTEM
;
298 error_invalid_parameter_format (arg
[i
]);
309 len
= GetCurrentDirectory (MAX_PATH
, szPath
);
310 if (szPath
[len
-1] != _T('\\'))
312 szPath
[len
] = _T('\\');
315 _tcscpy (szFileName
, _T("*.*"));
316 PrintAttribute (szPath
, szFileName
, bRecurse
);
321 /* get full file name */
322 for (i
= 0; i
< argc
; i
++)
324 if ((*arg
[i
] != _T('+')) && (*arg
[i
] != _T('-')) && (*arg
[i
] != _T('/')))
327 GetFullPathName (arg
[i
], MAX_PATH
, szPath
, NULL
);
328 p
= _tcsrchr (szPath
, _T('\\')) + 1;
329 _tcscpy (szFileName
, p
);
333 PrintAttribute (szPath
, szFileName
, bRecurse
);
335 ChangeAttribute (szPath
, szFileName
, dwMask
,
336 dwAttrib
, bRecurse
, bDirectories
);
344 #endif /* INCLUDE_CMD_ATTRIB */