diff options
Diffstat (limited to 'CPP/7zip/FileManager/FSDrives.cpp')
-rwxr-xr-x | CPP/7zip/FileManager/FSDrives.cpp | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/CPP/7zip/FileManager/FSDrives.cpp b/CPP/7zip/FileManager/FSDrives.cpp new file mode 100755 index 00000000..447ff4dc --- /dev/null +++ b/CPP/7zip/FileManager/FSDrives.cpp @@ -0,0 +1,240 @@ +// FSDrives.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "FSDrives.h" + +#include "Common/StringConvert.h" +#include "../PropID.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileDir.h" +#include "Windows/FileSystem.h" + +#include "SysIconUtils.h" +#include "FSFolder.h" +#include "PhysDriveFolder.h" +#include "LangUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +static const STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { L"Total Size", kpidTotalSize, VT_UI8}, + { L"Free Space", kpidFreeSpace, VT_UI8}, + { NULL, kpidType, VT_BSTR}, + { L"Label", kpidVolumeName, VT_BSTR}, + { L"File system", kpidFileSystem, VT_BSTR}, + { L"Cluster Size", kpidClusterSize, VT_UI8} +}; + +static const wchar_t *kDriveTypes[] = +{ + L"Unknown", + L"No Root Dir", + L"Removable", + L"Fixed", + L"Remote", + L"CD-ROM", + L"RAM disk" +}; + +STDMETHODIMP CFSDrives::LoadItems() +{ + _drives.Clear(); + + UStringVector driveStrings; + MyGetLogicalDriveStrings(driveStrings); + for (int i = 0; i < driveStrings.Size(); i++) + { + CDriveInfo driveInfo; + + const UString &driveName = driveStrings[i]; + + driveInfo.FullSystemName = driveName; + + driveInfo.Name = driveInfo.FullSystemName.Left( + driveInfo.FullSystemName.Length() - 1); + driveInfo.ClusterSize = 0; + driveInfo.DriveSize = 0; + driveInfo.FreeSpace = 0; + UINT driveType = NFile::NSystem::MyGetDriveType(driveName); + if (driveType < sizeof(kDriveTypes) / sizeof(kDriveTypes[0])) + { + driveInfo.Type = kDriveTypes[driveType]; + } + bool needRead = true; + if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) + { + /* + DWORD dwSerialNumber;` + if (!::GetVolumeInformation(driveInfo.FullSystemName, + NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0)) + */ + driveInfo.KnownSizes = false; + { + needRead = false; + } + } + if (needRead) + { + UString volumeName, fileSystemName; + DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags; + NFile::NSystem::MyGetVolumeInformation(driveName, + volumeName, + &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags, + fileSystemName); + driveInfo.VolumeName = volumeName; + driveInfo.FileSystemName = fileSystemName; + + NFile::NSystem::MyGetDiskFreeSpace(driveName, + driveInfo.ClusterSize, driveInfo.DriveSize, driveInfo.FreeSpace); + driveInfo.KnownSizes = true; + } + _drives.Add(driveInfo); + } + return S_OK; +} + +STDMETHODIMP CFSDrives::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _drives.Size(); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + if (itemIndex >= (UInt32)_drives.Size()) + return E_INVALIDARG; + NCOM::CPropVariant propVariant; + const CDriveInfo &driveInfo = _drives[itemIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + propVariant = driveInfo.Name; + break; + case kpidTotalSize: + if (driveInfo.KnownSizes) + propVariant = driveInfo.DriveSize; + break; + case kpidFreeSpace: + if (driveInfo.KnownSizes) + propVariant = driveInfo.FreeSpace; + break; + case kpidClusterSize: + if (driveInfo.KnownSizes) + propVariant = driveInfo.ClusterSize; + break; + case kpidType: + propVariant = driveInfo.Type; + break; + case kpidVolumeName: + propVariant = driveInfo.VolumeName; + break; + case kpidFileSystem: + propVariant = driveInfo.FileSystemName; + break; + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CFSDrives::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + CFSFolder *fsFolderSpec = new CFSFolder; + CMyComPtr<IFolderFolder> subFolder = fsFolderSpec; + RINOK(fsFolderSpec->Init(name, 0)); + *resultFolder = subFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + if (index >= (UInt32)_drives.Size()) + return E_INVALIDARG; + const CDriveInfo &driveInfo = _drives[index]; + if (_volumeMode) + { + *resultFolder = 0; + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + CMyComPtr<IFolderFolder> subFolder = folderSpec; + RINOK(folderSpec->Init(driveInfo.Name)); + *resultFolder = subFolder.Detach(); + return S_OK; + } + return BindToFolderSpec(driveInfo.FullSystemName, resultFolder); +} + +STDMETHODIMP CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + return BindToFolderSpec(name, resultFolder); +} + +STDMETHODIMP CFSDrives::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + return S_OK; +} + +STDMETHODIMP CFSDrives::GetName(BSTR * /* name */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CFSDrives::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + + +STDMETHODIMP CFSDrives::GetTypeID(BSTR *name) +{ + CMyComBSTR temp = L"FSDrives"; + *name = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetPath(BSTR *path) +{ + CMyComBSTR temp = LangString(IDS_COMPUTER, 0x03020300) + UString(L'\\'); + *path = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + *iconIndex = 0; + const CDriveInfo &driveInfo = _drives[index]; + int iconIndexTemp; + if (GetRealIconIndex(driveInfo.FullSystemName, 0, iconIndexTemp) != 0) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + return GetLastError(); +} + |