From 35533eb259e18addef2fe4900af332d650a780aa Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Sun, 4 Jun 2006 21:06:55 +0000
Subject: [PATCH] Introduces getdisksize() which reports the total number of
 bytes (or units, e.g. kilobytes)  of the disk (not just the "free space").

---
 src/xpdev/dirwrap.c | 53 ++++++++++++++++++++++++++++++++++-----------
 src/xpdev/dirwrap.h |  1 +
 2 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/src/xpdev/dirwrap.c b/src/xpdev/dirwrap.c
index 269367d5e2..eb213001d5 100644
--- a/src/xpdev/dirwrap.c
+++ b/src/xpdev/dirwrap.c
@@ -680,8 +680,8 @@ static int bit_num(ulong val)
 }
 #endif
 
-/* Unit should be a power-of-2 (e.g. 1024 to report kilobytes) */
-ulong DLLCALL getfreediskspace(const char* path, ulong unit)
+/* Unit should be a power-of-2 (e.g. 1024 to report kilobytes) or 1 (to report bytes) */
+static ulong getdiskspace(const char* path, ulong unit, BOOL freespace)
 {
 #if defined(_WIN32)
 	char			root[16];
@@ -707,20 +707,23 @@ ulong DLLCALL getfreediskspace(const char* path, ulong unit)
 			NULL))		/* receives the free bytes on disk */
 			return(0);
 
+		if(freespace)
+			size=avail;
+
 		if(unit>1)
-			avail.QuadPart=Int64ShrlMod32(avail.QuadPart,bit_num(unit));
+			size.QuadPart=Int64ShrlMod32(size.QuadPart,bit_num(unit));
 
 #if defined(_ANONYMOUS_STRUCT)
-		if(avail.HighPart)
+		if(size.HighPart)
 #else
-		if(avail.u.HighPart)
+		if(size.u.HighPart)
 #endif
 			return(0xffffffff);	/* 4GB max */
 
 #if defined(_ANONYMOUS_STRUCT)
-		return(avail.LowPart);
+		return(size.LowPart);
 #else
-		return(avail.u.LowPart);
+		return(size.u.LowPart);
 #endif
 	}
 
@@ -735,33 +738,47 @@ ulong DLLCALL getfreediskspace(const char* path, ulong unit)
 		))
 		return(0);
 
+	if(freespace)
+		TotalNumberOfClusters = NumberOfFreeClusters;
 	if(unit>1)
-		NumberOfFreeClusters/=unit;
-	return(NumberOfFreeClusters*SectorsPerCluster*BytesPerSector);
+		TotalNumberOfClusters/=unit;
+	return(TotalNumberOfClusters*SectorsPerCluster*BytesPerSector);
 
 
 #elif defined(__solaris__) || (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000 /* NetBSD 3.0 */))
 
 	struct statvfs fs;
+	unsigned long blocks;
 
     if (statvfs(path, &fs) < 0)
     	return 0;
 
+	if(freespace)
+		blocks=fs.f_bavail;
+	else
+		blocks=fs.f_blocks;
+
 	if(unit>1)
-		fs.f_bavail/=unit;
-    return fs.f_bsize * fs.f_bavail;
+		blocks/=unit;
+    return fs.f_bsize * blocks;
     
 /* statfs is also used under FreeBSD (Though it *supports* statvfs() now too) */
 #elif defined(__GLIBC__) || defined(BSD)
 
 	struct statfs fs;
+	unsigned long blocks;
 
     if (statfs(path, &fs) < 0)
     	return 0;
 
+	if(freespace)
+		blocks=fs.f_bavail;
+	else
+		blocks=fs.f_blocks;
+
 	if(unit>1)
-		fs.f_bavail/=unit;
-    return fs.f_bsize * fs.f_bavail;
+		blocks/=unit;
+    return fs.f_bsize * blocks;
     
 #else
 
@@ -771,6 +788,16 @@ ulong DLLCALL getfreediskspace(const char* path, ulong unit)
 #endif
 }
 
+ulong DLLCALL getfreediskspace(const char* path, ulong unit)
+{
+	return getdiskspace(path, unit, /* freespace? */TRUE);
+}
+
+ulong DLLCALL getdisksize(const char* path, ulong unit)
+{
+	return getdiskspace(path, unit, /* freespace? */FALSE);
+}
+
 /****************************************************************************/
 /* Resolves //, /./, and /../ in a path. Should work indetically to Windows */
 /****************************************************************************/
diff --git a/src/xpdev/dirwrap.h b/src/xpdev/dirwrap.h
index 659f694e59..cf9f52c6b6 100644
--- a/src/xpdev/dirwrap.h
+++ b/src/xpdev/dirwrap.h
@@ -227,6 +227,7 @@ DLLEXPORT BOOL		DLLCALL isfullpath(const char* filename);
 DLLEXPORT char*		DLLCALL getfname(const char* path);
 DLLEXPORT char*		DLLCALL getfext(const char* path);
 DLLEXPORT int		DLLCALL getfattr(const char* filename);
+DLLEXPORT ulong		DLLCALL getdisksize(const char* path, ulong unit);
 DLLEXPORT ulong		DLLCALL getfreediskspace(const char* path, ulong unit);
 DLLEXPORT ulong		DLLCALL delfiles(char *inpath, char *spec);
 DLLEXPORT char*		DLLCALL backslash(char* path);
-- 
GitLab