Author: weiden Date: Sat Jul 14 01:42:44 2007 New Revision: 27636
URL: http://svn.reactos.org/svn/reactos?rev=27636&view=rev Log: Add support for user quotas in GetDiskFreeSpaceExW
Modified: trunk/reactos/dll/win32/kernel32/file/volume.c trunk/reactos/include/ndk/iotypes.h
Modified: trunk/reactos/dll/win32/kernel32/file/volume.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/file/vol... ============================================================================== --- trunk/reactos/dll/win32/kernel32/file/volume.c (original) +++ trunk/reactos/dll/win32/kernel32/file/volume.c Sat Jul 14 01:42:44 2007 @@ -307,61 +307,104 @@ PULARGE_INTEGER lpTotalNumberOfFreeBytes ) { - FILE_FS_SIZE_INFORMATION FileFsSize; + union + { + FILE_FS_SIZE_INFORMATION FsSize; + FILE_FS_FULL_SIZE_INFORMATION FsFullSize; + } FsInfo; IO_STATUS_BLOCK IoStatusBlock; ULARGE_INTEGER BytesPerCluster; - WCHAR RootPathName[MAX_PATH]; HANDLE hFile; - NTSTATUS errCode; - - /* - FIXME: this is obviously wrong for UNC paths, symbolic directories etc. - -Gunnar - */ - if (lpDirectoryName) - { - wcsncpy (RootPathName, lpDirectoryName, 3); - } - else - { - GetCurrentDirectoryW (MAX_PATH, RootPathName); - } - RootPathName[3] = 0; - - hFile = InternalOpenDirW(RootPathName, FALSE); + NTSTATUS Status; + + if (lpDirectoryName == NULL) + lpDirectoryName = L"\"; + + hFile = InternalOpenDirW(lpDirectoryName, FALSE); if (INVALID_HANDLE_VALUE == hFile) { return FALSE; }
- errCode = NtQueryVolumeInformationFile(hFile, - &IoStatusBlock, - &FileFsSize, - sizeof(FILE_FS_SIZE_INFORMATION), - FileFsSizeInformation); - if (!NT_SUCCESS(errCode)) - { - CloseHandle(hFile); - SetLastErrorByStatus (errCode); + if (lpFreeBytesAvailableToCaller != NULL || lpTotalNumberOfBytes != NULL) + { + /* To get the free space available to the user associated with the + current thread, try FileFsFullSizeInformation. If this is not + supported by the file system, fall back to FileFsSize */ + + Status = NtQueryVolumeInformationFile(hFile, + &IoStatusBlock, + &FsInfo.FsFullSize, + sizeof(FsInfo.FsFullSize), + FileFsFullSizeInformation); + + if (NT_SUCCESS(Status)) + { + /* Close the handle before returning data + to avoid a handle leak in case of a fault! */ + CloseHandle(hFile); + + BytesPerCluster.QuadPart = + FsInfo.FsFullSize.BytesPerSector * FsInfo.FsFullSize.SectorsPerAllocationUnit; + + if (lpFreeBytesAvailableToCaller != NULL) + { + lpFreeBytesAvailableToCaller->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.CallerAvailableAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfBytes != NULL) + { + lpTotalNumberOfBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.TotalAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfFreeBytes != NULL) + { + lpTotalNumberOfFreeBytes->QuadPart = + BytesPerCluster.QuadPart * FsInfo.FsFullSize.ActualAvailableAllocationUnits.QuadPart; + } + + return TRUE; + } + } + + Status = NtQueryVolumeInformationFile(hFile, + &IoStatusBlock, + &FsInfo.FsSize, + sizeof(FsInfo.FsSize), + FileFsSizeInformation); + + /* Close the handle before returning data + to avoid a handle leak in case of a fault! */ + CloseHandle(hFile); + + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus (Status); return FALSE; }
BytesPerCluster.QuadPart = - FileFsSize.BytesPerSector * FileFsSize.SectorsPerAllocationUnit; - - // FIXME: Use quota information - if (lpFreeBytesAvailableToCaller) + FsInfo.FsSize.BytesPerSector * FsInfo.FsSize.SectorsPerAllocationUnit; + + if (lpFreeBytesAvailableToCaller) + { lpFreeBytesAvailableToCaller->QuadPart = - BytesPerCluster.QuadPart * FileFsSize.AvailableAllocationUnits.QuadPart; - - if (lpTotalNumberOfBytes) + BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfBytes) + { lpTotalNumberOfBytes->QuadPart = - BytesPerCluster.QuadPart * FileFsSize.TotalAllocationUnits.QuadPart; - if (lpTotalNumberOfFreeBytes) + BytesPerCluster.QuadPart * FsInfo.FsSize.TotalAllocationUnits.QuadPart; + } + + if (lpTotalNumberOfFreeBytes) + { lpTotalNumberOfFreeBytes->QuadPart = - BytesPerCluster.QuadPart * FileFsSize.AvailableAllocationUnits.QuadPart; - - CloseHandle(hFile); + BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart; + }
return TRUE; }
Modified: trunk/reactos/include/ndk/iotypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/iotypes.h?rev=2... ============================================================================== --- trunk/reactos/include/ndk/iotypes.h (original) +++ trunk/reactos/include/ndk/iotypes.h Sat Jul 14 01:42:44 2007 @@ -584,6 +584,15 @@ ULONG SectorsPerAllocationUnit; ULONG BytesPerSector; } FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + +typedef struct _FILE_FS_FULL_SIZE_INFORMATION +{ + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER CallerAvailableAllocationUnits; + LARGE_INTEGER ActualAvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
typedef struct _FILE_FS_LABEL_INFORMATION {