From a111d1fe6464870e095db7a1c99743fd01bf16d1 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 16 Mar 2020 16:01:10 +0100 Subject: [PATCH] winapi: Implement GetDiskFreeSpaceA() --- lib/winapi/fileapi.h | 2 ++ lib/winapi/filemanip.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/lib/winapi/fileapi.h b/lib/winapi/fileapi.h index aae3d73..68a9007 100644 --- a/lib/winapi/fileapi.h +++ b/lib/winapi/fileapi.h @@ -39,6 +39,7 @@ BOOL CreateDirectoryA (LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttrib BOOL MoveFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName); BOOL GetDiskFreeSpaceExA (LPCSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailableToCaller, PULARGE_INTEGER lpTotalNumberOfBytes, PULARGE_INTEGER lpTotalNumberOfFreeBytes); +BOOL GetDiskFreeSpaceA (LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters); #ifndef UNICODE #define GetFileAttributes GetFileAttributesA @@ -52,6 +53,7 @@ BOOL GetDiskFreeSpaceExA (LPCSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAva #define CreateDirectory(...) CreateDirectoryA(__VA_ARGS__) #define MoveFile(...) MoveFileA(__VA_ARGS__) #define GetDiskFreeSpaceEx GetDiskFreeSpaceExA +#define GetDiskFreeSpace GetDiskFreeSpaceA #else #error nxdk does not support the Unicode API #endif diff --git a/lib/winapi/filemanip.c b/lib/winapi/filemanip.c index a93c78b..a791a8d 100644 --- a/lib/winapi/filemanip.c +++ b/lib/winapi/filemanip.c @@ -288,3 +288,54 @@ BOOL GetDiskFreeSpaceExA (LPCSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAva return TRUE; } + +BOOL GetDiskFreeSpaceA (LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters) +{ + NTSTATUS status; + HANDLE handle; + ANSI_STRING path; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + FILE_FS_SIZE_INFORMATION fsSizeInfo; + + assert(lpRootPathName); + + RtlInitAnsiString(&path, lpRootPathName); + InitializeObjectAttributes(&objectAttributes, &path, OBJ_CASE_INSENSITIVE, ObDosDevicesDirectory(), NULL); + + status = NtOpenFile(&handle, FILE_LIST_DIRECTORY | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE | FILE_OPEN_FOR_FREE_SPACE_QUERY); + if (!NT_SUCCESS(status)) { + SetLastError(RtlNtStatusToDosError(status)); + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + SetLastError(ERROR_PATH_NOT_FOUND); + } + return FALSE; + } + + status = NtQueryVolumeInformationFile(handle, &ioStatusBlock, &fsSizeInfo, sizeof(fsSizeInfo), FileFsSizeInformation); + if (!NT_SUCCESS(status)) { + SetLastError(RtlNtStatusToDosError(status)); + return FALSE; + } + + status = NtClose(handle); + if (!NT_SUCCESS(status)) { + SetLastError(RtlNtStatusToDosError(status)); + return FALSE; + } + + if (lpSectorsPerCluster) { + *lpSectorsPerCluster = fsSizeInfo.SectorsPerAllocationUnit; + } + if (lpBytesPerSector) { + *lpBytesPerSector = fsSizeInfo.BytesPerSector; + } + if (lpNumberOfFreeClusters) { + *lpNumberOfFreeClusters = fsSizeInfo.AvailableAllocationUnits.HighPart ? 0xFFFFFFFF : fsSizeInfo.AvailableAllocationUnits.LowPart; + } + if (lpTotalNumberOfClusters) { + *lpTotalNumberOfClusters = fsSizeInfo.TotalAllocationUnits.HighPart ? 0xFFFFFFFF : fsSizeInfo.TotalAllocationUnits.LowPart; + } + + return TRUE; +}