Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/UI/FileManager/FSDrives.cpp')
-rw-r--r--[-rwxr-xr-x]CPP/7zip/UI/FileManager/FSDrives.cpp172
1 files changed, 109 insertions, 63 deletions
diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp
index 823b0826..84639de7 100755..100644
--- a/CPP/7zip/UI/FileManager/FSDrives.cpp
+++ b/CPP/7zip/UI/FileManager/FSDrives.cpp
@@ -4,14 +4,15 @@
#include "../../../../C/Alloc.h"
-#include "Common/ComTry.h"
-#include "Common/StringConvert.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Common/Defs.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
-#include "Windows/Defs.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileIO.h"
-#include "Windows/FileSystem.h"
-#include "Windows/PropVariant.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileIO.h"
+#include "../../../Windows/FileSystem.h"
+#include "../../../Windows/PropVariant.h"
#include "../../PropID.h"
@@ -26,7 +27,8 @@ using namespace NWindows;
using namespace NFile;
using namespace NFind;
-static CFSTR kVolPrefix = FTEXT("\\\\.\\");
+static CFSTR kVolPrefix = FTEXT("\\\\.\\");
+static CFSTR kLongPrefix = FTEXT("\\\\?\\");
FString CDriveInfo::GetDeviceFileIoName() const
{
@@ -43,7 +45,7 @@ struct CPhysTempBuffer
static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt64 fileSize,
UInt32 bufferSize, UInt64 progressStart, IProgress *progress)
{
- NFile::NIO::CInFile inFile;
+ NIO::CInFile inFile;
if (!inFile.Open(fromPath))
return GetLastError();
if (fileSize == (UInt64)(Int64)-1)
@@ -51,7 +53,7 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
if (!inFile.GetLength(fileSize))
::GetLastError();
}
- NFile::NIO::COutFile outFile;
+ NIO::COutFile outFile;
if (writeToDisk)
{
if (!outFile.Open(toPath, FILE_SHARE_WRITE, OPEN_EXISTING, 0))
@@ -62,7 +64,7 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
return GetLastError();
CPhysTempBuffer tempBuffer;
tempBuffer.buffer = MidAlloc(bufferSize);
- if (tempBuffer.buffer == 0)
+ if (!tempBuffer.buffer)
return E_OUTOFMEMORY;
for (UInt64 pos = 0; pos < fileSize;)
@@ -94,26 +96,26 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
return S_OK;
}
-static const STATPROPSTG kProps[] =
+static const PROPID kProps[] =
{
- { NULL, kpidName, VT_BSTR},
- { NULL, kpidTotalSize, VT_UI8},
- { NULL, kpidFreeSpace, VT_UI8},
- { NULL, kpidType, VT_BSTR},
- { NULL, kpidVolumeName, VT_BSTR},
- { NULL, kpidFileSystem, VT_BSTR},
- { NULL, kpidClusterSize, VT_UI8}
+ kpidName,
+ kpidTotalSize,
+ kpidFreeSpace,
+ kpidType,
+ kpidVolumeName,
+ kpidFileSystem,
+ kpidClusterSize
};
static const char *kDriveTypes[] =
{
- "Unknown",
- "No Root Dir",
- "Removable",
- "Fixed",
- "Remote",
- "CD-ROM",
- "RAM disk"
+ "Unknown"
+ , "No Root Dir"
+ , "Removable"
+ , "Fixed"
+ , "Remote"
+ , "CD-ROM"
+ , "RAM disk"
};
STDMETHODIMP CFSDrives::LoadItems()
@@ -122,7 +124,8 @@ STDMETHODIMP CFSDrives::LoadItems()
FStringVector driveStrings;
MyGetLogicalDriveStrings(driveStrings);
- for (int i = 0; i < driveStrings.Size(); i++)
+
+ FOR_VECTOR (i, driveStrings)
{
CDriveInfo di;
@@ -130,12 +133,13 @@ STDMETHODIMP CFSDrives::LoadItems()
di.FullSystemName = driveName;
if (!driveName.IsEmpty())
- di.Name = driveName.Left(driveName.Length() - 1);
+ di.Name.SetFrom(driveName, driveName.Len() - 1);
di.ClusterSize = 0;
di.DriveSize = 0;
di.FreeSpace = 0;
- di.DriveType = NFile::NSystem::MyGetDriveType(driveName);
+ di.DriveType = NSystem::MyGetDriveType(driveName);
bool needRead = true;
+
if (di.DriveType == DRIVE_CDROM || di.DriveType == DRIVE_REMOVABLE)
{
/*
@@ -143,25 +147,59 @@ STDMETHODIMP CFSDrives::LoadItems()
if (!::GetVolumeInformation(di.FullSystemName,
NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0))
*/
- di.KnownSizes = false;
{
needRead = false;
}
}
+
if (needRead)
{
DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
- NFile::NSystem::MyGetVolumeInformation(driveName,
+ NSystem::MyGetVolumeInformation(driveName,
di.VolumeName,
&volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
di.FileSystemName);
- NFile::NSystem::MyGetDiskFreeSpace(driveName,
+ NSystem::MyGetDiskFreeSpace(driveName,
di.ClusterSize, di.DriveSize, di.FreeSpace);
di.KnownSizes = true;
+ di.KnownSize = true;
}
+
_drives.Add(di);
}
+
+ if (_volumeMode)
+ {
+ // we must use IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
+ for (unsigned n = 0; n < 16; n++) // why 16 ?
+ {
+ FChar temp[16];
+ ConvertUInt32ToString(n, temp);
+ FString name = FTEXT("PhysicalDrive");
+ name += temp;
+ FString fullPath = kVolPrefix;
+ fullPath += name;
+
+ CFileInfo fi;
+ if (!fi.Find(fullPath))
+ continue;
+
+ CDriveInfo di;
+ di.Name = name;
+ di.FullSystemName = fullPath;
+ di.ClusterSize = 0;
+ di.DriveSize = fi.Size;
+ di.FreeSpace = 0;
+ di.DriveType = 0;
+
+ di.IsPhysicalDrive = true;
+ di.KnownSize = true;
+
+ _drives.Add(di);
+ }
+ }
+
return S_OK;
}
@@ -177,15 +215,15 @@ STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
return E_INVALIDARG;
NCOM::CPropVariant prop;
const CDriveInfo &di = _drives[itemIndex];
- switch(propID)
+ switch (propID)
{
case kpidIsDir: prop = !_volumeMode; break;
case kpidName: prop = di.Name; break;
- case kpidTotalSize: if (di.KnownSizes) prop = di.DriveSize; break;
+ case kpidTotalSize: if (di.KnownSize) prop = di.DriveSize; break;
case kpidFreeSpace: if (di.KnownSizes) prop = di.FreeSpace; break;
case kpidClusterSize: if (di.KnownSizes) prop = di.ClusterSize; break;
case kpidType:
- if (di.DriveType < sizeof(kDriveTypes) / sizeof(kDriveTypes[0]))
+ if (di.DriveType < ARRAY_SIZE(kDriveTypes))
prop = kDriveTypes[di.DriveType];
break;
case kpidVolumeName: prop = di.VolumeName; break;
@@ -202,7 +240,14 @@ HRESULT CFSDrives::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
return S_OK;
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
- RINOK(fsFolderSpec->Init(name, 0));
+ if (_longMode)
+ {
+ RINOK(fsFolderSpec->Init((FString)kLongPrefix + name, 0));
+ }
+ else
+ {
+ RINOK(fsFolderSpec->Init(name, 0));
+ }
*resultFolder = subFolder.Detach();
return S_OK;
}
@@ -243,15 +288,17 @@ IMP_IFolderFolder_Props(CFSDrives)
STDMETHODIMP CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- case kpidType: prop = L"FSDrives"; break;
+ case kpidType: prop = "FSDrives"; break;
case kpidPath:
if (_volumeMode)
- prop = fs2us(kVolPrefix);
+ prop = kVolPrefix;
+ else if (_longMode)
+ prop = kLongPrefix;
else
- prop = LangString(IDS_COMPUTER, 0x03020300) + UString(WCHAR_PATH_SEPARATOR);
+ prop = (UString)LangString(IDS_COMPUTER) + WCHAR_PATH_SEPARATOR;
break;
}
prop.Detach(value);
@@ -264,6 +311,8 @@ STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
{
*iconIndex = 0;
const CDriveInfo &di = _drives[index];
+ if (di.IsPhysicalDrive)
+ return S_OK;
int iconIndexTemp;
if (GetRealIconIndex(di.FullSystemName, 0, iconIndexTemp) != 0)
{
@@ -273,10 +322,10 @@ STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
return GetLastError();
}
-UString CFSDrives::GetExt(int index) const
+const wchar_t *CFSDrives::GetExt(unsigned index) const
{
const CDriveInfo &di = _drives[index];
- const wchar_t *ext = NULL;
+ const wchar_t *ext;
if (di.DriveType == DRIVE_CDROM)
ext = L"iso";
else if (di.FileSystemName.Find(L"NTFS") >= 0)
@@ -285,23 +334,27 @@ UString CFSDrives::GetExt(int index) const
ext = L"fat";
else
ext = L"img";
- return (UString)L'.' + ext;
+ return ext;
}
-HRESULT CFSDrives::GetLength(int index, UInt64 &length) const
+HRESULT CFSDrives::GetFileSize(unsigned index, UInt64 &fileSize) const
{
- NFile::NIO::CInFile inFile;
+ NIO::CInFile inFile;
if (!inFile.Open(_drives[index].GetDeviceFileIoName()))
return GetLastError();
- if (!inFile.LengthDefined)
+ if (!inFile.SizeDefined)
return E_FAIL;
- length = inFile.Length;
+ fileSize = inFile.Size;
return S_OK;
}
-STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
+STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
+ Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
const wchar_t *path, IFolderOperationsExtractCallback *callback)
{
+ if (moveMode)
+ return E_NOTIMPL;
+
if (numItems == 0)
return S_OK;
@@ -313,7 +366,7 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
for (i = 0; i < numItems; i++)
{
const CDriveInfo &di = _drives[indices[i]];
- if (di.KnownSizes)
+ if (di.KnownSize)
totalSize += di.DriveSize;
}
RINOK(callback->SetTotal(totalSize));
@@ -331,9 +384,10 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
UInt64 completedSize = 0;
RINOK(callback->SetCompleted(&completedSize));
+
for (i = 0; i < numItems; i++)
{
- int index = indices[i];
+ unsigned index = indices[i];
const CDriveInfo &di = _drives[index];
UString destPath2 = destPath;
UString name = fs2us(di.Name);
@@ -343,6 +397,7 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
if (!destName.IsEmpty() && destName.Back() == L':')
{
destName.DeleteBack();
+ destName += L'.';
destName += GetExt(index);
}
destPath2 += destName;
@@ -350,11 +405,11 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
FString srcPath = di.GetDeviceFileIoName();
UInt64 fileSize = 0;
- if (GetLength(index, fileSize) != S_OK)
+ if (GetFileSize(index, fileSize) != S_OK)
{
return E_FAIL;
}
- if (!di.KnownSizes)
+ if (!di.KnownSize)
totalSize += fileSize;
RINOK(callback->SetTotal(totalSize));
@@ -375,16 +430,7 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
return S_OK;
}
-STDMETHODIMP CFSDrives::MoveTo(
- const UInt32 * /* indices */,
- UInt32 /* numItems */,
- const wchar_t * /* path */,
- IFolderOperationsExtractCallback * /* callback */)
-{
- return E_NOTIMPL;
-}
-
-STDMETHODIMP CFSDrives::CopyFrom(const wchar_t * /* fromFolderPath */,
+STDMETHODIMP CFSDrives::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
{
return E_NOTIMPL;