From eadd7bd2cbef3ca0bde3e93ad9671a783e4e90b0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 25 Aug 2001 16:54:14 +0000 Subject: [PATCH] added wxGetDiskSpace for Win/Unix git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11476 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 3 +- docs/latex/wx/function.tex | 21 +++++++++ include/wx/utils.h | 15 ++++-- samples/console/console.cpp | 12 ++--- src/msw/utils.cpp | 91 +++++++++++++++++++++++++++++++++++++ src/unix/utilsunx.cpp | 32 +++++++++++++ 6 files changed, 164 insertions(+), 10 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 48d3c7cc7c..f7dc556f01 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -7,7 +7,8 @@ wxWindows 2 Change Log wxBase: - wxRegEx class added -- more fixes to wxMBConv classes. Conversion to and from wchar_t now works with +- wxGetDiskSpace() function added (Jonothan Farr, Markus Fieber) +- more fixes to wxMBConv classes. Conversion to and from wchar_t now works with glibc 2.2 as well as with glibc 2.1. Unix version now checks for iconv()'s capabilities at runtime instead of in the configure script. diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index aab0d2bcb6..f940c470ec 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -177,6 +177,27 @@ Returns the next file that matches the path passed to \helpref{wxFindFirstFile}{ See \helpref{wxFindFirstFile}{wxfindfirstfile} for an example. +\membersection{::wxGetDiskSpace}\label{wxgetdiskspace} + +\func{bool}{wxGetDiskSpace}{\param{const wxString\& }{path}, \path{wxLongLong }{*total = NULL}, \path{wxLongLong }{*free = NULL}} + +This function returns the total number of bytes and number of free bytes on +the disk containing the directory {\it path} (it should exist). Both +{\it total} and {\it free} parameters may be {\tt NULL} if the corresponding +information is not needed. + +\wxheading{Returns} + +{\tt TRUE} on success, {\tt FALSE} if an error occured (for example, the +directory doesn't exist). + +\wxheading{Portability} + +This function is implemented for Win16 (only for drives less than 2Gb), Win32, +Mac OS and generic Unix provided the system has {\tt statfs()} function. + +This function first appeared in wxWindows 2.3.2. + \membersection{::wxGetOSDirectory}\label{wxgetosdirectory} \func{wxString}{wxGetOSDirectory}{\void} diff --git a/include/wx/utils.h b/include/wx/utils.h index 601f3cedbb..0235857076 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -25,6 +25,10 @@ #include "wx/list.h" #include "wx/filefn.h" +// need this for wxGetDiskSpace() as we can't, unfortunately, forward declare +// wxLongLong +#include "wx/longlong.h" + #ifdef __X__ #include #include @@ -264,11 +268,16 @@ WXDLLEXPORT wxChar* wxGetUserHome(const wxString& user = wxEmptyString); #endif #ifdef __WXMAC__ -WXDLLEXPORT wxString wxMacFindFolder(short vRefNum, - OSType folderType, - Boolean createFolder); +WXDLLEXPORT wxString wxMacFindFolder(short vRefNum, + OSType folderType, + Boolean createFolder); #endif +// get number of total/free bytes on the disk where path belongs +WXDLLEXPORT bool wxGetDiskSpace(const wxString& path, + wxLongLong *pTotal = NULL, + wxLongLong *pFree = NULL); + #if wxUSE_GUI // GUI only things from now on // ---------------------------------------------------------------------------- diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 8a75d830ab..f7f43fc2ea 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -54,11 +54,11 @@ //#define TEST_FILENAME //#define TEST_FTP //#define TEST_HASH -//#define TEST_INFO_FUNCTIONS +#define TEST_INFO_FUNCTIONS //#define TEST_LIST //#define TEST_LOCALE //#define TEST_LOG -#define TEST_LONGLONG +//#define TEST_LONGLONG //#define TEST_MIME //#define TEST_PATHLIST //#define TEST_REGCONF @@ -1366,7 +1366,7 @@ static void TestMimeAssociate() static void TestDiskInfo() { - puts("*** Testing wxGetDiskSpace() ***\n"); + puts("*** Testing wxGetDiskSpace() ***"); for ( ;; ) { @@ -1385,9 +1385,9 @@ static void TestDiskInfo() } else { - wxPrintf(_T("%s total bytes, %s free bytes on '%s'.\n"), - total.ToString().c_str(), - free.ToString().c_str(), + wxPrintf(_T("%sKb total, %sKb free on '%s'.\n"), + (total / 1024).ToString().c_str(), + (free / 1024).ToString().c_str(), pathname); } } diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index f9db6a472b..686ff7d697 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -449,6 +449,97 @@ bool wxDirExists(const wxString& dir) #endif // Win32/16 } +bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree) +{ + if ( path.empty() ) + return FALSE; + +#ifdef __WIN32__ + // GetDiskFreeSpaceEx() is not available under original Win95, check for + // it + typedef BOOL (*GetDiskFreeSpaceEx_t)(LPCTSTR, + PULARGE_INTEGER, + PULARGE_INTEGER, + PULARGE_INTEGER); + + GetDiskFreeSpaceEx_t + pGetDiskFreeSpaceEx = ::GetProcAddress + ( + ::GetModuleHandle(_T("kernel32.dll")), +#if wxUSE_UNICODE + "GetDiskFreeSpaceExW" +#else + "GetDiskFreeSpaceExA" +#endif + ); + + if ( pGetDiskFreeSpaceEx ) + { + ULARGE_INTEGER bytesFree, bytesTotal; + + // may pass the path as is, GetDiskFreeSpaceEx() is smart enough + if ( !pGetDiskFreeSpaceEx(path, + &bytesFree, + &bytesTotal, + NULL) ) + { + wxLogLastError(_T("GetDiskFreeSpaceEx")); + + return FALSE; + } + + if ( pTotal ) + { + *pTotal = wxLongLong(bytesTotal.HighPart, bytesTotal.LowPart); + } + + if ( pFree ) + { + *pFree = wxLongLong(bytesFree.HighPart, bytesFree.LowPart); + } + } + else +#endif // Win32 + { + DWORD lSectorsPerCluster, + lBytesPerSector, + lNumberOfFreeClusters, + lTotalNumberOfClusters; + + // FIXME: this is wrong, we should extract the root drive from path + // instead, but this is the job for wxFileName... + if ( !::GetDiskFreeSpace(path, + &lSectorsPerCluster, + &lBytesPerSector, + &lNumberOfFreeClusters, + &lTotalNumberOfClusters) ) + { + wxLogLastError(_T("GetDiskFreeSpace")); + + return FALSE; + } + + // there's a problem with drives larger than 2GB on non Win32!! + // let's calculate it, nevertheless.... + wxLongLong lBytesPerCluster = lSectorsPerCluster; + lBytesPerCluster *= lBytesPerSector; + + if ( pTotal ) + { + *pTotal = lBytesPerCluster; + *pTotal *= lTotalNumberOfClusters; + } + + if ( pFree ) + { + *pFree = lBytesPerCluster; + *pFree *= lNumberOfFreeClusters; + } + } + + return TRUE; +} + // ---------------------------------------------------------------------------- // env vars // ---------------------------------------------------------------------------- diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index ad8a078fab..3bd19ffbf6 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -28,6 +28,10 @@ #include "wx/stream.h" +#ifdef HAVE_STATFS + #include +#endif // HAVE_STATFS + #if wxUSE_GUI #include "wx/unix/execute.h" #endif @@ -909,6 +913,34 @@ long wxGetFreeMemory() return -1; } +bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree) +{ +#ifdef HAVE_STATFS + + struct statfs fs; + if ( statfs(path, &fs) != 0 ) + { + wxLogSysError("Failed to get file system statistics"); + + return FALSE; + } + + if ( pTotal ) + { + *pTotal = wxLongLong(fs.f_blocks) * fs.f_bsize; + } + + if ( pFree ) + { + *pFree = wxLongLong(fs.f_bavail) * fs.f_bsize; + } + + return TRUE; +#endif // HAVE_STATFS + + return FALSE; +} + // ---------------------------------------------------------------------------- // env vars // ----------------------------------------------------------------------------