mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[SHELL32] Optimize change notification (#3030)
- Keep the directory lists only. - Don't remember file sizes and normal file paths. CORE-13950
This commit is contained in:
parent
1c40070561
commit
1f31905ecd
7 changed files with 227 additions and 330 deletions
122
dll/win32/shell32/shelldesktop/CDirectoryList.cpp
Normal file
122
dll/win32/shell32/shelldesktop/CDirectoryList.cpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* PROJECT: shell32
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Shell change notification
|
||||
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
#include "shelldesktop.h"
|
||||
#include "CDirectoryList.h"
|
||||
#include <assert.h> // for assert
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shcn);
|
||||
|
||||
BOOL CDirectoryList::ContainsPath(LPCWSTR pszPath) const
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath));
|
||||
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].IsEmpty())
|
||||
continue;
|
||||
|
||||
if (m_items[i].EqualPath(pszPath))
|
||||
return TRUE; // matched
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDirectoryList::AddPath(LPCWSTR pszPath)
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath));
|
||||
return m_items.Add(pszPath);
|
||||
}
|
||||
|
||||
BOOL CDirectoryList::RenamePath(LPCWSTR pszPath1, LPCWSTR pszPath2)
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath1));
|
||||
assert(!PathIsRelativeW(pszPath2));
|
||||
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].EqualPath(pszPath1))
|
||||
{
|
||||
// matched
|
||||
m_items[i].SetPath(pszPath2);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDirectoryList::DeletePath(LPCWSTR pszPath)
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath));
|
||||
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].EqualPath(pszPath))
|
||||
{
|
||||
// matched
|
||||
m_items[i].SetPath(NULL);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CDirectoryList::AddPathsFromDirectory(LPCWSTR pszDirectoryPath)
|
||||
{
|
||||
// get the full path
|
||||
WCHAR szPath[MAX_PATH];
|
||||
lstrcpynW(szPath, pszDirectoryPath, _countof(szPath));
|
||||
assert(!PathIsRelativeW(szPath));
|
||||
|
||||
// is it a directory?
|
||||
if (!PathIsDirectoryW(szPath))
|
||||
return FALSE;
|
||||
|
||||
// add the path
|
||||
if (!AddPath(szPath))
|
||||
return FALSE;
|
||||
|
||||
// enumerate the file items to remember
|
||||
PathAppendW(szPath, L"*");
|
||||
WIN32_FIND_DATAW find;
|
||||
HANDLE hFind = FindFirstFileW(szPath, &find);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ERR("FindFirstFileW failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LPWSTR pch;
|
||||
do
|
||||
{
|
||||
// ignore "." and ".."
|
||||
pch = find.cFileName;
|
||||
if (pch[0] == L'.' && (pch[1] == 0 || (pch[1] == L'.' && pch[2] == 0)))
|
||||
continue;
|
||||
|
||||
// build a path
|
||||
PathRemoveFileSpecW(szPath);
|
||||
if (lstrlenW(szPath) + lstrlenW(find.cFileName) + 1 > MAX_PATH)
|
||||
{
|
||||
ERR("szPath is too long\n");
|
||||
continue;
|
||||
}
|
||||
PathAppendW(szPath, find.cFileName);
|
||||
|
||||
// add the path and do recurse
|
||||
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (m_fRecursive)
|
||||
AddPathsFromDirectory(szPath);
|
||||
else
|
||||
AddPath(szPath);
|
||||
}
|
||||
} while (FindNextFileW(hFind, &find));
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
return TRUE;
|
||||
}
|
93
dll/win32/shell32/shelldesktop/CDirectoryList.h
Normal file
93
dll/win32/shell32/shelldesktop/CDirectoryList.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#pragma once
|
||||
|
||||
#include <atlsimpcoll.h> // for CSimpleArray
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// A pathname with info
|
||||
class CDirectoryItem
|
||||
{
|
||||
public:
|
||||
CDirectoryItem() : m_pszPath(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CDirectoryItem(LPCWSTR pszPath)
|
||||
{
|
||||
m_pszPath = _wcsdup(pszPath);
|
||||
}
|
||||
|
||||
CDirectoryItem(const CDirectoryItem& item)
|
||||
: m_pszPath(_wcsdup(item.m_pszPath))
|
||||
{
|
||||
}
|
||||
|
||||
CDirectoryItem& operator=(const CDirectoryItem& item)
|
||||
{
|
||||
if (this != &item)
|
||||
{
|
||||
free(m_pszPath);
|
||||
m_pszPath = _wcsdup(item.m_pszPath);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~CDirectoryItem()
|
||||
{
|
||||
free(m_pszPath);
|
||||
}
|
||||
|
||||
BOOL IsEmpty() const
|
||||
{
|
||||
return m_pszPath == NULL;
|
||||
}
|
||||
|
||||
LPCWSTR GetPath() const
|
||||
{
|
||||
return m_pszPath;
|
||||
}
|
||||
|
||||
void SetPath(LPCWSTR pszPath)
|
||||
{
|
||||
free(m_pszPath);
|
||||
m_pszPath = _wcsdup(pszPath);
|
||||
}
|
||||
|
||||
BOOL EqualPath(LPCWSTR pszPath) const
|
||||
{
|
||||
return m_pszPath != NULL && lstrcmpiW(m_pszPath, pszPath) == 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
LPWSTR m_pszPath; // A full path, malloc'ed
|
||||
};
|
||||
|
||||
// the directory list
|
||||
class CDirectoryList
|
||||
{
|
||||
public:
|
||||
CDirectoryList() : m_fRecursive(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
CDirectoryList(LPCWSTR pszDirectoryPath, BOOL fRecursive)
|
||||
: m_fRecursive(fRecursive)
|
||||
{
|
||||
AddPathsFromDirectory(pszDirectoryPath);
|
||||
}
|
||||
|
||||
BOOL ContainsPath(LPCWSTR pszPath) const;
|
||||
BOOL AddPath(LPCWSTR pszPath);
|
||||
BOOL AddPathsFromDirectory(LPCWSTR pszDirectoryPath);
|
||||
BOOL RenamePath(LPCWSTR pszPath1, LPCWSTR pszPath2);
|
||||
BOOL DeletePath(LPCWSTR pszPath);
|
||||
|
||||
void RemoveAll()
|
||||
{
|
||||
m_items.RemoveAll();
|
||||
}
|
||||
|
||||
protected:
|
||||
BOOL m_fRecursive;
|
||||
CSimpleArray<CDirectoryItem> m_items;
|
||||
};
|
|
@ -71,7 +71,7 @@ static void NTAPI _RequestAllTerminationAPC(ULONG_PTR Parameter)
|
|||
CDirectoryWatcher::CDirectoryWatcher(LPCWSTR pszDirectoryPath, BOOL fSubTree)
|
||||
: m_fDead(FALSE)
|
||||
, m_fRecursive(fSubTree)
|
||||
, m_file_list(pszDirectoryPath, fSubTree)
|
||||
, m_dir_list(pszDirectoryPath, fSubTree)
|
||||
{
|
||||
TRACE("CDirectoryWatcher::CDirectoryWatcher: %p, '%S'\n", this, pszDirectoryPath);
|
||||
|
||||
|
@ -139,24 +139,6 @@ void CDirectoryWatcher::ProcessNotification()
|
|||
DWORD dwEvent, cbName;
|
||||
BOOL fDir;
|
||||
|
||||
// if the watch is recursive
|
||||
if (m_fRecursive)
|
||||
{
|
||||
// get the first change
|
||||
if (!m_file_list.GetFirstChange(szPath))
|
||||
return;
|
||||
|
||||
// then, notify a SHCNE_UPDATEDIR
|
||||
if (lstrcmpiW(m_szDirectoryPath, szPath) != 0)
|
||||
PathRemoveFileSpecW(szPath);
|
||||
NotifyFileSystemChange(SHCNE_UPDATEDIR, szPath, NULL);
|
||||
|
||||
// refresh directory list
|
||||
m_file_list.RemoveAll();
|
||||
m_file_list.AddPathsFromDirectory(m_szDirectoryPath, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// for each entry in s_buffer
|
||||
szPath[0] = szTempPath[0] = 0;
|
||||
for (;;)
|
||||
|
@ -188,37 +170,37 @@ void CDirectoryWatcher::ProcessNotification()
|
|||
dwEvent = ConvertActionToEvent(pInfo->Action, fDir);
|
||||
|
||||
// convert SHCNE_DELETE to SHCNE_RMDIR if the path is a directory
|
||||
if (!fDir && (dwEvent == SHCNE_DELETE) && m_file_list.ContainsPath(szPath, TRUE))
|
||||
if (!fDir && (dwEvent == SHCNE_DELETE) && m_dir_list.ContainsPath(szPath))
|
||||
{
|
||||
fDir = TRUE;
|
||||
dwEvent = SHCNE_RMDIR;
|
||||
}
|
||||
|
||||
// update m_file_list
|
||||
// update m_dir_list
|
||||
switch (dwEvent)
|
||||
{
|
||||
case SHCNE_MKDIR:
|
||||
if (!m_file_list.AddPath(szPath, 0, TRUE))
|
||||
if (!PathIsDirectoryW(szPath) || !m_dir_list.AddPath(szPath))
|
||||
dwEvent = 0;
|
||||
break;
|
||||
case SHCNE_CREATE:
|
||||
if (!m_file_list.AddPath(szPath, INVALID_FILE_SIZE, FALSE))
|
||||
if (!PathFileExistsW(szPath) || PathIsDirectoryW(szPath))
|
||||
dwEvent = 0;
|
||||
break;
|
||||
case SHCNE_RENAMEFOLDER:
|
||||
if (!m_file_list.RenamePath(szTempPath, szPath, TRUE))
|
||||
if (!PathIsDirectoryW(szPath) || !m_dir_list.RenamePath(szTempPath, szPath))
|
||||
dwEvent = 0;
|
||||
break;
|
||||
case SHCNE_RENAMEITEM:
|
||||
if (!m_file_list.RenamePath(szTempPath, szPath, FALSE))
|
||||
if (!PathFileExistsW(szPath) || PathIsDirectoryW(szPath))
|
||||
dwEvent = 0;
|
||||
break;
|
||||
case SHCNE_RMDIR:
|
||||
if (!m_file_list.DeletePath(szPath, TRUE))
|
||||
if (PathIsDirectoryW(szPath) || !m_dir_list.DeletePath(szPath))
|
||||
dwEvent = 0;
|
||||
break;
|
||||
case SHCNE_DELETE:
|
||||
if (!m_file_list.DeletePath(szPath, FALSE))
|
||||
if (PathFileExistsW(szPath))
|
||||
dwEvent = 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CFilePathList.h"
|
||||
#include "CDirectoryList.h"
|
||||
|
||||
// NOTE: Regard to asynchronous procedure call (APC), please see:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleepex
|
||||
|
@ -31,7 +31,7 @@ public:
|
|||
protected:
|
||||
BOOL m_fDead;
|
||||
BOOL m_fRecursive;
|
||||
CFilePathList m_file_list;
|
||||
CDirectoryList m_dir_list;
|
||||
OVERLAPPED m_overlapped;
|
||||
|
||||
BOOL CreateAPCThread();
|
||||
|
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* PROJECT: shell32
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Shell change notification
|
||||
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
#include "shelldesktop.h"
|
||||
#include "CFilePathList.h"
|
||||
#include <assert.h> // for assert
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shcn);
|
||||
|
||||
BOOL CFilePathList::ContainsPath(LPCWSTR pszPath, BOOL fIsDirectory) const
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath));
|
||||
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].IsEmpty() || fIsDirectory != m_items[i].IsDirectory())
|
||||
continue;
|
||||
|
||||
if (m_items[i].EqualPath(pszPath))
|
||||
return TRUE; // matched
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static DWORD GetSizeOfFile(LPCWSTR pszPath)
|
||||
{
|
||||
WIN32_FIND_DATAW find;
|
||||
HANDLE hFind = FindFirstFileW(pszPath, &find);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
FindClose(hFind);
|
||||
return find.nFileSizeLow;
|
||||
}
|
||||
|
||||
BOOL CFilePathList::AddPath(LPCWSTR pszPath, DWORD dwFileSize, BOOL fIsDirectory)
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath));
|
||||
|
||||
if (dwFileSize == INVALID_FILE_SIZE)
|
||||
{
|
||||
dwFileSize = GetSizeOfFile(pszPath);
|
||||
}
|
||||
|
||||
CFilePathItem item(pszPath, dwFileSize, fIsDirectory);
|
||||
return m_items.Add(item);
|
||||
}
|
||||
|
||||
BOOL CFilePathList::RenamePath(LPCWSTR pszPath1, LPCWSTR pszPath2, BOOL fIsDirectory)
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath1));
|
||||
assert(!PathIsRelativeW(pszPath2));
|
||||
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].IsDirectory() == fIsDirectory && m_items[i].EqualPath(pszPath1))
|
||||
{
|
||||
// matched
|
||||
m_items[i].SetPath(pszPath2);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CFilePathList::DeletePath(LPCWSTR pszPath, BOOL fIsDirectory)
|
||||
{
|
||||
assert(!PathIsRelativeW(pszPath));
|
||||
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].IsDirectory() == fIsDirectory && m_items[i].EqualPath(pszPath))
|
||||
{
|
||||
// matched
|
||||
m_items[i].SetPath(NULL);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CFilePathList::AddPathsFromDirectory(LPCWSTR pszDirectoryPath, BOOL fRecursive)
|
||||
{
|
||||
// get the full path
|
||||
WCHAR szPath[MAX_PATH];
|
||||
lstrcpynW(szPath, pszDirectoryPath, _countof(szPath));
|
||||
assert(!PathIsRelativeW(szPath));
|
||||
|
||||
// is it a directory?
|
||||
if (!PathIsDirectoryW(szPath))
|
||||
return FALSE;
|
||||
|
||||
// add the path
|
||||
if (!AddPath(szPath, 0, TRUE))
|
||||
return FALSE;
|
||||
|
||||
// enumerate the file items to remember
|
||||
PathAppendW(szPath, L"*");
|
||||
WIN32_FIND_DATAW find;
|
||||
HANDLE hFind = FindFirstFileW(szPath, &find);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ERR("FindFirstFileW failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// ignore "." and ".."
|
||||
if (lstrcmpW(find.cFileName, L".") == 0 ||
|
||||
lstrcmpW(find.cFileName, L"..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// build a path
|
||||
PathRemoveFileSpecW(szPath);
|
||||
if (lstrlenW(szPath) + lstrlenW(find.cFileName) + 1 > MAX_PATH)
|
||||
{
|
||||
ERR("szPath is too long\n");
|
||||
continue;
|
||||
}
|
||||
PathAppendW(szPath, find.cFileName);
|
||||
|
||||
BOOL fIsDirectory = !!(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
// add the path and do recurse
|
||||
if (fRecursive && fIsDirectory)
|
||||
AddPathsFromDirectory(szPath, fRecursive);
|
||||
else
|
||||
AddPath(szPath, find.nFileSizeLow, fIsDirectory);
|
||||
} while (FindNextFileW(hFind, &find));
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CFilePathList::GetFirstChange(LPWSTR pszPath) const
|
||||
{
|
||||
// validate paths
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].IsEmpty())
|
||||
continue;
|
||||
|
||||
if (m_items[i].IsDirectory()) // item is a directory
|
||||
{
|
||||
if (!PathIsDirectoryW(m_items[i].GetPath()))
|
||||
{
|
||||
// mismatched
|
||||
lstrcpynW(pszPath, m_items[i].GetPath(), MAX_PATH);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else // item is a normal file
|
||||
{
|
||||
if (!PathFileExistsW(m_items[i].GetPath()) ||
|
||||
PathIsDirectoryW(m_items[i].GetPath()))
|
||||
{
|
||||
// mismatched
|
||||
lstrcpynW(pszPath, m_items[i].GetPath(), MAX_PATH);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check sizes
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATAW find;
|
||||
for (INT i = 0; i < m_items.GetSize(); ++i)
|
||||
{
|
||||
if (m_items[i].IsEmpty() || m_items[i].IsDirectory())
|
||||
continue;
|
||||
|
||||
// get size
|
||||
hFind = FindFirstFileW(m_items[i].GetPath(), &find);
|
||||
FindClose(hFind);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE ||
|
||||
find.nFileSizeLow != m_items[i].GetSize())
|
||||
{
|
||||
// different size
|
||||
lstrcpynW(pszPath, m_items[i].GetPath(), MAX_PATH);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <atlsimpcoll.h> // for CSimpleArray
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// A pathname with info
|
||||
class CFilePathItem
|
||||
{
|
||||
public:
|
||||
CFilePathItem() : m_pszPath(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CFilePathItem(LPCWSTR pszPath, DWORD dwFileSize, BOOL IsDirectory)
|
||||
{
|
||||
m_pszPath = _wcsdup(pszPath);
|
||||
m_dwFileSize = dwFileSize;
|
||||
m_fIsDirectory = IsDirectory;
|
||||
}
|
||||
|
||||
CFilePathItem(const CFilePathItem& item)
|
||||
: m_pszPath(_wcsdup(item.m_pszPath))
|
||||
, m_dwFileSize(item.m_dwFileSize)
|
||||
, m_fIsDirectory(item.m_fIsDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
CFilePathItem& operator=(const CFilePathItem& item)
|
||||
{
|
||||
free(m_pszPath);
|
||||
m_pszPath = _wcsdup(item.m_pszPath);
|
||||
m_dwFileSize = item.m_dwFileSize;
|
||||
m_fIsDirectory = item.m_fIsDirectory;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~CFilePathItem()
|
||||
{
|
||||
free(m_pszPath);
|
||||
}
|
||||
|
||||
BOOL IsEmpty() const
|
||||
{
|
||||
return m_pszPath == NULL;
|
||||
}
|
||||
|
||||
BOOL IsDirectory() const
|
||||
{
|
||||
return m_fIsDirectory;
|
||||
}
|
||||
|
||||
LPCWSTR GetPath() const
|
||||
{
|
||||
return m_pszPath;
|
||||
}
|
||||
|
||||
void SetPath(LPCWSTR pszPath)
|
||||
{
|
||||
free(m_pszPath);
|
||||
m_pszPath = _wcsdup(pszPath);
|
||||
}
|
||||
|
||||
BOOL EqualPath(LPCWSTR pszPath) const
|
||||
{
|
||||
return m_pszPath != NULL && lstrcmpiW(m_pszPath, pszPath) == 0;
|
||||
}
|
||||
|
||||
DWORD GetSize() const
|
||||
{
|
||||
return m_dwFileSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
LPWSTR m_pszPath; // A full path, malloc'ed
|
||||
DWORD m_dwFileSize; // the size of a file
|
||||
BOOL m_fIsDirectory; // is it a directory?
|
||||
};
|
||||
|
||||
// the file list
|
||||
class CFilePathList
|
||||
{
|
||||
public:
|
||||
CFilePathList()
|
||||
{
|
||||
}
|
||||
|
||||
CFilePathList(LPCWSTR pszDirectoryPath, BOOL fRecursive)
|
||||
{
|
||||
AddPathsFromDirectory(pszDirectoryPath, fRecursive);
|
||||
}
|
||||
|
||||
BOOL ContainsPath(LPCWSTR pszPath, BOOL fIsDirectory) const;
|
||||
BOOL GetFirstChange(LPWSTR pszPath) const;
|
||||
|
||||
BOOL AddPath(LPCWSTR pszPath, DWORD dwFileSize, BOOL fIsDirectory);
|
||||
BOOL AddPathsFromDirectory(LPCWSTR pszDirectoryPath, BOOL fRecursive);
|
||||
BOOL RenamePath(LPCWSTR pszPath1, LPCWSTR pszPath2, BOOL fIsDirectory);
|
||||
BOOL DeletePath(LPCWSTR pszPath, BOOL fIsDirectory);
|
||||
|
||||
void RemoveAll()
|
||||
{
|
||||
m_items.RemoveAll();
|
||||
}
|
||||
|
||||
protected:
|
||||
CSimpleArray<CFilePathItem> m_items;
|
||||
};
|
|
@ -13,7 +13,7 @@ list(APPEND SOURCE
|
|||
CChangeNotifyServer.cpp
|
||||
CDesktopBrowser.cpp
|
||||
CDirectoryWatcher.cpp
|
||||
CFilePathList.cpp
|
||||
CDirectoryList.cpp
|
||||
dde.cpp)
|
||||
|
||||
add_library(shelldesktop ${SOURCE})
|
||||
|
|
Loading…
Reference in a new issue