/* * Copyright (c) 2012 by Michael Berlin, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ #ifndef CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_ #define CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_ #define WIN32_LEAN_AND_MEAN #include // required for CbFS.h #include #include #include #include #include #include "xtfsutil/xtfsutil_server.h" #include "xtreemfs/GlobalTypes.pb.h" namespace xtreemfs { namespace pbrpc { class Stat; } // namespace pbrpc class CbFSOptions; class Client; class SystemUserMapping; class CbFSAdapter { public: /** Replace "\" path separator by "/" and convert UTF-16 to UTF-8. */ static std::string WindowsPathToUTF8Unix(const wchar_t* from); static void DebugPrintCreateFile( LPCWSTR OperationType, LPCTSTR FileName, ACCESS_MASK DesiredAccess, DWORD FileAttributes, DWORD ShareMode, PVOID FileHandleContext); /** Creates a new instance of CbFSAdapter, but does not create any * libxtreemfs Client yet. * * Use Start() to actually create the client and mount the volume given in * options. May modify options. */ explicit CbFSAdapter(CbFSOptions* options); ~CbFSAdapter(); /** Create client, open volume and start needed threads. */ void Start(); /** Shutdown threads, close Volume and Client and blocks until all threads * are stopped. */ void Stop(); /** Same as Stop(), but does not call cbfs_.UnmountMedia(). */ void StopWithoutUnmount(); void GetVolumeSize(CallbackFileSystem* Sender, __int64* TotalNumberOfSectors, __int64* NumberOfFreeSectors); void GetVolumeLabel(CallbackFileSystem* Sender, LPTSTR VolumeLabel); void GetVolumeId(CallbackFileSystem* Sender, PDWORD VolumeID); void CreateFile(CallbackFileSystem* Sender, LPCTSTR FileName, ACCESS_MASK DesiredAccess, DWORD FileAttributes, DWORD ShareMode, PVOID* FileHandleContext); void OpenFile(CallbackFileSystem* Sender, LPCTSTR FileName, ACCESS_MASK DesiredAccess, DWORD ShareMode, PVOID* FileHandleContext); void CloseFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, PVOID FileHandleContext); void GetFileInfo(CallbackFileSystem* Sender, LPCTSTR FileName, LPBOOL FileExists, PFILETIME CreationTime, PFILETIME LastAccessTime, PFILETIME LastWriteTime, __int64* EndOfFile, __int64* AllocationSize, __int64* FileId, PDWORD FileAttributes, LPTSTR LongFileName OPTIONAL, PWORD LongFileNameLength OPTIONAL); void EnumerateDirectory(CallbackFileSystem* Sender, CbFsFileInfo* DirectoryInfo, PVOID* EnumerationContext, LPCTSTR Mask, INT Index, BOOL Restart, LPBOOL FileFound, LPTSTR FileName, PDWORD FileNameLength, LPTSTR ShortFileName OPTIONAL, PUCHAR ShortFileNameLength OPTIONAL, PFILETIME CreationTime, PFILETIME LastAccessTime, PFILETIME LastWriteTime, __int64* EndOfFile, __int64* AllocationSize, __int64* FileId, PDWORD FileAttributes); void CloseEnumeration(CallbackFileSystem* Sender, CbFsFileInfo* DirectoryInfo, PVOID EnumerationContext); void SetAllocationSize(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, PVOID FileHandleContext, __int64 AllocationSize); void SetEndOfFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, PVOID FileHandleContext, __int64 EndOfFile); void SetFileAttributes(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, PVOID FileHandleContext, PFILETIME CreationTime, PFILETIME LastAccessTime, PFILETIME LastWriteTime, DWORD FileAttributes); void CanFileBeDeleted(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, BOOL* CanBeDeleted); void DeleteFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo); void RenameOrMoveFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, LPCTSTR NewFileName); void ReadFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, PVOID FileHandleContext, __int64 Position, PVOID Buffer, DWORD BytesToRead, PDWORD BytesRead); void WriteFile(CallbackFileSystem* Sender, CbFsFileInfo* FileInfo, PVOID FileHandleContext, __int64 Position, PVOID Buffer, DWORD BytesToWrite, PDWORD BytesWritten); void IsDirectoryEmpty(CallbackFileSystem* Sender, LPWSTR FileName, LPBOOL IsEmpty); void StorageEjected(CallbackFileSystem* Sender); /** Blocks until device was ejected by user. */ void WaitForEjection(); private: static const DWORD kMaxFileNameLength = 32767; static const size_t kMaxVolumeLabelLength = 32; /** Print debug output to stdout. */ static void DbgPrint(LPCWSTR format, ...); /** Output exception thrown by CBFS as string. */ static std::string ECBFSErrorToString(ECBFSError& e); /** Maps XtreemFS return values to Windows specific ones. */ static int ConvertXtreemFSErrnoToWindows( xtreemfs::pbrpc::POSIXErrno xtreemfs_errno); /** Convert UNIX timestamp (in nanoseconds) to Windows time format. */ static void XtreemFSTimeToWinTime(uint64_t utime_ns, DWORD* lower, DWORD* upper); /** Convert Windows timestamp to UNIX timestamp (in nanoseconds). */ static boost::uint64_t ConvertWinTimeToXtreemFSTime(DWORD lower, DWORD upper); /** Returns true if "stat" is a directory. */ static bool IsDirectory(const xtreemfs::pbrpc::Stat& stat); /** Convert "desired_access", passed at Create and Open, to e.g., O_RDWR. */ static xtreemfs::pbrpc::SYSTEM_V_FCNTL ConvertFlagsWindowsToXtreemFS( const ACCESS_MASK desired_access); /** Provides the CBFS library the required license key. */ void SetRegistrationKey(); /** Returns true if "path" is a directory. * @throws AddressToUUIDNotFoundException * @throws IOException * @throws PosixErrorException * @throws UnknownAddressSchemeException */ bool IsDirectory(const std::string& path); /** Same as GetFileInfo(), except that "path" is an UTF8 encoded UNIX path. */ void ConvertXtreemFSStatToCbFS(const xtreemfs::pbrpc::Stat& stat, PFILETIME CreationTime, PFILETIME LastAccessTime, PFILETIME LastWriteTime, __int64* EndOfFile, __int64* AllocationSize, __int64* FileId, PDWORD FileAttributes, LPTSTR LongFileName OPTIONAL, PWORD LongFileNameLength OPTIONAL); /** Contains all needed options to mount the requested volume. */ CbFSOptions* options_; /** Volume Label generated from the given XtreemFS URL. */ std::wstring volume_label_; /** The chosen UserMapping provides methods to translate between local and * remote usernames and groups. */ boost::scoped_ptr system_user_mapping_; /** Username and domain name of user executing the Dokan client. Will be used * by all XtreemFS operations. */ xtreemfs::pbrpc::UserCredentials user_credentials_; /** Created libxtreemfs Client. */ boost::scoped_ptr client_; /** Opened libxtreemfs Volume. */ Volume* volume_; /** Server for processing commands sent from the xtfsutil tool via xctl files. */ XtfsUtilServer xctl_; /** Callback Filesystem instance which provides a Windows user space * file system interface. */ CallbackFileSystem cbfs_; /** True if device was ejected by user. */ bool device_ejected_; /** Guards device_ejected_. */ boost::mutex device_ejected_mutex_; /** Used when waiting for a change of device_ejected_. */ boost::condition device_ejected_cond_; }; } // namespace xtreemfs #endif // CPP_INCLUDE_CBFS_CBFS_ADAPTER_H_