diff options
author | bseifert <none@none> | 2003-10-30 09:08:04 +0300 |
---|---|---|
committer | bseifert <none@none> | 2003-10-30 09:08:04 +0300 |
commit | f049e2df4b09dc19a7d76e2d33b8cfcb5370e9dc (patch) | |
tree | f2f04cd33835591b8e32953d093a1527a75f3464 /windirstat/mountpoints.cpp | |
parent | 98a363ad8bd075b1abd702b7d380692ec0c470d6 (diff) |
Initial revision
Diffstat (limited to 'windirstat/mountpoints.cpp')
-rw-r--r-- | windirstat/mountpoints.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/windirstat/mountpoints.cpp b/windirstat/mountpoints.cpp new file mode 100644 index 0000000..05744d2 --- /dev/null +++ b/windirstat/mountpoints.cpp @@ -0,0 +1,235 @@ +// mountpoints.cpp - Implementation of CMountPoints +// +// WinDirStat - Directory Statistics +// Copyright (C) 2003 Bernhard Seifert +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Author: bseifert@users.sourceforge.net, bseifert@daccord.net + +#include "stdafx.h" +#include "osspecific.h" + +#include "mountpoints.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +CMountPoints::~CMountPoints() +{ + Clear(); +} + +void CMountPoints::Clear() +{ + m_drive.RemoveAll(); + + POSITION pos= m_volume.GetStartPosition(); + while (pos != NULL) + { + CString volume; + PointVolumeArray *pva= NULL; + m_volume.GetNextAssoc(pos, volume, pva); + ASSERT_VALID(pva); + delete pva; + } + m_volume.RemoveAll(); +} + +void CMountPoints::Initialize() +{ + Clear(); + + if (!m_va.IsSupported()) + return; + + GetDriveVolumes(); + GetAllMountPoints(); +} + +void CMountPoints::GetDriveVolumes() +{ + m_drive.SetSize(32); + + DWORD drives= GetLogicalDrives(); + int i; + DWORD mask= 0x00000001; + for (i=0; i < 32; i++, mask <<= 1) + { + CString volume; + + if ((drives & mask) != 0) + { + CString s; + s.Format(_T("%c:\\"), i + _T('A')); + + BOOL b= m_va.GetVolumeNameForVolumeMountPoint(s, volume.GetBuffer(_MAX_PATH), _MAX_PATH); + volume.ReleaseBuffer(); + + if (!b) + { + TRACE(_T("GetVolumeNameForVolumeMountPoint(%s) failed.\n"), s); + volume.Empty(); + } + } + + m_drive[i]= volume; + } +} + +void CMountPoints::GetAllMountPoints() +{ + TCHAR volume[_MAX_PATH]; + HANDLE hvol= m_va.FindFirstVolume(volume, countof(volume)); + if (hvol == INVALID_HANDLE_VALUE) + { + TRACE(_T("No volumes found.\r\n")); + return; + } + + for (BOOL bContinue=true; bContinue; bContinue= m_va.FindNextVolume(hvol, volume, countof(volume))) + { + PointVolumeArray *pva= new PointVolumeArray; + ASSERT_VALID(pva); + + DWORD sysflags; + CString fsname; + BOOL b= GetVolumeInformation(volume, NULL, 0, NULL, NULL, &sysflags, fsname.GetBuffer(_MAX_PATH), _MAX_PATH); + fsname.ReleaseBuffer(); + + if (!b) + { + TRACE(_T("This file system (%s) is not ready.\r\n"), volume); + m_volume.SetAt(volume, pva); + continue; + } + + if ((sysflags & FILE_SUPPORTS_REPARSE_POINTS) == 0) + { + // No support for reparse points, and therefore for volume + // mount points, which are implemented using reparse points. + TRACE(_T("This file system (%s) does not support volume mount points.\r\n"), volume); + m_volume.SetAt(volume, pva); + continue; + } + + TCHAR point[_MAX_PATH]; + HANDLE h= m_va.FindFirstVolumeMountPoint(volume, point, countof(point)); + if (h == INVALID_HANDLE_VALUE) + { + TRACE(_T("No volume mount points found on %s.\r\n"), volume); + m_volume.SetAt(volume, pva); + continue; + } + + for (BOOL bCont=true; bCont; bCont= m_va.FindNextVolumeMountPoint(h, point, countof(point))) + { + CString uniquePath= volume; + uniquePath+= point; + CString mountedVolume; + + BOOL b= m_va.GetVolumeNameForVolumeMountPoint(uniquePath, mountedVolume.GetBuffer(_MAX_PATH), _MAX_PATH); + mountedVolume.ReleaseBuffer(); + + if (!b) + { + TRACE(_T("GetVolumeNameForVolumeMountPoint(%s) failed.\r\n"), uniquePath); + continue; + } + + SPointVolume pv; + pv.point= point; + pv.volume= mountedVolume; + + pv.point.MakeLower(); + + pva->Add(pv); + } + m_va.FindVolumeMountPointClose(h); + + m_volume.SetAt(volume, pva); + } + + (void)m_va.FindVolumeClose(hvol); + +#ifdef _DEBUG + POSITION pos= m_volume.GetStartPosition(); + while (pos != NULL) + { + CString volume; + PointVolumeArray *pva= NULL; + m_volume.GetNextAssoc(pos, volume, pva); + pva->AssertValid(); + } +#endif + +} + + +bool CMountPoints::IsMountPoint(CString path) +{ + if (path.GetLength() < 3 || path[1] != _T(':') || path[2] != _T('\\')) + { + // Don't know how to make out mount points on UNC paths ### + return false; + } + + ASSERT(path.GetLength() >= 3); + ASSERT(path[1] == _T(':')); + ASSERT(path[2] == _T('\\')); + + if (!m_va.IsSupported()) + return false; + + if (path.Right(1) != _T('\\')) + path+= _T("\\"); + + path.MakeLower(); + + CString volume= m_drive[path[0] - _T('a')]; + path= path.Mid(3); + + return IsVolumeMountPoint(volume, path); +} + +bool CMountPoints::IsVolumeMountPoint(CString volume, CString path) +{ + for (;;) + { + PointVolumeArray *pva; + if (!m_volume.Lookup(volume, pva)) + { + TRACE(_T("CMountPoints: Volume(%s) unknown!\r\n"), volume); + return false; + } + + CString point; + for (int i=0; i < pva->GetSize(); i++) + { + point= (*pva)[i].point; + if (path.Left(point.GetLength()) == point) + break; + } + if (i >= pva->GetSize()) + return false; + + if (path.GetLength() == point.GetLength()) + return true; + + volume= (*pva)[i].volume; + path= path.Mid(point.GetLength()); + } +} |