1 /* 2 * PROJECT: shell32 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Shell change notification 5 * COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 6 */ 7 #include "shelldesktop.h" 8 #include "CDirectoryList.h" 9 #include <assert.h> // for assert 10 11 WINE_DEFAULT_DEBUG_CHANNEL(shcn); 12 13 BOOL CDirectoryList::ContainsPath(LPCWSTR pszPath) const 14 { 15 assert(!PathIsRelativeW(pszPath)); 16 17 for (INT i = 0; i < m_items.GetSize(); ++i) 18 { 19 if (m_items[i].IsEmpty()) 20 continue; 21 22 if (m_items[i].EqualPath(pszPath)) 23 return TRUE; // matched 24 } 25 return FALSE; 26 } 27 28 BOOL CDirectoryList::AddPath(LPCWSTR pszPath) 29 { 30 assert(!PathIsRelativeW(pszPath)); 31 if (ContainsPath(pszPath)) 32 return FALSE; 33 for (INT i = 0; i < m_items.GetSize(); ++i) 34 { 35 if (m_items[i].IsEmpty()) 36 { 37 m_items[i].SetPath(pszPath); 38 return TRUE; 39 } 40 } 41 return m_items.Add(pszPath); 42 } 43 44 BOOL CDirectoryList::RenamePath(LPCWSTR pszPath1, LPCWSTR pszPath2) 45 { 46 assert(!PathIsRelativeW(pszPath1)); 47 assert(!PathIsRelativeW(pszPath2)); 48 49 for (INT i = 0; i < m_items.GetSize(); ++i) 50 { 51 if (m_items[i].EqualPath(pszPath1)) 52 { 53 // matched 54 m_items[i].SetPath(pszPath2); 55 return TRUE; 56 } 57 } 58 return FALSE; 59 } 60 61 BOOL CDirectoryList::DeletePath(LPCWSTR pszPath) 62 { 63 assert(!PathIsRelativeW(pszPath)); 64 65 for (INT i = 0; i < m_items.GetSize(); ++i) 66 { 67 if (m_items[i].EqualPath(pszPath)) 68 { 69 // matched 70 m_items[i].SetPath(NULL); 71 return TRUE; 72 } 73 } 74 return FALSE; 75 } 76 77 BOOL CDirectoryList::AddPathsFromDirectory(LPCWSTR pszDirectoryPath) 78 { 79 // get the full path 80 WCHAR szPath[MAX_PATH]; 81 lstrcpynW(szPath, pszDirectoryPath, _countof(szPath)); 82 assert(!PathIsRelativeW(szPath)); 83 84 // is it a directory? 85 if (!PathIsDirectoryW(szPath)) 86 return FALSE; 87 88 // add the path 89 if (!AddPath(szPath)) 90 return FALSE; 91 92 // enumerate the file items to remember 93 PathAppendW(szPath, L"*"); 94 WIN32_FIND_DATAW find; 95 HANDLE hFind = FindFirstFileW(szPath, &find); 96 if (hFind == INVALID_HANDLE_VALUE) 97 { 98 ERR("FindFirstFileW failed\n"); 99 return FALSE; 100 } 101 102 LPWSTR pch; 103 do 104 { 105 // ignore "." and ".." 106 pch = find.cFileName; 107 if (pch[0] == L'.' && (pch[1] == 0 || (pch[1] == L'.' && pch[2] == 0))) 108 continue; 109 110 // build a path 111 PathRemoveFileSpecW(szPath); 112 if (lstrlenW(szPath) + lstrlenW(find.cFileName) + 1 > MAX_PATH) 113 { 114 ERR("szPath is too long\n"); 115 continue; 116 } 117 PathAppendW(szPath, find.cFileName); 118 119 // add the path and do recurse 120 if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 121 { 122 if (m_fRecursive) 123 AddPathsFromDirectory(szPath); 124 else 125 AddPath(szPath); 126 } 127 } while (FindNextFileW(hFind, &find)); 128 129 FindClose(hFind); 130 131 return TRUE; 132 } 133