diff --git a/reactos/include/ascii.h b/reactos/include/ascii.h index 8c74f748a86..2a47024668b 100644 --- a/reactos/include/ascii.h +++ b/reactos/include/ascii.h @@ -526,6 +526,15 @@ GetDiskFreeSpaceA( LPDWORD lpTotalNumberOfClusters ); +WINBOOL +STDCALL +GetDiskFreeSpaceExA( + LPCSTR lpDirectoryName, + PULARGE_INTEGER lpFreeBytesAvailableToCaller, + PULARGE_INTEGER lpTotalNumberOfBytes, + PULARGE_INTEGER lpTotalNumberOfFreeBytes + ); + WINBOOL STDCALL CreateDirectoryA( diff --git a/reactos/include/unicode.h b/reactos/include/unicode.h index 01a07ac4ee1..86cd5b203be 100644 --- a/reactos/include/unicode.h +++ b/reactos/include/unicode.h @@ -527,6 +527,15 @@ GetDiskFreeSpaceW( LPDWORD lpTotalNumberOfClusters ); +WINBOOL +STDCALL +GetDiskFreeSpaceExW( + LPCWSTR lpDirectoryName, + PULARGE_INTEGER lpFreeBytesAvailableToCaller, + PULARGE_INTEGER lpTotalNumberOfBytes, + PULARGE_INTEGER lpTotalNumberOfFreeBytes + ); + WINBOOL STDCALL CreateDirectoryW( diff --git a/reactos/lib/kernel32/file/volume.c b/reactos/lib/kernel32/file/volume.c index b724a7f9477..036057dae71 100644 --- a/reactos/lib/kernel32/file/volume.c +++ b/reactos/lib/kernel32/file/volume.c @@ -184,6 +184,88 @@ GetDiskFreeSpaceW( return TRUE; } +WINBOOL +STDCALL +GetDiskFreeSpaceExA( + LPCSTR lpDirectoryName, + PULARGE_INTEGER lpFreeBytesAvailableToCaller, + PULARGE_INTEGER lpTotalNumberOfBytes, + PULARGE_INTEGER lpTotalNumberOfFreeBytes + ) +{ + WCHAR DirectoryNameW[MAX_PATH]; + ULONG i; + + i = 0; + while ((*lpDirectoryName)!=0 && i < MAX_PATH) + { + DirectoryNameW[i] = *lpDirectoryName; + lpDirectoryName++; + i++; + } + DirectoryNameW[i] = 0; + return GetDiskFreeSpaceExW(DirectoryNameW, + lpFreeBytesAvailableToCaller, + lpTotalNumberOfBytes, + lpTotalNumberOfFreeBytes); +} + + +WINBOOL +STDCALL +GetDiskFreeSpaceExW( + LPCWSTR lpDirectoryName, + PULARGE_INTEGER lpFreeBytesAvailableToCaller, + PULARGE_INTEGER lpTotalNumberOfBytes, + PULARGE_INTEGER lpTotalNumberOfFreeBytes + ) +{ + FILE_FS_SIZE_INFORMATION FileFsSize; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE hFile; + NTSTATUS errCode; + WCHAR RootPath[4]; + ULARGE_INTEGER BytesPerCluster; + + wcsncpy (RootPath, lpDirectoryName, 3); + + hFile = CreateFileW(RootPath, + FILE_READ_ATTRIBUTES, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + errCode = NtQueryVolumeInformationFile(hFile, + &IoStatusBlock, + &FileFsSize, + sizeof(FILE_FS_SIZE_INFORMATION), + FileFsSizeInformation); + if (!NT_SUCCESS(errCode)) + { + CloseHandle(hFile); + SetLastError(RtlNtStatusToDosError(errCode)); + return FALSE; + } + + BytesPerCluster.QuadPart = + FileFsSize.BytesPerSector * FileFsSize.SectorsPerAllocationUnit; + + // FIXME: Use quota information + lpFreeBytesAvailableToCaller->QuadPart = + BytesPerCluster.QuadPart * FileFsSize.AvailableAllocationUnits.QuadPart; + + lpTotalNumberOfBytes->QuadPart = + BytesPerCluster.QuadPart * FileFsSize.TotalAllocationUnits.LowPart; + lpTotalNumberOfFreeBytes->QuadPart = + BytesPerCluster.QuadPart * FileFsSize.AvailableAllocationUnits.QuadPart; + + CloseHandle(hFile); + return TRUE; +} + + UINT STDCALL GetDriveTypeA( diff --git a/reactos/lib/kernel32/kernel32.def b/reactos/lib/kernel32/kernel32.def index a3d32ee7d52..5003b7e8c36 100644 --- a/reactos/lib/kernel32/kernel32.def +++ b/reactos/lib/kernel32/kernel32.def @@ -289,6 +289,10 @@ GetDiskFreeSpaceA@20 GetDiskFreeSpaceA = GetDiskFreeSpaceA@20 GetDiskFreeSpaceW@20 GetDiskFreeSpaceW = GetDiskFreeSpaceW@20 +GetDiskFreeSpaceExA@16 +GetDiskFreeSpaceExA = GetDiskFreeSpaceExA@16 +GetDiskFreeSpaceExW@16 +GetDiskFreeSpaceExW = GetDiskFreeSpaceExW@16 ;GetDriveTypeA@4 ;GetDriveTypeW@4 ;GetEnvironmentStrings@0