Improved GetDiskFreeSpace32A().
diff --git a/files/drive.c b/files/drive.c
index 384d589..c1c3740 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -450,9 +450,9 @@
BY_HANDLE_FILE_INFORMATION info;
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
- TRACE(dosfs, "(%c:,%s)\n", 'A' + drive, path );
strcpy( buffer, "A:" );
buffer[0] += drive;
+ TRACE(dosfs, "(%c:,%s)\n", buffer[0], path );
lstrcpyn32A( buffer + 2, path, sizeof(buffer) - 2 );
if (!DOSFS_GetFullName( buffer, TRUE, &full_name )) return 0;
@@ -630,6 +630,30 @@
/***********************************************************************
* GetDiskFreeSpace32A (KERNEL32.206)
+ *
+ * Fails if expression resulting from current drive's dir and "root"
+ * is not a root dir of the target drive.
+ *
+ * UNDOC: setting some LPDWORDs to NULL is perfectly possible
+ * if the corresponding info is unneeded.
+ *
+ * FIXME: needs to support UNC names from Win95 OSR2 on.
+ *
+ * Behaviour under Win95a:
+ * CurrDir root result
+ * "E:\\TEST" "E:" FALSE
+ * "E:\\" "E:" TRUE
+ * "E:\\" "E" FALSE
+ * "E:\\" "\\" TRUE
+ * "E:\\TEST" "\\" TRUE
+ * "E:\\TEST" ":\\" FALSE
+ * "E:\\TEST" "E:\\" TRUE
+ * "E:\\TEST" "" FALSE
+ * "E:\\" "" FALSE (!)
+ * "E:\\" 0x0 TRUE
+ * "E:\\TEST" 0x0 TRUE (!)
+ * "E:\\TEST" "C:" TRUE (when CurrDir of "C:" set to "\\")
+ * "E:\\TEST" "C:" FALSE (when CurrDir of "C:" set to "\\TEST")
*/
BOOL32 WINAPI GetDiskFreeSpace32A( LPCSTR root, LPDWORD cluster_sectors,
LPDWORD sector_bytes, LPDWORD free_clusters,
@@ -637,17 +661,27 @@
{
int drive;
DWORD size,available;
+ LPCSTR path;
+ DWORD cluster_sec;
- if (!root) drive = DRIVE_GetCurrentDrive();
+ if ((!root) || (root == "\\"))
+ drive = DRIVE_GetCurrentDrive();
else
+ if ( (strlen(root) >= 2) && (root[1] == ':')) /* root contains drive tag */
{
- if ((root[1]) && ((root[1] != ':') || (root[2] != '\\')))
- {
- WARN(dosfs, "invalid root '%s'\n", root );
- return FALSE;
- }
drive = toupper(root[0]) - 'A';
+ path = &root[2];
+ if (path[0] == '\0')
+ path = DRIVE_GetDosCwd(drive);
+ else
+ if (path[0] == '\\')
+ path++;
+ if (strlen(path)) /* oops, we are in a subdir */
+ return FALSE;
}
+ else
+ return FALSE;
+
if (!DRIVE_GetFreeSpace(drive, &size, &available)) return FALSE;
/* Cap the size and available at 2GB as per specs. */
@@ -655,19 +689,26 @@
if (available > 0x7fffffff) available = 0x7fffffff;
if (DRIVE_GetType(drive)==TYPE_CDROM) {
+ if (sector_bytes)
*sector_bytes = 2048;
size /= 2048;
available /= 2048;
} else {
+ if (sector_bytes)
*sector_bytes = 512;
size /= 512;
available /= 512;
}
/* fixme: probably have to adjust those variables too for CDFS */
- *cluster_sectors = 1;
- while (*cluster_sectors * 65536 < size) *cluster_sectors *= 2;
- *free_clusters = available/ *cluster_sectors;
- *total_clusters = size/ *cluster_sectors;
+ cluster_sec = 1;
+ while (cluster_sec * 65536 < size) cluster_sec *= 2;
+
+ if (cluster_sectors)
+ *cluster_sectors = cluster_sec;
+ if (free_clusters)
+ *free_clusters = available / cluster_sec;
+ if (total_clusters)
+ *total_clusters = size / cluster_sec;
return TRUE;
}