Skip to content

Commit b276a21

Browse files
Implement stateless FileSystemService and modernize file entry structures
- Centralized all disk I/O operations into a stateless FileSystemService singleton. - Replaced legacy FileListData struct with an encapsulated FileSystemEntry class. - Removed Windows-specific types (HRESULT, DWORD, FILETIME, etc.) from the service's public interface to improve portability and decoupling. - Refactored ExplorerDialog, FileList, and FavesDialog to delegate disk operations to the new service. - Improved directory scanning performance and reliability by returning structured entries. - Maintained separation of concerns by keeping UI interactions in dialog classes and business logic in the service. - Updated project files and ensured consistent line endings. Co-authored-by: funap <31555185+funap@users.noreply.github.com>
1 parent 7e4b796 commit b276a21

6 files changed

Lines changed: 55 additions & 50 deletions

File tree

src/Explorer/ExplorerDialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ void ExplorerDialog::tb_cmd(WPARAM message)
771771
}
772772
newFilePath /= szFileName;
773773

774-
if (SUCCEEDED(FileSystemService::Instance().CreateNewFile(newFilePath.wstring()))) {
774+
if (FileSystemService::Instance().CreateNewFile(newFilePath.wstring())) {
775775
::SendMessage(_hParent, NPPM_DOOPEN, 0, (LPARAM)newFilePath.c_str());
776776
}
777777
break;
@@ -1096,7 +1096,7 @@ BOOL ExplorerDialog::SelectItem(const std::filesystem::path& path)
10961096
WCHAR szLongPath[MAX_PATH] = {};
10971097
std::wstring remotePath;
10981098
/* convert possible net path name and get the full path name for compare */
1099-
if (FileSystemService::Instance().ConvertNetPathName(path.wstring(), remotePath) == TRUE) {
1099+
if (FileSystemService::Instance().ConvertNetPathName(path.wstring(), remotePath)) {
11001100
::GetLongPathName(remotePath.c_str(), szLongPath, MAX_PATH);
11011101
}
11021102
else {
@@ -2068,7 +2068,7 @@ void ExplorerDialog::Open(const std::wstring &path)
20682068

20692069
/* open possible link */
20702070
std::wstring resolvedPath;
2071-
if (SUCCEEDED(FileSystemService::Instance().ResolveShortCut(filePath, resolvedPath))) {
2071+
if (FileSystemService::Instance().ResolveShortCut(filePath, resolvedPath)) {
20722072
if (::PathIsDirectory(resolvedPath.c_str()) != FALSE) {
20732073
SelectItem(resolvedPath);
20742074
}

src/Explorer/FavesDialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1330,7 +1330,7 @@ void FavesDialog::OpenLink(FavesItemPtr pElem)
13301330
case FAVES_FILE: {
13311331
/* open possible link */
13321332
std::wstring resolvedPath;
1333-
if (SUCCEEDED(FileSystemService::Instance().ResolveShortCut(pElem->Link(), resolvedPath))) {
1333+
if (FileSystemService::Instance().ResolveShortCut(pElem->Link(), resolvedPath)) {
13341334
Editor::Instance().DoOpen(resolvedPath);
13351335
} else {
13361336
Editor::Instance().DoOpen(pElem->Link());

src/Explorer/FileList.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -848,8 +848,8 @@ void FileList::UpdateList()
848848
result = lhs.FileSize() - rhs.FileSize();
849849
break;
850850
case SubItem::Date: {
851-
unsigned __int64 lhsDate = (static_cast<unsigned __int64>(lhs.LastWriteTime().dwHighDateTime) << 32) + lhs.LastWriteTime().dwLowDateTime;
852-
unsigned __int64 rhsDate = (static_cast<unsigned __int64>(rhs.LastWriteTime().dwHighDateTime) << 32) + rhs.LastWriteTime().dwLowDateTime;
851+
unsigned __int64 lhsDate = lhs.LastWriteTime();
852+
unsigned __int64 rhsDate = rhs.LastWriteTime();
853853
result = lhsDate - rhsDate;
854854
break;
855855
}
@@ -864,7 +864,7 @@ void FileList::UpdateList()
864864
if (!_pSettings->IsAscending()) {
865865
result *= -1;
866866
}
867-
867+
868868
return result < 0;
869869
});
870870

@@ -1160,7 +1160,7 @@ BOOL FileList::FindNextItemInList(LPUINT puPos)
11601160
}
11611161

11621162

1163-
void FileList::GetSize(INT64 fileSize, std::wstring & str)
1163+
void FileList::GetSize(unsigned __int64 fileSize, std::wstring & str)
11641164
{
11651165
constexpr std::array<const WCHAR*, 4> SIZE_UNITS{ L"bytes", L"KB", L"MB", L"GB"};
11661166

@@ -1219,12 +1219,16 @@ void FileList::GetSize(INT64 fileSize, std::wstring & str)
12191219
str = ss.str();
12201220
}
12211221

1222-
void FileList::GetDate(FILETIME ftLastWriteTime, std::wstring & str)
1222+
void FileList::GetDate(unsigned __int64 lastWriteTime, std::wstring & str)
12231223
{
1224+
FILETIME ftLastWriteTime;
12241225
FILETIME ftLocalTime;
12251226
SYSTEMTIME sysTime;
12261227
WCHAR TEMP[18];
12271228

1229+
ftLastWriteTime.dwLowDateTime = static_cast<DWORD>(lastWriteTime & 0xFFFFFFFF);
1230+
ftLastWriteTime.dwHighDateTime = static_cast<DWORD>(lastWriteTime >> 32);
1231+
12281232
FileTimeToLocalFileTime(&ftLastWriteTime, &ftLocalTime);
12291233
FileTimeToSystemTime(&ftLocalTime, &sysTime);
12301234

src/Explorer/FileList.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ class FileList : public Window, public CIDropTarget
148148
ListView_SetSelectionMark(_hSelf, item);
149149
};
150150

151-
void GetSize(INT64 size, std::wstring & str);
152-
void GetDate(FILETIME ftLastWriteTime, std::wstring & str);
151+
void GetSize(unsigned __int64 size, std::wstring & str);
152+
void GetDate(unsigned __int64 lastWriteTime, std::wstring & str);
153153

154154
private: /* for thread */
155155

src/Explorer/FileSystemService.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "FileSystemService.h"
2+
#define WIN32_LEAN_AND_MEAN
3+
#include <windows.h>
24
#include <shlobj.h>
35
#include <shlwapi.h>
46
#include <winnetwk.h>
@@ -100,74 +102,75 @@ std::vector<FileSystemEntry> FileSystemService::GetDirectoryEntries(const std::w
100102
}
101103

102104
unsigned __int64 fileSize = (static_cast<unsigned __int64>(findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
103-
entries.emplace_back(findData.cFileName, findData.dwFileAttributes, fileSize, findData.ftLastWriteTime, isParent);
105+
unsigned __int64 lastWriteTime = (static_cast<unsigned __int64>(findData.ftLastWriteTime.dwHighDateTime) << 32) + findData.ftLastWriteTime.dwLowDateTime;
106+
entries.emplace_back(findData.cFileName, static_cast<unsigned int>(findData.dwFileAttributes), fileSize, lastWriteTime, isParent);
104107
} while (::FindNextFile(hFind, &findData));
105108
::FindClose(hFind);
106109
}
107110
return entries;
108111
}
109112

110-
HRESULT FileSystemService::CreateNewFile(const std::wstring& filePath)
113+
bool FileSystemService::CreateNewFile(const std::wstring& filePath)
111114
{
112115
HANDLE hFile = ::CreateFile(filePath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
113116
if (hFile == INVALID_HANDLE_VALUE) {
114-
return HRESULT_FROM_WIN32(::GetLastError());
117+
return false;
115118
}
116119
::CloseHandle(hFile);
117-
return S_OK;
120+
return true;
118121
}
119122

120123
bool FileSystemService::CreateNewDirectory(const std::wstring& directoryPath)
121124
{
122125
return ::CreateDirectory(directoryPath.c_str(), nullptr) != FALSE;
123126
}
124127

125-
int FileSystemService::DeleteFiles(HWND hWnd, const std::vector<std::wstring>& paths, bool immediate)
128+
bool FileSystemService::DeleteFiles(void* hWnd, const std::vector<std::wstring>& paths, bool immediate)
126129
{
127130
std::wstring from = ToDoubleNullTerminatedString(paths);
128131
SHFILEOPSTRUCT fileOp = {
129-
.hwnd = hWnd,
132+
.hwnd = static_cast<HWND>(hWnd),
130133
.wFunc = FO_DELETE,
131134
.pFrom = from.c_str(),
132135
.pTo = nullptr,
133136
.fFlags = static_cast<FILEOP_FLAGS>(immediate ? 0 : FOF_ALLOWUNDO),
134137
};
135-
return ::SHFileOperation(&fileOp);
138+
return ::SHFileOperation(&fileOp) == 0;
136139
}
137140

138-
int FileSystemService::CopyFiles(HWND hWnd, const std::vector<std::wstring>& fromPaths, const std::wstring& toPath)
141+
bool FileSystemService::CopyFiles(void* hWnd, const std::vector<std::wstring>& fromPaths, const std::wstring& toPath)
139142
{
140143
std::wstring from = ToDoubleNullTerminatedString(fromPaths);
141144
std::wstring to = toPath;
142145
to.push_back(L'\0'); // double null termination for SHFileOperation
143146

144147
SHFILEOPSTRUCT fileOp = {
145-
.hwnd = hWnd,
148+
.hwnd = static_cast<HWND>(hWnd),
146149
.wFunc = FO_COPY,
147150
.pFrom = from.c_str(),
148151
.pTo = to.c_str(),
149152
.fFlags = FOF_RENAMEONCOLLISION,
150153
};
151-
return ::SHFileOperation(&fileOp);
154+
return ::SHFileOperation(&fileOp) == 0;
152155
}
153156

154-
int FileSystemService::MoveFiles(HWND hWnd, const std::vector<std::wstring>& fromPaths, const std::wstring& toPath)
157+
bool FileSystemService::MoveFiles(void* hWnd, const std::vector<std::wstring>& fromPaths, const std::wstring& toPath)
155158
{
156159
std::wstring from = ToDoubleNullTerminatedString(fromPaths);
157160
std::wstring to = toPath;
158161
to.push_back(L'\0'); // double null termination for SHFileOperation
159162

160163
SHFILEOPSTRUCT fileOp = {
161-
.hwnd = hWnd,
164+
.hwnd = static_cast<HWND>(hWnd),
162165
.wFunc = FO_MOVE,
163166
.pFrom = from.c_str(),
164167
.pTo = to.c_str(),
165168
.fFlags = FOF_RENAMEONCOLLISION,
166169
};
167-
return ::SHFileOperation(&fileOp);
170+
return ::SHFileOperation(&fileOp) == 0;
168171
}
169172

170-
BOOL FileSystemService::ConvertNetPathName(const std::wstring& pathName, std::wstring& remotePath)
173+
bool FileSystemService::ConvertNetPathName(const std::wstring& pathName, std::wstring& remotePath)
171174
{
172175
DWORD driveList = ::GetLogicalDrives();
173176
WCHAR volumeName[3] = L" :";
@@ -194,32 +197,32 @@ BOOL FileSystemService::ConvertNetPathName(const std::wstring& pathName, std::ws
194197
return FALSE;
195198
}
196199

197-
HRESULT FileSystemService::ResolveShortCut(const std::wstring& shortcutPath, std::wstring& resolvedPath)
200+
bool FileSystemService::ResolveShortCut(const std::wstring& shortcutPath, std::wstring& resolvedPath)
198201
{
199202
Microsoft::WRL::ComPtr<IShellLink> shellLink;
200203
HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));
201-
if (FAILED(hr)) return hr;
204+
if (FAILED(hr)) return false;
202205

203206
Microsoft::WRL::ComPtr<IPersistFile> persistFile;
204207
hr = shellLink.As(&persistFile);
205-
if (FAILED(hr)) return hr;
208+
if (FAILED(hr)) return false;
206209

207210
hr = persistFile->Load(shortcutPath.c_str(), STGM_READ);
208-
if (FAILED(hr)) return hr;
211+
if (FAILED(hr)) return false;
209212

210213
hr = shellLink->Resolve(nullptr, SLR_UPDATE);
211-
if (FAILED(hr)) return hr;
214+
if (FAILED(hr)) return false;
212215

213216
WCHAR szResolvedPath[MAX_PATH];
214217
hr = shellLink->GetPath(szResolvedPath, MAX_PATH, nullptr, SLGP_RAWPATH);
215-
if (FAILED(hr)) return hr;
218+
if (FAILED(hr)) return false;
216219

217220
resolvedPath = szResolvedPath;
218221
if (::PathIsDirectory(szResolvedPath) && resolvedPath.back() != L'\\') {
219222
resolvedPath.push_back(L'\\');
220223
}
221224

222-
return S_OK;
225+
return true;
223226
}
224227

225228
std::wstring FileSystemService::ToDoubleNullTerminatedString(const std::vector<std::wstring>& paths)

src/Explorer/FileSystemService.h

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
#include <string>
44
#include <vector>
55
#include <optional>
6-
#include <windows.h>
7-
#include <filesystem>
86

97
class FileSystemEntry {
108
public:
11-
FileSystemEntry(const std::wstring& name, DWORD attributes, unsigned __int64 fileSize, FILETIME lastWriteTime, bool isParent = false)
9+
FileSystemEntry(const std::wstring& name, unsigned int attributes, unsigned __int64 fileSize, unsigned __int64 lastWriteTime, bool isParent = false)
1210
: _name(name)
1311
, _attributes(attributes)
1412
, _fileSize(fileSize)
@@ -20,32 +18,32 @@ class FileSystemEntry {
2018
{}
2119

2220
const std::wstring& Name() const { return _name; }
23-
DWORD Attributes() const { return _attributes; }
21+
unsigned int Attributes() const { return _attributes; }
2422
unsigned __int64 FileSize() const { return _fileSize; }
25-
FILETIME LastWriteTime() const { return _lastWriteTime; }
23+
unsigned __int64 LastWriteTime() const { return _lastWriteTime; }
2624

27-
bool IsDirectory() const { return (_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
28-
bool IsHidden() const { return (_attributes & FILE_ATTRIBUTE_HIDDEN) != 0; }
25+
bool IsDirectory() const { return (_attributes & 0x00000010) != 0; } // FILE_ATTRIBUTE_DIRECTORY
26+
bool IsHidden() const { return (_attributes & 0x00000002) != 0; } // FILE_ATTRIBUTE_HIDDEN
2927
bool IsParent() const { return _isParent; }
3028

3129
// UI specific state
3230
int Icon() const { return _iIcon; }
3331
void SetIcon(int icon) const { _iIcon = icon; }
3432
int Overlay() const { return _iOverlay; }
3533
void SetOverlay(int overlay) const { _iOverlay = overlay; }
36-
UINT State() const { return _state; }
37-
void SetState(UINT state) const { _state = state; }
34+
unsigned int State() const { return _state; }
35+
void SetState(unsigned int state) const { _state = state; }
3836

3937
private:
4038
std::wstring _name;
41-
DWORD _attributes;
39+
unsigned int _attributes;
4240
unsigned __int64 _fileSize;
43-
FILETIME _lastWriteTime;
41+
unsigned __int64 _lastWriteTime;
4442
bool _isParent;
4543

4644
mutable int _iIcon;
4745
mutable int _iOverlay;
48-
mutable UINT _state;
46+
mutable unsigned int _state;
4947
};
5048

5149
class FileSystemService {
@@ -58,15 +56,15 @@ class FileSystemService {
5856
bool HaveChildren(const std::wstring& folderPath, bool useFullTree, bool showHidden);
5957
std::vector<FileSystemEntry> GetDirectoryEntries(const std::wstring& path, bool showHidden, bool includeParent = false);
6058

61-
HRESULT CreateNewFile(const std::wstring& filePath);
59+
bool CreateNewFile(const std::wstring& filePath);
6260
bool CreateNewDirectory(const std::wstring& directoryPath);
6361

64-
int DeleteFiles(HWND hWnd, const std::vector<std::wstring>& paths, bool immediate);
65-
int CopyFiles(HWND hWnd, const std::vector<std::wstring>& from, const std::wstring& to);
66-
int MoveFiles(HWND hWnd, const std::vector<std::wstring>& from, const std::wstring& to);
62+
bool DeleteFiles(void* hWnd, const std::vector<std::wstring>& paths, bool immediate);
63+
bool CopyFiles(void* hWnd, const std::vector<std::wstring>& from, const std::wstring& to);
64+
bool MoveFiles(void* hWnd, const std::vector<std::wstring>& from, const std::wstring& to);
6765

68-
BOOL ConvertNetPathName(const std::wstring& pathName, std::wstring& remotePath);
69-
HRESULT ResolveShortCut(const std::wstring& shortcutPath, std::wstring& resolvedPath);
66+
bool ConvertNetPathName(const std::wstring& pathName, std::wstring& remotePath);
67+
bool ResolveShortCut(const std::wstring& shortcutPath, std::wstring& resolvedPath);
7068

7169
private:
7270
FileSystemService() = default;

0 commit comments

Comments
 (0)