https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7d44c1cb0729b37d76575…
commit 7d44c1cb0729b37d7657585f3740c68030e755d8
Author: Kyle Katarn <contact(a)kcsoftwares.com>
AuthorDate: Thu Sep 10 20:48:40 2020 +0200
Commit: GitHub <noreply(a)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(a)gmail.com>
Co-authored-by: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
Co-authored-by: Adam Stachowicz <saibamenppl(a)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