diff --git a/src/xpdev/dirwrap.c b/src/xpdev/dirwrap.c
index 269367d5e26600d741d7ed8d7b339fc2bd50d25c..eb213001d554c8c2d5ce1dbb432aa83dc783cf02 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 659f694e5992397ab5d269e5a669c51ae1972bb8..cf9f52c6b618e2051c384ffe7b04f3fabc0f0fce 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);