https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7d44c1cb0729b37d765758...
commit 7d44c1cb0729b37d7657585f3740c68030e755d8 Author: Kyle Katarn contact@kcsoftwares.com AuthorDate: Thu Sep 10 20:48:40 2020 +0200 Commit: GitHub noreply@github.com CommitDate: Thu Sep 10 20:48:40 2020 +0200
[SHELL32] Show "size on disk" in file/folder properties (#3107)
Co-authored-by: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com Co-authored-by: Hermès BÉLUSCA - MAÏTO hermes.belusca-maito@reactos.org Co-authored-by: Adam Stachowicz saibamenppl@gmail.com --- dll/win32/shell32/dialogs/filedefext.cpp | 118 +++++++++++++++++++++++++------ dll/win32/shell32/dialogs/filedefext.h | 4 +- 2 files changed, 97 insertions(+), 25 deletions(-)
diff --git a/dll/win32/shell32/dialogs/filedefext.cpp b/dll/win32/shell32/dialogs/filedefext.cpp index f4b587dae1e..edcb44ff1b4 100644 --- a/dll/win32/shell32/dialogs/filedefext.cpp +++ b/dll/win32/shell32/dialogs/filedefext.cpp @@ -21,10 +21,64 @@
#include "precomp.h"
+#define NTOS_MODE_USER +#include <ndk/iofuncs.h> +#include <ndk/obfuncs.h> + WINE_DEFAULT_DEBUG_CHANNEL(shell);
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath);
+BOOL GetPhysicalFileSize(LPCWSTR PathBuffer, PULARGE_INTEGER Size) +{ + UNICODE_STRING FileName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + FILE_STANDARD_INFORMATION FileInfo; + NTSTATUS Status; + + if (!RtlDosPathNameToNtPathName_U(PathBuffer, &FileName, NULL, NULL)) + { + ERR("RtlDosPathNameToNtPathName_U failed\n"); + return FALSE; + } + + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&FileHandle, + FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); + RtlFreeUnicodeString(&FileName); + if (!NT_SUCCESS(Status)) + { + ERR("NtOpenFile failed for %S (Status 0x%08lx)\n", PathBuffer, Status); + return FALSE; + } + + /* Query the file size */ + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FileInfo), + FileStandardInformation); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + ERR("NtQueryInformationFile failed for %S (Status: %08lX)\n", PathBuffer, Status); + return FALSE; + } + + Size->QuadPart = FileInfo.AllocationSize.QuadPart; + return TRUE; +} + BOOL CFileVersionInfo::Load(LPCWSTR pwszPath) { ULONG cbInfo = GetFileVersionInfoSizeW(pwszPath, NULL); @@ -552,7 +606,17 @@ CFileDefExt::InitFileAttr(HWND hwndDlg) FileSize.u.LowPart = FileInfo.nFileSizeLow; FileSize.u.HighPart = FileInfo.nFileSizeHigh; if (SH_FormatFileSizeWithBytes(&FileSize, wszBuf, _countof(wszBuf))) + { SetDlgItemTextW(hwndDlg, 14011, wszBuf); + + // Compute file on disk. If fails, use logical size + if (GetPhysicalFileSize(m_wszPath, &FileSize)) + SH_FormatFileSizeWithBytes(&FileSize, wszBuf, _countof(wszBuf)); + else + ERR("Unreliable size on disk\n"); + + SetDlgItemTextW(hwndDlg, 14012, wszBuf); + } } }
@@ -562,8 +626,7 @@ CFileDefExt::InitFileAttr(HWND hwndDlg)
_CountFolderAndFilesData *data = static_cast<_CountFolderAndFilesData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(_CountFolderAndFilesData))); data->This = this; - data->pwszBuf = static_cast<LPWSTR>(HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * MAX_PATH)); - data->cchBufMax = MAX_PATH; + data->pwszBuf = static_cast<LPWSTR>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR) * MAX_PATH)); data->hwndDlg = hwndDlg; this->AddRef(); StringCchCopyW(data->pwszBuf, MAX_PATH, m_wszPath); @@ -574,6 +637,9 @@ CFileDefExt::InitFileAttr(HWND hwndDlg) if (SH_FormatFileSizeWithBytes(&m_DirSize, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14011, wszBuf);
+ if (SH_FormatFileSizeWithBytes(&m_DirSizeOnDisc, wszBuf, _countof(wszBuf))) + SetDlgItemTextW(hwndDlg, 14012, wszBuf); + /* Display files and folders count */ WCHAR wszFormat[256]; LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, wszFormat, _countof(wszFormat)); @@ -1159,6 +1225,7 @@ CFileDefExt::CFileDefExt(): { m_wszPath[0] = L'\0'; m_DirSize.QuadPart = 0ull; + m_DirSizeOnDisc.QuadPart = 0ull;
m_szFolderIconPath[0] = 0; m_nFolderIconIndex = 0; @@ -1293,7 +1360,7 @@ CFileDefExt::_CountFolderAndFilesThreadProc(LPVOID lpParameter) { _CountFolderAndFilesData *data = static_cast<_CountFolderAndFilesData*>(lpParameter); DWORD ticks = 0; - data->This->CountFolderAndFiles(data->hwndDlg, data->pwszBuf, data->cchBufMax, &ticks); + data->This->CountFolderAndFiles(data->hwndDlg, data->pwszBuf, &ticks);
//Release the CFileDefExt and data object holds in the copying thread. data->This->Release(); @@ -1304,25 +1371,19 @@ CFileDefExt::_CountFolderAndFilesThreadProc(LPVOID lpParameter) }
BOOL -CFileDefExt::CountFolderAndFiles(HWND hwndDlg, LPWSTR pwszBuf, UINT cchBufMax, DWORD *ticks) +CFileDefExt::CountFolderAndFiles(HWND hwndDlg, LPCWSTR pwszBuf, DWORD *ticks) { - /* Find filename position */ - UINT cchBuf = wcslen(pwszBuf); - WCHAR *pwszFilename = pwszBuf + cchBuf; - size_t cchFilenameMax = cchBufMax - cchBuf; - if (!cchFilenameMax) - return FALSE; - *(pwszFilename++) = '\'; - --cchFilenameMax; - - /* Find all files, FIXME: shouldn't be "*"? */ - StringCchCopyW(pwszFilename, cchFilenameMax, L"*"); + CString sBuf = pwszBuf; + sBuf += L"\" ; + CString sSearch = sBuf; + sSearch += L"*" ; + CString sFileName;
WIN32_FIND_DATAW wfd; - HANDLE hFind = FindFirstFileW(pwszBuf, &wfd); + HANDLE hFind = FindFirstFileW(sSearch, &wfd); if (hFind == INVALID_HANDLE_VALUE) { - ERR("FindFirstFileW %ls failed\n", pwszBuf); + ERR("FindFirstFileW %ls failed\n", sSearch.GetString()); return FALSE; }
@@ -1334,6 +1395,8 @@ CFileDefExt::CountFolderAndFiles(HWND hwndDlg, LPWSTR pwszBuf, UINT cchBufMax, D
do { + sFileName = sBuf; + sFileName += wfd.cFileName; if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { /* Don't process "." and ".." items */ @@ -1342,8 +1405,7 @@ CFileDefExt::CountFolderAndFiles(HWND hwndDlg, LPWSTR pwszBuf, UINT cchBufMax, D
++m_cFolders;
- StringCchCopyW(pwszFilename, cchFilenameMax, wfd.cFileName); - CountFolderAndFiles(hwndDlg, pwszBuf, cchBufMax, ticks); + CountFolderAndFiles(hwndDlg, sFileName, ticks); } else { @@ -1353,19 +1415,26 @@ CFileDefExt::CountFolderAndFiles(HWND hwndDlg, LPWSTR pwszBuf, UINT cchBufMax, D FileSize.u.LowPart = wfd.nFileSizeLow; FileSize.u.HighPart = wfd.nFileSizeHigh; m_DirSize.QuadPart += FileSize.QuadPart; + // Calculate size on disc + if (!GetPhysicalFileSize(sFileName.GetString(), &FileSize)) + ERR("GetPhysicalFileSize failed for %ls\n", sFileName.GetString()); + m_DirSizeOnDisc.QuadPart += FileSize.QuadPart; } if (GetTickCount() - *ticks > (DWORD) 300) { /* FIXME Using IsWindow is generally ill advised */ if (IsWindow(hwndDlg)) { - WCHAR wszBuf[MAX_PATH]; + WCHAR wszBuf[100];
if (SH_FormatFileSizeWithBytes(&m_DirSize, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14011, wszBuf);
+ if (SH_FormatFileSizeWithBytes(&m_DirSizeOnDisc, wszBuf, _countof(wszBuf))) + SetDlgItemTextW(hwndDlg, 14012, wszBuf); + /* Display files and folders count */ - WCHAR wszFormat[256]; + WCHAR wszFormat[100]; LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, wszFormat, _countof(wszFormat)); StringCchPrintfW(wszBuf, _countof(wszBuf), wszFormat, m_cFiles, m_cFolders); SetDlgItemTextW(hwndDlg, 14027, wszBuf); @@ -1378,13 +1447,16 @@ CFileDefExt::CountFolderAndFiles(HWND hwndDlg, LPWSTR pwszBuf, UINT cchBufMax, D
if (root && IsWindow(hwndDlg)) { - WCHAR wszBuf[MAX_PATH]; + WCHAR wszBuf[100];
if (SH_FormatFileSizeWithBytes(&m_DirSize, wszBuf, _countof(wszBuf))) SetDlgItemTextW(hwndDlg, 14011, wszBuf);
+ if (SH_FormatFileSizeWithBytes(&m_DirSizeOnDisc, wszBuf, _countof(wszBuf))) + SetDlgItemTextW(hwndDlg, 14012, wszBuf); + /* Display files and folders count */ - WCHAR wszFormat[256]; + WCHAR wszFormat[100]; LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, wszFormat, _countof(wszFormat)); StringCchPrintfW(wszBuf, _countof(wszBuf), wszFormat, m_cFiles, m_cFolders); SetDlgItemTextW(hwndDlg, 14027, wszBuf); diff --git a/dll/win32/shell32/dialogs/filedefext.h b/dll/win32/shell32/dialogs/filedefext.h index ce56b84bff1..e093bec7689 100644 --- a/dll/win32/shell32/dialogs/filedefext.h +++ b/dll/win32/shell32/dialogs/filedefext.h @@ -75,7 +75,7 @@ private: static INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK VersionPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK FolderCustomizePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - BOOL CountFolderAndFiles(HWND hwndDlg, LPWSTR pwszBuf, UINT cchBufMax, LPDWORD ticks); + BOOL CountFolderAndFiles(HWND hwndDlg, LPCWSTR pwszBuf, LPDWORD ticks);
WCHAR m_wszPath[MAX_PATH]; CFileVersionInfo m_VerInfo; @@ -84,6 +84,7 @@ private: DWORD m_cFiles; DWORD m_cFolders; ULARGE_INTEGER m_DirSize; + ULARGE_INTEGER m_DirSizeOnDisc;
static DWORD WINAPI _CountFolderAndFilesThreadProc(LPVOID lpParameter);
@@ -136,7 +137,6 @@ struct _CountFolderAndFilesData { CFileDefExt *This; HWND hwndDlg; LPWSTR pwszBuf; - UINT cchBufMax; };
#endif /* _FILE_DEF_EXT_H_ */ \ No newline at end of file