From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/ntdll/tests/file.c | 71 +++++++++++++++++++++++++++++++++++++++++ include/winioctl.h | 17 ++++++++++ 2 files changed, 88 insertions(+)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 8465ad4543a..f30c0a22341 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1337,13 +1337,16 @@ static void test_file_io_completion(void) static void test_file_full_size_information(void) { IO_STATUS_BLOCK io; + FILE_FS_FULL_SIZE_INFORMATION_EX ffsie; FILE_FS_FULL_SIZE_INFORMATION ffsi; FILE_FS_SIZE_INFORMATION fsi; + ULONGLONG expected; HANDLE h; NTSTATUS res;
if(!(h = create_temp_file(0))) return ;
+ memset(&ffsie,0,sizeof(ffsie)); memset(&ffsi,0,sizeof(ffsi)); memset(&fsi,0,sizeof(fsi));
@@ -1383,6 +1386,74 @@ static void test_file_full_size_information(void) ok(ffsi.BytesPerSector == 512, "[ffsi] BytesPerSector expected 512, got %ld\n",ffsi.BytesPerSector); ok(ffsi.SectorsPerAllocationUnit == 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %ld\n",ffsi.SectorsPerAllocationUnit);
+ /* FileFsFullSizeInformationEx is supported on Windows 10 build 1809 and later */ + res = pNtQueryVolumeInformationFile(h, &io, &ffsie, sizeof ffsie, FileFsFullSizeInformationEx); + ok(res == STATUS_INVALID_PARAMETER || res == STATUS_SUCCESS, "cannot get attributes, res %lx\n", res); + + if (res == STATUS_NOT_IMPLEMENTED || res == STATUS_INVALID_PARAMETER) + { + skip( "FileFsFullSizeInformationEx not supported.\n" ); + CloseHandle( h ); + return; + } + + expected = ffsie.ActualAvailableAllocationUnits + ffsie.ActualPoolUnavailableAllocationUnits + + ffsie.UsedAllocationUnits + ffsie.TotalReservedAllocationUnits; + ok(ffsie.ActualTotalAllocationUnits == expected, + "[ffsie] ActualTotalAllocationUnits expected 0x%s, got 0x%s\n", wine_dbgstr_longlong(expected), + wine_dbgstr_longlong(ffsie.ActualTotalAllocationUnits)); + expected = ffsie.ActualTotalAllocationUnits - ffsie.UsedAllocationUnits - ffsie.TotalReservedAllocationUnits; + ok(ffsie.ActualAvailableAllocationUnits == expected, + "[ffsie] ActualAvailableAllocationUnits expected 0x%s, got 0x%s\n", + wine_dbgstr_longlong(expected), wine_dbgstr_longlong(ffsie.ActualAvailableAllocationUnits)); + ok(ffsie.ActualPoolUnavailableAllocationUnits == 0, + "[ffsie] ActualPoolUnavailableAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(ffsie.ActualPoolUnavailableAllocationUnits)); + expected = ffsie.CallerAvailableAllocationUnits + ffsie.CallerPoolUnavailableAllocationUnits + + ffsie.UsedAllocationUnits + ffsie.TotalReservedAllocationUnits; + ok(ffsie.CallerTotalAllocationUnits == expected, + "[ffsie] CallerTotalAllocationUnits expected 0x%s, got 0x%s\n", wine_dbgstr_longlong(expected), + wine_dbgstr_longlong(ffsie.CallerTotalAllocationUnits)); + ok((LONGLONG)ffsie.CallerAvailableAllocationUnits > 0, + "[ffsie] CallerAvailableAllocationUnits expected positive, got 0x%s\n", + wine_dbgstr_longlong(ffsie.CallerAvailableAllocationUnits)); + ok(ffsie.CallerPoolUnavailableAllocationUnits == 0, + "[ffsie] CallerPoolUnavailableAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(ffsie.CallerPoolUnavailableAllocationUnits)); + ok((LONGLONG)ffsie.UsedAllocationUnits > 0, "[ffsie] UsedAllocationUnits expected positive, got 0x%s\n", + wine_dbgstr_longlong(ffsie.UsedAllocationUnits)); + ok((LONGLONG)ffsie.TotalReservedAllocationUnits >= 0, + "[ffsie] TotalReservedAllocationUnits expected >= 0, got 0x%s\n", + wine_dbgstr_longlong(ffsie.TotalReservedAllocationUnits)); + ok(ffsie.VolumeStorageReserveAllocationUnits <= ffsie.TotalReservedAllocationUnits, + "[ffsie] VolumeStorageReserveAllocationUnits expected <= 0x%s, got 0x%s\n", + wine_dbgstr_longlong(ffsie.TotalReservedAllocationUnits), + wine_dbgstr_longlong(ffsie.VolumeStorageReserveAllocationUnits)); + ok(ffsie.AvailableCommittedAllocationUnits == 0 + /* in win10 can be (0 - UsedAllocationUnits - TotalReservedAllocationUnits) */ + || broken((LONGLONG)ffsie.AvailableCommittedAllocationUnits < 0), + "[ffsie] AvailableCommittedAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(ffsie.AvailableCommittedAllocationUnits)); + ok(ffsie.PoolAvailableAllocationUnits == 0, + "[ffsie] PoolAvailableAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(ffsie.PoolAvailableAllocationUnits)); + ok(ffsie.ActualTotalAllocationUnits == ffsi.TotalAllocationUnits.QuadPart, + "[ffsie] TotalAllocationUnits error ffsi:0x%s, ffsie:0x%s\n", + wine_dbgstr_longlong(ffsi.TotalAllocationUnits.QuadPart), + wine_dbgstr_longlong(ffsie.ActualTotalAllocationUnits)); + ok(ffsie.CallerAvailableAllocationUnits == ffsi.CallerAvailableAllocationUnits.QuadPart, + "[ffsie] CallerAvailableAllocationUnits error ffsi:0x%s, ffsie:0x%s\n", + wine_dbgstr_longlong(ffsi.CallerAvailableAllocationUnits.QuadPart), + wine_dbgstr_longlong(ffsie.CallerAvailableAllocationUnits)); + ok(ffsie.ActualAvailableAllocationUnits == ffsi.ActualAvailableAllocationUnits.QuadPart, + "[ffsie] ActualAvailableAllocationUnits error ffsi:0x%s, ffsie:0x%s\n", + wine_dbgstr_longlong(ffsi.ActualAvailableAllocationUnits.QuadPart), + wine_dbgstr_longlong(ffsie.ActualAvailableAllocationUnits)); + + /* Assume file system is NTFS */ + ok(ffsie.BytesPerSector == 512, "[ffsie] BytesPerSector expected 512, got %ld\n",ffsie.BytesPerSector); + ok(ffsie.SectorsPerAllocationUnit == 8, "[ffsie] SectorsPerAllocationUnit expected 8, got %ld\n",ffsie.SectorsPerAllocationUnit); + CloseHandle( h ); }
diff --git a/include/winioctl.h b/include/winioctl.h index ae04c37a462..08fb307a321 100644 --- a/include/winioctl.h +++ b/include/winioctl.h @@ -652,6 +652,23 @@ typedef struct _FILE_FS_FULL_SIZE_INFORMATION { ULONG BytesPerSector; } FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
+/* FileFsFullSizeInformationEx = 14 */ +typedef struct _FILE_FS_FULL_SIZE_INFORMATION_EX { + ULONGLONG ActualTotalAllocationUnits; + ULONGLONG ActualAvailableAllocationUnits; + ULONGLONG ActualPoolUnavailableAllocationUnits; + ULONGLONG CallerTotalAllocationUnits; + ULONGLONG CallerAvailableAllocationUnits; + ULONGLONG CallerPoolUnavailableAllocationUnits; + ULONGLONG UsedAllocationUnits; + ULONGLONG TotalReservedAllocationUnits; + ULONGLONG VolumeStorageReserveAllocationUnits; + ULONGLONG AvailableCommittedAllocationUnits; + ULONGLONG PoolAvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_FULL_SIZE_INFORMATION_EX, *PFILE_FS_FULL_SIZE_INFORMATION_EX; + typedef struct _FILE_PIPE_WAIT_FOR_BUFFER { LARGE_INTEGER Timeout; ULONG NameLength;
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/kernel32/tests/volume.c | 93 ++++++++++++++++++++++++++++++++++++ include/winbase.h | 17 +++++++ 2 files changed, 110 insertions(+)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 24a9a2e7124..0819a50b2c0 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -60,6 +60,7 @@ static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameA)(LPCSTR, LPSTR, DWORD, LP static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameW)(LPCWSTR, LPWSTR, DWORD, LPDWORD); static BOOL (WINAPI *pCreateSymbolicLinkA)(const char *, const char *, DWORD); static BOOL (WINAPI *pGetVolumeInformationByHandleW)(HANDLE, WCHAR *, DWORD, DWORD *, DWORD *, DWORD *, WCHAR *, DWORD); +static HRESULT (WINAPI *pGetDiskSpaceInformationA)(LPCSTR, DISK_SPACE_INFORMATION *);
/* ############################### */
@@ -1736,6 +1737,96 @@ static void test_mountmgr_query_points(void) free(output); }
+#define check_disk_space_information(a) check_disk_space_information_(__LINE__, a) +static void check_disk_space_information_(unsigned int line, const DISK_SPACE_INFORMATION *info) +{ + ULONGLONG expected; + + expected = info->ActualAvailableAllocationUnits + info->ActualPoolUnavailableAllocationUnits + + info->UsedAllocationUnits + info->TotalReservedAllocationUnits; + ok_(__FILE__,line)(info->ActualTotalAllocationUnits == expected, + "ActualTotalAllocationUnits expected 0x%s, got 0x%s\n", wine_dbgstr_longlong(expected), + wine_dbgstr_longlong(info->ActualTotalAllocationUnits)); + expected = info->ActualTotalAllocationUnits - info->UsedAllocationUnits - info->TotalReservedAllocationUnits; + ok_(__FILE__,line)(info->ActualAvailableAllocationUnits == expected, + "ActualAvailableAllocationUnits expected 0x%s, got 0x%s\n", + wine_dbgstr_longlong(expected), wine_dbgstr_longlong(info->ActualAvailableAllocationUnits)); + ok_(__FILE__,line)(info->ActualPoolUnavailableAllocationUnits == 0, + "ActualPoolUnavailableAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(info->ActualPoolUnavailableAllocationUnits)); + expected = info->CallerAvailableAllocationUnits + info->CallerPoolUnavailableAllocationUnits + + info->UsedAllocationUnits + info->TotalReservedAllocationUnits; + ok_(__FILE__,line)(info->CallerTotalAllocationUnits == expected, + "CallerTotalAllocationUnits expected 0x%s, got 0x%s\n", wine_dbgstr_longlong(expected), + wine_dbgstr_longlong(info->CallerTotalAllocationUnits)); + ok_(__FILE__,line)((LONGLONG)info->CallerAvailableAllocationUnits > 0, + "CallerAvailableAllocationUnits expected positive, got 0x%s\n", + wine_dbgstr_longlong(info->CallerAvailableAllocationUnits)); + ok_(__FILE__,line)(info->CallerPoolUnavailableAllocationUnits == 0, + "CallerPoolUnavailableAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(info->CallerPoolUnavailableAllocationUnits)); + ok_(__FILE__,line)((LONGLONG)info->UsedAllocationUnits > 0, "UsedAllocationUnits expected positive, got 0x%s\n", + wine_dbgstr_longlong(info->UsedAllocationUnits)); + ok_(__FILE__,line)((LONGLONG)info->TotalReservedAllocationUnits >= 0, + "TotalReservedAllocationUnits expected >= 0, got 0x%s\n", + wine_dbgstr_longlong(info->TotalReservedAllocationUnits)); + ok_(__FILE__,line)(info->VolumeStorageReserveAllocationUnits <= info->TotalReservedAllocationUnits, + "VolumeStorageReserveAllocationUnits expected <= 0x%s, got 0x%s\n", + wine_dbgstr_longlong(info->TotalReservedAllocationUnits), + wine_dbgstr_longlong(info->VolumeStorageReserveAllocationUnits)); + ok_(__FILE__,line)(info->AvailableCommittedAllocationUnits == 0 + /* in win10 can be (0 - UsedAllocationUnits - TotalReservedAllocationUnits) */ + || broken((LONGLONG)info->AvailableCommittedAllocationUnits < 0), + "AvailableCommittedAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(info->AvailableCommittedAllocationUnits)); + ok_(__FILE__,line)(info->PoolAvailableAllocationUnits == 0, + "PoolAvailableAllocationUnits expected zero, got 0x%s\n", + wine_dbgstr_longlong(info->PoolAvailableAllocationUnits)); + + /* Assume file system is NTFS */ + ok_(__FILE__,line)(info->BytesPerSector == 512, "BytesPerSector expected 512, got %ld\n",info->BytesPerSector); + ok_(__FILE__,line)(info->SectorsPerAllocationUnit == 8, "SectorsPerAllocationUnit expected 8, got %ld\n",info->SectorsPerAllocationUnit); +} + +static void test_GetDiskSpaceInformationA(void) +{ + DISK_SPACE_INFORMATION info; + HRESULT hr; + + /* GetDiskSpaceInformation() is supported on Windows 10 build 1809 and later */ + if (!pGetDiskSpaceInformationA) + { + skip("GetDiskSpaceInformationA is not present.\n"); + return; + } + + memset(&info,0,sizeof(info)); + + hr = pGetDiskSpaceInformationA("Q:\", &info); + todo_wine + ok(hr == HRESULT_FROM_NT(ERROR_BAD_NET_RESP | ERROR_SEVERITY_WARNING | ERROR_SEVERITY_INFORMATIONAL), + "unexpected 0x%08lx\n", hr); + + hr = pGetDiskSpaceInformationA("", &info); + ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "unexpected 0x%08lx\n", hr); + + hr = pGetDiskSpaceInformationA(NULL, NULL); + ok(hr == HRESULT_FROM_NT(ERROR_INVALID_DATA | ERROR_SEVERITY_WARNING | ERROR_SEVERITY_INFORMATIONAL), + "unexpected 0x%08lx\n", hr); + + hr = pGetDiskSpaceInformationA(NULL, &info); + ok(hr == S_OK, "failed 0x%08lx\n", hr); + check_disk_space_information(&info); + + hr = pGetDiskSpaceInformationA("C:\", &info); + ok(hr == S_OK, "failed 0x%08lx\n", hr); + check_disk_space_information(&info); + + hr = pGetDiskSpaceInformationA("\\?\C:\", &info); + ok(hr == S_OK, "failed 0x%08lx\n", hr); + check_disk_space_information(&info); +} + START_TEST(volume) { hdll = GetModuleHandleA("kernel32.dll"); @@ -1748,6 +1839,7 @@ START_TEST(volume) pGetVolumePathNamesForVolumeNameW = (void *) GetProcAddress(hdll, "GetVolumePathNamesForVolumeNameW"); pCreateSymbolicLinkA = (void *) GetProcAddress(hdll, "CreateSymbolicLinkA"); pGetVolumeInformationByHandleW = (void *) GetProcAddress(hdll, "GetVolumeInformationByHandleW"); + pGetDiskSpaceInformationA = (void *) GetProcAddress(hdll, "GetDiskSpaceInformationA");
test_query_dos_deviceA(); test_dos_devices(); @@ -1768,4 +1860,5 @@ START_TEST(volume) test_mounted_folder(); test_GetVolumeInformationByHandle(); test_mountmgr_query_points(); + test_GetDiskSpaceInformationA(); } diff --git a/include/winbase.h b/include/winbase.h index 1ff60ed2769..03c610d5079 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1803,6 +1803,23 @@ typedef enum _PROCESS_INFORMATION_CLASS ProcessInformationClassMax } PROCESS_INFORMATION_CLASS;
+typedef struct DISK_SPACE_INFORMATION +{ + ULONGLONG ActualTotalAllocationUnits; + ULONGLONG ActualAvailableAllocationUnits; + ULONGLONG ActualPoolUnavailableAllocationUnits; + ULONGLONG CallerTotalAllocationUnits; + ULONGLONG CallerAvailableAllocationUnits; + ULONGLONG CallerPoolUnavailableAllocationUnits; + ULONGLONG UsedAllocationUnits; + ULONGLONG TotalReservedAllocationUnits; + ULONGLONG VolumeStorageReserveAllocationUnits; + ULONGLONG AvailableCommittedAllocationUnits; + ULONGLONG PoolAvailableAllocationUnits; + DWORD SectorsPerAllocationUnit; + DWORD BytesPerSector; +} DISK_SPACE_INFORMATION; + WINBASEAPI BOOL WINAPI ActivateActCtx(HANDLE,ULONG_PTR *); WINADVAPI BOOL WINAPI AddAccessAllowedAce(PACL,DWORD,DWORD,PSID); WINADVAPI BOOL WINAPI AddAccessAllowedAceEx(PACL,DWORD,DWORD,DWORD,PSID);
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/ntdll/tests/file.c | 2 +- dlls/ntdll/unix/file.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index f30c0a22341..cc0afdbdb64 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1392,7 +1392,7 @@ static void test_file_full_size_information(void)
if (res == STATUS_NOT_IMPLEMENTED || res == STATUS_INVALID_PARAMETER) { - skip( "FileFsFullSizeInformationEx not supported.\n" ); + win_skip( "FileFsFullSizeInformationEx not supported.\n" ); CloseHandle( h ); return; } diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 8bc69557057..913ed5f32bc 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -2122,6 +2122,31 @@ static NTSTATUS get_full_size_info(int fd, FILE_FS_FULL_SIZE_INFORMATION *info) return STATUS_SUCCESS; }
+static NTSTATUS get_full_size_info_ex(int fd, FILE_FS_FULL_SIZE_INFORMATION_EX *info) +{ + FILE_FS_FULL_SIZE_INFORMATION full_info; + NTSTATUS status; + + if ((status = get_full_size_info(fd, &full_info)) != STATUS_SUCCESS) + return status; + + info->ActualTotalAllocationUnits = full_info.TotalAllocationUnits.QuadPart; + info->ActualAvailableAllocationUnits = full_info.ActualAvailableAllocationUnits.QuadPart; + info->ActualPoolUnavailableAllocationUnits = 0; + info->CallerAvailableAllocationUnits = full_info.CallerAvailableAllocationUnits.QuadPart; + info->CallerPoolUnavailableAllocationUnits = 0; + info->UsedAllocationUnits = info->ActualTotalAllocationUnits - info->ActualAvailableAllocationUnits; + info->CallerTotalAllocationUnits = info->CallerAvailableAllocationUnits + info->UsedAllocationUnits; + info->TotalReservedAllocationUnits = 0; + info->VolumeStorageReserveAllocationUnits = 0; + info->AvailableCommittedAllocationUnits = 0; + info->PoolAvailableAllocationUnits = 0; + info->SectorsPerAllocationUnit = full_info.SectorsPerAllocationUnit; + info->BytesPerSector = full_info.BytesPerSector; + + return STATUS_SUCCESS; +} +
static NTSTATUS server_get_file_info( HANDLE handle, IO_STATUS_BLOCK *io, void *buffer, ULONG length, FILE_INFORMATION_CLASS info_class ) @@ -7037,6 +7062,17 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io } break;
+ case FileFsFullSizeInformationEx: + if (length < sizeof(FILE_FS_FULL_SIZE_INFORMATION_EX)) + status = STATUS_BUFFER_TOO_SMALL; + else + { + FILE_FS_FULL_SIZE_INFORMATION_EX *info = buffer; + if ((status = get_full_size_info_ex(fd, info)) == STATUS_SUCCESS) + io->Information = sizeof(*info); + } + break; + case FileFsObjectIdInformation: FIXME( "%p: object id info not supported\n", handle ); status = STATUS_NOT_IMPLEMENTED;
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/kernel32/kernel32.spec | 1 + dlls/kernelbase/kernelbase.spec | 1 + dlls/kernelbase/volume.c | 25 +++++++++++++++++++++++++ include/winbase.h | 1 + 4 files changed, 28 insertions(+)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 3b6ef866705..70b23720095 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -659,6 +659,7 @@ @ stdcall -import GetDiskFreeSpaceExA (str ptr ptr ptr) @ stdcall -import GetDiskFreeSpaceExW (wstr ptr ptr ptr) @ stdcall -import GetDiskFreeSpaceW(wstr ptr ptr ptr ptr) +@ stdcall -import GetDiskSpaceInformationW(wstr ptr) @ stdcall GetDllDirectoryA(long ptr) @ stdcall GetDllDirectoryW(long ptr) @ stdcall -import GetDriveTypeA(str) diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 50c765c792a..3e9982762a4 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -514,6 +514,7 @@ @ stdcall GetDiskFreeSpaceExA(str ptr ptr ptr) @ stdcall GetDiskFreeSpaceExW(wstr ptr ptr ptr) @ stdcall GetDiskFreeSpaceW(wstr ptr ptr ptr ptr) +@ stdcall GetDiskSpaceInformationW(wstr ptr) @ stdcall GetDriveTypeA(str) @ stdcall GetDriveTypeW(wstr) # @ stub GetDurationFormatEx diff --git a/dlls/kernelbase/volume.c b/dlls/kernelbase/volume.c index d4895228525..38205fa57cf 100644 --- a/dlls/kernelbase/volume.c +++ b/dlls/kernelbase/volume.c @@ -736,6 +736,31 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceA( LPCSTR root, LPDWORD cluster_se }
+/*********************************************************************** + * GetDiskSpaceInformationW (kernelbase.@) + */ +HRESULT WINAPI DECLSPEC_HOTPATCH GetDiskSpaceInformationW( LPCWSTR root, DISK_SPACE_INFORMATION *info ) +{ + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE handle; + + TRACE( "%s,%p\n", debugstr_w(root), info ); + + if (!info) + return HRESULT_FROM_NT( ERROR_INVALID_DATA | ERROR_SEVERITY_WARNING | ERROR_SEVERITY_INFORMATIONAL ); + + if (!open_device_root( root, &handle )) return HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ); + + status = NtQueryVolumeInformationFile( handle, &io, (FILE_FS_FULL_SIZE_INFORMATION_EX *)info, sizeof(*info), + FileFsFullSizeInformationEx ); + NtClose( handle ); + if (!set_ntstatus( status )) return status; + + return S_OK; +} + + static BOOL is_dos_path( const UNICODE_STRING *path ) { static const WCHAR global_prefix[4] = {'\','?','?','\'}; diff --git a/include/winbase.h b/include/winbase.h index 03c610d5079..7361e6dc697 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2201,6 +2201,7 @@ WINBASEAPI BOOL WINAPI GetDiskFreeSpaceW(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, WINBASEAPI BOOL WINAPI GetDiskFreeSpaceExA(LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); WINBASEAPI BOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); #define GetDiskFreeSpaceEx WINELIB_NAME_AW(GetDiskFreeSpaceEx) +WINBASEAPI HRESULT WINAPI GetDiskSpaceInformationW(LPCWSTR,DISK_SPACE_INFORMATION*); WINBASEAPI DWORD WINAPI GetDllDirectoryA(DWORD,LPSTR); WINBASEAPI DWORD WINAPI GetDllDirectoryW(DWORD,LPWSTR); #define GetDllDirectory WINELIB_NAME_AW(GetDllDirectory)
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/kernel32/kernel32.spec | 1 + dlls/kernel32/tests/volume.c | 2 +- dlls/kernelbase/kernelbase.spec | 1 + dlls/kernelbase/volume.c | 12 ++++++++++++ include/winbase.h | 2 ++ 5 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 70b23720095..375b5b470c6 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -659,6 +659,7 @@ @ stdcall -import GetDiskFreeSpaceExA (str ptr ptr ptr) @ stdcall -import GetDiskFreeSpaceExW (wstr ptr ptr ptr) @ stdcall -import GetDiskFreeSpaceW(wstr ptr ptr ptr ptr) +@ stdcall -import GetDiskSpaceInformationA(str ptr) @ stdcall -import GetDiskSpaceInformationW(wstr ptr) @ stdcall GetDllDirectoryA(long ptr) @ stdcall GetDllDirectoryW(long ptr) diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 0819a50b2c0..a227c4251d5 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -1796,7 +1796,7 @@ static void test_GetDiskSpaceInformationA(void) /* GetDiskSpaceInformation() is supported on Windows 10 build 1809 and later */ if (!pGetDiskSpaceInformationA) { - skip("GetDiskSpaceInformationA is not present.\n"); + win_skip("GetDiskSpaceInformationA is not present.\n"); return; }
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 3e9982762a4..f0a041d1de6 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -514,6 +514,7 @@ @ stdcall GetDiskFreeSpaceExA(str ptr ptr ptr) @ stdcall GetDiskFreeSpaceExW(wstr ptr ptr ptr) @ stdcall GetDiskFreeSpaceW(wstr ptr ptr ptr ptr) +@ stdcall GetDiskSpaceInformationA(str ptr) @ stdcall GetDiskSpaceInformationW(wstr ptr) @ stdcall GetDriveTypeA(str) @ stdcall GetDriveTypeW(wstr) diff --git a/dlls/kernelbase/volume.c b/dlls/kernelbase/volume.c index 38205fa57cf..1d22e1c3afb 100644 --- a/dlls/kernelbase/volume.c +++ b/dlls/kernelbase/volume.c @@ -761,6 +761,18 @@ HRESULT WINAPI DECLSPEC_HOTPATCH GetDiskSpaceInformationW( LPCWSTR root, DISK_SP }
+/*********************************************************************** + * GetDiskSpaceInformationA (kernelbase.@) + */ +HRESULT WINAPI DECLSPEC_HOTPATCH GetDiskSpaceInformationA( LPCSTR root, DISK_SPACE_INFORMATION *info ) +{ + WCHAR *rootW = NULL; + + if (root && !(rootW = file_name_AtoW( root, FALSE ))) return FALSE; + return GetDiskSpaceInformationW( rootW, info ); +} + + static BOOL is_dos_path( const UNICODE_STRING *path ) { static const WCHAR global_prefix[4] = {'\','?','?','\'}; diff --git a/include/winbase.h b/include/winbase.h index 7361e6dc697..0d04fa09af0 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2201,7 +2201,9 @@ WINBASEAPI BOOL WINAPI GetDiskFreeSpaceW(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, WINBASEAPI BOOL WINAPI GetDiskFreeSpaceExA(LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); WINBASEAPI BOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); #define GetDiskFreeSpaceEx WINELIB_NAME_AW(GetDiskFreeSpaceEx) +WINBASEAPI HRESULT WINAPI GetDiskSpaceInformationA(LPCSTR,DISK_SPACE_INFORMATION*); WINBASEAPI HRESULT WINAPI GetDiskSpaceInformationW(LPCWSTR,DISK_SPACE_INFORMATION*); +#define GetDiskSpaceInformation WINELIB_NAME_AW(GetDiskSpaceInformation) WINBASEAPI DWORD WINAPI GetDllDirectoryA(DWORD,LPSTR); WINBASEAPI DWORD WINAPI GetDllDirectoryW(DWORD,LPWSTR); #define GetDllDirectory WINELIB_NAME_AW(GetDllDirectory)