https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f83f650dd695cf6dbb8490...
commit f83f650dd695cf6dbb8490588e9d63c4fe9cfafa Author: Doug Lyons douglyons@douglyons.com AuthorDate: Sun Dec 8 09:24:28 2019 -0600 Commit: Victor Perevertkin victor@perevertkin.ru CommitDate: Tue Dec 28 02:03:54 2021 +0300
attrib command improvements --- base/applications/cmdutils/attrib/attrib.c | 217 ++++++++++++++++------------- 1 file changed, 117 insertions(+), 100 deletions(-)
diff --git a/base/applications/cmdutils/attrib/attrib.c b/base/applications/cmdutils/attrib/attrib.c index 4691821c3c6..0b226898185 100644 --- a/base/applications/cmdutils/attrib/attrib.c +++ b/base/applications/cmdutils/attrib/attrib.c @@ -86,17 +86,22 @@ ErrorMessage( ConPrintf(StdOut, L"%s\n", szMsg); }
+/* Returns TRUE if anything found and listed, FALSE otherwise */ static -INT +BOOL PrintAttribute( LPWSTR pszPath, LPWSTR pszFile, - BOOL bRecurse) + BOOL bRecurse, + BOOL bDirectories) { WIN32_FIND_DATAW findData; HANDLE hFind; WCHAR szFullName[MAX_PATH]; LPWSTR pszFileName; + BOOL bFound = FALSE; + BOOL bIsDir; + BOOL bExactMatch;
/* prepare full file name buffer */ wcscpy(szFullName, pszPath); @@ -105,14 +110,16 @@ PrintAttribute( /* display all subdirectories */ if (bRecurse) { - /* append file name */ - wcscpy(pszFileName, pszFile); + /* append *.* */ + wcscpy(pszFileName, L"*.*");
hFind = FindFirstFileW(szFullName, &findData); if (hFind == INVALID_HANDLE_VALUE) { - ErrorMessage(GetLastError(), pszFile); - return 1; + if ((GetLastError() != ERROR_DIRECTORY) && (GetLastError() != ERROR_SHARING_VIOLATION) + && (GetLastError() != ERROR_FILE_NOT_FOUND)) + ErrorMessage(GetLastError(), pszFile); + return FALSE; }
do @@ -120,31 +127,39 @@ PrintAttribute( if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue;
- if (!wcscmp(findData.cFileName, L".") || - !wcscmp(findData.cFileName, L"..")) + if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L"..")) continue;
wcscpy(pszFileName, findData.cFileName); wcscat(pszFileName, L"\"); - PrintAttribute(szFullName, pszFile, bRecurse); + bFound = PrintAttribute(szFullName, pszFile, bRecurse, + bDirectories) || bFound; } - while(FindNextFileW(hFind, &findData)); + while (FindNextFileW(hFind, &findData)); FindClose(hFind); }
/* append file name */ wcscpy(pszFileName, pszFile);
- /* display current directory */ + /* search current directory */ hFind = FindFirstFileW(szFullName, &findData); if (hFind == INVALID_HANDLE_VALUE) { - ErrorMessage(GetLastError(), pszFile); - return 1; + 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; + wcscpy(pszFileName, findData.cFileName);
ConPrintf(StdOut, @@ -154,129 +169,112 @@ PrintAttribute( (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? L'H' : L' ', (findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? L'R' : L' ', szFullName); + bFound = TRUE; } while(FindNextFileW(hFind, &findData)); FindClose(hFind);
- return 0; + return bFound; }
+/* Returns TRUE if anything changed, FALSE otherwise */ static BOOL ChangeAttribute( LPWSTR pszPath, LPWSTR pszFile, + BOOL bRecurse, + BOOL bDirectories, DWORD dwMask, - DWORD dwAttrib, - BOOL bRecurse, - BOOL bDirectories) + DWORD dwAttrib) { WIN32_FIND_DATAW findData; HANDLE hFind; - DWORD dwAttribute; WCHAR szFullName[MAX_PATH]; LPWSTR pszFileName; - BOOL bWildcard = (wcschr(pszFile, L'*') || wcschr(pszFile, L'?')); + BOOL bFound = FALSE; + BOOL bIsDir; + BOOL bExactMatch; + DWORD dwAttribute;
/* prepare full file name buffer */ wcscpy(szFullName, pszPath); pszFileName = szFullName + wcslen(szFullName);
+ /* display all subdirectories */ + if (bRecurse) + { + /* append *.* */ + wcscpy(pszFileName, L"*.*"); + + hFind = FindFirstFileW(szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + if ((GetLastError() != ERROR_DIRECTORY) && (GetLastError() != ERROR_SHARING_VIOLATION) + && (GetLastError() != ERROR_FILE_NOT_FOUND)) + ErrorMessage(GetLastError(), pszFile); + return FALSE; + } + + do + { + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; + + if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L"..")) + continue; + + wcscpy(pszFileName, findData.cFileName); + wcscat(pszFileName, L"\"); + bFound = ChangeAttribute(szFullName, pszFile, bRecurse, bDirectories, + dwMask, dwAttrib) || bFound; + } + while (FindNextFileW(hFind, &findData)); + FindClose(hFind); + } + /* append file name */ wcscpy(pszFileName, pszFile);
+ /* search current directory */ hFind = FindFirstFileW(szFullName, &findData); if (hFind == INVALID_HANDLE_VALUE) - return FALSE; - - dwAttribute = findData.dwFileAttributes; - - if (!bWildcard) { - FindClose(hFind); - if (dwAttribute & FILE_ATTRIBUTE_DIRECTORY) - { - dwAttribute = (dwAttribute & ~dwMask) | dwAttrib; - SetFileAttributes(szFullName, dwAttribute); - if (bRecurse) - { - 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; - } + return bFound; } - else + + do { - if ((dwAttribute & FILE_ATTRIBUTE_DIRECTORY) && (!bRecurse || !bDirectories)) - return FALSE; + bIsDir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + bExactMatch = wcsicmp(findData.cFileName, pszFile) == 0;
- do - { - dwAttribute = findData.dwFileAttributes; - if (dwAttribute & FILE_ATTRIBUTE_DIRECTORY) - { - if (!bDirectories) - continue; - - if (!wcscmp(findData.cFileName, L".") || - !wcscmp(findData.cFileName, L"..")) - 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)); + if (bIsDir && !bDirectories && !bExactMatch) + continue;
- FindClose(hFind); + 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 TRUE; + return bFound; }
int wmain(int argc, WCHAR *argv[]) { 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]; BOOL bRecurse = FALSE; BOOL bDirectories = FALSE; @@ -389,7 +387,7 @@ int wmain(int argc, WCHAR *argv[]) szPath[len + 1] = UNICODE_NULL; } wcscpy(szFileName, L"*.*"); - PrintAttribute(szPath, szFileName, bRecurse); + PrintAttribute(szPath, szFileName, bRecurse, bDirectories); return 0; }
@@ -405,14 +403,33 @@ int wmain(int argc, WCHAR *argv[])
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, - dwAttrib, bRecurse, bDirectories)) + else if (!ChangeAttribute(szPath, szFileName, bRecurse, bDirectories, dwMask, dwAttrib)) { 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; }