mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
attrib command improvements
This commit is contained in:
parent
b34b47056a
commit
f83f650dd6
1 changed files with 118 additions and 101 deletions
|
@ -86,17 +86,22 @@ ErrorMessage(
|
||||||
ConPrintf(StdOut, L"%s\n", szMsg);
|
ConPrintf(StdOut, L"%s\n", szMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns TRUE if anything found and listed, FALSE otherwise */
|
||||||
static
|
static
|
||||||
INT
|
BOOL
|
||||||
PrintAttribute(
|
PrintAttribute(
|
||||||
LPWSTR pszPath,
|
LPWSTR pszPath,
|
||||||
LPWSTR pszFile,
|
LPWSTR pszFile,
|
||||||
BOOL bRecurse)
|
BOOL bRecurse,
|
||||||
|
BOOL bDirectories)
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATAW findData;
|
WIN32_FIND_DATAW findData;
|
||||||
HANDLE hFind;
|
HANDLE hFind;
|
||||||
WCHAR szFullName[MAX_PATH];
|
WCHAR szFullName[MAX_PATH];
|
||||||
LPWSTR pszFileName;
|
LPWSTR pszFileName;
|
||||||
|
BOOL bFound = FALSE;
|
||||||
|
BOOL bIsDir;
|
||||||
|
BOOL bExactMatch;
|
||||||
|
|
||||||
/* prepare full file name buffer */
|
/* prepare full file name buffer */
|
||||||
wcscpy(szFullName, pszPath);
|
wcscpy(szFullName, pszPath);
|
||||||
|
@ -105,14 +110,16 @@ PrintAttribute(
|
||||||
/* display all subdirectories */
|
/* display all subdirectories */
|
||||||
if (bRecurse)
|
if (bRecurse)
|
||||||
{
|
{
|
||||||
/* append file name */
|
/* append *.* */
|
||||||
wcscpy(pszFileName, pszFile);
|
wcscpy(pszFileName, L"*.*");
|
||||||
|
|
||||||
hFind = FindFirstFileW(szFullName, &findData);
|
hFind = FindFirstFileW(szFullName, &findData);
|
||||||
if (hFind == INVALID_HANDLE_VALUE)
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
ErrorMessage(GetLastError(), pszFile);
|
if ((GetLastError() != ERROR_DIRECTORY) && (GetLastError() != ERROR_SHARING_VIOLATION)
|
||||||
return 1;
|
&& (GetLastError() != ERROR_FILE_NOT_FOUND))
|
||||||
|
ErrorMessage(GetLastError(), pszFile);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -120,31 +127,39 @@ PrintAttribute(
|
||||||
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!wcscmp(findData.cFileName, L".") ||
|
if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L".."))
|
||||||
!wcscmp(findData.cFileName, L".."))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wcscpy(pszFileName, findData.cFileName);
|
wcscpy(pszFileName, findData.cFileName);
|
||||||
wcscat(pszFileName, L"\\");
|
wcscat(pszFileName, L"\\");
|
||||||
PrintAttribute(szFullName, pszFile, bRecurse);
|
bFound = PrintAttribute(szFullName, pszFile, bRecurse,
|
||||||
|
bDirectories) || bFound;
|
||||||
}
|
}
|
||||||
while(FindNextFileW(hFind, &findData));
|
while (FindNextFileW(hFind, &findData));
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* append file name */
|
/* append file name */
|
||||||
wcscpy(pszFileName, pszFile);
|
wcscpy(pszFileName, pszFile);
|
||||||
|
|
||||||
/* display current directory */
|
/* search current directory */
|
||||||
hFind = FindFirstFileW(szFullName, &findData);
|
hFind = FindFirstFileW(szFullName, &findData);
|
||||||
if (hFind == INVALID_HANDLE_VALUE)
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
ErrorMessage(GetLastError(), pszFile);
|
return bFound;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
bIsDir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
bExactMatch = wcsicmp(findData.cFileName, pszFile) == 0;
|
||||||
|
|
||||||
|
if (bIsDir && !bDirectories && !bExactMatch)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
wcscpy(pszFileName, findData.cFileName);
|
wcscpy(pszFileName, findData.cFileName);
|
||||||
|
|
||||||
ConPrintf(StdOut,
|
ConPrintf(StdOut,
|
||||||
|
@ -154,129 +169,112 @@ PrintAttribute(
|
||||||
(findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? L'H' : L' ',
|
(findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? L'H' : L' ',
|
||||||
(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? L'R' : L' ',
|
(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? L'R' : L' ',
|
||||||
szFullName);
|
szFullName);
|
||||||
|
bFound = TRUE;
|
||||||
}
|
}
|
||||||
while(FindNextFileW(hFind, &findData));
|
while(FindNextFileW(hFind, &findData));
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
|
|
||||||
return 0;
|
return bFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns TRUE if anything changed, FALSE otherwise */
|
||||||
static
|
static
|
||||||
BOOL
|
BOOL
|
||||||
ChangeAttribute(
|
ChangeAttribute(
|
||||||
LPWSTR pszPath,
|
LPWSTR pszPath,
|
||||||
LPWSTR pszFile,
|
LPWSTR pszFile,
|
||||||
|
BOOL bRecurse,
|
||||||
|
BOOL bDirectories,
|
||||||
DWORD dwMask,
|
DWORD dwMask,
|
||||||
DWORD dwAttrib,
|
DWORD dwAttrib)
|
||||||
BOOL bRecurse,
|
|
||||||
BOOL bDirectories)
|
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATAW findData;
|
WIN32_FIND_DATAW findData;
|
||||||
HANDLE hFind;
|
HANDLE hFind;
|
||||||
DWORD dwAttribute;
|
|
||||||
WCHAR szFullName[MAX_PATH];
|
WCHAR szFullName[MAX_PATH];
|
||||||
LPWSTR pszFileName;
|
LPWSTR pszFileName;
|
||||||
BOOL bWildcard = (wcschr(pszFile, L'*') || wcschr(pszFile, L'?'));
|
BOOL bFound = FALSE;
|
||||||
|
BOOL bIsDir;
|
||||||
|
BOOL bExactMatch;
|
||||||
|
DWORD dwAttribute;
|
||||||
|
|
||||||
/* prepare full file name buffer */
|
/* prepare full file name buffer */
|
||||||
wcscpy(szFullName, pszPath);
|
wcscpy(szFullName, pszPath);
|
||||||
pszFileName = szFullName + wcslen(szFullName);
|
pszFileName = szFullName + wcslen(szFullName);
|
||||||
|
|
||||||
/* append file name */
|
/* display all subdirectories */
|
||||||
wcscpy(pszFileName, pszFile);
|
if (bRecurse)
|
||||||
|
|
||||||
hFind = FindFirstFileW(szFullName, &findData);
|
|
||||||
if (hFind == INVALID_HANDLE_VALUE)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
dwAttribute = findData.dwFileAttributes;
|
|
||||||
|
|
||||||
if (!bWildcard)
|
|
||||||
{
|
{
|
||||||
FindClose(hFind);
|
/* append *.* */
|
||||||
if (dwAttribute & FILE_ATTRIBUTE_DIRECTORY)
|
wcscpy(pszFileName, L"*.*");
|
||||||
|
|
||||||
|
hFind = FindFirstFileW(szFullName, &findData);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
dwAttribute = (dwAttribute & ~dwMask) | dwAttrib;
|
if ((GetLastError() != ERROR_DIRECTORY) && (GetLastError() != ERROR_SHARING_VIOLATION)
|
||||||
SetFileAttributes(szFullName, dwAttribute);
|
&& (GetLastError() != ERROR_FILE_NOT_FOUND))
|
||||||
if (bRecurse)
|
ErrorMessage(GetLastError(), pszFile);
|
||||||
{
|
|
||||||
if (bDirectories)
|
|
||||||
{
|
|
||||||
ChangeAttribute(szFullName, L"*", dwMask, dwAttrib,
|
|
||||||
bRecurse, bDirectories);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ChangeAttribute(szFullName, L"*", dwMask, dwAttrib,
|
|
||||||
bRecurse, FALSE))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!bDirectories)
|
|
||||||
{
|
|
||||||
ChangeAttribute(szFullName, L"*", dwMask, dwAttrib,
|
|
||||||
bRecurse, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dwAttribute = (dwAttribute & ~dwMask) | dwAttrib;
|
|
||||||
SetFileAttributes(szFullName, dwAttribute);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((dwAttribute & FILE_ATTRIBUTE_DIRECTORY) && (!bRecurse || !bDirectories))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
dwAttribute = findData.dwFileAttributes;
|
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
if (dwAttribute & FILE_ATTRIBUTE_DIRECTORY)
|
continue;
|
||||||
{
|
|
||||||
if (!bDirectories)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!wcscmp(findData.cFileName, L".") ||
|
if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L".."))
|
||||||
!wcscmp(findData.cFileName, L".."))
|
continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
wcscpy(pszFileName, findData.cFileName);
|
|
||||||
dwAttribute = (dwAttribute & ~dwMask) | dwAttrib;
|
|
||||||
SetFileAttributes(szFullName, dwAttribute);
|
|
||||||
|
|
||||||
if (bRecurse)
|
|
||||||
{
|
|
||||||
ChangeAttribute(szFullName, findData.cFileName, dwMask,
|
|
||||||
dwAttrib, bRecurse, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wcscpy(pszFileName, findData.cFileName);
|
|
||||||
dwAttribute = (dwAttribute & ~dwMask) | dwAttrib;
|
|
||||||
SetFileAttributes(szFullName, dwAttribute);
|
|
||||||
}
|
|
||||||
} while (FindNextFileW(hFind, &findData));
|
|
||||||
|
|
||||||
|
wcscpy(pszFileName, findData.cFileName);
|
||||||
|
wcscat(pszFileName, L"\\");
|
||||||
|
bFound = ChangeAttribute(szFullName, pszFile, bRecurse, bDirectories,
|
||||||
|
dwMask, dwAttrib) || bFound;
|
||||||
|
}
|
||||||
|
while (FindNextFileW(hFind, &findData));
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
/* append file name */
|
||||||
|
wcscpy(pszFileName, pszFile);
|
||||||
|
|
||||||
|
/* search current directory */
|
||||||
|
hFind = FindFirstFileW(szFullName, &findData);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
return bFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bIsDir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
bExactMatch = wcsicmp(findData.cFileName, pszFile) == 0;
|
||||||
|
|
||||||
|
if (bIsDir && !bDirectories && !bExactMatch)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (bRecurse && bIsDir && !bDirectories)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wcscpy(pszFileName, findData.cFileName);
|
||||||
|
|
||||||
|
dwAttribute = (findData.dwFileAttributes & ~dwMask) | dwAttrib;
|
||||||
|
|
||||||
|
SetFileAttributes(szFullName, dwAttribute);
|
||||||
|
bFound = TRUE;
|
||||||
|
}
|
||||||
|
while(FindNextFileW(hFind, &findData));
|
||||||
|
FindClose(hFind);
|
||||||
|
|
||||||
|
return bFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wmain(int argc, WCHAR *argv[])
|
int wmain(int argc, WCHAR *argv[])
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
WCHAR szPath[MAX_PATH];
|
WCHAR szPath[MAX_PATH] = L""; // For case we only use 'attrib +h /s' there is no szPath
|
||||||
WCHAR szFileName [MAX_PATH];
|
WCHAR szFileName [MAX_PATH];
|
||||||
BOOL bRecurse = FALSE;
|
BOOL bRecurse = FALSE;
|
||||||
BOOL bDirectories = FALSE;
|
BOOL bDirectories = FALSE;
|
||||||
|
@ -389,7 +387,7 @@ int wmain(int argc, WCHAR *argv[])
|
||||||
szPath[len + 1] = UNICODE_NULL;
|
szPath[len + 1] = UNICODE_NULL;
|
||||||
}
|
}
|
||||||
wcscpy(szFileName, L"*.*");
|
wcscpy(szFileName, L"*.*");
|
||||||
PrintAttribute(szPath, szFileName, bRecurse);
|
PrintAttribute(szPath, szFileName, bRecurse, bDirectories);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,14 +403,33 @@ int wmain(int argc, WCHAR *argv[])
|
||||||
|
|
||||||
if (dwMask == 0)
|
if (dwMask == 0)
|
||||||
{
|
{
|
||||||
PrintAttribute(szPath, szFileName, bRecurse);
|
if (!PrintAttribute(szPath, szFileName, bRecurse, bDirectories))
|
||||||
|
{
|
||||||
|
ConResPrintf(StdOut, STRING_FILE_NOT_FOUND, argv[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!ChangeAttribute(szPath, szFileName, dwMask,
|
else if (!ChangeAttribute(szPath, szFileName, bRecurse, bDirectories, dwMask, dwAttrib))
|
||||||
dwAttrib, bRecurse, bDirectories))
|
|
||||||
{
|
{
|
||||||
ConResPrintf(StdOut, STRING_FILE_NOT_FOUND, argv[i]);
|
ConResPrintf(StdOut, STRING_FILE_NOT_FOUND, argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Code below handles the special case of 'attrib +h /s' and similar
|
||||||
|
|
||||||
|
if (bRecurse && dwMask && (wcscmp(szPath, L"") == 0))
|
||||||
|
{
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
len = GetCurrentDirectory(MAX_PATH, szPath);
|
||||||
|
if (szPath[len-1] != L'\\')
|
||||||
|
{
|
||||||
|
szPath[len] = L'\\';
|
||||||
|
szPath[len + 1] = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
wcscpy(szFileName, L"*.*");
|
||||||
|
if (!ChangeAttribute(szPath, szFileName, bRecurse, bDirectories, dwMask, dwAttrib))
|
||||||
|
ConResPrintf(StdOut, STRING_FILE_NOT_FOUND, szFileName);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue