Reactos
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
11WINE_DEFAULT_DEBUG_CHANNEL(shcn);
12
13BOOL 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
28BOOL 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
44BOOL 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
61BOOL 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
77BOOL 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}