mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-09 22:36:59 -05:00
macOS: stabilize FUSE-T SMB mount metadata
Make /aux-device-info readable for SMB, verify that FUSE records hdiutil device info after mount and recover missing virtual devices from hdiutil before dismounting auxiliary mounts.
This commit is contained in:
committed by
Mounir IDRASSI
parent
4271b8e6f5
commit
deb7f55bfb
+22
-13
@@ -350,7 +350,7 @@ namespace VeraCrypt
|
|||||||
// The list is already filtered to VeraCrypt auxiliary mounts; in
|
// The list is already filtered to VeraCrypt auxiliary mounts; in
|
||||||
// FUSE-T builds, the mount table device name varies by backend.
|
// FUSE-T builds, the mount table device name varies by backend.
|
||||||
#ifdef VC_MACOSX_FUSET
|
#ifdef VC_MACOSX_FUSET
|
||||||
int controlFileRetries = 10; // 10 retries with 500ms sleep each, total 5 seconds
|
int controlFileRetries = volumePath.IsEmpty() ? 1 : 10; // Up to 10 attempts with 500ms sleeps for specific volume lookups
|
||||||
string controlFileError;
|
string controlFileError;
|
||||||
while (!mountedVol && (controlFileRetries-- > 0))
|
while (!mountedVol && (controlFileRetries-- > 0))
|
||||||
#endif
|
#endif
|
||||||
@@ -372,9 +372,12 @@ namespace VeraCrypt
|
|||||||
{
|
{
|
||||||
#ifdef VC_MACOSX_FUSET
|
#ifdef VC_MACOSX_FUSET
|
||||||
controlFileError = StringConverter::ToSingle (StringConverter::ToExceptionString (e));
|
controlFileError = StringConverter::ToSingle (StringConverter::ToExceptionString (e));
|
||||||
// FUSE-T's SMB backend can briefly expose the auxiliary mount
|
if (controlFileRetries > 0)
|
||||||
// before the control file is readable and deserializable.
|
{
|
||||||
Thread::Sleep (500);
|
// FUSE-T's SMB backend can briefly expose the auxiliary mount
|
||||||
|
// before the control file is readable and deserializable.
|
||||||
|
Thread::Sleep (500);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
(void) e;
|
(void) e;
|
||||||
#endif
|
#endif
|
||||||
@@ -383,9 +386,12 @@ namespace VeraCrypt
|
|||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
controlFileError = "unknown exception";
|
controlFileError = "unknown exception";
|
||||||
// FUSE-T's SMB backend can briefly expose the auxiliary mount
|
if (controlFileRetries > 0)
|
||||||
// before the control file is readable and deserializable.
|
{
|
||||||
Thread::Sleep (500);
|
// FUSE-T's SMB backend can briefly expose the auxiliary mount
|
||||||
|
// before the control file is readable and deserializable.
|
||||||
|
Thread::Sleep (500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -393,12 +399,15 @@ namespace VeraCrypt
|
|||||||
if (!mountedVol)
|
if (!mountedVol)
|
||||||
{
|
{
|
||||||
#ifdef VC_MACOSX_FUSET
|
#ifdef VC_MACOSX_FUSET
|
||||||
stringstream logMessage;
|
if (!volumePath.IsEmpty())
|
||||||
logMessage << "Failed to read VeraCrypt auxiliary mount control file after retries: "
|
{
|
||||||
<< string (mf.MountPoint) << FuseService::GetControlPath();
|
stringstream logMessage;
|
||||||
if (!controlFileError.empty())
|
logMessage << "Failed to read VeraCrypt auxiliary mount control file after retries: "
|
||||||
logMessage << ": " << controlFileError;
|
<< string (mf.MountPoint) << FuseService::GetControlPath();
|
||||||
SystemLog::WriteError (logMessage.str());
|
if (!controlFileError.empty())
|
||||||
|
logMessage << ": " << controlFileError;
|
||||||
|
SystemLog::WriteError (logMessage.str());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
continue; // Skip to the next mounted filesystem
|
continue; // Skip to the next mounted filesystem
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,170 @@
|
|||||||
#include "CoreMacOSX.h"
|
#include "CoreMacOSX.h"
|
||||||
#include "Driver/Fuse/FuseService.h"
|
#include "Driver/Fuse/FuseService.h"
|
||||||
#include "Core/Unix/CoreServiceProxy.h"
|
#include "Core/Unix/CoreServiceProxy.h"
|
||||||
|
#include "Platform/FileStream.h"
|
||||||
|
#include "Platform/MemoryStream.h"
|
||||||
|
#include "Platform/Serializable.h"
|
||||||
|
#include "Platform/SystemLog.h"
|
||||||
|
|
||||||
namespace VeraCrypt
|
namespace VeraCrypt
|
||||||
{
|
{
|
||||||
|
static string DecodePlistXmlString (const string &xmlString)
|
||||||
|
{
|
||||||
|
string decoded;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < xmlString.size(); ++i)
|
||||||
|
{
|
||||||
|
if (xmlString[i] != '&')
|
||||||
|
{
|
||||||
|
decoded += xmlString[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmlString.compare (i, 5, "&") == 0)
|
||||||
|
{
|
||||||
|
decoded += '&';
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
else if (xmlString.compare (i, 4, "<") == 0)
|
||||||
|
{
|
||||||
|
decoded += '<';
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
else if (xmlString.compare (i, 4, ">") == 0)
|
||||||
|
{
|
||||||
|
decoded += '>';
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
else if (xmlString.compare (i, 6, """) == 0)
|
||||||
|
{
|
||||||
|
decoded += '"';
|
||||||
|
i += 5;
|
||||||
|
}
|
||||||
|
else if (xmlString.compare (i, 6, "'") == 0)
|
||||||
|
{
|
||||||
|
decoded += '\'';
|
||||||
|
i += 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
decoded += xmlString[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ExtractPlistString (const string &xml, const string &key, size_t start, size_t limit, string &value, size_t *endPos = nullptr)
|
||||||
|
{
|
||||||
|
string keyTag = "<key>" + key + "</key>";
|
||||||
|
size_t p = xml.find (keyTag, start);
|
||||||
|
if (p == string::npos || p >= limit)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
p = xml.find ("<string>", p + keyTag.size());
|
||||||
|
if (p == string::npos || p >= limit)
|
||||||
|
return false;
|
||||||
|
p += 8;
|
||||||
|
|
||||||
|
size_t e = xml.find ("</string>", p);
|
||||||
|
if (e == string::npos || e > limit)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
value = DecodePlistXmlString (xml.substr (p, e - p));
|
||||||
|
if (endPos)
|
||||||
|
*endPos = e + 9;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string NormalizeDiskImagePath (const string &path)
|
||||||
|
{
|
||||||
|
string normalized;
|
||||||
|
bool previousSlash = false;
|
||||||
|
|
||||||
|
for (string::const_iterator i = path.begin(); i != path.end(); ++i)
|
||||||
|
{
|
||||||
|
if (*i == '/')
|
||||||
|
{
|
||||||
|
if (previousSlash)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
previousSlash = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
previousSlash = false;
|
||||||
|
|
||||||
|
normalized += *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalized.find ("/private/var/") == 0)
|
||||||
|
normalized.erase (0, 8);
|
||||||
|
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DevicePath FindVirtualDeviceByImagePath (const string &imagePath)
|
||||||
|
{
|
||||||
|
list <string> args;
|
||||||
|
args.push_back ("info");
|
||||||
|
args.push_back ("-plist");
|
||||||
|
|
||||||
|
string xml = Process::Execute ("/usr/bin/hdiutil", args);
|
||||||
|
string normalizedImagePath = NormalizeDiskImagePath (imagePath);
|
||||||
|
|
||||||
|
for (size_t p = 0; ; )
|
||||||
|
{
|
||||||
|
size_t imageKeyPos = xml.find ("<key>image-path</key>", p);
|
||||||
|
if (imageKeyPos == string::npos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
string currentImagePath;
|
||||||
|
size_t imageValueEnd = 0;
|
||||||
|
if (!ExtractPlistString (xml, "image-path", imageKeyPos, string::npos, currentImagePath, &imageValueEnd))
|
||||||
|
{
|
||||||
|
p = imageKeyPos + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nextImageKeyPos = xml.find ("<key>image-path</key>", imageValueEnd);
|
||||||
|
if (NormalizeDiskImagePath (currentImagePath) == normalizedImagePath)
|
||||||
|
{
|
||||||
|
string devEntry;
|
||||||
|
if (ExtractPlistString (xml, "dev-entry", imageValueEnd, nextImageKeyPos, devEntry))
|
||||||
|
return StringConverter::Trim (devEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = imageValueEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DevicePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool AuxiliaryControlFileHasVirtualDevice (const DirectoryPath &auxMountPoint, const DevicePath &virtualDev)
|
||||||
|
{
|
||||||
|
for (int t = 0; t < 50; ++t)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
shared_ptr <File> controlFile (new File);
|
||||||
|
controlFile->Open (string (auxMountPoint) + FuseService::GetControlPath());
|
||||||
|
|
||||||
|
FileStream controlFileReader (controlFile);
|
||||||
|
string controlFileData = controlFileReader.ReadToEnd();
|
||||||
|
if (controlFileData.empty() || controlFileData.size() > 1024 * 1024)
|
||||||
|
throw ParameterIncorrect (SRC_POS);
|
||||||
|
|
||||||
|
shared_ptr <Stream> controlFileStream (new MemoryStream (ConstBufferPtr ((const uint8 *) controlFileData.data(), controlFileData.size())));
|
||||||
|
shared_ptr <VolumeInfo> mountedVol = Serializable::DeserializeNew <VolumeInfo> (controlFileStream);
|
||||||
|
if (mountedVol && string (mountedVol->VirtualDevice) == string (virtualDev))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (...) { }
|
||||||
|
|
||||||
|
Thread::Sleep (100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CoreMacOSX::CoreMacOSX ()
|
CoreMacOSX::CoreMacOSX ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -36,6 +197,17 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
shared_ptr <VolumeInfo> CoreMacOSX::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
|
shared_ptr <VolumeInfo> CoreMacOSX::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
|
||||||
{
|
{
|
||||||
|
if (mountedVolume->VirtualDevice.IsEmpty() && !mountedVolume->AuxMountPoint.IsEmpty())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DevicePath recoveredVirtualDevice = FindVirtualDeviceByImagePath (string (mountedVolume->AuxMountPoint) + FuseService::GetVolumeImagePath());
|
||||||
|
if (!recoveredVirtualDevice.IsEmpty())
|
||||||
|
mountedVolume->VirtualDevice = recoveredVirtualDevice;
|
||||||
|
}
|
||||||
|
catch (...) { }
|
||||||
|
}
|
||||||
|
|
||||||
if (!mountedVolume->VirtualDevice.IsEmpty() && mountedVolume->VirtualDevice.IsBlockDevice())
|
if (!mountedVolume->VirtualDevice.IsEmpty() && mountedVolume->VirtualDevice.IsBlockDevice())
|
||||||
{
|
{
|
||||||
list <string> args;
|
list <string> args;
|
||||||
@@ -223,6 +395,16 @@ namespace VeraCrypt
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
FuseService::SendAuxDeviceInfo (auxMountPoint, virtualDev);
|
FuseService::SendAuxDeviceInfo (auxMountPoint, virtualDev);
|
||||||
|
if (!AuxiliaryControlFileHasVirtualDevice (auxMountPoint, virtualDev))
|
||||||
|
{
|
||||||
|
stringstream logMessage;
|
||||||
|
logMessage << "VeraCrypt auxiliary mount did not report hdiutil device after mount: "
|
||||||
|
<< string (auxMountPoint) << FuseService::GetControlPath()
|
||||||
|
<< ", expected " << string (virtualDev);
|
||||||
|
SystemLog::WriteError (logMessage.str());
|
||||||
|
|
||||||
|
throw TimeOut (SRC_POS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@@ -230,7 +412,7 @@ namespace VeraCrypt
|
|||||||
{
|
{
|
||||||
list <string> args;
|
list <string> args;
|
||||||
args.push_back ("detach");
|
args.push_back ("detach");
|
||||||
args.push_back (volImage);
|
args.push_back (virtualDev);
|
||||||
args.push_back ("-force");
|
args.push_back ("-force");
|
||||||
|
|
||||||
Process::Execute ("/usr/bin/hdiutil", args);
|
Process::Execute ("/usr/bin/hdiutil", args);
|
||||||
|
|||||||
@@ -75,6 +75,14 @@ namespace VeraCrypt
|
|||||||
statData->st_blocks = fuse_service_ceil_div ((uint64) statData->st_size, VC_FUSE_STAT_BLOCK_SIZE);
|
statData->st_blocks = fuse_service_ceil_div ((uint64) statData->st_size, VC_FUSE_STAT_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static shared_ptr <Buffer> fuse_service_get_control_info (struct fuse_file_info *fi)
|
||||||
|
{
|
||||||
|
if (fi && fi->fh)
|
||||||
|
return *reinterpret_cast <shared_ptr <Buffer> *> (fi->fh);
|
||||||
|
|
||||||
|
return FuseService::GetVolumeInfo();
|
||||||
|
}
|
||||||
|
|
||||||
static int fuse_service_fill_dir_entry (void *buf, fuse_fill_dir_t filler, const char *name, mode_t mode, ino_t ino, off_t nextOff)
|
static int fuse_service_fill_dir_entry (void *buf, fuse_fill_dir_t filler, const char *name, mode_t mode, ino_t ino, off_t nextOff)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@@ -200,7 +208,7 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
if (strcmp (path, FuseService::GetAuxDeviceInfoPath()) == 0)
|
if (strcmp (path, FuseService::GetAuxDeviceInfoPath()) == 0)
|
||||||
{
|
{
|
||||||
statData->st_mode = S_IFREG | 0200;
|
statData->st_mode = S_IFREG | 0600;
|
||||||
statData->st_nlink = 1;
|
statData->st_nlink = 1;
|
||||||
statData->st_size = VC_FUSE_BLOCK_SIZE;
|
statData->st_size = VC_FUSE_BLOCK_SIZE;
|
||||||
statData->st_ino = VC_FUSE_INODE_AUX_DEVICE_INFO;
|
statData->st_ino = VC_FUSE_INODE_AUX_DEVICE_INFO;
|
||||||
@@ -218,7 +226,7 @@ namespace VeraCrypt
|
|||||||
{
|
{
|
||||||
statData->st_mode = S_IFREG | 0600;
|
statData->st_mode = S_IFREG | 0600;
|
||||||
statData->st_nlink = 1;
|
statData->st_nlink = 1;
|
||||||
statData->st_size = FuseService::GetVolumeInfo()->Size();
|
statData->st_size = VC_FUSE_BLOCK_SIZE;
|
||||||
statData->st_ino = VC_FUSE_INODE_CONTROL;
|
statData->st_ino = VC_FUSE_INODE_CONTROL;
|
||||||
fuse_service_set_stat_blocks (statData);
|
fuse_service_set_stat_blocks (statData);
|
||||||
}
|
}
|
||||||
@@ -314,6 +322,7 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
if (strcmp (path, FuseService::GetControlPath()) == 0)
|
if (strcmp (path, FuseService::GetControlPath()) == 0)
|
||||||
{
|
{
|
||||||
|
fi->fh = reinterpret_cast <uint64> (new shared_ptr <Buffer> (FuseService::GetVolumeInfo()));
|
||||||
fi->direct_io = 1;
|
fi->direct_io = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -372,7 +381,22 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
if (strcmp (path, FuseService::GetControlPath()) == 0)
|
if (strcmp (path, FuseService::GetControlPath()) == 0)
|
||||||
{
|
{
|
||||||
shared_ptr <Buffer> infoBuf = FuseService::GetVolumeInfo();
|
shared_ptr <Buffer> infoBuf = fuse_service_get_control_info (fi);
|
||||||
|
BufferPtr outBuf ((uint8 *)buf, size);
|
||||||
|
|
||||||
|
if (offset >= (off_t) infoBuf->Size())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (offset + size > infoBuf->Size())
|
||||||
|
size = infoBuf->Size () - offset;
|
||||||
|
|
||||||
|
outBuf.CopyFrom (infoBuf->GetRange (offset, size));
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (path, FuseService::GetAuxDeviceInfoPath()) == 0)
|
||||||
|
{
|
||||||
|
shared_ptr <Buffer> infoBuf = FuseService::GetAuxDeviceInfo();
|
||||||
BufferPtr outBuf ((uint8 *)buf, size);
|
BufferPtr outBuf ((uint8 *)buf, size);
|
||||||
|
|
||||||
if (offset >= (off_t) infoBuf->Size())
|
if (offset >= (off_t) infoBuf->Size())
|
||||||
@@ -393,6 +417,24 @@ namespace VeraCrypt
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fuse_service_release (const char *path, struct fuse_file_info *fi)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (strcmp (path, FuseService::GetControlPath()) == 0 && fi && fi->fh)
|
||||||
|
{
|
||||||
|
delete reinterpret_cast <shared_ptr <Buffer> *> (fi->fh);
|
||||||
|
fi->fh = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return FuseService::ExceptionToErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fuse_service_readdir_impl (const char *path, void *buf, fuse_fill_dir_t filler, struct fuse_file_info *fi)
|
static int fuse_service_readdir_impl (const char *path, void *buf, fuse_fill_dir_t filler, struct fuse_file_info *fi)
|
||||||
{
|
{
|
||||||
(void) fi;
|
(void) fi;
|
||||||
@@ -413,7 +455,7 @@ namespace VeraCrypt
|
|||||||
return 0;
|
return 0;
|
||||||
if (fuse_service_fill_dir_entry (buf, filler, FuseService::GetControlPath() + 1, S_IFREG | 0600, VC_FUSE_INODE_CONTROL, 0) != 0)
|
if (fuse_service_fill_dir_entry (buf, filler, FuseService::GetControlPath() + 1, S_IFREG | 0600, VC_FUSE_INODE_CONTROL, 0) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (fuse_service_fill_dir_entry (buf, filler, FuseService::GetAuxDeviceInfoPath() + 1, S_IFREG | 0200, VC_FUSE_INODE_AUX_DEVICE_INFO, 0) != 0)
|
if (fuse_service_fill_dir_entry (buf, filler, FuseService::GetAuxDeviceInfoPath() + 1, S_IFREG | 0600, VC_FUSE_INODE_AUX_DEVICE_INFO, 0) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
@@ -548,6 +590,25 @@ namespace VeraCrypt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr <Buffer> FuseService::GetAuxDeviceInfo ()
|
||||||
|
{
|
||||||
|
shared_ptr <Stream> stream (new MemoryStream);
|
||||||
|
Serializer sr (stream);
|
||||||
|
|
||||||
|
{
|
||||||
|
ScopeLock lock (OpenVolumeInfoMutex);
|
||||||
|
|
||||||
|
sr.Serialize ("VirtualDevice", string (OpenVolumeInfo.VirtualDevice));
|
||||||
|
sr.Serialize ("LoopDevice", string (OpenVolumeInfo.LoopDevice));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstBufferPtr infoBuf = dynamic_cast <MemoryStream&> (*stream);
|
||||||
|
shared_ptr <Buffer> outBuf (new Buffer (infoBuf.Size()));
|
||||||
|
outBuf->CopyFrom (infoBuf);
|
||||||
|
|
||||||
|
return outBuf;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr <Buffer> FuseService::GetVolumeInfo ()
|
shared_ptr <Buffer> FuseService::GetVolumeInfo ()
|
||||||
{
|
{
|
||||||
shared_ptr <Stream> stream (new MemoryStream);
|
shared_ptr <Stream> stream (new MemoryStream);
|
||||||
@@ -666,6 +727,7 @@ namespace VeraCrypt
|
|||||||
sr.Serialize ("VirtualDevice", string (virtualDevice));
|
sr.Serialize ("VirtualDevice", string (virtualDevice));
|
||||||
sr.Serialize ("LoopDevice", string (loopDevice));
|
sr.Serialize ("LoopDevice", string (loopDevice));
|
||||||
fuseServiceControl.Write (dynamic_cast <MemoryStream&> (*stream));
|
fuseServiceControl.Write (dynamic_cast <MemoryStream&> (*stream));
|
||||||
|
fuseServiceControl.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuseService::WriteVolumeSectors (const ConstBufferPtr &buffer, uint64 byteOffset)
|
void FuseService::WriteVolumeSectors (const ConstBufferPtr &buffer, uint64 byteOffset)
|
||||||
@@ -728,6 +790,7 @@ namespace VeraCrypt
|
|||||||
fuse_service_oper.opendir = fuse_service_opendir;
|
fuse_service_oper.opendir = fuse_service_opendir;
|
||||||
fuse_service_oper.read = fuse_service_read;
|
fuse_service_oper.read = fuse_service_read;
|
||||||
fuse_service_oper.readdir = fuse_service_readdir;
|
fuse_service_oper.readdir = fuse_service_readdir;
|
||||||
|
fuse_service_oper.release = fuse_service_release;
|
||||||
fuse_service_oper.statfs = fuse_service_statfs;
|
fuse_service_oper.statfs = fuse_service_statfs;
|
||||||
fuse_service_oper.write = fuse_service_write;
|
fuse_service_oper.write = fuse_service_write;
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ namespace VeraCrypt
|
|||||||
static string GetDeviceType () { return "veracrypt"; }
|
static string GetDeviceType () { return "veracrypt"; }
|
||||||
static gid_t GetGroupId () { return GroupId; }
|
static gid_t GetGroupId () { return GroupId; }
|
||||||
static uid_t GetUserId () { return UserId; }
|
static uid_t GetUserId () { return UserId; }
|
||||||
|
static shared_ptr <Buffer> GetAuxDeviceInfo ();
|
||||||
static shared_ptr <Buffer> GetVolumeInfo ();
|
static shared_ptr <Buffer> GetVolumeInfo ();
|
||||||
static uint64 GetVolumeSize ();
|
static uint64 GetVolumeSize ();
|
||||||
static uint64 GetVolumeSectorSize () { return MountedVolume->GetSectorSize(); }
|
static uint64 GetVolumeSectorSize () { return MountedVolume->GetSectorSize(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user