[ros-diffs] [weiden] 27636: Add support for user quotas in GetDiskFreeSpaceExW

weiden at svn.reactos.org weiden at svn.reactos.org
Fri Jul 13 23:42:44 CEST 2007


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/volume.c?rev=27636&r1=27635&r2=27636&view=diff
==============================================================================
--- 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=27636&r1=27635&r2=27636&view=diff
==============================================================================
--- 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
 {




More information about the Ros-diffs mailing list