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 hardcode string to En.rc
37 #ifdef INCLUDE_CMD_ATTRIB
41 PrintAttribute (LPTSTR pszPath
, LPTSTR pszFile
, BOOL bRecurse
)
43 WIN32_FIND_DATA findData
;
45 TCHAR szFullName
[MAX_PATH
];
48 /* prepare full file name buffer */
49 _tcscpy (szFullName
, pszPath
);
50 pszFileName
= szFullName
+ _tcslen (szFullName
);
52 /* display all subdirectories */
55 /* append file name */
56 _tcscpy (pszFileName
, pszFile
);
58 hFind
= FindFirstFile (szFullName
, &findData
);
59 if (hFind
== INVALID_HANDLE_VALUE
)
61 ErrorMessage (GetLastError (), pszFile
);
67 if (!(findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
70 if (!_tcscmp (findData
.cFileName
, _T(".")) ||
71 !_tcscmp (findData
.cFileName
, _T("..")))
74 _tcscpy (pszFileName
, findData
.cFileName
);
75 _tcscat (pszFileName
, _T("\\"));
76 PrintAttribute (szFullName
, pszFile
, bRecurse
);
78 while (FindNextFile (hFind
, &findData
));
82 /* append file name */
83 _tcscpy (pszFileName
, pszFile
);
85 /* display current directory */
86 hFind
= FindFirstFile (szFullName
, &findData
);
87 if (hFind
== INVALID_HANDLE_VALUE
)
89 ErrorMessage (GetLastError (), pszFile
);
95 if (findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
98 _tcscpy (pszFileName
, findData
.cFileName
);
100 ConOutPrintf (_T("%c %c%c%c %s\n"),
101 (findData
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) ? _T('A') : _T(' '),
102 (findData
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) ? _T('S') : _T(' '),
103 (findData
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) ? _T('H') : _T(' '),
104 (findData
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) ? _T('R') : _T(' '),
107 while (FindNextFile (hFind
, &findData
));
113 ChangeAttribute (LPTSTR pszPath
, LPTSTR pszFile
, DWORD dwMask
,
114 DWORD dwAttrib
, BOOL bRecurse
, BOOL bDirectories
)
116 WIN32_FIND_DATA findData
;
119 TCHAR szFullName
[MAX_PATH
];
123 /* prepare full file name buffer */
124 _tcscpy (szFullName
, pszPath
);
125 pszFileName
= szFullName
+ _tcslen (szFullName
);
127 /* change all subdirectories */
130 /* append file name */
131 _tcscpy (pszFileName
, _T("*.*"));
133 hFind
= FindFirstFile (szFullName
, &findData
);
134 if (hFind
== INVALID_HANDLE_VALUE
)
136 ErrorMessage (GetLastError (), pszFile
);
143 if (findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
145 if (!_tcscmp (findData
.cFileName
, _T(".")) ||
146 !_tcscmp (findData
.cFileName
, _T("..")))
149 _tcscpy (pszFileName
, findData
.cFileName
);
150 _tcscat (pszFileName
, _T("\\"));
152 ChangeAttribute (szFullName
, pszFile
, dwMask
,
153 dwAttrib
, bRecurse
, bDirectories
);
156 while (FindNextFile (hFind
, &findData
));
160 /* append file name */
161 _tcscpy (pszFileName
, pszFile
);
163 hFind
= FindFirstFile (szFullName
, &findData
);
164 if (hFind
== INVALID_HANDLE_VALUE
)
166 ErrorMessage (GetLastError (), pszFile
);
173 if (findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
176 _tcscpy (pszFileName
, findData
.cFileName
);
178 dwAttribute
= GetFileAttributes (szFullName
);
180 if (dwAttribute
!= 0xFFFFFFFF)
182 dwAttribute
= (dwAttribute
& ~dwMask
) | dwAttrib
;
183 SetFileAttributes (szFullName
, dwAttribute
);
186 while (FindNextFile (hFind
, &findData
));
191 INT
CommandAttrib (LPTSTR param
)
195 TCHAR szPath
[MAX_PATH
];
196 TCHAR szFileName
[MAX_PATH
];
197 BOOL bRecurse
= FALSE
;
198 BOOL bDirectories
= FALSE
;
202 /* initialize strings */
203 szPath
[0] = _T('\0');
204 szFileName
[0] = _T('\0');
207 if (!_tcsncmp (param
, _T("/?"), 2))
209 ConOutResPaging(TRUE
,STRING_ATTRIB_HELP
);
215 /* build parameter array */
216 arg
= split (param
, &argc
, FALSE
);
218 /* check for options */
219 for (i
= 0; i
< argc
; i
++)
221 if (_tcsicmp (arg
[i
], _T("/s")) == 0)
223 else if (_tcsicmp (arg
[i
], _T("/d")) == 0)
227 /* create attributes and mask */
228 for (i
= 0; i
< argc
; i
++)
230 if (*arg
[i
] == _T('+'))
232 if (_tcslen (arg
[i
]) != 2)
234 error_invalid_parameter_format (arg
[i
]);
239 switch ((TCHAR
)_totupper (arg
[i
][1]))
242 dwMask
|= FILE_ATTRIBUTE_ARCHIVE
;
243 dwAttrib
|= FILE_ATTRIBUTE_ARCHIVE
;
247 dwMask
|= FILE_ATTRIBUTE_HIDDEN
;
248 dwAttrib
|= FILE_ATTRIBUTE_HIDDEN
;
252 dwMask
|= FILE_ATTRIBUTE_READONLY
;
253 dwAttrib
|= FILE_ATTRIBUTE_READONLY
;
257 dwMask
|= FILE_ATTRIBUTE_SYSTEM
;
258 dwAttrib
|= FILE_ATTRIBUTE_SYSTEM
;
262 error_invalid_parameter_format (arg
[i
]);
267 else if (*arg
[i
] == _T('-'))
269 if (_tcslen (arg
[i
]) != 2)
271 error_invalid_parameter_format (arg
[i
]);
276 switch ((TCHAR
)_totupper (arg
[i
][1]))
279 dwMask
|= FILE_ATTRIBUTE_ARCHIVE
;
280 dwAttrib
&= ~FILE_ATTRIBUTE_ARCHIVE
;
284 dwMask
|= FILE_ATTRIBUTE_HIDDEN
;
285 dwAttrib
&= ~FILE_ATTRIBUTE_HIDDEN
;
289 dwMask
|= FILE_ATTRIBUTE_READONLY
;
290 dwAttrib
&= ~FILE_ATTRIBUTE_READONLY
;
294 dwMask
|= FILE_ATTRIBUTE_SYSTEM
;
295 dwAttrib
&= ~FILE_ATTRIBUTE_SYSTEM
;
299 error_invalid_parameter_format (arg
[i
]);
310 len
= GetCurrentDirectory (MAX_PATH
, szPath
);
311 if (szPath
[len
-1] != _T('\\'))
313 szPath
[len
] = _T('\\');
316 _tcscpy (szFileName
, _T("*.*"));
317 PrintAttribute (szPath
, szFileName
, bRecurse
);
322 /* get full file name */
323 for (i
= 0; i
< argc
; i
++)
325 if ((*arg
[i
] != _T('+')) && (*arg
[i
] != _T('-')) && (*arg
[i
] != _T('/')))
328 GetFullPathName (arg
[i
], MAX_PATH
, szPath
, NULL
);
329 p
= _tcsrchr (szPath
, _T('\\')) + 1;
330 _tcscpy (szFileName
, p
);
334 PrintAttribute (szPath
, szFileName
, bRecurse
);
336 ChangeAttribute (szPath
, szFileName
, dwMask
,
337 dwAttrib
, bRecurse
, bDirectories
);
345 #endif /* INCLUDE_CMD_ATTRIB */