xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/FSDrives.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // FSDrives.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/Alloc.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Defs.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileIO.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileSystem.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #include "../../PropID.h"
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker #include "FSDrives.h"
21*f6dc9357SAndroid Build Coastguard Worker #include "FSFolder.h"
22*f6dc9357SAndroid Build Coastguard Worker #include "LangUtils.h"
23*f6dc9357SAndroid Build Coastguard Worker #include "SysIconUtils.h"
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #include "resource.h"
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
28*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
29*f6dc9357SAndroid Build Coastguard Worker using namespace NFind;
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker static const char * const kVolPrefix   = "\\\\.\\";
32*f6dc9357SAndroid Build Coastguard Worker static const char * const kSuperPrefix = "\\\\?\\";
33*f6dc9357SAndroid Build Coastguard Worker 
GetDeviceFileIoName() const34*f6dc9357SAndroid Build Coastguard Worker FString CDriveInfo::GetDeviceFileIoName() const
35*f6dc9357SAndroid Build Coastguard Worker {
36*f6dc9357SAndroid Build Coastguard Worker   FString f (kVolPrefix);
37*f6dc9357SAndroid Build Coastguard Worker   f += Name;
38*f6dc9357SAndroid Build Coastguard Worker   return f;
39*f6dc9357SAndroid Build Coastguard Worker }
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker struct CPhysTempBuffer
42*f6dc9357SAndroid Build Coastguard Worker {
43*f6dc9357SAndroid Build Coastguard Worker   void *buffer;
CPhysTempBufferCPhysTempBuffer44*f6dc9357SAndroid Build Coastguard Worker   CPhysTempBuffer(): buffer(NULL) {}
~CPhysTempBufferCPhysTempBuffer45*f6dc9357SAndroid Build Coastguard Worker   ~CPhysTempBuffer() { MidFree(buffer); }
46*f6dc9357SAndroid Build Coastguard Worker };
47*f6dc9357SAndroid Build Coastguard Worker 
CopyFileSpec(CFSTR fromPath,CFSTR toPath,bool writeToDisk,UInt64 fileSize,UInt32 bufferSize,UInt64 progressStart,IProgress * progress)48*f6dc9357SAndroid Build Coastguard Worker static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath,
49*f6dc9357SAndroid Build Coastguard Worker     bool writeToDisk, UInt64 fileSize,
50*f6dc9357SAndroid Build Coastguard Worker     UInt32 bufferSize, UInt64 progressStart, IProgress *progress)
51*f6dc9357SAndroid Build Coastguard Worker {
52*f6dc9357SAndroid Build Coastguard Worker   NIO::CInFile inFile;
53*f6dc9357SAndroid Build Coastguard Worker   if (!inFile.Open(fromPath))
54*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
55*f6dc9357SAndroid Build Coastguard Worker   if (fileSize == (UInt64)(Int64)-1)
56*f6dc9357SAndroid Build Coastguard Worker   {
57*f6dc9357SAndroid Build Coastguard Worker     if (!inFile.GetLength(fileSize))
58*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
59*f6dc9357SAndroid Build Coastguard Worker   }
60*f6dc9357SAndroid Build Coastguard Worker 
61*f6dc9357SAndroid Build Coastguard Worker   NIO::COutFile outFile;
62*f6dc9357SAndroid Build Coastguard Worker   if (writeToDisk)
63*f6dc9357SAndroid Build Coastguard Worker   {
64*f6dc9357SAndroid Build Coastguard Worker     if (!outFile.Open(toPath, FILE_SHARE_WRITE, OPEN_EXISTING, 0))
65*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
66*f6dc9357SAndroid Build Coastguard Worker   }
67*f6dc9357SAndroid Build Coastguard Worker   else
68*f6dc9357SAndroid Build Coastguard Worker     if (!outFile.Create_ALWAYS(toPath))
69*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
70*f6dc9357SAndroid Build Coastguard Worker 
71*f6dc9357SAndroid Build Coastguard Worker   CPhysTempBuffer tempBuffer;
72*f6dc9357SAndroid Build Coastguard Worker   tempBuffer.buffer = MidAlloc(bufferSize);
73*f6dc9357SAndroid Build Coastguard Worker   if (!tempBuffer.buffer)
74*f6dc9357SAndroid Build Coastguard Worker     return E_OUTOFMEMORY;
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker   for (UInt64 pos = 0; pos < fileSize;)
77*f6dc9357SAndroid Build Coastguard Worker   {
78*f6dc9357SAndroid Build Coastguard Worker     {
79*f6dc9357SAndroid Build Coastguard Worker       const UInt64 progressCur = progressStart + pos;
80*f6dc9357SAndroid Build Coastguard Worker       RINOK(progress->SetCompleted(&progressCur))
81*f6dc9357SAndroid Build Coastguard Worker     }
82*f6dc9357SAndroid Build Coastguard Worker     const UInt64 rem = fileSize - pos;
83*f6dc9357SAndroid Build Coastguard Worker     UInt32 curSize = (UInt32)MyMin(rem, (UInt64)bufferSize);
84*f6dc9357SAndroid Build Coastguard Worker     UInt32 processedSize;
85*f6dc9357SAndroid Build Coastguard Worker     if (!inFile.Read(tempBuffer.buffer, curSize, processedSize))
86*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
87*f6dc9357SAndroid Build Coastguard Worker     if (processedSize == 0)
88*f6dc9357SAndroid Build Coastguard Worker       break;
89*f6dc9357SAndroid Build Coastguard Worker     curSize = processedSize;
90*f6dc9357SAndroid Build Coastguard Worker     if (writeToDisk)
91*f6dc9357SAndroid Build Coastguard Worker     {
92*f6dc9357SAndroid Build Coastguard Worker       const UInt32 kMask = 0x1FF;
93*f6dc9357SAndroid Build Coastguard Worker       curSize = (curSize + kMask) & ~kMask;
94*f6dc9357SAndroid Build Coastguard Worker       if (curSize > bufferSize)
95*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
96*f6dc9357SAndroid Build Coastguard Worker     }
97*f6dc9357SAndroid Build Coastguard Worker     if (!outFile.Write(tempBuffer.buffer, curSize, processedSize))
98*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
99*f6dc9357SAndroid Build Coastguard Worker     if (curSize != processedSize)
100*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
101*f6dc9357SAndroid Build Coastguard Worker     pos += curSize;
102*f6dc9357SAndroid Build Coastguard Worker   }
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
105*f6dc9357SAndroid Build Coastguard Worker }
106*f6dc9357SAndroid Build Coastguard Worker 
107*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
108*f6dc9357SAndroid Build Coastguard Worker {
109*f6dc9357SAndroid Build Coastguard Worker   kpidName,
110*f6dc9357SAndroid Build Coastguard Worker   // kpidOutName,
111*f6dc9357SAndroid Build Coastguard Worker   kpidTotalSize,
112*f6dc9357SAndroid Build Coastguard Worker   kpidFreeSpace,
113*f6dc9357SAndroid Build Coastguard Worker   kpidType,
114*f6dc9357SAndroid Build Coastguard Worker   kpidVolumeName,
115*f6dc9357SAndroid Build Coastguard Worker   kpidFileSystem,
116*f6dc9357SAndroid Build Coastguard Worker   kpidClusterSize
117*f6dc9357SAndroid Build Coastguard Worker };
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker static const char * const kDriveTypes[] =
120*f6dc9357SAndroid Build Coastguard Worker {
121*f6dc9357SAndroid Build Coastguard Worker     "Unknown"
122*f6dc9357SAndroid Build Coastguard Worker   , "No Root Dir"
123*f6dc9357SAndroid Build Coastguard Worker   , "Removable"
124*f6dc9357SAndroid Build Coastguard Worker   , "Fixed"
125*f6dc9357SAndroid Build Coastguard Worker   , "Remote"
126*f6dc9357SAndroid Build Coastguard Worker   , "CD-ROM"
127*f6dc9357SAndroid Build Coastguard Worker   , "RAM disk"
128*f6dc9357SAndroid Build Coastguard Worker };
129*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::LoadItems ())130*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::LoadItems())
131*f6dc9357SAndroid Build Coastguard Worker {
132*f6dc9357SAndroid Build Coastguard Worker   _drives.Clear();
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker   FStringVector driveStrings;
135*f6dc9357SAndroid Build Coastguard Worker   MyGetLogicalDriveStrings(driveStrings);
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, driveStrings)
138*f6dc9357SAndroid Build Coastguard Worker   {
139*f6dc9357SAndroid Build Coastguard Worker     CDriveInfo di;
140*f6dc9357SAndroid Build Coastguard Worker     const FString &driveName = driveStrings[i];
141*f6dc9357SAndroid Build Coastguard Worker     di.FullSystemName = driveName;
142*f6dc9357SAndroid Build Coastguard Worker     if (!driveName.IsEmpty())
143*f6dc9357SAndroid Build Coastguard Worker       di.Name.SetFrom(driveName, driveName.Len() - 1);
144*f6dc9357SAndroid Build Coastguard Worker     di.ClusterSize = 0;
145*f6dc9357SAndroid Build Coastguard Worker     di.DriveSize = 0;
146*f6dc9357SAndroid Build Coastguard Worker     di.FreeSpace = 0;
147*f6dc9357SAndroid Build Coastguard Worker     di.DriveType = NSystem::MyGetDriveType(driveName);
148*f6dc9357SAndroid Build Coastguard Worker     bool needRead = true;
149*f6dc9357SAndroid Build Coastguard Worker 
150*f6dc9357SAndroid Build Coastguard Worker     if (di.DriveType == DRIVE_CDROM || di.DriveType == DRIVE_REMOVABLE)
151*f6dc9357SAndroid Build Coastguard Worker     {
152*f6dc9357SAndroid Build Coastguard Worker       /*
153*f6dc9357SAndroid Build Coastguard Worker       DWORD dwSerialNumber;`
154*f6dc9357SAndroid Build Coastguard Worker       if (!::GetVolumeInformation(di.FullSystemName,
155*f6dc9357SAndroid Build Coastguard Worker           NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0))
156*f6dc9357SAndroid Build Coastguard Worker       */
157*f6dc9357SAndroid Build Coastguard Worker       {
158*f6dc9357SAndroid Build Coastguard Worker         needRead = false;
159*f6dc9357SAndroid Build Coastguard Worker       }
160*f6dc9357SAndroid Build Coastguard Worker     }
161*f6dc9357SAndroid Build Coastguard Worker 
162*f6dc9357SAndroid Build Coastguard Worker     if (needRead)
163*f6dc9357SAndroid Build Coastguard Worker     {
164*f6dc9357SAndroid Build Coastguard Worker       DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
165*f6dc9357SAndroid Build Coastguard Worker       NSystem::MyGetVolumeInformation(driveName,
166*f6dc9357SAndroid Build Coastguard Worker           di.VolumeName,
167*f6dc9357SAndroid Build Coastguard Worker           &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
168*f6dc9357SAndroid Build Coastguard Worker           di.FileSystemName);
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker       NSystem::MyGetDiskFreeSpace(driveName,
171*f6dc9357SAndroid Build Coastguard Worker           di.ClusterSize, di.DriveSize, di.FreeSpace);
172*f6dc9357SAndroid Build Coastguard Worker       di.KnownSizes = true;
173*f6dc9357SAndroid Build Coastguard Worker       di.KnownSize = true;
174*f6dc9357SAndroid Build Coastguard Worker     }
175*f6dc9357SAndroid Build Coastguard Worker 
176*f6dc9357SAndroid Build Coastguard Worker     _drives.Add(di);
177*f6dc9357SAndroid Build Coastguard Worker   }
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker   if (_volumeMode)
180*f6dc9357SAndroid Build Coastguard Worker   {
181*f6dc9357SAndroid Build Coastguard Worker     // we must use IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
182*f6dc9357SAndroid Build Coastguard Worker     for (unsigned n = 0; n < 16; n++) // why 16 ?
183*f6dc9357SAndroid Build Coastguard Worker     {
184*f6dc9357SAndroid Build Coastguard Worker       FString name ("PhysicalDrive");
185*f6dc9357SAndroid Build Coastguard Worker       name.Add_UInt32(n);
186*f6dc9357SAndroid Build Coastguard Worker       FString fullPath (kVolPrefix);
187*f6dc9357SAndroid Build Coastguard Worker       fullPath += name;
188*f6dc9357SAndroid Build Coastguard Worker       CFileInfo fi;
189*f6dc9357SAndroid Build Coastguard Worker       if (!fi.Find(fullPath))
190*f6dc9357SAndroid Build Coastguard Worker         continue;
191*f6dc9357SAndroid Build Coastguard Worker 
192*f6dc9357SAndroid Build Coastguard Worker       CDriveInfo di;
193*f6dc9357SAndroid Build Coastguard Worker       di.Name = name;
194*f6dc9357SAndroid Build Coastguard Worker       // if (_volumeMode == true) we use CDriveInfo::FullSystemName only in GetSystemIconIndex().
195*f6dc9357SAndroid Build Coastguard Worker       // And we need name without "\\\\.\\" prefix in GetSystemIconIndex().
196*f6dc9357SAndroid Build Coastguard Worker       // So we don't set di.FullSystemName = fullPath;
197*f6dc9357SAndroid Build Coastguard Worker       di.FullSystemName = name;
198*f6dc9357SAndroid Build Coastguard Worker       di.ClusterSize = 0;
199*f6dc9357SAndroid Build Coastguard Worker       di.DriveSize = fi.Size;
200*f6dc9357SAndroid Build Coastguard Worker       di.FreeSpace = 0;
201*f6dc9357SAndroid Build Coastguard Worker       di.DriveType = 0;
202*f6dc9357SAndroid Build Coastguard Worker       di.IsPhysicalDrive = true;
203*f6dc9357SAndroid Build Coastguard Worker       di.KnownSize = true;
204*f6dc9357SAndroid Build Coastguard Worker       _drives.Add(di);
205*f6dc9357SAndroid Build Coastguard Worker     }
206*f6dc9357SAndroid Build Coastguard Worker   }
207*f6dc9357SAndroid Build Coastguard Worker 
208*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
209*f6dc9357SAndroid Build Coastguard Worker }
210*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::GetNumberOfItems (UInt32 * numItems))211*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::GetNumberOfItems(UInt32 *numItems))
212*f6dc9357SAndroid Build Coastguard Worker {
213*f6dc9357SAndroid Build Coastguard Worker   *numItems = _drives.Size();
214*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
215*f6dc9357SAndroid Build Coastguard Worker }
216*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::GetProperty (UInt32 itemIndex,PROPID propID,PROPVARIANT * value))217*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value))
218*f6dc9357SAndroid Build Coastguard Worker {
219*f6dc9357SAndroid Build Coastguard Worker   if (itemIndex >= _drives.Size())
220*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
221*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
222*f6dc9357SAndroid Build Coastguard Worker   const CDriveInfo &di = _drives[itemIndex];
223*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
224*f6dc9357SAndroid Build Coastguard Worker   {
225*f6dc9357SAndroid Build Coastguard Worker     case kpidIsDir:  prop = !_volumeMode; break;
226*f6dc9357SAndroid Build Coastguard Worker     case kpidName:  prop = fs2us(di.Name); break;
227*f6dc9357SAndroid Build Coastguard Worker     case kpidOutName:
228*f6dc9357SAndroid Build Coastguard Worker       if (!di.Name.IsEmpty() && di.Name.Back() == ':')
229*f6dc9357SAndroid Build Coastguard Worker       {
230*f6dc9357SAndroid Build Coastguard Worker         FString s = di.Name;
231*f6dc9357SAndroid Build Coastguard Worker         s.DeleteBack();
232*f6dc9357SAndroid Build Coastguard Worker         AddExt(s, itemIndex);
233*f6dc9357SAndroid Build Coastguard Worker         prop = fs2us(s);
234*f6dc9357SAndroid Build Coastguard Worker       }
235*f6dc9357SAndroid Build Coastguard Worker       break;
236*f6dc9357SAndroid Build Coastguard Worker 
237*f6dc9357SAndroid Build Coastguard Worker     case kpidTotalSize:   if (di.KnownSize) prop = di.DriveSize; break;
238*f6dc9357SAndroid Build Coastguard Worker     case kpidFreeSpace:   if (di.KnownSizes) prop = di.FreeSpace; break;
239*f6dc9357SAndroid Build Coastguard Worker     case kpidClusterSize: if (di.KnownSizes) prop = di.ClusterSize; break;
240*f6dc9357SAndroid Build Coastguard Worker     case kpidType:
241*f6dc9357SAndroid Build Coastguard Worker       if (di.DriveType < Z7_ARRAY_SIZE(kDriveTypes))
242*f6dc9357SAndroid Build Coastguard Worker         prop = kDriveTypes[di.DriveType];
243*f6dc9357SAndroid Build Coastguard Worker       break;
244*f6dc9357SAndroid Build Coastguard Worker     case kpidVolumeName:  prop = di.VolumeName; break;
245*f6dc9357SAndroid Build Coastguard Worker     case kpidFileSystem:  prop = di.FileSystemName; break;
246*f6dc9357SAndroid Build Coastguard Worker   }
247*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
248*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
249*f6dc9357SAndroid Build Coastguard Worker }
250*f6dc9357SAndroid Build Coastguard Worker 
BindToFolderSpec(CFSTR name,IFolderFolder ** resultFolder)251*f6dc9357SAndroid Build Coastguard Worker HRESULT CFSDrives::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
252*f6dc9357SAndroid Build Coastguard Worker {
253*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
254*f6dc9357SAndroid Build Coastguard Worker   if (_volumeMode)
255*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
256*f6dc9357SAndroid Build Coastguard Worker   NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
257*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
258*f6dc9357SAndroid Build Coastguard Worker   FString path;
259*f6dc9357SAndroid Build Coastguard Worker   if (_superMode)
260*f6dc9357SAndroid Build Coastguard Worker     path = kSuperPrefix;
261*f6dc9357SAndroid Build Coastguard Worker   path += name;
262*f6dc9357SAndroid Build Coastguard Worker   RINOK(fsFolderSpec->Init(path))
263*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = subFolder.Detach();
264*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
265*f6dc9357SAndroid Build Coastguard Worker }
266*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::BindToFolder (UInt32 index,IFolderFolder ** resultFolder))267*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder))
268*f6dc9357SAndroid Build Coastguard Worker {
269*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
270*f6dc9357SAndroid Build Coastguard Worker   if (index >= _drives.Size())
271*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
272*f6dc9357SAndroid Build Coastguard Worker   const CDriveInfo &di = _drives[index];
273*f6dc9357SAndroid Build Coastguard Worker   /*
274*f6dc9357SAndroid Build Coastguard Worker   if (_volumeMode)
275*f6dc9357SAndroid Build Coastguard Worker   {
276*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = 0;
277*f6dc9357SAndroid Build Coastguard Worker     CPhysDriveFolder *folderSpec = new CPhysDriveFolder;
278*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IFolderFolder> subFolder = folderSpec;
279*f6dc9357SAndroid Build Coastguard Worker     RINOK(folderSpec->Init(di.Name));
280*f6dc9357SAndroid Build Coastguard Worker     *resultFolder = subFolder.Detach();
281*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
282*f6dc9357SAndroid Build Coastguard Worker   }
283*f6dc9357SAndroid Build Coastguard Worker   */
284*f6dc9357SAndroid Build Coastguard Worker   return BindToFolderSpec(di.FullSystemName, resultFolder);
285*f6dc9357SAndroid Build Coastguard Worker }
286*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::BindToFolder (const wchar_t * name,IFolderFolder ** resultFolder))287*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder))
288*f6dc9357SAndroid Build Coastguard Worker {
289*f6dc9357SAndroid Build Coastguard Worker   return BindToFolderSpec(us2fs(name), resultFolder);
290*f6dc9357SAndroid Build Coastguard Worker }
291*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::BindToParentFolder (IFolderFolder ** resultFolder))292*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::BindToParentFolder(IFolderFolder **resultFolder))
293*f6dc9357SAndroid Build Coastguard Worker {
294*f6dc9357SAndroid Build Coastguard Worker   *resultFolder = NULL;
295*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
296*f6dc9357SAndroid Build Coastguard Worker }
297*f6dc9357SAndroid Build Coastguard Worker 
298*f6dc9357SAndroid Build Coastguard Worker IMP_IFolderFolder_Props(CFSDrives)
299*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::GetFolderProperty (PROPID propID,PROPVARIANT * value))300*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value))
301*f6dc9357SAndroid Build Coastguard Worker {
302*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
303*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
304*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
305*f6dc9357SAndroid Build Coastguard Worker   {
306*f6dc9357SAndroid Build Coastguard Worker     case kpidType: prop = "FSDrives"; break;
307*f6dc9357SAndroid Build Coastguard Worker     case kpidPath:
308*f6dc9357SAndroid Build Coastguard Worker       if (_volumeMode)
309*f6dc9357SAndroid Build Coastguard Worker         prop = kVolPrefix;
310*f6dc9357SAndroid Build Coastguard Worker       else if (_superMode)
311*f6dc9357SAndroid Build Coastguard Worker         prop = kSuperPrefix;
312*f6dc9357SAndroid Build Coastguard Worker       else
313*f6dc9357SAndroid Build Coastguard Worker         prop = (UString)LangString(IDS_COMPUTER) + WCHAR_PATH_SEPARATOR;
314*f6dc9357SAndroid Build Coastguard Worker       break;
315*f6dc9357SAndroid Build Coastguard Worker   }
316*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
317*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
318*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
319*f6dc9357SAndroid Build Coastguard Worker }
320*f6dc9357SAndroid Build Coastguard Worker 
321*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::GetSystemIconIndex (UInt32 index,Int32 * iconIndex))322*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
323*f6dc9357SAndroid Build Coastguard Worker {
324*f6dc9357SAndroid Build Coastguard Worker   *iconIndex = -1;
325*f6dc9357SAndroid Build Coastguard Worker   const CDriveInfo &di = _drives[index];
326*f6dc9357SAndroid Build Coastguard Worker   return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
327*f6dc9357SAndroid Build Coastguard Worker       di.FullSystemName,
328*f6dc9357SAndroid Build Coastguard Worker       _volumeMode ?
329*f6dc9357SAndroid Build Coastguard Worker           FILE_ATTRIBUTE_ARCHIVE:
330*f6dc9357SAndroid Build Coastguard Worker           FILE_ATTRIBUTE_DIRECTORY,
331*f6dc9357SAndroid Build Coastguard Worker       iconIndex);
332*f6dc9357SAndroid Build Coastguard Worker }
333*f6dc9357SAndroid Build Coastguard Worker 
AddExt(FString & s,unsigned index) const334*f6dc9357SAndroid Build Coastguard Worker void CFSDrives::AddExt(FString &s, unsigned index) const
335*f6dc9357SAndroid Build Coastguard Worker {
336*f6dc9357SAndroid Build Coastguard Worker   s.Add_Dot();
337*f6dc9357SAndroid Build Coastguard Worker   const CDriveInfo &di = _drives[index];
338*f6dc9357SAndroid Build Coastguard Worker   UString n = di.FileSystemName;
339*f6dc9357SAndroid Build Coastguard Worker   n.MakeLower_Ascii();
340*f6dc9357SAndroid Build Coastguard Worker   const char *ext;
341*f6dc9357SAndroid Build Coastguard Worker   if (di.DriveType == DRIVE_CDROM)
342*f6dc9357SAndroid Build Coastguard Worker     ext = "iso";
343*f6dc9357SAndroid Build Coastguard Worker   else
344*f6dc9357SAndroid Build Coastguard Worker   {
345*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
346*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < n.Len(); i++)
347*f6dc9357SAndroid Build Coastguard Worker     {
348*f6dc9357SAndroid Build Coastguard Worker       const wchar_t c = n[i];
349*f6dc9357SAndroid Build Coastguard Worker       if (c < 'a' || c > 'z')
350*f6dc9357SAndroid Build Coastguard Worker         break;
351*f6dc9357SAndroid Build Coastguard Worker     }
352*f6dc9357SAndroid Build Coastguard Worker     if (i != 0)
353*f6dc9357SAndroid Build Coastguard Worker     {
354*f6dc9357SAndroid Build Coastguard Worker       n.DeleteFrom(i);
355*f6dc9357SAndroid Build Coastguard Worker       s += us2fs(n);
356*f6dc9357SAndroid Build Coastguard Worker       return;
357*f6dc9357SAndroid Build Coastguard Worker     }
358*f6dc9357SAndroid Build Coastguard Worker     ext = "img";
359*f6dc9357SAndroid Build Coastguard Worker   }
360*f6dc9357SAndroid Build Coastguard Worker   /*
361*f6dc9357SAndroid Build Coastguard Worker        if (n.IsPrefixedBy_Ascii_NoCase("NTFS")) ext = "ntfs";
362*f6dc9357SAndroid Build Coastguard Worker   else if (n.IsPrefixedBy_Ascii_NoCase("UDF")) ext = "udf";
363*f6dc9357SAndroid Build Coastguard Worker   else if (n.IsPrefixedBy_Ascii_NoCase("exFAT")) ext = "exfat";
364*f6dc9357SAndroid Build Coastguard Worker   */
365*f6dc9357SAndroid Build Coastguard Worker   s += ext;
366*f6dc9357SAndroid Build Coastguard Worker }
367*f6dc9357SAndroid Build Coastguard Worker 
GetFileSize(unsigned index,UInt64 & fileSize) const368*f6dc9357SAndroid Build Coastguard Worker HRESULT CFSDrives::GetFileSize(unsigned index, UInt64& fileSize) const
369*f6dc9357SAndroid Build Coastguard Worker {
370*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_DEVICE_FILE
371*f6dc9357SAndroid Build Coastguard Worker   NIO::CInFile inFile;
372*f6dc9357SAndroid Build Coastguard Worker   if (!inFile.Open(_drives[index].GetDeviceFileIoName()))
373*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
374*f6dc9357SAndroid Build Coastguard Worker   if (inFile.SizeDefined)
375*f6dc9357SAndroid Build Coastguard Worker   {
376*f6dc9357SAndroid Build Coastguard Worker     fileSize = inFile.Size;
377*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
378*f6dc9357SAndroid Build Coastguard Worker   }
379*f6dc9357SAndroid Build Coastguard Worker #else
380*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(index)
381*f6dc9357SAndroid Build Coastguard Worker #endif
382*f6dc9357SAndroid Build Coastguard Worker   fileSize = 0;
383*f6dc9357SAndroid Build Coastguard Worker   return E_FAIL;
384*f6dc9357SAndroid Build Coastguard Worker }
385*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::CopyTo (Int32 moveMode,const UInt32 * indices,UInt32 numItems,Int32,Int32,const wchar_t * path,IFolderOperationsExtractCallback * callback))386*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
387*f6dc9357SAndroid Build Coastguard Worker     Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
388*f6dc9357SAndroid Build Coastguard Worker     const wchar_t *path, IFolderOperationsExtractCallback *callback))
389*f6dc9357SAndroid Build Coastguard Worker {
390*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
391*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
392*f6dc9357SAndroid Build Coastguard Worker   if (moveMode)
393*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
394*f6dc9357SAndroid Build Coastguard Worker   if (!_volumeMode)
395*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
396*f6dc9357SAndroid Build Coastguard Worker 
397*f6dc9357SAndroid Build Coastguard Worker   UInt64 totalSize = 0;
398*f6dc9357SAndroid Build Coastguard Worker   UInt32 i;
399*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numItems; i++)
400*f6dc9357SAndroid Build Coastguard Worker   {
401*f6dc9357SAndroid Build Coastguard Worker     const CDriveInfo &di = _drives[indices[i]];
402*f6dc9357SAndroid Build Coastguard Worker     if (di.KnownSize)
403*f6dc9357SAndroid Build Coastguard Worker       totalSize += di.DriveSize;
404*f6dc9357SAndroid Build Coastguard Worker   }
405*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->SetTotal(totalSize))
406*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->SetNumFiles(numItems))
407*f6dc9357SAndroid Build Coastguard Worker 
408*f6dc9357SAndroid Build Coastguard Worker   const FString destPath = us2fs(path);
409*f6dc9357SAndroid Build Coastguard Worker   if (destPath.IsEmpty())
410*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
411*f6dc9357SAndroid Build Coastguard Worker 
412*f6dc9357SAndroid Build Coastguard Worker   const bool isAltDest = NName::IsAltPathPrefix(destPath);
413*f6dc9357SAndroid Build Coastguard Worker   const bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
414*f6dc9357SAndroid Build Coastguard Worker 
415*f6dc9357SAndroid Build Coastguard Worker   if (isDirectPath)
416*f6dc9357SAndroid Build Coastguard Worker   {
417*f6dc9357SAndroid Build Coastguard Worker     if (numItems > 1)
418*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
419*f6dc9357SAndroid Build Coastguard Worker   }
420*f6dc9357SAndroid Build Coastguard Worker 
421*f6dc9357SAndroid Build Coastguard Worker   UInt64 completedSize = 0;
422*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->SetCompleted(&completedSize))
423*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numItems; i++)
424*f6dc9357SAndroid Build Coastguard Worker   {
425*f6dc9357SAndroid Build Coastguard Worker     const unsigned index = indices[i];
426*f6dc9357SAndroid Build Coastguard Worker     const CDriveInfo &di = _drives[index];
427*f6dc9357SAndroid Build Coastguard Worker     FString destPath2 = destPath;
428*f6dc9357SAndroid Build Coastguard Worker 
429*f6dc9357SAndroid Build Coastguard Worker     if (!isDirectPath)
430*f6dc9357SAndroid Build Coastguard Worker     {
431*f6dc9357SAndroid Build Coastguard Worker       FString destName = di.Name;
432*f6dc9357SAndroid Build Coastguard Worker       if (!destName.IsEmpty() && destName.Back() == ':')
433*f6dc9357SAndroid Build Coastguard Worker       {
434*f6dc9357SAndroid Build Coastguard Worker         destName.DeleteBack();
435*f6dc9357SAndroid Build Coastguard Worker         AddExt(destName, index);
436*f6dc9357SAndroid Build Coastguard Worker       }
437*f6dc9357SAndroid Build Coastguard Worker       destPath2 += destName;
438*f6dc9357SAndroid Build Coastguard Worker     }
439*f6dc9357SAndroid Build Coastguard Worker 
440*f6dc9357SAndroid Build Coastguard Worker     const FString srcPath = di.GetDeviceFileIoName();
441*f6dc9357SAndroid Build Coastguard Worker 
442*f6dc9357SAndroid Build Coastguard Worker     UInt64 fileSize = 0;
443*f6dc9357SAndroid Build Coastguard Worker     if (GetFileSize(index, fileSize) != S_OK)
444*f6dc9357SAndroid Build Coastguard Worker     {
445*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
446*f6dc9357SAndroid Build Coastguard Worker     }
447*f6dc9357SAndroid Build Coastguard Worker     if (!di.KnownSize)
448*f6dc9357SAndroid Build Coastguard Worker     {
449*f6dc9357SAndroid Build Coastguard Worker       totalSize += fileSize;
450*f6dc9357SAndroid Build Coastguard Worker       RINOK(callback->SetTotal(totalSize))
451*f6dc9357SAndroid Build Coastguard Worker     }
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker     Int32 writeAskResult;
454*f6dc9357SAndroid Build Coastguard Worker     CMyComBSTR destPathResult;
455*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->AskWrite(fs2us(srcPath), BoolToInt(false), NULL, &fileSize,
456*f6dc9357SAndroid Build Coastguard Worker         fs2us(destPath2), &destPathResult, &writeAskResult))
457*f6dc9357SAndroid Build Coastguard Worker 
458*f6dc9357SAndroid Build Coastguard Worker     if (!IntToBool(writeAskResult))
459*f6dc9357SAndroid Build Coastguard Worker     {
460*f6dc9357SAndroid Build Coastguard Worker       if (totalSize >= fileSize)
461*f6dc9357SAndroid Build Coastguard Worker         totalSize -= fileSize;
462*f6dc9357SAndroid Build Coastguard Worker       RINOK(callback->SetTotal(totalSize))
463*f6dc9357SAndroid Build Coastguard Worker       continue;
464*f6dc9357SAndroid Build Coastguard Worker     }
465*f6dc9357SAndroid Build Coastguard Worker 
466*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->SetCurrentFilePath(fs2us(srcPath)))
467*f6dc9357SAndroid Build Coastguard Worker 
468*f6dc9357SAndroid Build Coastguard Worker     const UInt32 kBufferSize = (4 << 20);
469*f6dc9357SAndroid Build Coastguard Worker     const UInt32 bufferSize = (di.DriveType == DRIVE_REMOVABLE) ? (18 << 10) * 4 : kBufferSize;
470*f6dc9357SAndroid Build Coastguard Worker     RINOK(CopyFileSpec(srcPath, us2fs(destPathResult), false, fileSize, bufferSize, completedSize, callback))
471*f6dc9357SAndroid Build Coastguard Worker     completedSize += fileSize;
472*f6dc9357SAndroid Build Coastguard Worker   }
473*f6dc9357SAndroid Build Coastguard Worker 
474*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
475*f6dc9357SAndroid Build Coastguard Worker }
476*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::CopyFrom (Int32,const wchar_t *,const wchar_t * const *,UInt32,IProgress *))477*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
478*f6dc9357SAndroid Build Coastguard Worker     const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */))
479*f6dc9357SAndroid Build Coastguard Worker {
480*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
481*f6dc9357SAndroid Build Coastguard Worker }
482*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::CopyFromFile (UInt32,const wchar_t *,IProgress *))483*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */))
484*f6dc9357SAndroid Build Coastguard Worker {
485*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
486*f6dc9357SAndroid Build Coastguard Worker }
487*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::CreateFolder (const wchar_t *,IProgress *))488*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */))
489*f6dc9357SAndroid Build Coastguard Worker {
490*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
491*f6dc9357SAndroid Build Coastguard Worker }
492*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::CreateFile (const wchar_t *,IProgress *))493*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::CreateFile(const wchar_t * /* name */, IProgress * /* progress */))
494*f6dc9357SAndroid Build Coastguard Worker {
495*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
496*f6dc9357SAndroid Build Coastguard Worker }
497*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::Rename (UInt32,const wchar_t *,IProgress *))498*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::Rename(UInt32 /* index */, const wchar_t * /* newName */, IProgress * /* progress */))
499*f6dc9357SAndroid Build Coastguard Worker {
500*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
501*f6dc9357SAndroid Build Coastguard Worker }
502*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::Delete (const UInt32 *,UInt32,IProgress *))503*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::Delete(const UInt32 * /* indices */, UInt32 /* numItems */, IProgress * /* progress */))
504*f6dc9357SAndroid Build Coastguard Worker {
505*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
506*f6dc9357SAndroid Build Coastguard Worker }
507*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CFSDrives::SetProperty (UInt32,PROPID,const PROPVARIANT *,IProgress *))508*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CFSDrives::SetProperty(UInt32 /* index */, PROPID /* propID */,
509*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT * /* value */, IProgress * /* progress */))
510*f6dc9357SAndroid Build Coastguard Worker {
511*f6dc9357SAndroid Build Coastguard Worker   return E_NOTIMPL;
512*f6dc9357SAndroid Build Coastguard Worker }
513