bool CoreUnix::FilesystemSupportsLargeFiles (const FilePath &filePath) const { string path = filePath; size_t pos; while ((pos = path.find_last_of ('/')) != string::npos) { path = path.substr (0, pos); if (path.empty()) break; try { MountedFilesystemList filesystems = GetMountedFilesystems (DevicePath(), path); if (!filesystems.empty()) { const MountedFilesystem &fs = *filesystems.front(); if (fs.Type == "fat" || fs.Type == "fat32" || fs.Type == "vfat" || fs.Type == "fatfs" || fs.Type == "msdos" || fs.Type == "msdosfs" || fs.Type == "umsdos" || fs.Type == "dos" || fs.Type == "dosfs" || fs.Type == "pcfs" ) { return false; } return true; } } catch (...) { } } return true; // Prevent errors if the filesystem cannot be identified }
void CoreUnix::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const { if (GetMountedFilesystems (DevicePath(), mountPoint).size() > 0) throw MountPointUnavailable (SRC_POS); list <string> args; string options; if (!filesystemType.empty()) { #ifdef TC_SOLARIS args.push_back ("-F"); #else args.push_back ("-t"); #endif args.push_back (filesystemType); } if (readOnly) options = "-oro"; if (!systemMountOptions.empty()) { if (options.empty()) options = "-o"; else options += ","; options += systemMountOptions; } if (!options.empty()) args.push_back (options); args.push_back ("--"); args.push_back (devicePath); args.push_back (mountPoint); Process::Execute ("mount", args); }
shared_ptr <VolumeInfo> CoreUnix::MountVolume (MountOptions &options) { CoalesceSlotNumberAndMountPoint (options); if (IsVolumeMounted (*options.Path)) throw VolumeAlreadyMounted (SRC_POS); Cipher::EnableHwSupport (!options.NoHardwareCrypto); shared_ptr <Volume> volume; while (true) { try { volume = OpenVolume ( options.Path, options.PreserveTimestamps, options.Password, options.Keyfiles, options.Protection, options.ProtectionPassword, options.ProtectionKeyfiles, options.SharedAccessAllowed, VolumeType::Unknown, options.UseBackupHeaders, options.PartitionInSystemEncryptionScope ); options.Password.reset(); } catch (SystemException &e) { if (options.Protection != VolumeProtection::ReadOnly && (e.GetErrorCode() == EROFS || e.GetErrorCode() == EACCES || e.GetErrorCode() == EPERM)) { // Read-only filesystem options.Protection = VolumeProtection::ReadOnly; continue; } throw; } break; } if (options.Path->IsDevice()) { if (volume->GetFile()->GetDeviceSectorSize() != volume->GetSectorSize()) throw ParameterIncorrect (SRC_POS); #if defined (TC_LINUX) if (volume->GetSectorSize() != TC_SECTOR_SIZE_LEGACY) { if (options.Protection == VolumeProtection::HiddenVolumeReadOnly) throw UnsupportedSectorSizeHiddenVolumeProtection(); if (options.NoKernelCrypto) throw UnsupportedSectorSizeNoKernelCrypto(); } #endif } // Find a free mount point for FUSE service MountedFilesystemList mountedFilesystems = GetMountedFilesystems (); string fuseMountPoint; for (int i = 1; true; i++) { stringstream path; path << GetTempDirectory() << "/" << GetFuseMountDirPrefix() << i; FilesystemPath fsPath (path.str()); bool inUse = false; foreach_ref (const MountedFilesystem &mf, mountedFilesystems) { if (mf.MountPoint == path.str()) { inUse = true; break; } } if (!inUse) { try { if (fsPath.IsDirectory()) fsPath.Delete(); throw_sys_sub_if (mkdir (path.str().c_str(), S_IRUSR | S_IXUSR) == -1, path.str()); fuseMountPoint = fsPath; break; } catch (...) { if (i > 255) throw TemporaryDirectoryFailure (SRC_POS, StringConverter::ToWide (path.str())); } } } try { FuseService::Mount (volume, options.SlotNumber, fuseMountPoint); } catch (...) { try { DirectoryPath (fuseMountPoint).Delete(); } catch (...) { } throw; } try { // Create a mount directory if a default path has been specified bool mountDirCreated = false; string mountPoint; if (!options.NoFilesystem && options.MountPoint) { mountPoint = *options.MountPoint; #ifndef TC_MACOSX if (mountPoint.find (GetDefaultMountPointPrefix()) == 0 && !options.MountPoint->IsDirectory()) { Directory::Create (*options.MountPoint); try { throw_sys_sub_if (chown (mountPoint.c_str(), GetRealUserId(), GetRealGroupId()) == -1, mountPoint); } catch (ParameterIncorrect&) { } mountDirCreated = true; } #endif } try { try { MountVolumeNative (volume, options, fuseMountPoint); } catch (NotApplicable&) { MountAuxVolumeImage (fuseMountPoint, options); } } catch (...) { if (mountDirCreated) remove (mountPoint.c_str()); throw; } } catch (...) { try { VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path); if (mountedVolumes.size() > 0) { shared_ptr <VolumeInfo> mountedVolume (mountedVolumes.front()); DismountVolume (mountedVolume); } } catch (...) { } throw; } VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path); if (mountedVolumes.size() != 1) throw ParameterIncorrect (SRC_POS); VolumeEventArgs eventArgs (mountedVolumes.front()); VolumeMountedEvent.Raise (eventArgs); return mountedVolumes.front(); }
bool CoreUnix::IsMountPointAvailable (const DirectoryPath &mountPoint) const { return GetMountedFilesystems (DevicePath(), mountPoint).size() == 0; }