From 3cb7fdea950dd2d0377f0d9ad8a88fcb7c48b842 Mon Sep 17 00:00:00 2001 From: Jedidiah Barber Date: Wed, 14 Jul 2021 11:27:03 +1200 Subject: Initial mirror commit --- Platform/Buffer.cpp | 142 +++++++++++++++ Platform/Buffer.h | 115 ++++++++++++ Platform/Directory.h | 29 +++ Platform/Event.cpp | 47 +++++ Platform/Event.h | 86 +++++++++ Platform/Exception.cpp | 52 ++++++ Platform/Exception.h | 110 ++++++++++++ Platform/File.h | 110 ++++++++++++ Platform/FileCommon.cpp | 87 +++++++++ Platform/FileStream.h | 58 ++++++ Platform/FilesystemPath.h | 73 ++++++++ Platform/Finally.h | 46 +++++ Platform/ForEach.h | 118 ++++++++++++ Platform/Functor.h | 29 +++ Platform/Memory.cpp | 58 ++++++ Platform/Memory.h | 174 ++++++++++++++++++ Platform/MemoryStream.cpp | 47 +++++ Platform/MemoryStream.h | 36 ++++ Platform/Mutex.h | 61 +++++++ Platform/Platform.h | 28 +++ Platform/Platform.make | 35 ++++ Platform/PlatformBase.h | 134 ++++++++++++++ Platform/PlatformTest.cpp | 350 ++++++++++++++++++++++++++++++++++++ Platform/PlatformTest.h | 43 +++++ Platform/Serializable.cpp | 39 ++++ Platform/Serializable.h | 82 +++++++++ Platform/Serializer.cpp | 299 +++++++++++++++++++++++++++++++ Platform/Serializer.h | 74 ++++++++ Platform/SerializerFactory.cpp | 54 ++++++ Platform/SerializerFactory.h | 93 ++++++++++ Platform/SharedPtr.h | 162 +++++++++++++++++ Platform/SharedVal.h | 71 ++++++++ Platform/Stream.h | 34 ++++ Platform/StringConverter.cpp | 367 ++++++++++++++++++++++++++++++++++++++ Platform/StringConverter.h | 60 +++++++ Platform/SyncEvent.h | 47 +++++ Platform/System.h | 16 ++ Platform/SystemException.h | 46 +++++ Platform/SystemInfo.h | 28 +++ Platform/SystemLog.h | 42 +++++ Platform/TextReader.cpp | 37 ++++ Platform/TextReader.h | 35 ++++ Platform/Thread.h | 74 ++++++++ Platform/Time.h | 30 ++++ Platform/Unix/Directory.cpp | 62 +++++++ Platform/Unix/File.cpp | 348 ++++++++++++++++++++++++++++++++++++ Platform/Unix/FilesystemPath.cpp | 96 ++++++++++ Platform/Unix/Mutex.cpp | 62 +++++++ Platform/Unix/Pipe.cpp | 65 +++++++ Platform/Unix/Pipe.h | 38 ++++ Platform/Unix/Poller.cpp | 57 ++++++ Platform/Unix/Poller.h | 33 ++++ Platform/Unix/Process.cpp | 202 +++++++++++++++++++++ Platform/Unix/Process.h | 40 +++++ Platform/Unix/SyncEvent.cpp | 68 +++++++ Platform/Unix/System.h | 12 ++ Platform/Unix/SystemException.cpp | 66 +++++++ Platform/Unix/SystemInfo.cpp | 69 +++++++ Platform/Unix/SystemLog.cpp | 27 +++ Platform/Unix/Thread.cpp | 54 ++++++ Platform/Unix/Time.cpp | 23 +++ Platform/User.h | 32 ++++ 62 files changed, 5112 insertions(+) create mode 100644 Platform/Buffer.cpp create mode 100644 Platform/Buffer.h create mode 100644 Platform/Directory.h create mode 100644 Platform/Event.cpp create mode 100644 Platform/Event.h create mode 100644 Platform/Exception.cpp create mode 100644 Platform/Exception.h create mode 100644 Platform/File.h create mode 100644 Platform/FileCommon.cpp create mode 100644 Platform/FileStream.h create mode 100644 Platform/FilesystemPath.h create mode 100644 Platform/Finally.h create mode 100644 Platform/ForEach.h create mode 100644 Platform/Functor.h create mode 100644 Platform/Memory.cpp create mode 100644 Platform/Memory.h create mode 100644 Platform/MemoryStream.cpp create mode 100644 Platform/MemoryStream.h create mode 100644 Platform/Mutex.h create mode 100644 Platform/Platform.h create mode 100644 Platform/Platform.make create mode 100644 Platform/PlatformBase.h create mode 100644 Platform/PlatformTest.cpp create mode 100644 Platform/PlatformTest.h create mode 100644 Platform/Serializable.cpp create mode 100644 Platform/Serializable.h create mode 100644 Platform/Serializer.cpp create mode 100644 Platform/Serializer.h create mode 100644 Platform/SerializerFactory.cpp create mode 100644 Platform/SerializerFactory.h create mode 100644 Platform/SharedPtr.h create mode 100644 Platform/SharedVal.h create mode 100644 Platform/Stream.h create mode 100644 Platform/StringConverter.cpp create mode 100644 Platform/StringConverter.h create mode 100644 Platform/SyncEvent.h create mode 100644 Platform/System.h create mode 100644 Platform/SystemException.h create mode 100644 Platform/SystemInfo.h create mode 100644 Platform/SystemLog.h create mode 100644 Platform/TextReader.cpp create mode 100644 Platform/TextReader.h create mode 100644 Platform/Thread.h create mode 100644 Platform/Time.h create mode 100644 Platform/Unix/Directory.cpp create mode 100644 Platform/Unix/File.cpp create mode 100644 Platform/Unix/FilesystemPath.cpp create mode 100644 Platform/Unix/Mutex.cpp create mode 100644 Platform/Unix/Pipe.cpp create mode 100644 Platform/Unix/Pipe.h create mode 100644 Platform/Unix/Poller.cpp create mode 100644 Platform/Unix/Poller.h create mode 100644 Platform/Unix/Process.cpp create mode 100644 Platform/Unix/Process.h create mode 100644 Platform/Unix/SyncEvent.cpp create mode 100644 Platform/Unix/System.h create mode 100644 Platform/Unix/SystemException.cpp create mode 100644 Platform/Unix/SystemInfo.cpp create mode 100644 Platform/Unix/SystemLog.cpp create mode 100644 Platform/Unix/Thread.cpp create mode 100644 Platform/Unix/Time.cpp create mode 100644 Platform/User.h (limited to 'Platform') diff --git a/Platform/Buffer.cpp b/Platform/Buffer.cpp new file mode 100644 index 0000000..869d640 --- /dev/null +++ b/Platform/Buffer.cpp @@ -0,0 +1,142 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Buffer.h" +#include "Exception.h" + +namespace TrueCrypt +{ + Buffer::Buffer () : DataPtr (nullptr), DataSize (0) + { + } + + Buffer::Buffer (size_t size) : DataPtr (nullptr), DataSize (0) + { + Allocate (size); + } + + Buffer::~Buffer () + { + if (DataPtr != nullptr) + Free (); + } + + void Buffer::Allocate (size_t size) + { + if (size < 1) + throw ParameterIncorrect (SRC_POS); + + if (DataPtr != nullptr) + { + if (DataSize == size) + return; + Free(); + } + + try + { + DataPtr = static_cast (Memory::Allocate (size)); + DataSize = size; + } + catch (...) + { + DataPtr = nullptr; + DataSize = 0; + throw; + } + } + + void Buffer::CopyFrom (const ConstBufferPtr &bufferPtr) + { + if (!IsAllocated ()) + Allocate (bufferPtr.Size()); + else if (bufferPtr.Size() > DataSize) + throw ParameterTooLarge (SRC_POS); + + Memory::Copy (DataPtr, bufferPtr.Get(), bufferPtr.Size()); + } + + void Buffer::Erase () + { + if (DataSize > 0) + Memory::Erase (DataPtr, DataSize); + } + + void Buffer::Free () + { + if (DataPtr == nullptr) + throw NotInitialized (SRC_POS); + + Memory::Free (DataPtr); + DataPtr = nullptr; + DataSize = 0; + } + + BufferPtr Buffer::GetRange (size_t offset, size_t size) const + { + if (offset + size > DataSize) + throw ParameterIncorrect (SRC_POS); + + return BufferPtr (DataPtr + offset, size); + } + + void Buffer::Zero () + { + if (DataSize > 0) + Memory::Zero (DataPtr, DataSize); + } + + SecureBuffer::SecureBuffer (size_t size) + { + Allocate (size); + } + + SecureBuffer::~SecureBuffer () + { + if (DataPtr != nullptr && DataSize != 0) + Free (); + } + + void SecureBuffer::Allocate (size_t size) + { + Buffer::Allocate (size); + } + + void SecureBuffer::Free () + { + if (DataPtr == nullptr) + throw NotInitialized (SRC_POS); + + Erase (); + Buffer::Free (); + } + + void BufferPtr::CopyFrom (const ConstBufferPtr &bufferPtr) const + { + if (bufferPtr.Size() > DataSize) + throw ParameterTooLarge (SRC_POS); + + Memory::Copy (DataPtr, bufferPtr.Get(), bufferPtr.Size()); + } + + BufferPtr BufferPtr::GetRange (size_t offset, size_t size) const + { + if (offset + size > DataSize) + throw ParameterIncorrect (SRC_POS); + + return BufferPtr (DataPtr + offset, size); + } + + ConstBufferPtr ConstBufferPtr::GetRange (size_t offset, size_t size) const + { + if (offset + size > DataSize) + throw ParameterIncorrect (SRC_POS); + + return ConstBufferPtr (DataPtr + offset, size); + } +} diff --git a/Platform/Buffer.h b/Platform/Buffer.h new file mode 100644 index 0000000..2e02171 --- /dev/null +++ b/Platform/Buffer.h @@ -0,0 +1,115 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Buffer +#define TC_HEADER_Platform_Buffer + +#include "PlatformBase.h" +#include "Memory.h" + +namespace TrueCrypt +{ + + class ConstBufferPtr + { + public: + ConstBufferPtr () + : DataPtr (nullptr), DataSize (0) { } + ConstBufferPtr (const byte *data, size_t size) + : DataPtr (data), DataSize (size) { } + virtual ~ConstBufferPtr () { } + + operator const byte * () const { return DataPtr; } + + bool IsDataEqual (const ConstBufferPtr &other) const { return Memory::Compare (DataPtr, DataSize, other.DataPtr, other.DataSize) == 0; } + const byte *Get () const { return DataPtr; } + ConstBufferPtr GetRange (size_t offset, size_t size) const; + void Set (const byte *data, size_t size) { DataPtr = data; DataSize = size; } + size_t Size () const { return DataSize; } + + protected: + const byte *DataPtr; + size_t DataSize; + }; + + + class BufferPtr + { + public: + BufferPtr () + : DataPtr (nullptr), DataSize (0) { } + BufferPtr (byte *data, size_t size) + : DataPtr (data), DataSize (size) { } + virtual ~BufferPtr () { } + + operator byte * () const { return DataPtr; } + void CopyFrom (const ConstBufferPtr &bufferPtr) const; + void Erase () const { Zero(); } + byte *Get () const { return DataPtr; } + BufferPtr GetRange (size_t offset, size_t size) const; + void Set (byte *data, size_t size) { DataPtr = data; DataSize = size; } + size_t Size () const { return DataSize; } + void Zero () const { Memory::Zero (DataPtr, DataSize); } + + operator ConstBufferPtr () const { return ConstBufferPtr (DataPtr, DataSize); } + + protected: + byte *DataPtr; + size_t DataSize; + }; + + class Buffer + { + public: + Buffer (); + Buffer (size_t size); + Buffer (const ConstBufferPtr &bufferPtr) { CopyFrom (bufferPtr); } + virtual ~Buffer (); + + virtual void Allocate (size_t size); + virtual void CopyFrom (const ConstBufferPtr &bufferPtr); + virtual byte *Ptr () const { return DataPtr; } + virtual void Erase (); + virtual void Free (); + virtual BufferPtr GetRange (size_t offset, size_t size) const; + virtual size_t Size () const { return DataSize; } + virtual bool IsAllocated () const { return DataSize != 0; } + virtual void Zero (); + + virtual operator byte * () const { return DataPtr; } + virtual operator BufferPtr () const { return BufferPtr (DataPtr, DataSize); } + virtual operator ConstBufferPtr () const { return ConstBufferPtr (DataPtr, DataSize); } + + protected: + byte *DataPtr; + size_t DataSize; + + private: + Buffer (const Buffer &); + Buffer &operator= (const Buffer &); + }; + + class SecureBuffer : public Buffer + { + public: + SecureBuffer () { } + SecureBuffer (size_t size); + SecureBuffer (const ConstBufferPtr &bufferPtr) { CopyFrom (bufferPtr); } + virtual ~SecureBuffer (); + + virtual void Allocate (size_t size); + virtual void Free (); + + private: + SecureBuffer (const SecureBuffer &); + SecureBuffer &operator= (const SecureBuffer &); + }; + +} + +#endif // TC_HEADER_Platform_Buffer diff --git a/Platform/Directory.h b/Platform/Directory.h new file mode 100644 index 0000000..ad75610 --- /dev/null +++ b/Platform/Directory.h @@ -0,0 +1,29 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Directory +#define TC_HEADER_Platform_Directory + +#include "PlatformBase.h" +#include "FilesystemPath.h" + +namespace TrueCrypt +{ + class Directory + { + public: + static void Create (const DirectoryPath &path); + static DirectoryPath AppendSeparator (const DirectoryPath &path); + static FilePathList GetFilePaths (const DirectoryPath &path = L".", bool regularFilesOnly = true); + + private: + Directory (); + }; +} + +#endif // TC_HEADER_Platform_Directory diff --git a/Platform/Event.cpp b/Platform/Event.cpp new file mode 100644 index 0000000..677ed1c --- /dev/null +++ b/Platform/Event.cpp @@ -0,0 +1,47 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Event.h" + +namespace TrueCrypt +{ + void Event::Connect (const EventConnectorBase &connector) + { + ScopeLock lock (HandlersMutex); + ConnectedHandlers.push_back (shared_ptr (connector.CloneNew())); + } + + void Event::Disconnect (void *handler) + { + ScopeLock lock (HandlersMutex); + + EventHandlerList newConnectedHandlers; + foreach (shared_ptr h, ConnectedHandlers) + { + if (h->GetHandler() != handler) + newConnectedHandlers.push_back (h); + } + + ConnectedHandlers = newConnectedHandlers; + } + + void Event::Raise () + { + EventArgs args; + Raise (args); + } + + void Event::Raise (EventArgs &args) + { + ScopeLock lock (HandlersMutex); + foreach_ref (EventConnectorBase &handler, ConnectedHandlers) + { + handler (args); + } + } +} diff --git a/Platform/Event.h b/Platform/Event.h new file mode 100644 index 0000000..c49e357 --- /dev/null +++ b/Platform/Event.h @@ -0,0 +1,86 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Event +#define TC_HEADER_Platform_Event + +#include "PlatformBase.h" +#include "ForEach.h" +#include "Mutex.h" +#include "SharedPtr.h" + +namespace TrueCrypt +{ + struct EventArgs + { + virtual ~EventArgs () { } + }; + + class EventConnectorBase + { + public: + virtual ~EventConnectorBase () { } + virtual void operator() (EventArgs &args) = 0; + + virtual EventConnectorBase *CloneNew () const = 0; + virtual void *GetHandler () const = 0; + }; + + typedef list < shared_ptr > EventHandlerList; + + template + class EventConnector : public EventConnectorBase + { + public: + typedef void (T::*EventHandlerFunction) (EventArgs &); + + EventConnector (T *handler, EventHandlerFunction function) + : Handler (handler), Function (function) { } + + virtual void operator() (EventArgs &args) { (Handler->*Function) (args); } + + virtual EventConnectorBase *CloneNew () const { return new EventConnector (*this); } + virtual void *GetHandler () const { return Handler; } + + protected: + T *Handler; + EventHandlerFunction Function; + }; + + class Event + { + public: + Event () { } + virtual ~Event () { } + + void Connect (const EventConnectorBase &connector); + void Disconnect (void *handler); + void Raise (); + void Raise (EventArgs &args); + + protected: + EventHandlerList ConnectedHandlers; + Mutex HandlersMutex; + + private: + Event (const Event &); + Event &operator= (const Event &); + }; + + struct ExceptionEventArgs : public EventArgs + { + ExceptionEventArgs (exception &ex) : mException (ex) { } + exception &mException; + + private: + ExceptionEventArgs (const ExceptionEventArgs &); + ExceptionEventArgs &operator= (const ExceptionEventArgs &); + }; +} + +#endif // TC_HEADER_Platform_Event diff --git a/Platform/Exception.cpp b/Platform/Exception.cpp new file mode 100644 index 0000000..e039b3c --- /dev/null +++ b/Platform/Exception.cpp @@ -0,0 +1,52 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Exception.h" +#include "SerializerFactory.h" + +namespace TrueCrypt +{ + void Exception::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + sr.Deserialize ("Message", Message); + sr.Deserialize ("Subject", Subject); + } + + void Exception::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("Message", Message); + sr.Serialize ("Subject", Subject); + } + + void ExecutedProcessFailed::Deserialize (shared_ptr stream) + { + Exception::Deserialize (stream); + Serializer sr (stream); + sr.Deserialize ("Command", Command); + sr.Deserialize ("ExitCode", ExitCode); + sr.Deserialize ("ErrorOutput", ErrorOutput); + } + + void ExecutedProcessFailed::Serialize (shared_ptr stream) const + { + Exception::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("Command", Command); + sr.Serialize ("ExitCode", ExitCode); + sr.Serialize ("ErrorOutput", ErrorOutput); + } + +#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +#undef TC_EXCEPTION_NODECL +#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (Exception); +} diff --git a/Platform/Exception.h b/Platform/Exception.h new file mode 100644 index 0000000..a39a4b7 --- /dev/null +++ b/Platform/Exception.h @@ -0,0 +1,110 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Exception +#define TC_HEADER_Platform_Exception + +#include +#include "PlatformBase.h" +#include "Serializable.h" + +namespace TrueCrypt +{ +#define TC_SERIALIZABLE_EXCEPTION(TYPE) TC_SERIALIZABLE (TYPE); \ + virtual Exception *CloneNew () { return new TYPE (*this); } \ + virtual void Throw () const { throw *this; } + + struct Exception : public exception, public Serializable + { + public: + Exception () { } + Exception (const string &message) : Message (message) { } + Exception (const string &message, const wstring &subject) : Message (message), Subject (subject) { } + virtual ~Exception () throw () { } + + TC_SERIALIZABLE_EXCEPTION (Exception); + + virtual const char *what () const throw () { return Message.c_str(); } + virtual const wstring &GetSubject() const { return Subject; } + + protected: + string Message; + wstring Subject; + }; + + struct ExecutedProcessFailed : public Exception + { + ExecutedProcessFailed () { } + ExecutedProcessFailed (const string &message, const string &command, int exitCode, const string &errorOutput) + : Exception (message), Command (command), ExitCode (exitCode), ErrorOutput (errorOutput) { } + virtual ~ExecutedProcessFailed () throw () { } + + TC_SERIALIZABLE_EXCEPTION (ExecutedProcessFailed); + + string GetCommand () const { return Command; } + int64 GetExitCode () const { return ExitCode; } + string GetErrorOutput () const { return ErrorOutput; } + + protected: + string Command; + int64 ExitCode; + string ErrorOutput; + }; + +#define TC_EXCEPTION_DECL(NAME,BASE) \ + struct NAME : public BASE \ + { \ + NAME () { } \ + NAME (const string &message) : BASE (message) { } \ + NAME (const string &message, const wstring &subject) : BASE (message, subject) { } \ + virtual Exception *CloneNew () { return new NAME (*this); } \ + static Serializable *GetNewSerializable () { return new NAME (); } \ + virtual void Throw () const { throw *this; } \ + } + +#define TC_EXCEPTION_NODECL(dummy) // +#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,Exception) + +#ifdef TC_EXCEPTION_SET +#undef TC_EXCEPTION_SET +#endif +#define TC_EXCEPTION_SET \ + TC_EXCEPTION_NODECL (Exception); \ + TC_EXCEPTION_NODECL (ExecutedProcessFailed); \ + TC_EXCEPTION (AlreadyInitialized); \ + TC_EXCEPTION (AssertionFailed); \ + TC_EXCEPTION (ExternalException); \ + TC_EXCEPTION (InsufficientData); \ + TC_EXCEPTION (NotApplicable); \ + TC_EXCEPTION (NotImplemented); \ + TC_EXCEPTION (NotInitialized); \ + TC_EXCEPTION (ParameterIncorrect); \ + TC_EXCEPTION (ParameterTooLarge); \ + TC_EXCEPTION (PartitionDeviceRequired); \ + TC_EXCEPTION (StringConversionFailed); \ + TC_EXCEPTION (TestFailed); \ + TC_EXCEPTION (TimeOut); \ + TC_EXCEPTION (UnknownException); \ + TC_EXCEPTION (UserAbort) + + TC_EXCEPTION_SET; + +#undef TC_EXCEPTION +} + +#ifdef assert +# undef assert +#endif + +#ifdef DEBUG +# define assert(condition) do { if (!(condition)) throw AssertionFailed (SRC_POS); } while (false) +#else +# define assert(condition) ((void) 0) +#endif + +#endif // TC_HEADER_Platform_Exception diff --git a/Platform/File.h b/Platform/File.h new file mode 100644 index 0000000..264b683 --- /dev/null +++ b/Platform/File.h @@ -0,0 +1,110 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_File +#define TC_HEADER_Platform_File + +#include "PlatformBase.h" +#include "Buffer.h" +#include "FilesystemPath.h" +#include "SystemException.h" + +namespace TrueCrypt +{ + class File + { + public: + enum FileOpenMode + { + CreateReadWrite, + CreateWrite, + OpenRead, + OpenWrite, + OpenReadWrite + }; + + enum FileShareMode + { + ShareNone, + ShareRead, + ShareReadWrite, + ShareReadWriteIgnoreLock + }; + + enum FileOpenFlags + { + // Bitmap + FlagsNone = 0, + PreserveTimestamps = 1 << 0, + DisableWriteCaching = 1 << 1 + }; + +#ifdef TC_WINDOWS + typedef FILE* SystemFileHandleType; +#else + typedef int SystemFileHandleType; +#endif + + File () : FileIsOpen (false), SharedHandle (false) { } + virtual ~File (); + + void AssignSystemHandle (SystemFileHandleType openFileHandle, bool sharedHandle = true) + { + if (FileIsOpen) + Close(); + FileHandle = openFileHandle; + FileIsOpen = true; + SharedHandle = sharedHandle; + } + + void Close (); + static void Copy (const FilePath &sourcePath, const FilePath &destinationPath, bool preserveTimestamps = true); + void Delete (); + void Flush () const; + uint32 GetDeviceSectorSize () const; + static size_t GetOptimalReadSize () { return OptimalReadSize; } + static size_t GetOptimalWriteSize () { return OptimalWriteSize; } + uint64 GetPartitionDeviceStartOffset () const; + bool IsOpen () const { return FileIsOpen; } + FilePath GetPath () const; + uint64 Length () const; + void Open (const FilePath &path, FileOpenMode mode = OpenRead, FileShareMode shareMode = ShareReadWrite, FileOpenFlags flags = FlagsNone); + uint64 Read (const BufferPtr &buffer) const; + void ReadCompleteBuffer (const BufferPtr &buffer) const; + uint64 ReadAt (const BufferPtr &buffer, uint64 position) const; + void SeekAt (uint64 position) const; + void SeekEnd (int ofset) const; + void Write (const ConstBufferPtr &buffer) const; + void Write (const ConstBufferPtr &buffer, size_t length) const { Write (buffer.GetRange (0, length)); } + void WriteAt (const ConstBufferPtr &buffer, uint64 position) const; + + protected: + void ValidateState () const; + + static const size_t OptimalReadSize = 256 * 1024; + static const size_t OptimalWriteSize = 256 * 1024; + + bool FileIsOpen; + FileOpenFlags mFileOpenFlags; + bool SharedHandle; + FilePath Path; + SystemFileHandleType FileHandle; + +#ifdef TC_WINDOWS +#else + time_t AccTime; + time_t ModTime; +#endif + + private: + File (const File &); + File &operator= (const File &); + }; +} + +#endif // TC_HEADER_Platform_File diff --git a/Platform/FileCommon.cpp b/Platform/FileCommon.cpp new file mode 100644 index 0000000..f25f18f --- /dev/null +++ b/Platform/FileCommon.cpp @@ -0,0 +1,87 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "File.h" +#ifdef TC_UNIX +#include +#include +#include +#include +#endif + +namespace TrueCrypt +{ + File::~File () + { + try + { + if (FileIsOpen) + Close(); + } + catch (...) { } + } + + void File::Copy (const FilePath &sourcePath, const FilePath &destinationPath, bool preserveTimestamps) + { + File source; + source.Open (sourcePath); + + File destination; + destination.Open (destinationPath, CreateWrite); + + SecureBuffer buffer (OptimalReadSize); + uint64 len; + + while ((len = source.Read (buffer)) > 0) + { + destination.Write (buffer, static_cast (len)); + } + + if (preserveTimestamps) + { + destination.Flush(); +#ifndef TC_WINDOWS + struct stat statData; + throw_sys_sub_if (stat (string (sourcePath).c_str(), &statData) == -1, wstring (sourcePath)); + + struct utimbuf u; + u.actime = statData.st_atime; + u.modtime = statData.st_mtime; + throw_sys_sub_if (utime (string (destinationPath).c_str(), &u) == -1, wstring (destinationPath)); +#endif + } + } + + FilePath File::GetPath () const + { + if_debug (ValidateState()); + return Path; + } + + void File::ReadCompleteBuffer (const BufferPtr &buffer) const + { + size_t dataLeft = buffer.Size(); + size_t offset = 0; + + while (dataLeft > 0) + { + size_t dataRead = static_cast (Read (buffer.GetRange (offset, dataLeft))); + if (dataRead == 0) + throw InsufficientData (SRC_POS); + + dataLeft -= dataRead; + offset += dataRead; + } + } + + void File::ValidateState () const + { + if (!FileIsOpen) + throw NotInitialized (SRC_POS); + } +} diff --git a/Platform/FileStream.h b/Platform/FileStream.h new file mode 100644 index 0000000..969ed58 --- /dev/null +++ b/Platform/FileStream.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_FileStream +#define TC_HEADER_Platform_FileStream + +#include "PlatformBase.h" +#include "File.h" +#include "SharedPtr.h" +#include "Stream.h" + +namespace TrueCrypt +{ + class FileStream : public Stream + { + public: + FileStream (shared_ptr file) : DataFile (file) { } + FileStream (File::SystemFileHandleType openFileHandle) { DataFile.reset (new File ()); DataFile->AssignSystemHandle (openFileHandle); } + virtual ~FileStream () { } + + virtual uint64 Read (const BufferPtr &buffer) + { + return DataFile->Read (buffer); + } + + virtual void ReadCompleteBuffer (const BufferPtr &buffer) + { + DataFile->ReadCompleteBuffer (buffer); + } + + virtual string ReadToEnd () + { + string str; + vector buffer (4096); + uint64 len; + + while ((len = DataFile->Read (BufferPtr (reinterpret_cast (&buffer[0]), buffer.size()))) > 0) + str.insert (str.end(), buffer.begin(), buffer.begin() + static_cast (len)); + + return str; + } + + virtual void Write (const ConstBufferPtr &data) + { + DataFile->Write (data); + } + + protected: + shared_ptr DataFile; + }; +} + +#endif // TC_HEADER_Platform_FileStream diff --git a/Platform/FilesystemPath.h b/Platform/FilesystemPath.h new file mode 100644 index 0000000..0e12d66 --- /dev/null +++ b/Platform/FilesystemPath.h @@ -0,0 +1,73 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_FilesystemPath +#define TC_HEADER_Platform_FilesystemPath + +#include "PlatformBase.h" +#include "Platform/User.h" +#include "SharedPtr.h" +#include "StringConverter.h" + +namespace TrueCrypt +{ + struct FilesystemPathType + { + enum Enum + { + Unknown, + File, + Directory, + SymbolickLink, + BlockDevice, + CharacterDevice + }; + }; + + class FilesystemPath + { + public: + FilesystemPath () { } + FilesystemPath (const char *path) : Path (StringConverter::ToWide (path)) { } + FilesystemPath (string path) : Path (StringConverter::ToWide (path)) { } + FilesystemPath (const wchar_t *path) : Path (path) { } + FilesystemPath (wstring path) : Path (path) { } + virtual ~FilesystemPath () { } + + bool operator== (const FilesystemPath &other) const { return Path == other.Path; } + bool operator!= (const FilesystemPath &other) const { return Path != other.Path; } + operator string () const { return StringConverter::ToSingle (Path); } + operator wstring () const { return Path; } + + void Delete () const; + UserId GetOwner () const; + FilesystemPathType::Enum GetType () const; + bool IsBlockDevice () const throw () { try { return GetType() == FilesystemPathType::BlockDevice; } catch (...) { return false; }; } + bool IsCharacterDevice () const throw () { try { return GetType() == FilesystemPathType::CharacterDevice; } catch (...) { return false; }; } + bool IsDevice () const throw () { return IsBlockDevice() || IsCharacterDevice(); } + bool IsDirectory () const throw () { try { return GetType() == FilesystemPathType::Directory; } catch (...) { return false; } } + bool IsEmpty () const throw () { try { return Path.empty(); } catch (...) { return false; } } + bool IsFile () const throw () { try { return GetType() == FilesystemPathType::File; } catch (...) { return false; } } + FilesystemPath ToBaseName () const; + FilesystemPath ToHostDriveOfPartition () const; + + static const int MaxSize = 260; + + protected: + wstring Path; + }; + + typedef FilesystemPath DevicePath; + typedef FilesystemPath DirectoryPath; + typedef FilesystemPath FilePath; + + typedef list < shared_ptr > DirectoryPathList; + typedef list < shared_ptr > FilePathList; +} + +#endif // TC_HEADER_Platform_FilesystemPath diff --git a/Platform/Finally.h b/Platform/Finally.h new file mode 100644 index 0000000..c6afed3 --- /dev/null +++ b/Platform/Finally.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Finally +#define TC_HEADER_Platform_Finally + +#include "PlatformBase.h" + +// Execute code when leaving scope +#define finally_do(code) \ +struct TC_JOIN(Finally,__LINE__) \ +{ \ + TC_JOIN(~Finally,__LINE__) () { try { code } catch (...) { } } \ +} \ +TC_UNUSED_VAR \ +TC_JOIN(finally,__LINE__) + +// Execute code with argument 'finally_arg' when leaving scope +#define finally_do_arg(argType, arg, code) \ +struct TC_JOIN(Finally,__LINE__) \ +{ \ + TC_JOIN(Finally,__LINE__) (argType a) : finally_arg (a) { } \ + TC_JOIN(~Finally,__LINE__) () { try { code } catch (...) { } } \ + argType finally_arg; \ +} \ +TC_UNUSED_VAR \ +TC_JOIN(finally,__LINE__) (arg) + +#define finally_do_arg2(argType, arg, argType2, arg2, code) \ +struct TC_JOIN(Finally,__LINE__) \ +{ \ + TC_JOIN(Finally,__LINE__) (argType a, argType2 a2) : finally_arg (a), finally_arg2 (a2) { } \ + TC_JOIN(~Finally,__LINE__) () { try { code } catch (...) { } } \ + argType finally_arg; \ + argType2 finally_arg2; \ +} \ +TC_UNUSED_VAR \ +TC_JOIN(finally,__LINE__) (arg, arg2) + + +#endif // TC_HEADER_Platform_Finally diff --git a/Platform/ForEach.h b/Platform/ForEach.h new file mode 100644 index 0000000..180ceec --- /dev/null +++ b/Platform/ForEach.h @@ -0,0 +1,118 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_ForEach +#define TC_HEADER_Platform_ForEach + +namespace TrueCrypt +{ + class ForEach + { + public: + struct Container + { + Container () : InnerContinue (true), InnerEndCondition (false) { } + virtual ~Container () { } + + void Continue () const { InnerContinue = true; } + bool InnerIsNotEnd () const { return InnerEndCondition = !InnerEndCondition; } + virtual bool IsNotEnd () const = 0; + virtual void Next () const = 0; + + mutable bool InnerContinue; + mutable bool InnerEndCondition; + }; + + protected: + template + struct ContainerForward : Container + { + ContainerForward (const T &container) + : ContainerCopy (container), EndIterator (ContainerCopy.end()), Iterator (ContainerCopy.begin()) { } + + virtual bool IsNotEnd () const { bool r = InnerContinue && Iterator != EndIterator; InnerContinue = false; return r; } + virtual void Next () const { ++Iterator; } + + const T ContainerCopy; // Support for temporary objects + typename T::const_iterator EndIterator; + mutable typename T::const_iterator Iterator; + + private: + ContainerForward &operator= (const ContainerForward &); + }; + + template + struct ContainerReverse : Container + { + ContainerReverse (const T &container) + : ContainerCopy (container), EndIterator (ContainerCopy.rend()), Iterator (ContainerCopy.rbegin()) { } + + virtual bool IsNotEnd () const { bool r = InnerContinue && Iterator != EndIterator; InnerContinue = false; return r; } + virtual void Next () const { ++Iterator; } + + const T ContainerCopy; + typename T::const_reverse_iterator EndIterator; + mutable typename T::const_reverse_iterator Iterator; + + private: + ContainerReverse &operator= (const ContainerReverse &); + }; + + public: + template + static ContainerForward GetContainerForward (const T &container) + { + return ContainerForward (container); + } + + template + static ContainerReverse GetContainerReverse (const T &container) + { + return ContainerReverse (container); + } + + protected: + template + struct TypeWrapper { }; + + public: + template + static TypeWrapper ToTypeWrapper (const T &x) { return TypeWrapper (); } + + struct TypeWrapperDummy + { + template + operator TypeWrapper () const { return TypeWrapper (); } + }; + + template + static const ContainerForward &GetContainerForward (const Container &forEachContainer, const TypeWrapper &) + { + return static_cast &> (forEachContainer); + } + + template + static const ContainerReverse &GetContainerReverse (const Container &forEachContainer, const TypeWrapper &) + { + return static_cast &> (forEachContainer); + } + }; +} + + +#define FOREACH_TEMPLATE(dereference,listType,variable,listInstance) \ + for (const ForEach::Container &forEachContainer = ForEach::GetContainer##listType (listInstance); forEachContainer.IsNotEnd(); forEachContainer.Next()) \ + for (variable = dereference(ForEach::GetContainer##listType (forEachContainer, (true ? ForEach::TypeWrapperDummy() : ForEach::ToTypeWrapper (listInstance))).Iterator); forEachContainer.InnerIsNotEnd(); forEachContainer.Continue()) + +#define foreach(variable,listInstance) FOREACH_TEMPLATE(*, Forward, variable, listInstance) +#define foreach_ref(variable,listInstance) FOREACH_TEMPLATE(**, Forward, variable, listInstance) +#define foreach_reverse(variable,listInstance) FOREACH_TEMPLATE(*, Reverse, variable, listInstance) +#define foreach_reverse_ref(variable,listInstance) FOREACH_TEMPLATE(**, Reverse, variable, listInstance) + + +#endif // TC_HEADER_Platform_ForEach diff --git a/Platform/Functor.h b/Platform/Functor.h new file mode 100644 index 0000000..d13a7f6 --- /dev/null +++ b/Platform/Functor.h @@ -0,0 +1,29 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Functor +#define TC_HEADER_Platform_Functor + +#include "PlatformBase.h" + +namespace TrueCrypt +{ + struct Functor + { + virtual ~Functor () { } + virtual void operator() () = 0; + }; + + struct GetStringFunctor + { + virtual ~GetStringFunctor () { } + virtual void operator() (string &str) = 0; + }; +} + +#endif // TC_HEADER_Platform_Functor diff --git a/Platform/Memory.cpp b/Platform/Memory.cpp new file mode 100644 index 0000000..7df4868 --- /dev/null +++ b/Platform/Memory.cpp @@ -0,0 +1,58 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Common/Tcdefs.h" +#include "Memory.h" +#include "Exception.h" + +namespace TrueCrypt +{ + void *Memory::Allocate (std::size_t size) + { + if (size < 1) + throw ParameterIncorrect (SRC_POS); + + void *bufPtr = malloc (size); + if (!bufPtr) + throw bad_alloc(); + + return bufPtr; + } + + int Memory::Compare (const void *memory1, size_t size1, const void *memory2, size_t size2) + { + if (size1 > size2) + return 1; + else if (size1 < size2) + return -1; + + return memcmp (memory1, memory2, size1); + } + + void Memory::Copy (void *memoryDestination, const void *memorySource, size_t size) + { + assert (memoryDestination != nullptr && memorySource != nullptr); + memcpy (memoryDestination, memorySource, size); + } + + void Memory::Erase (void *memory, size_t size) + { + burn (memory, size); + } + + void Memory::Zero (void *memory, size_t size) + { + memset (memory, 0, size); + } + + void Memory::Free (void *memory) + { + assert (memory != nullptr); + free (memory); + } +} diff --git a/Platform/Memory.h b/Platform/Memory.h new file mode 100644 index 0000000..ae43987 --- /dev/null +++ b/Platform/Memory.h @@ -0,0 +1,174 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Memory +#define TC_HEADER_Platform_Memory + +#include +#include +#include "PlatformBase.h" + +#ifdef TC_WINDOWS + +# ifndef LITTLE_ENDIAN +# define LITTLE_ENDIAN 1234 +# endif +# ifndef BYTE_ORDER +# define BYTE_ORDER LITTLE_ENDIAN +# endif + +#elif !defined(BYTE_ORDER) + +# ifdef TC_MACOSX +# include +# elif defined (TC_BSD) +# include +# elif defined (TC_SOLARIS) +# include +# define LITTLE_ENDIAN 1234 +# define BIG_ENDIAN 4321 +# ifdef _BIG_ENDIAN +# define BYTE_ORDER BIG_ENDIAN +# else +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# else +# include +# endif + +# ifndef BYTE_ORDER +# ifndef __BYTE_ORDER +# error Byte ordering cannot be determined (BYTE_ORDER undefined). +# endif + +# define BYTE_ORDER __BYTE_ORDER +# endif + +# ifndef LITTLE_ENDIAN +# define LITTLE_ENDIAN __LITTLE_ENDIAN +# endif + +# ifndef BIG_ENDIAN +# define BIG_ENDIAN __BIG_ENDIAN +# endif + +#endif // !BYTE_ORDER + +#if BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN +# error Unsupported byte ordering detected. +#endif + +namespace TrueCrypt +{ + class Memory + { + public: + static void *Allocate (size_t size); + static int Compare (const void *memory1, size_t size1, const void *memory2, size_t size2); + static void Copy (void *memoryDestination, const void *memorySource, size_t size); + static void Erase (void *memory, size_t size); + static void Free (void *memory); + static void Zero (void *memory, size_t size); + }; + + class Endian + { + public: + static byte Big (const byte &x) + { + return x; + } + + static uint16 Big (const uint16 &x) + { +#if BYTE_ORDER == BIG_ENDIAN + return x; +#else + return MirrorBytes (x); +#endif + } + + static uint32 Big (const uint32 &x) + { +#if BYTE_ORDER == BIG_ENDIAN + return x; +#else + return MirrorBytes (x); +#endif + } + + static uint64 Big (const uint64 &x) + { +#if BYTE_ORDER == BIG_ENDIAN + return x; +#else + return MirrorBytes (x); +#endif + } + + static byte Little (const byte &x) + { + return x; + } + + static uint16 Little (const uint16 &x) + { +#if BYTE_ORDER == LITTLE_ENDIAN + return x; +#else + return MirrorBytes (x); +#endif + } + + static uint32 Little (const uint32 &x) + { +#if BYTE_ORDER == LITTLE_ENDIAN + return x; +#else + return MirrorBytes (x); +#endif + } + + static uint64 Little (const uint64 &x) + { +#if BYTE_ORDER == LITTLE_ENDIAN + return x; +#else + return MirrorBytes (x); +#endif + } + + protected: + static uint16 MirrorBytes (const uint16 &x) + { + return (x << 8) | (x >> 8); + } + + static uint32 MirrorBytes (const uint32 &x) + { + uint32 n = (byte) x; + n <<= 8; n |= (byte) (x >> 8); + n <<= 8; n |= (byte) (x >> 16); + return (n << 8) | (byte) (x >> 24); + } + + static uint64 MirrorBytes (const uint64 &x) + { + uint64 n = (byte) x; + n <<= 8; n |= (byte) (x >> 8); + n <<= 8; n |= (byte) (x >> 16); + n <<= 8; n |= (byte) (x >> 24); + n <<= 8; n |= (byte) (x >> 32); + n <<= 8; n |= (byte) (x >> 40); + n <<= 8; n |= (byte) (x >> 48); + return (n << 8) | (byte) (x >> 56); + } + }; +} + +#endif // TC_HEADER_Platform_Memory diff --git a/Platform/MemoryStream.cpp b/Platform/MemoryStream.cpp new file mode 100644 index 0000000..a43f846 --- /dev/null +++ b/Platform/MemoryStream.cpp @@ -0,0 +1,47 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Exception.h" +#include "MemoryStream.h" + +namespace TrueCrypt +{ + MemoryStream::MemoryStream (const ConstBufferPtr &data) : + ReadPosition (0) + { + Data = vector (data.Size()); + BufferPtr (&Data[0], Data.size()).CopyFrom (data); + } + + uint64 MemoryStream::Read (const BufferPtr &buffer) + { + if (Data.size() == 0) + throw ParameterIncorrect (SRC_POS); + + ConstBufferPtr streamBuf (*this); + size_t len = buffer.Size(); + if (streamBuf.Size() - ReadPosition < len) + len = streamBuf.Size() - ReadPosition; + + BufferPtr(buffer).CopyFrom (streamBuf.GetRange (ReadPosition, len)); + ReadPosition += len; + return len; + } + + void MemoryStream::ReadCompleteBuffer (const BufferPtr &buffer) + { + if (Read (buffer) != buffer.Size()) + throw InsufficientData (SRC_POS); + } + + void MemoryStream::Write (const ConstBufferPtr &data) + { + for (uint64 i = 0; i < data.Size(); i++) + Data.push_back (data[i]); + } +} diff --git a/Platform/MemoryStream.h b/Platform/MemoryStream.h new file mode 100644 index 0000000..c49c63d --- /dev/null +++ b/Platform/MemoryStream.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_MemoryStream +#define TC_HEADER_Platform_MemoryStream + +#include "PlatformBase.h" +#include "Stream.h" + +namespace TrueCrypt +{ + class MemoryStream : public Stream + { + public: + MemoryStream () : ReadPosition (0) { } + MemoryStream (const ConstBufferPtr &data); + virtual ~MemoryStream () { } + + operator ConstBufferPtr () const { return ConstBufferPtr (&Data[0], Data.size()); } + + virtual uint64 Read (const BufferPtr &buffer); + virtual void ReadCompleteBuffer (const BufferPtr &buffer); + virtual void Write (const ConstBufferPtr &data); + + protected: + vector Data; + size_t ReadPosition; + }; +} + +#endif // TC_HEADER_Platform_MemoryStream diff --git a/Platform/Mutex.h b/Platform/Mutex.h new file mode 100644 index 0000000..972e98e --- /dev/null +++ b/Platform/Mutex.h @@ -0,0 +1,61 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Mutex +#define TC_HEADER_Platform_Mutex + +#ifdef TC_WINDOWS +# include "System.h" +#else +# include +#endif +#include "PlatformBase.h" + +namespace TrueCrypt +{ + class Mutex + { +#ifdef TC_WINDOWS + typedef CRITICAL_SECTION SystemMutex_t; +#else + typedef pthread_mutex_t SystemMutex_t; +#endif + + public: + Mutex (); + ~Mutex (); + + SystemMutex_t *GetSystemHandle () { return &SystemMutex; } + void Lock (); + void Unlock (); + + protected: + bool Initialized; + SystemMutex_t SystemMutex; + + private: + Mutex (const Mutex &); + Mutex &operator= (const Mutex &); + }; + + class ScopeLock + { + public: + ScopeLock (Mutex &mutex) : ScopeMutex (mutex) { mutex.Lock(); } + ~ScopeLock () { ScopeMutex.Unlock(); } + + protected: + Mutex &ScopeMutex; + + private: + ScopeLock (const ScopeLock &); + ScopeLock &operator= (const ScopeLock &); + }; +} + +#endif // TC_HEADER_Platform_Mutex diff --git a/Platform/Platform.h b/Platform/Platform.h new file mode 100644 index 0000000..73d4888 --- /dev/null +++ b/Platform/Platform.h @@ -0,0 +1,28 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform +#define TC_HEADER_Platform + +#include "PlatformBase.h" +#include "Buffer.h" +#include "Exception.h" +#include "Directory.h" +#include "Event.h" +#include "File.h" +#include "FilesystemPath.h" +#include "Finally.h" +#include "ForEach.h" +#include "Functor.h" +#include "Memory.h" +#include "Mutex.h" +#include "SharedPtr.h" +#include "SystemException.h" +#include "Thread.h" + +#endif // TC_HEADER_Platform diff --git a/Platform/Platform.make b/Platform/Platform.make new file mode 100644 index 0000000..e871fa1 --- /dev/null +++ b/Platform/Platform.make @@ -0,0 +1,35 @@ +# +# Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. +# +# Governed by the TrueCrypt License 3.0 the full text of which is contained in +# the file License.txt included in TrueCrypt binary and source code distribution +# packages. +# + +OBJS := Buffer.o +OBJS += Exception.o +OBJS += Event.o +OBJS += FileCommon.o +OBJS += MemoryStream.o +OBJS += Memory.o +OBJS += PlatformTest.o +OBJS += Serializable.o +OBJS += Serializer.o +OBJS += SerializerFactory.o +OBJS += StringConverter.o +OBJS += TextReader.o +OBJS += Unix/Directory.o +OBJS += Unix/File.o +OBJS += Unix/FilesystemPath.o +OBJS += Unix/Mutex.o +OBJS += Unix/Pipe.o +OBJS += Unix/Poller.o +OBJS += Unix/Process.o +OBJS += Unix/SyncEvent.o +OBJS += Unix/SystemException.o +OBJS += Unix/SystemInfo.o +OBJS += Unix/SystemLog.o +OBJS += Unix/Thread.o +OBJS += Unix/Time.o + +include $(BUILD_INC)/Makefile.inc diff --git a/Platform/PlatformBase.h b/Platform/PlatformBase.h new file mode 100644 index 0000000..0b08297 --- /dev/null +++ b/Platform/PlatformBase.h @@ -0,0 +1,134 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_PlatformBase +#define TC_HEADER_Platform_PlatformBase + +#include +#include +#include +#include +#include +#include +#include + +#ifndef _MSC_VER +#include +#endif + +using namespace std; + +#ifdef nullptr +#undef nullptr +#endif + +#if !(defined(_MSC_VER) && _MSC_VER >= 1600) +#define nullptr 0 +#endif + +namespace TrueCrypt +{ +#ifdef _MSC_VER +# ifndef TC_INT_TYPES_DEFINED + typedef __int8 int8; + typedef __int16 int16; + typedef __int32 int32; + typedef __int64 int64; + typedef unsigned __int8 byte; + typedef unsigned __int16 uint16; + typedef unsigned __int32 uint32; + typedef unsigned __int64 uint64; +# endif +#else + typedef int8_t int8; + typedef int16_t int16; + typedef int32_t int32; + typedef int64_t int64; + typedef uint8_t byte; + typedef uint16_t uint16; + typedef uint32_t uint32; + typedef uint64_t uint64; +#endif +} + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(TC_WINDOWS) +# define TC_WINDOWS +#endif + +#if defined(_DEBUG) && !defined(DEBUG) +# define DEBUG +#endif + +#ifndef TC_TO_STRING +# define TC_TO_STRING2(n) #n +# define TC_TO_STRING(n) TC_TO_STRING2(n) +#endif + +#define TC_JOIN_ARGS(a,b) a##b +#define TC_JOIN(a,b) TC_JOIN_ARGS(a,b) + +#ifdef __GNUC__ + template string GetFunctionName (T pos) + { + string s (pos); + size_t p = s.find ('('); + if (p == string::npos) + return s; + s = s.substr (0, p); + p = s.find_last_of (" "); + if (p == string::npos) + return s; + return s.substr (p + 1); + } +# define SRC_POS (GetFunctionName (__PRETTY_FUNCTION__) += ":" TC_TO_STRING(__LINE__)) +# define TC_UNUSED_VAR __attribute__ ((unused)) +#else +# define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__)) +# define TC_UNUSED_VAR +#endif + +#ifdef trace_point +# undef trace_point +#endif + +#ifdef trace_msg +# undef trace_msg +#endif + +#ifdef DEBUG +# define if_debug(...) __VA_ARGS__ + +# ifdef TC_WINDOWS +# define trace_point OutputDebugStringA ((string (SRC_POS) + "\n").c_str()) +# define trace_msg(stream_args) do { stringstream s; s << (SRC_POS) << ": " << stream_args << endl; OutputDebugStringA (s.str().c_str()); } while (0) +# define trace_msgw(stream_args) do { wstringstream s; s << (SRC_POS) << L": " << stream_args << endl; OutputDebugStringW (s.str().c_str()); } while (0) +# else +# include +# define trace_point cerr << (SRC_POS) << endl +# define trace_msg(stream_args) cerr << (SRC_POS) << ": " << stream_args << endl +# define trace_msgw(stream_args) cerr << (SRC_POS); wcerr << L": " << stream_args << endl +# endif + +# include "Platform/SystemLog.h" +# define trace_log_point SystemLog::WriteError (SRC_POS) +# define trace_log_msg(stream_args) do { stringstream s; s << (SRC_POS) << ": " << stream_args; SystemLog::WriteError (s.str()); } while (0) + +#else +# define if_debug(...) +# define trace_point +# define trace_msg(...) +# define trace_msgw(...) +# define trace_log_point +# define trace_log_msg(...) +#endif + +#define trace_val(VAL) trace_msg (#VAL << '=' << (VAL)); + +#define array_capacity(arr) (sizeof (arr) / sizeof ((arr)[0])) + +#endif // TC_HEADER_Platform_PlatformBase diff --git a/Platform/PlatformTest.cpp b/Platform/PlatformTest.cpp new file mode 100644 index 0000000..7c7b7e8 --- /dev/null +++ b/Platform/PlatformTest.cpp @@ -0,0 +1,350 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "PlatformTest.h" +#include "Exception.h" +#include "FileStream.h" +#include "Finally.h" +#include "ForEach.h" +#include "MemoryStream.h" +#include "Mutex.h" +#include "Serializable.h" +#include "SharedPtr.h" +#include "StringConverter.h" +#include "SyncEvent.h" +#include "Thread.h" +#include "Common/Tcdefs.h" + +namespace TrueCrypt +{ + // make_shared_auto, File, Stream, MemoryStream, Endian, Serializer, Serializable + void PlatformTest::SerializerTest () + { + shared_ptr stream (new MemoryStream); + +#if 0 + make_shared_auto (File, file); + finally_do_arg (File&, *file, { if (finally_arg.IsOpen()) finally_arg.Delete(); }); + + try + { + file->Open ("truecrypt-serializer-test.tmp", File::CreateReadWrite); + stream = shared_ptr (new FileStream (file)); + } + catch (...) { } +#endif + + Serializer ser (stream); + + uint32 i32 = 0x12345678; + uint64 i64 = 0x0123456789abcdefULL; + string str = "string test"; + wstring wstr = L"wstring test"; + + string convStr = "test"; + StringConverter::ToSingle (wstr, convStr); + if (convStr != "wstring test") + throw TestFailed (SRC_POS); + + StringConverter::Erase (convStr); + if (convStr != " ") + throw TestFailed (SRC_POS); + + wstring wEraseTest = L"erase test"; + StringConverter::Erase (wEraseTest); + if (wEraseTest != L" ") + throw TestFailed (SRC_POS); + + list stringList; + stringList.push_back (str + "1"); + stringList.push_back (str + "2"); + stringList.push_back (str + "3"); + + list wstringList; + wstringList.push_back (wstr + L"1"); + wstringList.push_back (wstr + L"2"); + wstringList.push_back (wstr + L"3"); + + Buffer buffer (10); + for (size_t i = 0; i < buffer.Size(); i++) + buffer[i] = (byte) i; + + ser.Serialize ("int32", i32); + ser.Serialize ("int64", i64); + ser.Serialize ("string", str); + ser.Serialize ("wstring", wstr); + ser.Serialize ("stringList", stringList); + ser.Serialize ("wstringList", wstringList); + ser.Serialize ("buffer", ConstBufferPtr (buffer)); + + ExecutedProcessFailed ex (SRC_POS, "cmd", -123, "error output"); + ex.Serialize (stream); + + list < shared_ptr > exList; + exList.push_back (make_shared (ExecutedProcessFailed (SRC_POS, "cmd", -123, "error output1"))); + exList.push_back (make_shared (ExecutedProcessFailed (SRC_POS, "cmd", -234, "error output2"))); + exList.push_back (make_shared (ExecutedProcessFailed (SRC_POS, "cmd", -567, "error output3"))); + Serializable::SerializeList (stream, exList); + +#if 0 + if (file->IsOpen()) + file->SeekAt (0); +#endif + + uint32 di32; + ser.Deserialize ("int32", di32); + if (i32 != di32) + throw TestFailed (SRC_POS); + + uint64 di64; + ser.Deserialize ("int64", di64); + if (i64 != di64) + throw TestFailed (SRC_POS); + + string dstr; + ser.Deserialize ("string", dstr); + if (str != dstr) + throw TestFailed (SRC_POS); + + wstring dwstr; + ser.Deserialize ("wstring", dwstr); + if (str != dstr) + throw TestFailed (SRC_POS); + + int i = 1; + foreach (string item, ser.DeserializeStringList ("stringList")) + { + stringstream s; + s << str << i++; + if (item != s.str()) + throw TestFailed (SRC_POS); + } + + i = 1; + foreach (wstring item, ser.DeserializeWStringList ("wstringList")) + { + wstringstream s; + s << wstr << i++; + if (item != s.str()) + throw TestFailed (SRC_POS); + } + + Buffer dbuffer (10); + ser.Deserialize ("buffer", buffer); + for (size_t i = 0; i < buffer.Size(); i++) + if (buffer[i] != (byte) i) + throw TestFailed (SRC_POS); + + shared_ptr dex = Serializable::DeserializeNew (stream); + if (!dex + || dex->GetCommand() != "cmd" + || dex->GetExitCode() != -123 + || dex->GetErrorOutput() != "error output") + throw TestFailed (SRC_POS); + + list < shared_ptr > dexList; + Serializable::DeserializeList (stream, dexList); + i = 1; + foreach_ref (const ExecutedProcessFailed &ex, dexList) + { + stringstream s; + s << "error output" << i++; + if (ex.GetErrorOutput() != s.str()) + throw TestFailed (SRC_POS); + } + } + + // shared_ptr, Mutex, ScopeLock, SyncEvent, Thread + static struct + { + shared_ptr SharedIntPtr; + Mutex IntMutex; + SyncEvent ExitAllowedEvent; + } ThreadTestData; + + void PlatformTest::ThreadTest () + { + Mutex mutex; + mutex.Lock(); + mutex.Unlock(); + + const int maxThreads = 3; + ThreadTestData.SharedIntPtr.reset (new int (0)); + + for (int i = 0; i < maxThreads; i++) + { + Thread t; + t.Start (&ThreadTestProc, (void *) &ThreadTestData); + } + + for (int i = 0; i < 50; i++) + { + { + ScopeLock sl (ThreadTestData.IntMutex); + if (*ThreadTestData.SharedIntPtr == maxThreads) + break; + } + + Thread::Sleep(100); + } + + if (*ThreadTestData.SharedIntPtr != maxThreads) + throw TestFailed (SRC_POS); + + for (int i = 0; i < 60000; i++) + { + ThreadTestData.ExitAllowedEvent.Signal(); + Thread::Sleep(1); + + ScopeLock sl (ThreadTestData.IntMutex); + if (*ThreadTestData.SharedIntPtr == 0) + break; + } + + if (*ThreadTestData.SharedIntPtr != 0) + throw TestFailed (SRC_POS); + } + + TC_THREAD_PROC PlatformTest::ThreadTestProc (void *arg) + { + + if (arg != (void *) &ThreadTestData) + return 0; + + { + ScopeLock sl (ThreadTestData.IntMutex); + ++(*ThreadTestData.SharedIntPtr); + } + + ThreadTestData.ExitAllowedEvent.Wait(); + + { + ScopeLock sl (ThreadTestData.IntMutex); + --(*ThreadTestData.SharedIntPtr); + } + + return 0; + } + + bool PlatformTest::TestAll () + { + // Integer types + if (sizeof (byte) != 1 || sizeof (int8) != 1 || sizeof (__int8) != 1) throw TestFailed (SRC_POS); + if (sizeof (uint16) != 2 || sizeof (int16) != 2 || sizeof (__int16) != 2) throw TestFailed (SRC_POS); + if (sizeof (uint32) != 4 || sizeof (int32) != 4 || sizeof (__int32) != 4) throw TestFailed (SRC_POS); + if (sizeof (uint64) != 8 || sizeof (int64) != 8) throw TestFailed (SRC_POS); + + // Exception handling + TestFlag = false; + try + { + try + { + throw TestFailed (SRC_POS); + } + catch (...) + { + throw; + } + return false; + } + catch (Exception &) + { + TestFlag = true; + } + if (!TestFlag) + return false; + + // RTTI + RttiTest rtti; + RttiTestBase &rttiBaseRef = rtti; + RttiTestBase *rttiBasePtr = &rtti; + + if (typeid (rttiBaseRef) != typeid (rtti)) + throw TestFailed (SRC_POS); + + if (typeid (*rttiBasePtr) != typeid (rtti)) + throw TestFailed (SRC_POS); + + if (dynamic_cast (rttiBasePtr) == nullptr) + throw TestFailed (SRC_POS); + + try + { + dynamic_cast (rttiBaseRef); + } + catch (...) + { + throw TestFailed (SRC_POS); + } + + // finally + TestFlag = false; + { + finally_do ({ TestFlag = true; }); + if (TestFlag) + throw TestFailed (SRC_POS); + } + if (!TestFlag) + throw TestFailed (SRC_POS); + + TestFlag = false; + { + finally_do_arg (bool*, &TestFlag, { *finally_arg = true; }); + if (TestFlag) + throw TestFailed (SRC_POS); + } + if (!TestFlag) + throw TestFailed (SRC_POS); + + TestFlag = false; + int tesFlag2 = 0; + { + finally_do_arg2 (bool*, &TestFlag, int*, &tesFlag2, { *finally_arg = true; *finally_arg2 = 2; }); + if (TestFlag || tesFlag2 != 0) + throw TestFailed (SRC_POS); + } + if (!TestFlag || tesFlag2 != 2) + throw TestFailed (SRC_POS); + + // uint64, vector, list, string, wstring, stringstream, wstringstream + // shared_ptr, make_shared, StringConverter, foreach + list > numList; + + numList.push_front (make_shared (StringConverter::ToUInt64 (StringConverter::FromNumber ((uint64) 0xFFFFffffFFFFfffeULL)))); + numList.push_front (make_shared (StringConverter::ToUInt32 (StringConverter::GetTrailingNumber ("str2")))); + numList.push_front (make_shared (3)); + + list testList; + wstringstream wstream (L"test"); + foreach_reverse_ref (uint64 n, numList) + { + wstream.str (L""); + wstream << L"str" << n; + testList.push_back (wstream.str()); + } + + stringstream sstream; + sstream << "dummy"; + sstream.str (""); + sstream << "str18446744073709551614,str2" << " str" << StringConverter::Trim (StringConverter::ToSingle (L"\t 3 \r\n")); + foreach (const string &s, StringConverter::Split (sstream.str(), ", ")) + { + if (testList.front() != StringConverter::ToWide (s)) + throw TestFailed (SRC_POS); + testList.pop_front(); + } + + SerializerTest(); + ThreadTest(); + + return true; + } + + bool PlatformTest::TestFlag; +} diff --git a/Platform/PlatformTest.h b/Platform/PlatformTest.h new file mode 100644 index 0000000..94158b7 --- /dev/null +++ b/Platform/PlatformTest.h @@ -0,0 +1,43 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_PlatformTest +#define TC_HEADER_Platform_PlatformTest + +#include "PlatformBase.h" +#include "Thread.h" + +namespace TrueCrypt +{ + class PlatformTest + { + public: + static bool TestAll (); + + protected: + class RttiTestBase + { + public: + virtual ~RttiTestBase () { }; + }; + + class RttiTest : public RttiTestBase { + public: + virtual ~RttiTest () { }; + }; + + PlatformTest (); + static void SerializerTest (); + static void ThreadTest (); + static TC_THREAD_PROC ThreadTestProc (void *param); + + static bool TestFlag; + }; +} + +#endif // TC_HEADER_Platform_PlatformTest diff --git a/Platform/Serializable.cpp b/Platform/Serializable.cpp new file mode 100644 index 0000000..9932515 --- /dev/null +++ b/Platform/Serializable.cpp @@ -0,0 +1,39 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Serializable.h" +#include "SerializerFactory.h" + +namespace TrueCrypt +{ + string Serializable::DeserializeHeader (shared_ptr stream) + { + Serializer sr (stream); + return sr.DeserializeString ("SerializableName"); + } + + Serializable *Serializable::DeserializeNew (shared_ptr stream) + { + string name = Serializable::DeserializeHeader (stream); + Serializable *serializable = SerializerFactory::GetNewSerializable (name); + serializable->Deserialize (stream); + + return serializable; + } + + void Serializable::Serialize (shared_ptr stream) const + { + Serializer sr (stream); + Serializable::SerializeHeader (sr, SerializerFactory::GetName (typeid (*this))); + } + + void Serializable::SerializeHeader (Serializer &serializer, const string &name) + { + serializer.Serialize ("SerializableName", name); + } +} diff --git a/Platform/Serializable.h b/Platform/Serializable.h new file mode 100644 index 0000000..3344aeb --- /dev/null +++ b/Platform/Serializable.h @@ -0,0 +1,82 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Serializable +#define TC_HEADER_Platform_Serializable + +#include +#include "PlatformBase.h" +#include "ForEach.h" +#include "Serializer.h" +#include "SerializerFactory.h" + +namespace TrueCrypt +{ + class Serializable + { + public: + virtual ~Serializable () { } + + virtual void Deserialize (shared_ptr stream) = 0; + static string DeserializeHeader (shared_ptr stream); + static Serializable *DeserializeNew (shared_ptr stream); + + template + static shared_ptr DeserializeNew (shared_ptr stream) + { + shared_ptr p (dynamic_cast (DeserializeNew (stream))); + if (!p) + throw std::runtime_error (SRC_POS); + return p; + } + + template + static void DeserializeList (shared_ptr stream, list < shared_ptr > &dataList) + { + if (DeserializeHeader (stream) != string ("list<") + SerializerFactory::GetName (typeid (T)) + ">") + throw std::runtime_error (SRC_POS); + + Serializer sr (stream); + uint64 listSize; + sr.Deserialize ("ListSize", listSize); + + for (size_t i = 0; i < listSize; i++) + { + shared_ptr p (dynamic_cast (DeserializeNew (stream))); + if (!p) + throw std::runtime_error (SRC_POS); + dataList.push_back (p); + } + } + + virtual void Serialize (shared_ptr stream) const; + + template + static void SerializeList (shared_ptr stream, const list < shared_ptr > &dataList) + { + Serializer sr (stream); + SerializeHeader (sr, string ("list<") + SerializerFactory::GetName (typeid (T)) + ">"); + + sr.Serialize ("ListSize", (uint64) dataList.size()); + foreach_ref (const T &item, dataList) + item.Serialize (stream); + } + + static void SerializeHeader (Serializer &serializer, const string &name); + + protected: + Serializable () { } + }; +} + +#define TC_SERIALIZABLE(TYPE) \ + static Serializable *GetNewSerializable () { return new TYPE(); } \ + virtual void Deserialize (shared_ptr stream); \ + virtual void Serialize (shared_ptr stream) const + +#endif // TC_HEADER_Platform_Serializable diff --git a/Platform/Serializer.cpp b/Platform/Serializer.cpp new file mode 100644 index 0000000..85a9b20 --- /dev/null +++ b/Platform/Serializer.cpp @@ -0,0 +1,299 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Exception.h" +#include "ForEach.h" +#include "Memory.h" +#include "Serializer.h" + +namespace TrueCrypt +{ + template + T Serializer::Deserialize () + { + uint64 size; + DataStream->ReadCompleteBuffer (BufferPtr ((byte *) &size, sizeof (size))); + + if (Endian::Big (size) != sizeof (T)) + throw ParameterIncorrect (SRC_POS); + + T data; + DataStream->ReadCompleteBuffer (BufferPtr ((byte *) &data, sizeof (data))); + + return Endian::Big (data); + } + + void Serializer::Deserialize (const string &name, bool &data) + { + ValidateName (name); + data = Deserialize () == 1; + } + + void Serializer::Deserialize (const string &name, byte &data) + { + ValidateName (name); + data = Deserialize (); + } + + void Serializer::Deserialize (const string &name, int32 &data) + { + ValidateName (name); + data = (int32) Deserialize (); + } + + void Serializer::Deserialize (const string &name, int64 &data) + { + ValidateName (name); + data = (int64) Deserialize (); + } + + void Serializer::Deserialize (const string &name, uint32 &data) + { + ValidateName (name); + data = Deserialize (); + } + + void Serializer::Deserialize (const string &name, uint64 &data) + { + ValidateName (name); + data = Deserialize (); + } + + void Serializer::Deserialize (const string &name, string &data) + { + ValidateName (name); + data = DeserializeString (); + } + + void Serializer::Deserialize (const string &name, wstring &data) + { + ValidateName (name); + data = DeserializeWString (); + } + + void Serializer::Deserialize (const string &name, const BufferPtr &data) + { + ValidateName (name); + + uint64 size = Deserialize (); + if (data.Size() != size) + throw ParameterIncorrect (SRC_POS); + + DataStream->ReadCompleteBuffer (data); + } + + bool Serializer::DeserializeBool (const string &name) + { + bool data; + Deserialize (name, data); + return data; + } + + int32 Serializer::DeserializeInt32 (const string &name) + { + ValidateName (name); + return Deserialize (); + } + + int64 Serializer::DeserializeInt64 (const string &name) + { + ValidateName (name); + return Deserialize (); + } + + uint32 Serializer::DeserializeUInt32 (const string &name) + { + ValidateName (name); + return Deserialize (); + } + + uint64 Serializer::DeserializeUInt64 (const string &name) + { + ValidateName (name); + return Deserialize (); + } + + string Serializer::DeserializeString () + { + uint64 size = Deserialize (); + + vector data ((size_t) size); + DataStream->ReadCompleteBuffer (BufferPtr ((byte *) &data[0], (size_t) size)); + + return string (&data[0]); + } + + string Serializer::DeserializeString (const string &name) + { + ValidateName (name); + return DeserializeString (); + } + + list Serializer::DeserializeStringList (const string &name) + { + ValidateName (name); + list deserializedList; + uint64 listSize = Deserialize (); + + for (size_t i = 0; i < listSize; i++) + deserializedList.push_back (DeserializeString ()); + + return deserializedList; + } + + wstring Serializer::DeserializeWString () + { + uint64 size = Deserialize (); + + vector data ((size_t) size / sizeof (wchar_t)); + DataStream->ReadCompleteBuffer (BufferPtr ((byte *) &data[0], (size_t) size)); + + return wstring (&data[0]); + } + + list Serializer::DeserializeWStringList (const string &name) + { + ValidateName (name); + list deserializedList; + uint64 listSize = Deserialize (); + + for (size_t i = 0; i < listSize; i++) + deserializedList.push_back (DeserializeWString ()); + + return deserializedList; + } + + wstring Serializer::DeserializeWString (const string &name) + { + ValidateName (name); + return DeserializeWString (); + } + + template + void Serializer::Serialize (T data) + { + uint64 size = Endian::Big (uint64 (sizeof (data))); + DataStream->Write (ConstBufferPtr ((byte *) &size, sizeof (size))); + + data = Endian::Big (data); + DataStream->Write (ConstBufferPtr ((byte *) &data, sizeof (data))); + } + + void Serializer::Serialize (const string &name, bool data) + { + SerializeString (name); + byte d = data ? 1 : 0; + Serialize (d); + } + + void Serializer::Serialize (const string &name, byte data) + { + SerializeString (name); + Serialize (data); + } + + void Serializer::Serialize (const string &name, const char *data) + { + Serialize (name, string (data)); + } + + void Serializer::Serialize (const string &name, int32 data) + { + SerializeString (name); + Serialize ((uint32) data); + } + + void Serializer::Serialize (const string &name, int64 data) + { + SerializeString (name); + Serialize ((uint64) data); + } + + void Serializer::Serialize (const string &name, uint32 data) + { + SerializeString (name); + Serialize (data); + } + + void Serializer::Serialize (const string &name, uint64 data) + { + SerializeString (name); + Serialize (data); + } + + void Serializer::Serialize (const string &name, const string &data) + { + SerializeString (name); + SerializeString (data); + } + + void Serializer::Serialize (const string &name, const wchar_t *data) + { + Serialize (name, wstring (data)); + } + + void Serializer::Serialize (const string &name, const wstring &data) + { + SerializeString (name); + SerializeWString (data); + } + + void Serializer::Serialize (const string &name, const list &stringList) + { + SerializeString (name); + + uint64 listSize = stringList.size(); + Serialize (listSize); + + foreach (const string &item, stringList) + SerializeString (item); + } + + void Serializer::Serialize (const string &name, const list &stringList) + { + SerializeString (name); + + uint64 listSize = stringList.size(); + Serialize (listSize); + + foreach (const wstring &item, stringList) + SerializeWString (item); + } + + void Serializer::Serialize (const string &name, const ConstBufferPtr &data) + { + SerializeString (name); + + uint64 size = data.Size(); + Serialize (size); + + DataStream->Write (data); + } + + void Serializer::SerializeString (const string &data) + { + Serialize ((uint64) data.size() + 1); + DataStream->Write (ConstBufferPtr ((byte *) (data.data() ? data.data() : data.c_str()), data.size() + 1)); + } + + void Serializer::SerializeWString (const wstring &data) + { + uint64 size = (data.size() + 1) * sizeof (wchar_t); + Serialize (size); + DataStream->Write (ConstBufferPtr ((byte *) (data.data() ? data.data() : data.c_str()), (size_t) size)); + } + + void Serializer::ValidateName (const string &name) + { + string dName = DeserializeString(); + if (dName != name) + { + throw ParameterIncorrect (SRC_POS); + } + } +} diff --git a/Platform/Serializer.h b/Platform/Serializer.h new file mode 100644 index 0000000..ccd94ad --- /dev/null +++ b/Platform/Serializer.h @@ -0,0 +1,74 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Serializer +#define TC_HEADER_Platform_Serializer + +#include "PlatformBase.h" +#include "Buffer.h" +#include "SharedPtr.h" +#include "Stream.h" + +namespace TrueCrypt +{ + class Serializer + { + public: + Serializer (shared_ptr stream) : DataStream (stream) { } + virtual ~Serializer () { } + + void Deserialize (const string &name, bool &data); + void Deserialize (const string &name, byte &data); + void Deserialize (const string &name, int32 &data); + void Deserialize (const string &name, int64 &data); + void Deserialize (const string &name, uint32 &data); + void Deserialize (const string &name, uint64 &data); + void Deserialize (const string &name, string &data); + void Deserialize (const string &name, wstring &data); + void Deserialize (const string &name, const BufferPtr &data); + bool DeserializeBool (const string &name); + int32 DeserializeInt32 (const string &name); + int64 DeserializeInt64 (const string &name); + uint32 DeserializeUInt32 (const string &name); + uint64 DeserializeUInt64 (const string &name); + string DeserializeString (const string &name); + list DeserializeStringList (const string &name); + wstring DeserializeWString (const string &name); + list DeserializeWStringList (const string &name); + void Serialize (const string &name, bool data); + void Serialize (const string &name, byte data); + void Serialize (const string &name, const char *data); + void Serialize (const string &name, int32 data); + void Serialize (const string &name, int64 data); + void Serialize (const string &name, uint32 data); + void Serialize (const string &name, uint64 data); + void Serialize (const string &name, const string &data); + void Serialize (const string &name, const wstring &data); + void Serialize (const string &name, const wchar_t *data); + void Serialize (const string &name, const list &stringList); + void Serialize (const string &name, const list &stringList); + void Serialize (const string &name, const ConstBufferPtr &data); + + protected: + template T Deserialize (); + string DeserializeString (); + wstring DeserializeWString (); + template void Serialize (T data); + void SerializeString (const string &data); + void SerializeWString (const wstring &data); + void ValidateName (const string &name); + + shared_ptr DataStream; + + private: + Serializer (const Serializer &); + Serializer &operator= (const Serializer &); + }; +} + +#endif // TC_HEADER_Platform_Serializer diff --git a/Platform/SerializerFactory.cpp b/Platform/SerializerFactory.cpp new file mode 100644 index 0000000..794bb4b --- /dev/null +++ b/Platform/SerializerFactory.cpp @@ -0,0 +1,54 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "SerializerFactory.h" + +namespace TrueCrypt +{ + void SerializerFactory::Deinitialize () + { + if (--UseCount == 0) + { + delete NameToTypeMap; + delete TypeToNameMap; + } + } + + string SerializerFactory::GetName (const type_info &typeInfo) + { + string typeName = StringConverter::GetTypeName (typeInfo); + if (TypeToNameMap->find (typeName) == TypeToNameMap->end()) + throw std::runtime_error (SRC_POS); + + return (*TypeToNameMap)[typeName]; + } + + Serializable *SerializerFactory::GetNewSerializable (const string &typeName) + { + if (NameToTypeMap->find (typeName) == NameToTypeMap->end()) + throw std::runtime_error (SRC_POS); + + return (*NameToTypeMap)[typeName].GetNewPtr(); + } + + void SerializerFactory::Initialize () + { + if (UseCount == 0) + { + NameToTypeMap = new map ; + TypeToNameMap = new map ; + } + + ++UseCount; + } + + map *SerializerFactory::NameToTypeMap; + map *SerializerFactory::TypeToNameMap; + int SerializerFactory::UseCount; +} diff --git a/Platform/SerializerFactory.h b/Platform/SerializerFactory.h new file mode 100644 index 0000000..083ce0e --- /dev/null +++ b/Platform/SerializerFactory.h @@ -0,0 +1,93 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_SerializerFactory +#define TC_HEADER_Platform_SerializerFactory + +#include +#include "PlatformBase.h" +#include "StringConverter.h" + +namespace TrueCrypt +{ + class Serializable; + + class SerializerFactory + { + public: + ~SerializerFactory (); + + static void Deinitialize (); + static string GetName (const type_info &typeInfo); + static Serializable *GetNewSerializable (const string &typeName); + static void Initialize (); + + struct MapEntry + { + MapEntry () { } + MapEntry (const string &typeName, Serializable* (*getNewPtr) ()) + : TypeName (typeName), GetNewPtr (getNewPtr) { } + + MapEntry &operator= (const MapEntry &right) + { + TypeName = right.TypeName; + GetNewPtr = right.GetNewPtr; + return *this; + } + + string TypeName; + Serializable* (*GetNewPtr) (); + }; + + static map *NameToTypeMap; + static map *TypeToNameMap; + + protected: + SerializerFactory (); + + static int UseCount; + }; + +} + +#define TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET(TYPE) \ + struct TYPE##SerializerFactoryInitializer \ + { \ + TYPE##SerializerFactoryInitializer () \ + { \ + SerializerFactory::Initialize(); \ + TC_EXCEPTION_SET; \ + } \ + ~TYPE##SerializerFactoryInitializer () \ + { \ + SerializerFactory::Deinitialize(); \ + } \ + }; \ + static TYPE##SerializerFactoryInitializer TYPE##SerializerFactoryInitializer + +#define TC_SERIALIZER_FACTORY_ADD_CLASS(TYPE) \ + struct TYPE##SerializerFactoryInitializer \ + { \ + TYPE##SerializerFactoryInitializer () \ + { \ + SerializerFactory::Initialize(); \ + TC_SERIALIZER_FACTORY_ADD (TYPE); \ + } \ + ~TYPE##SerializerFactoryInitializer () \ + { \ + SerializerFactory::Deinitialize(); \ + } \ + }; \ + static TYPE##SerializerFactoryInitializer TYPE##SerializerFactoryInitializerInst + +#define TC_SERIALIZER_FACTORY_ADD(TYPE) \ + (*SerializerFactory::NameToTypeMap)[#TYPE] = SerializerFactory::MapEntry (StringConverter::GetTypeName (typeid (TYPE)), &TYPE::GetNewSerializable); \ + (*SerializerFactory::TypeToNameMap)[StringConverter::GetTypeName (typeid (TYPE))] = #TYPE + + +#endif // TC_HEADER_Platform_SerializerFactory diff --git a/Platform/SharedPtr.h b/Platform/SharedPtr.h new file mode 100644 index 0000000..257bdf1 --- /dev/null +++ b/Platform/SharedPtr.h @@ -0,0 +1,162 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_SharedPtr +#define TC_HEADER_Platform_SharedPtr + +#include +#include "SharedVal.h" + +#ifdef nullptr + +namespace TrueCrypt +{ + template + class SharedPtr + { + public: + explicit SharedPtr () + : Pointer (nullptr), UseCount (nullptr) { } + + explicit SharedPtr (T *pointer) + : Pointer (pointer), UseCount (new SharedVal (1)) { } + + SharedPtr (const SharedPtr &source) + { + CopyFrom (source); + } + + ~SharedPtr () + { + Release(); + } + + SharedPtr &operator= (const SharedPtr &source) + { + if (&source == this) + return *this; + + Release(); + CopyFrom (source); + return *this; + } + + bool operator == (const SharedPtr &other) + { + return get() == other.get(); + } + + bool operator != (const SharedPtr &other) + { + return get() != other.get(); + } + + T &operator* () const + { +#ifdef DEBUG + if (Pointer == nullptr) + throw std::runtime_error (SRC_POS); +#endif + return *Pointer; + } + + T *operator-> () const + { +#ifdef DEBUG + if (Pointer == nullptr) + throw std::runtime_error (SRC_POS); +#endif + return Pointer; + } + + operator bool () const + { + return Pointer != nullptr; + } + + T *get () const + { + return Pointer; + } + + void reset () + { + Release(); + } + + void reset (T *pointer) + { + *this = SharedPtr (pointer); + } + + uint64 use_count () const + { + if (!UseCount) + return 0; + + return *UseCount; + } + + protected: + void CopyFrom (const SharedPtr &source) + { + Pointer = source.Pointer; + UseCount = source.UseCount; + + if (UseCount) + UseCount->Increment(); + } + + void Release () + { + if (UseCount != nullptr) + { + if (UseCount->Decrement() == 0) + { + if (Pointer != nullptr) + delete Pointer; + delete UseCount; + } + + Pointer = nullptr; + UseCount = nullptr; + } + } + + T *Pointer; + SharedVal *UseCount; + }; + +#ifdef shared_ptr +#undef shared_ptr +#endif +#define shared_ptr TrueCrypt::SharedPtr + +#ifdef make_shared +#undef make_shared +#endif + + template shared_ptr make_shared () + { + return shared_ptr (new T ()); + } + + template shared_ptr make_shared (const A &arg) + { + return shared_ptr (new T (arg)); + } + +#define make_shared TrueCrypt::make_shared + +} + +#endif // nullptr + +#define make_shared_auto(typeName,instanceName) shared_ptr instanceName (new typeName ()) + +#endif // TC_HEADER_Platform_SharedPtr diff --git a/Platform/SharedVal.h b/Platform/SharedVal.h new file mode 100644 index 0000000..d1c2274 --- /dev/null +++ b/Platform/SharedVal.h @@ -0,0 +1,71 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_SharedVal +#define TC_HEADER_Platform_SharedVal + +#include "PlatformBase.h" +#include "Mutex.h" + +namespace TrueCrypt +{ + template + class SharedVal + { + public: + SharedVal () { } + explicit SharedVal (T value) : Value (value) { } + virtual ~SharedVal () { } + + operator T () + { + return Get (); + } + + T Decrement () + { + ValMutex.Lock(); + T r = --Value; + ValMutex.Unlock(); + return r; + } + + T Get () + { + ValMutex.Lock(); + T r = Value; + ValMutex.Unlock(); + return r; + } + + T Increment () + { + ValMutex.Lock(); + T r = ++Value; + ValMutex.Unlock(); + return r; + } + + void Set (T value) + { + ValMutex.Lock(); + Value = value; + ValMutex.Unlock(); + } + + protected: + volatile T Value; + Mutex ValMutex; + + private: + SharedVal (const SharedVal &); + SharedVal &operator= (const SharedVal &); + }; +} + +#endif // TC_HEADER_Platform_SharedVal diff --git a/Platform/Stream.h b/Platform/Stream.h new file mode 100644 index 0000000..ecc8bbc --- /dev/null +++ b/Platform/Stream.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Stream +#define TC_HEADER_Platform_Stream + +#include "PlatformBase.h" +#include "Buffer.h" + +namespace TrueCrypt +{ + class Stream + { + public: + virtual ~Stream () { } + virtual uint64 Read (const BufferPtr &buffer) = 0; + virtual void ReadCompleteBuffer (const BufferPtr &buffer) = 0; + virtual void Write (const ConstBufferPtr &data) = 0; + + protected: + Stream () { }; + + private: + Stream (const Stream &); + Stream &operator= (const Stream &); + }; +} + +#endif // TC_HEADER_Platform_Stream diff --git a/Platform/StringConverter.cpp b/Platform/StringConverter.cpp new file mode 100644 index 0000000..6e52ee7 --- /dev/null +++ b/Platform/StringConverter.cpp @@ -0,0 +1,367 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifdef __GNUC__ +# include +#endif +#include +#include +#include "Buffer.h" +#include "Exception.h" +#include "ForEach.h" +#include "StringConverter.h" +#include "SystemException.h" + +namespace TrueCrypt +{ + void StringConverter::Erase (string &str) + { + for (size_t i = 0; i < str.size(); ++i) + { + str[i] = ' '; + } + } + + void StringConverter::Erase (wstring &str) + { + for (size_t i = 0; i < str.size(); ++i) + { + str[i] = ' '; + } + } + + wstring StringConverter::FromNumber (double number) + { + wstringstream s; + s << number; + return s.str(); + } + + wstring StringConverter::FromNumber (int32 number) + { + wstringstream s; + s << number; + return s.str(); + } + + wstring StringConverter::FromNumber (uint32 number) + { + wstringstream s; + s << number; + return s.str(); + } + + wstring StringConverter::FromNumber (int64 number) + { + wstringstream s; + s << number; + return s.str(); + } + + wstring StringConverter::FromNumber (uint64 number) + { + wstringstream s; + s << number; + return s.str(); + } + + string StringConverter::GetTrailingNumber (const string &str) + { + size_t start = str.find_last_not_of ("0123456789"); + if (start == string::npos) + return str; + + string s = str.substr (start + 1); + if (s.empty ()) + throw ParameterIncorrect (SRC_POS); + + return s; + } + + string StringConverter::GetTypeName (const type_info &typeInfo) + { + try + { +#ifdef _MSC_VER + // type_info::name() leaks memory as of MS VC++ 8.0 + string rawName (typeInfo.raw_name()); + + size_t cut1 = (rawName.find (".?A") != string::npos) ? 4 : string::npos; + size_t cut2 = rawName.find ("@"); + size_t cut3 = rawName.find ("@@"); + + if (cut1 == string::npos || cut2 == string::npos || cut3 == string::npos) + return typeInfo.name(); + + return rawName.substr (cut2 + 1, cut3 - cut2 - 1) + "::" + rawName.substr (cut1, cut2 - cut1); + +#elif defined (__GNUC__) + int status; + char *name = abi::__cxa_demangle (typeInfo.name(), nullptr, nullptr, &status); + + if (name) + { + string s (name); + free (name); + return s; + } +#endif + } + catch (...) { } + + return typeInfo.name(); + } + + wstring StringConverter::QuoteSpaces (const wstring &str) + { + if (str.find (L' ') == string::npos) + return str; + + wstring escaped (L"'"); + foreach (wchar_t c, str) + { + if (c == L'\'') + escaped += L'\''; + escaped += c; + } + return escaped + L'\''; + } + + vector StringConverter::Split (const string &str, const string &separators, bool returnEmptyFields) + { + vector elements; + + if (!returnEmptyFields) + { + size_t p = 0; + while ((p = str.find_first_not_of (separators, p)) != string::npos) + { + size_t end = str.find_first_of (separators, p); + if (end == string::npos) + { + elements.push_back (str.substr (p)); + break; + } + + elements.push_back (str.substr (p, end - p)); + p = end; + } + } + else + { + string element; + elements.push_back (element); + foreach (char c, str) + { + if (separators.find (c) != string::npos) + { + element.erase(); + elements.push_back (element); + } + else + { + elements.back() += c; + } + } + } + + return elements; + } + + string StringConverter::StripTrailingNumber (const string &str) + { + size_t start = str.find_last_not_of ("0123456789"); + if (start == string::npos) + return ""; + + return str.substr (0, start + 1); + } + + wstring StringConverter::ToExceptionString (const exception &ex) + { + const SystemException *sysEx = dynamic_cast (&ex); + if (sysEx) + return ToWide (sysEx->what()) + L": " + sysEx->SystemText() + L": " + sysEx->GetSubject(); + + if (ex.what() && !string (ex.what()).empty()) + return ToWide (GetTypeName (typeid (ex)) + ": " + ex.what()); + + return ToWide (GetTypeName (typeid (ex))); + } + + string StringConverter::ToLower (const string &str) + { + string s; + foreach (char c, str) + s += tolower (c, locale()); + return s; + } + + string StringConverter::ToSingle (const wstring &wstr, bool noThrow) + { + string str; + ToSingle (wstr, str, noThrow); + return str; + } + + void StringConverter::ToSingle (const wstring &wstr, string &str, bool noThrow) + { + try + { + mbstate_t mbState; + Memory::Zero (&mbState, sizeof (mbState)); + const wchar_t *src = wstr.c_str(); + + size_t size = wcsrtombs (nullptr, &src, 0, &mbState); + if (size == (size_t) -1) + throw StringConversionFailed (SRC_POS, wstr); + + vector buf (size + 1); + Memory::Zero (&mbState, sizeof (mbState)); + + if ((size = wcsrtombs (&buf[0], &src, buf.size(), &mbState)) == (size_t) -1) + throw StringConversionFailed (SRC_POS, wstr); + + str.clear(); + str.insert (0, &buf.front(), size); + Memory::Erase (&buf.front(), buf.size()); + } + catch (...) + { + if (!noThrow) + throw; + } + } + + uint32 StringConverter::ToUInt32 (const string &str) + { + uint32 n; + stringstream ss (str); + + ss >> n; + if (ss.fail() || n == 0xffffFFFFU) + throw ParameterIncorrect (SRC_POS); + + return n; + } + + uint32 StringConverter::ToUInt32 (const wstring &str) + { + uint32 n; + wstringstream ss (str); + + ss >> n; + if (ss.fail() || n == 0xffffFFFFU) + throw ParameterIncorrect (SRC_POS); + + return n; + } + + uint64 StringConverter::ToUInt64 (const string &str) + { + uint64 n; + stringstream ss (str); + + ss >> n; + if (ss.fail() || n == 0xffffFFFFffffFFFFULL) + throw ParameterIncorrect (SRC_POS); + + return n; + } + + uint64 StringConverter::ToUInt64 (const wstring &str) + { + uint64 n; + wstringstream ss (str); + + ss >> n; + if (ss.fail() || n == 0xffffFFFFffffFFFFULL) + throw ParameterIncorrect (SRC_POS); + + return n; + } + + string StringConverter::ToUpper (const string &str) + { + string s; + foreach (char c, str) + s += toupper (c, locale()); + return s; + } + + wstring StringConverter::ToWide (const string &str, bool noThrow) + { + try + { + mbstate_t mbState; + Memory::Zero (&mbState, sizeof (mbState)); + const char *src = str.c_str(); + + size_t size = mbsrtowcs (nullptr, &src, 0, &mbState); + if (size == (size_t) -1) + throw StringConversionFailed (SRC_POS); + + vector buf (size + 1); + Memory::Zero (&mbState, sizeof (mbState)); + + if ((size = mbsrtowcs (&buf[0], &src, buf.size(), &mbState)) == (size_t) -1) + throw StringConversionFailed (SRC_POS); + + wstring s; + s.insert (s.begin(), buf.begin(), buf.begin() + size); + return s; + } + catch (...) + { + if (noThrow) + return L""; + throw; + } + } + + void StringConverter::ToWideBuffer (const wstring &str, wchar_t *buffer, size_t bufferSize) + { + if (str.length() < 1) + { + buffer[0] = 0; + return; + } + + BufferPtr ( + (byte *) buffer, + bufferSize).CopyFrom ( + ConstBufferPtr ((byte *) (wstring (str).c_str()), + (str.length() + 1) * sizeof (wchar_t) + ) + ); + } + + string StringConverter::Trim (const string &str) + { + size_t start = 0; + size_t end = str.size(); + if (end < 1) + return str; + + foreach (char c, str) + { + if (c > ' ') + break; + ++start; + } + + foreach_reverse (char c, str) + { + if (c > ' ') + break; + --end; + } + + return str.substr (start, end - start); + } +} diff --git a/Platform/StringConverter.h b/Platform/StringConverter.h new file mode 100644 index 0000000..a02c371 --- /dev/null +++ b/Platform/StringConverter.h @@ -0,0 +1,60 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_StringConverter +#define TC_HEADER_Platform_StringConverter + +#include +#include "PlatformBase.h" + +namespace TrueCrypt +{ + class StringConverter + { + public: + static void Erase (string &str); + static void Erase (wstring &str); + static wstring FromNumber (double number); + static wstring FromNumber (int32 number); + static wstring FromNumber (uint32 number); + static wstring FromNumber (int64 number); + static wstring FromNumber (uint64 number); + static string GetTrailingNumber (const string &str); + static string GetTypeName (const type_info &typeInfo); + static wstring QuoteSpaces (const wstring &str); + static vector Split (const string &str, const string &separators = " \t\r\n", bool returnEmptyFields = false); + static string StripTrailingNumber (const string &str); + static wstring ToExceptionString (const exception &ex); + static string ToLower (const string &str); + static uint32 ToUInt32 (const string &str); + static uint32 ToUInt32 (const wstring &str); + static uint64 ToUInt64 (const string &str); + static uint64 ToUInt64 (const wstring &str); + static string ToSingle (double number) { return ToSingle (FromNumber (number)); } + static string ToSingle (int32 number) { return ToSingle (FromNumber (number)); } + static string ToSingle (uint32 number) { return ToSingle (FromNumber (number)); } + static string ToSingle (int64 number) { return ToSingle (FromNumber (number)); } + static string ToSingle (uint64 number) { return ToSingle (FromNumber (number)); } + static string ToSingle (const wstring &wstr, bool noThrow = false); + static void ToSingle (const wstring &wstr, string &str, bool noThrow = false); + static string ToUpper (const string &str); + static wstring ToWide (double number) { return FromNumber (number); } + static wstring ToWide (int32 number) { return FromNumber (number); } + static wstring ToWide (uint32 number) { return FromNumber (number); } + static wstring ToWide (int64 number) { return FromNumber (number); } + static wstring ToWide (uint64 number) { return FromNumber (number); } + static wstring ToWide (const string &str, bool noThrow = false); + static void ToWideBuffer (const wstring &str, wchar_t *buffer, size_t bufferSize); + static string Trim (const string &str); + + private: + StringConverter (); + }; +} + +#endif // TC_HEADER_Platform_StringConverter diff --git a/Platform/SyncEvent.h b/Platform/SyncEvent.h new file mode 100644 index 0000000..8abb1e6 --- /dev/null +++ b/Platform/SyncEvent.h @@ -0,0 +1,47 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_SyncEvent +#define TC_HEADER_Platform_SyncEvent + +#ifdef TC_WINDOWS +# include "System.h" +#else +# include +#endif +#include "PlatformBase.h" +#include "Mutex.h" + +namespace TrueCrypt +{ + class SyncEvent + { + public: + SyncEvent (); + ~SyncEvent (); + + void Signal (); + void Wait (); + + protected: + bool Initialized; +#ifdef TC_WINDOWS + HANDLE SystemSyncEvent; +#else + volatile bool Signaled; + pthread_cond_t SystemSyncEvent; + Mutex EventMutex; +#endif + + private: + SyncEvent (const SyncEvent &); + SyncEvent &operator= (const SyncEvent &); + }; +} + +#endif // TC_HEADER_Platform_SyncEvent diff --git a/Platform/System.h b/Platform/System.h new file mode 100644 index 0000000..a798b3f --- /dev/null +++ b/Platform/System.h @@ -0,0 +1,16 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_System +#define TC_HEADER_Platform_System + +#ifdef TC_WINDOWS +#include "Windows/System.h" +#endif + +#endif // TC_HEADER_Platform_System diff --git a/Platform/SystemException.h b/Platform/SystemException.h new file mode 100644 index 0000000..0f26016 --- /dev/null +++ b/Platform/SystemException.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_SystemException +#define TC_HEADER_Platform_SystemException + +#include "PlatformBase.h" +#include "Exception.h" + +namespace TrueCrypt +{ + class SystemException : public Exception + { + public: + SystemException (); + SystemException (const string &message); + SystemException (const string &message, const string &subject); + SystemException (const string &message, const wstring &subject); + SystemException (const string &message, int64 errorCode) + : Exception (message), ErrorCode (errorCode) { } + virtual ~SystemException () throw () { } + + TC_SERIALIZABLE_EXCEPTION (SystemException); + + int64 GetErrorCode () const { return ErrorCode; } + bool IsError () const; + wstring SystemText () const; + + protected: + int64 ErrorCode; + }; + +#undef TC_EXCEPTION_SET +#define TC_EXCEPTION_SET \ + TC_EXCEPTION_NODECL (SystemException); +} + +#define throw_sys_if(condition) do { if (condition) throw SystemException (SRC_POS); } while (false) +#define throw_sys_sub_if(condition,subject) do { if (condition) throw SystemException (SRC_POS, (subject)); } while (false) + +#endif // TC_HEADER_Platform_SystemException diff --git a/Platform/SystemInfo.h b/Platform/SystemInfo.h new file mode 100644 index 0000000..30ff2b4 --- /dev/null +++ b/Platform/SystemInfo.h @@ -0,0 +1,28 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_SystemInfo +#define TC_HEADER_Platform_SystemInfo + +#include "PlatformBase.h" + +namespace TrueCrypt +{ + class SystemInfo + { + public: + static wstring GetPlatformName (); + static vector GetVersion (); + static bool IsVersionAtLeast (int versionNumber1, int versionNumber2, int versionNumber3 = 0); + + protected: + SystemInfo (); + }; +} + +#endif // TC_HEADER_Platform_SystemInfo diff --git a/Platform/SystemLog.h b/Platform/SystemLog.h new file mode 100644 index 0000000..affea36 --- /dev/null +++ b/Platform/SystemLog.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_SystemLog +#define TC_HEADER_Platform_SystemLog + +#include "Platform/PlatformBase.h" +#include "Platform/StringConverter.h" + +namespace TrueCrypt +{ + class SystemLog + { + public: + static void WriteDebug (const string &debugMessage); + static void WriteError (const string &errorMessage); + + static void WriteException (const exception &ex) + { + WriteError (string ("exception: ") + StringConverter::ToSingle (StringConverter::ToExceptionString (ex))); + } + + protected: + SystemLog (); + }; + +#ifdef DEBUG +# define tracelog_point do { stringstream s; s << (SRC_POS); SystemLog::WriteError (s.str()); } while (false) +# define tracelog_msg(stream_args) do { stringstream s; s << (SRC_POS) << ": " << stream_args; SystemLog::WriteError (s.str()); } while (false) +#else +# define tracelog_point +# define tracelog_msg(stream_args) while (false) { stringstream s; s << stream_args; } +#endif + +} + +#endif // TC_HEADER_Platform_SystemLog diff --git a/Platform/TextReader.cpp b/Platform/TextReader.cpp new file mode 100644 index 0000000..d4be504 --- /dev/null +++ b/Platform/TextReader.cpp @@ -0,0 +1,37 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "TextReader.h" + +namespace TrueCrypt +{ + TextReader::TextReader (const FilePath &path) + { + InputFile.reset (new File); + InputFile->Open (path); + InputStream = shared_ptr (new FileStream (InputFile)); + } + + bool TextReader::ReadLine (string &outputString) + { + outputString.erase(); + + char c; + while (InputStream->Read (BufferPtr ((byte *) &c, sizeof (c))) == sizeof (c)) + { + if (c == '\r') + continue; + + if (c == '\n') + return true; + + outputString += c; + } + return !outputString.empty(); + } +} diff --git a/Platform/TextReader.h b/Platform/TextReader.h new file mode 100644 index 0000000..e4f9cff --- /dev/null +++ b/Platform/TextReader.h @@ -0,0 +1,35 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_TextReader +#define TC_HEADER_Platform_TextReader + +#include "PlatformBase.h" +#include "FileStream.h" +#include "FilesystemPath.h" +#include "SharedPtr.h" +#include "Stream.h" + +namespace TrueCrypt +{ + class TextReader + { + public: + TextReader (const FilePath &path); + TextReader (shared_ptr stream) : InputStream (stream) { } + virtual ~TextReader () { } + + virtual bool ReadLine (string &outputString); + + protected: + shared_ptr InputFile; + shared_ptr InputStream; + }; +} + +#endif // TC_HEADER_Platform_TextReader diff --git a/Platform/Thread.h b/Platform/Thread.h new file mode 100644 index 0000000..7a934b1 --- /dev/null +++ b/Platform/Thread.h @@ -0,0 +1,74 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Thread +#define TC_HEADER_Platform_Thread + +#ifdef TC_WINDOWS +# include "System.h" +# define TC_THREAD_PROC DWORD WINAPI +#else +# include +# define TC_THREAD_PROC void* +#endif +#include "PlatformBase.h" +#include "Functor.h" +#include "SharedPtr.h" +#include "SyncEvent.h" + +namespace TrueCrypt +{ + class Thread + { + public: +#ifdef TC_WINDOWS + typedef HANDLE ThreadSystemHandle; + typedef LPTHREAD_START_ROUTINE ThreadProcPtr; +#else + typedef pthread_t ThreadSystemHandle; + typedef void* (*ThreadProcPtr) (void *); +#endif + Thread () { }; + virtual ~Thread () { }; + + void Join () const; + void Start (ThreadProcPtr threadProc, void *parameter = nullptr); + + void Start (Functor *functor) + { + Start (Thread::FunctorEntry, (void *)functor); + } + + static void Sleep (uint32 milliSeconds); + + protected: + static TC_THREAD_PROC FunctorEntry (void *functorArg) + { + Functor *functor = (Functor *) functorArg; + try + { + (*functor) (); + } + catch (...) { } + + delete functor; + return 0; + } + + static const size_t MinThreadStackSize = 1024 * 1024; + + ThreadSystemHandle SystemHandle; + + private: + Thread (const Thread &); + Thread &operator= (const Thread &); + }; + +} + +#endif // TC_HEADER_Platform_Thread diff --git a/Platform/Time.h b/Platform/Time.h new file mode 100644 index 0000000..470f82b --- /dev/null +++ b/Platform/Time.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Time +#define TC_HEADER_Platform_Time + +#include "PlatformBase.h" + +namespace TrueCrypt +{ + class Time + { + public: + Time () { } + virtual ~Time () { } + + static uint64 GetCurrent (); // Returns time in hundreds of nanoseconds since 1601/01/01 + + private: + Time (const Time &); + Time &operator= (const Time &); + }; +} + +#endif // TC_HEADER_Platform_Time diff --git a/Platform/Unix/Directory.cpp b/Platform/Unix/Directory.cpp new file mode 100644 index 0000000..0a0088a --- /dev/null +++ b/Platform/Unix/Directory.cpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include "System.h" +#include "Platform/Directory.h" +#include "Platform/Finally.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + static Mutex ReadDirMutex; // readdir_r() may be unsafe on some systems + + void Directory::Create (const DirectoryPath &path) + { + string p = path; + throw_sys_sub_if (mkdir (p.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) == -1, p); + } + + DirectoryPath Directory::AppendSeparator (const DirectoryPath &path) + { + wstring p (path); + + if (p.find_last_of (L'/') + 1 != p.size()) + return p + L'/'; + + return p; + } + + FilePathList Directory::GetFilePaths (const DirectoryPath &path, bool regularFilesOnly) + { + DIR *dir = opendir (string (path).c_str()); + throw_sys_sub_if (!dir, wstring (path)); + finally_do_arg (DIR*, dir, { closedir (finally_arg); }); + + ScopeLock lock (ReadDirMutex); + + FilePathList files; + struct dirent *dirEntry; + errno = 0; + while ((dirEntry = readdir (dir)) != nullptr) + { + shared_ptr filePath (new FilePath (string (AppendSeparator (path)) + string (dirEntry->d_name))); + + if (!regularFilesOnly || filePath->IsFile()) + files.push_back (filePath); + + errno = 0; + } + + throw_sys_sub_if (errno != 0, wstring (path)); + return files; + } +} diff --git a/Platform/Unix/File.cpp b/Platform/Unix/File.cpp new file mode 100644 index 0000000..d69cb1d --- /dev/null +++ b/Platform/Unix/File.cpp @@ -0,0 +1,348 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include + +#ifdef TC_LINUX +#include +#endif + +#ifdef TC_BSD +#include +#endif + +#ifdef TC_SOLARIS +#include +#include +#endif + +#include +#include +#include + +#include "Platform/File.h" +#include "Platform/TextReader.h" + +namespace TrueCrypt +{ +#if 0 +# define TC_TRACE_FILE_OPERATIONS + + static void TraceFileOperation (int fileHandle, FilePath filePath, bool write, uint64 length, int64 position = -1) + { + string path = filePath; + if (path.empty() || path.find ("truecrypt_aux_mnt") != string::npos) + return; + + stringstream s; + s << path << ": " << (write ? "W " : "R ") << (position == -1 ? lseek (fileHandle, 0, SEEK_CUR) : position) << " (" << length << ")"; + SystemLog::WriteError (s.str()); + } +#endif + + void File::Close () + { + if_debug (ValidateState()); + + if (!SharedHandle) + { + close (FileHandle); + FileIsOpen = false; + + if ((mFileOpenFlags & File::PreserveTimestamps) && Path.IsFile()) + { + struct utimbuf u; + u.actime = AccTime; + u.modtime = ModTime; + + try + { + throw_sys_sub_if (utime (string (Path).c_str(), &u) == -1, wstring (Path)); + } + catch (...) // Suppress errors to allow using read-only files + { +#ifdef DEBUG + throw; +#endif + } + } + } + } + + void File::Delete () + { + Close(); + Path.Delete(); + } + + + void File::Flush () const + { + if_debug (ValidateState()); + throw_sys_sub_if (fsync (FileHandle) != 0, wstring (Path)); + } + + uint32 File::GetDeviceSectorSize () const + { + if (Path.IsDevice()) + { +#ifdef TC_LINUX + int blockSize; + throw_sys_sub_if (ioctl (FileHandle, BLKSSZGET, &blockSize) == -1, wstring (Path)); + return blockSize; + +#elif defined (TC_MACOSX) + uint32 blockSize; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path)); + return blockSize; + +#elif defined (TC_FREEBSD) + u_int sectorSize; + throw_sys_sub_if (ioctl (FileHandle, DIOCGSECTORSIZE, §orSize) == -1, wstring (Path)); + return (uint32) sectorSize; + +#elif defined (TC_SOLARIS) + struct dk_minfo mediaInfo; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGMEDIAINFO, &mediaInfo) == -1, wstring (Path)); + return mediaInfo.dki_lbsize; + +#else +# error GetDeviceSectorSize() +#endif + } + else + throw ParameterIncorrect (SRC_POS); + } + + uint64 File::GetPartitionDeviceStartOffset () const + { +#ifdef TC_LINUX + + // HDIO_GETGEO ioctl is limited by the size of long + TextReader tr ("/sys/block/" + string (Path.ToHostDriveOfPartition().ToBaseName()) + "/" + string (Path.ToBaseName()) + "/start"); + + string line; + tr.ReadLine (line); + return StringConverter::ToUInt64 (line) * GetDeviceSectorSize(); + +#elif defined (TC_MACOSX) + +#ifndef DKIOCGETBASE +# define DKIOCGETBASE _IOR('d', 73, uint64) +#endif + uint64 offset; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBASE, &offset) == -1, wstring (Path)); + return offset; + +#elif defined (TC_SOLARIS) + + struct extpart_info partInfo; + throw_sys_sub_if (ioctl (FileHandle, DKIOCEXTPARTINFO, &partInfo) == -1, wstring (Path)); + return partInfo.p_start * GetDeviceSectorSize(); + +#else + throw NotImplemented (SRC_POS); +#endif + } + + uint64 File::Length () const + { + if_debug (ValidateState()); + + // BSD does not support seeking to the end of a device +#ifdef TC_BSD + if (Path.IsBlockDevice() || Path.IsCharacterDevice()) + { +# ifdef TC_MACOSX + uint32 blockSize; + uint64 blockCount; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path)); + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKCOUNT, &blockCount) == -1, wstring (Path)); + return blockCount * blockSize; +# else + uint64 mediaSize; + throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path)); + return mediaSize; +# endif + } +#endif + off_t current = lseek (FileHandle, 0, SEEK_CUR); + throw_sys_sub_if (current == -1, wstring (Path)); + SeekEnd (0); + uint64 length = lseek (FileHandle, 0, SEEK_CUR); + SeekAt (current); + return length; + } + + void File::Open (const FilePath &path, FileOpenMode mode, FileShareMode shareMode, FileOpenFlags flags) + { +#ifdef TC_LINUX + int sysFlags = O_LARGEFILE; +#else + int sysFlags = 0; +#endif + + switch (mode) + { + case CreateReadWrite: + sysFlags |= O_CREAT | O_TRUNC | O_RDWR; + break; + + case CreateWrite: + sysFlags |= O_CREAT | O_TRUNC | O_WRONLY; + break; + + case OpenRead: + sysFlags |= O_RDONLY; + break; + + case OpenWrite: + sysFlags |= O_WRONLY; + break; + + case OpenReadWrite: + sysFlags |= O_RDWR; + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + + if ((flags & File::PreserveTimestamps) && path.IsFile()) + { + struct stat statData; + throw_sys_sub_if (stat (string (path).c_str(), &statData) == -1, wstring (path)); + AccTime = statData.st_atime; + ModTime = statData.st_mtime; + } + + FileHandle = open (string (path).c_str(), sysFlags, S_IRUSR | S_IWUSR); + throw_sys_sub_if (FileHandle == -1, wstring (path)); + +#if 0 // File locking is disabled to avoid remote filesystem locking issues + try + { + struct flock fl; + memset (&fl, 0, sizeof (fl)); + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + + switch (shareMode) + { + case ShareNone: + fl.l_type = F_WRLCK; + if (fcntl (FileHandle, F_SETLK, &fl) == -1) + throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path)); + break; + + case ShareRead: + fl.l_type = F_RDLCK; + if (fcntl (FileHandle, F_SETLK, &fl) == -1) + throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path)); + break; + + case ShareReadWrite: + fl.l_type = (mode == OpenRead ? F_RDLCK : F_WRLCK); + if (fcntl (FileHandle, F_GETLK, &fl) != -1 && fl.l_type != F_UNLCK) + { + errno = EAGAIN; + throw SystemException (SRC_POS, wstring (path)); + } + break; + + case ShareReadWriteIgnoreLock: + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + } + catch (...) + { + close (FileHandle); + throw; + } +#endif // 0 + + Path = path; + mFileOpenFlags = flags; + FileIsOpen = true; + } + + uint64 File::Read (const BufferPtr &buffer) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, false, buffer.Size()); +#endif + ssize_t bytesRead = read (FileHandle, buffer, buffer.Size()); + throw_sys_sub_if (bytesRead == -1, wstring (Path)); + + return bytesRead; + } + + uint64 File::ReadAt (const BufferPtr &buffer, uint64 position) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, false, buffer.Size(), position); +#endif + ssize_t bytesRead = pread (FileHandle, buffer, buffer.Size(), position); + throw_sys_sub_if (bytesRead == -1, wstring (Path)); + + return bytesRead; + } + + void File::SeekAt (uint64 position) const + { + if_debug (ValidateState()); + throw_sys_sub_if (lseek (FileHandle, position, SEEK_SET) == -1, wstring (Path)); + } + + void File::SeekEnd (int offset) const + { + if_debug (ValidateState()); + + // BSD does not support seeking to the end of a device +#ifdef TC_BSD + if (Path.IsBlockDevice() || Path.IsCharacterDevice()) + { + SeekAt (Length() + offset); + return; + } +#endif + + throw_sys_sub_if (lseek (FileHandle, offset, SEEK_END) == -1, wstring (Path)); + } + + void File::Write (const ConstBufferPtr &buffer) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, true, buffer.Size()); +#endif + throw_sys_sub_if (write (FileHandle, buffer, buffer.Size()) != (ssize_t) buffer.Size(), wstring (Path)); + } + + void File::WriteAt (const ConstBufferPtr &buffer, uint64 position) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, true, buffer.Size(), position); +#endif + throw_sys_sub_if (pwrite (FileHandle, buffer, buffer.Size(), position) != (ssize_t) buffer.Size(), wstring (Path)); + } +} diff --git a/Platform/Unix/FilesystemPath.cpp b/Platform/Unix/FilesystemPath.cpp new file mode 100644 index 0000000..ef52fe8 --- /dev/null +++ b/Platform/Unix/FilesystemPath.cpp @@ -0,0 +1,96 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/FilesystemPath.h" +#include "Platform/SystemException.h" +#include "Platform/StringConverter.h" +#include +#include + +namespace TrueCrypt +{ + void FilesystemPath::Delete () const + { + throw_sys_sub_if (remove (string (*this).c_str()) == -1, Path); + } + + UserId FilesystemPath::GetOwner () const + { + struct stat statData; + throw_sys_if (stat (StringConverter::ToSingle (Path).c_str(), &statData) == -1); + + UserId owner; + owner.SystemId = statData.st_uid; + return owner; + } + + FilesystemPathType::Enum FilesystemPath::GetType () const + { + // Strip trailing directory separator + wstring path = Path; + size_t pos = path.find_last_not_of (L'/'); + if (path.size() > 2 && pos != path.size() - 1) + path = path.substr (0, pos + 1); + + struct stat statData; + throw_sys_sub_if (stat (StringConverter::ToSingle (path).c_str(), &statData) != 0, Path); + + if (S_ISREG (statData.st_mode)) return FilesystemPathType::File; + if (S_ISDIR (statData.st_mode)) return FilesystemPathType::Directory; + if (S_ISCHR (statData.st_mode)) return FilesystemPathType::CharacterDevice; + if (S_ISBLK (statData.st_mode)) return FilesystemPathType::BlockDevice; + if (S_ISLNK (statData.st_mode)) return FilesystemPathType::SymbolickLink; + + return FilesystemPathType::Unknown; + } + + FilesystemPath FilesystemPath::ToBaseName () const + { + wstring path = Path; + size_t pos = path.find_last_of (L'/'); + + if (pos == string::npos) + return Path; + + return Path.substr (pos + 1); + } + + FilesystemPath FilesystemPath::ToHostDriveOfPartition () const + { + DevicePath path; + +#ifdef TC_LINUX + + path = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path)); + +#elif defined (TC_MACOSX) + + string pathStr = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path)); + path = pathStr.substr (0, pathStr.size() - 1); + +#elif defined (TC_FREEBSD) + + string pathStr = StringConverter::ToSingle (Path); + size_t p = pathStr.rfind ("s"); + if (p == string::npos) + throw PartitionDeviceRequired (SRC_POS); + path = pathStr.substr (0, p); + +#elif defined (TC_SOLARIS) + + path = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path)) + "0"; + +#else + throw NotImplemented (SRC_POS); +#endif + if (!path.IsDevice()) + throw PartitionDeviceRequired (SRC_POS); + + return path; + } +} diff --git a/Platform/Unix/Mutex.cpp b/Platform/Unix/Mutex.cpp new file mode 100644 index 0000000..aae5d78 --- /dev/null +++ b/Platform/Unix/Mutex.cpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "Platform/Mutex.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + Mutex::Mutex () + { + pthread_mutexattr_t attributes; + + int status = pthread_mutexattr_init (&attributes); + if (status != 0) + throw SystemException (SRC_POS, status); + + status = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); + if (status != 0) + throw SystemException (SRC_POS, status); + + status = pthread_mutex_init (&SystemMutex, &attributes); + if (status != 0) + throw SystemException (SRC_POS, status); + + Initialized = true; + } + + Mutex::~Mutex () + { + Initialized = false; +#ifdef DEBUG + int status = +#endif + pthread_mutex_destroy (&SystemMutex); + +#ifdef DEBUG + if (status != 0) + SystemLog::WriteException (SystemException (SRC_POS, status)); +#endif + } + + void Mutex::Lock () + { + assert (Initialized); + int status = pthread_mutex_lock (&SystemMutex); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void Mutex::Unlock () + { + int status = pthread_mutex_unlock (&SystemMutex); + if (status != 0) + throw SystemException (SRC_POS, status); + } +} diff --git a/Platform/Unix/Pipe.cpp b/Platform/Unix/Pipe.cpp new file mode 100644 index 0000000..d346540 --- /dev/null +++ b/Platform/Unix/Pipe.cpp @@ -0,0 +1,65 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "Pipe.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + Pipe::Pipe () + { + int fd[2]; + throw_sys_if (pipe (fd) == -1); + ReadFileDescriptor = fd[0]; + WriteFileDescriptor = fd[1]; + } + + Pipe::~Pipe () + { + try + { + Close(); + } + catch (...) { } + } + + void Pipe::Close () + { + if (ReadFileDescriptor != -1) + close (ReadFileDescriptor); + if (WriteFileDescriptor != -1) + close (WriteFileDescriptor); + } + + int Pipe::GetReadFD () + { + assert (ReadFileDescriptor != -1); + + if (WriteFileDescriptor != -1) + { + close (WriteFileDescriptor); + WriteFileDescriptor = -1; + } + + return ReadFileDescriptor; + } + + int Pipe::GetWriteFD () + { + assert (WriteFileDescriptor != -1); + + if (ReadFileDescriptor != -1) + { + close (ReadFileDescriptor); + ReadFileDescriptor = -1; + } + + return WriteFileDescriptor; + } +} diff --git a/Platform/Unix/Pipe.h b/Platform/Unix/Pipe.h new file mode 100644 index 0000000..9aa5bf9 --- /dev/null +++ b/Platform/Unix/Pipe.h @@ -0,0 +1,38 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_Pipe +#define TC_HEADER_Platform_Unix_Pipe + +#include "Platform/PlatformBase.h" + +namespace TrueCrypt +{ + class Pipe + { + public: + Pipe (); + virtual ~Pipe (); + + void Close (); + int GetReadFD (); + int GetWriteFD (); + int PeekReadFD () const { return ReadFileDescriptor; } + int PeekWriteFD () const { return WriteFileDescriptor; } + + protected: + int ReadFileDescriptor; + int WriteFileDescriptor; + + private: + Pipe (const Pipe &); + Pipe &operator= (const Pipe &); + }; +} + +#endif // TC_HEADER_Platform_Unix_Pipe diff --git a/Platform/Unix/Poller.cpp b/Platform/Unix/Poller.cpp new file mode 100644 index 0000000..3950eab --- /dev/null +++ b/Platform/Unix/Poller.cpp @@ -0,0 +1,57 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include "Poller.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + Poller::Poller (int fileDescriptor1, int fileDescriptor2, int fileDescriptor3, int fileDescriptor4) + { + FileDescriptors.push_back (fileDescriptor1); + + if (fileDescriptor2 != -1) + FileDescriptors.push_back (fileDescriptor2); + + if (fileDescriptor3 != -1) + FileDescriptors.push_back (fileDescriptor3); + + if (fileDescriptor4 != -1) + FileDescriptors.push_back (fileDescriptor4); + } + + list Poller::WaitForData (int timeOut) const + { + vector pfd (FileDescriptors.size()); + for (size_t i = 0; i < FileDescriptors.size(); i++) + { + pfd[i].fd = FileDescriptors[i]; + pfd[i].events = POLLIN; + } + + list descList; + + int pollRes = poll (&pfd[0], pfd.size(), timeOut); + + if (pollRes == 0 && timeOut != -1) + throw TimeOut (SRC_POS); + + if (pollRes > 0) + { + for (size_t i = 0; i < pfd.size(); i++) + { + if (pfd[i].revents & POLLIN) + descList.push_back (pfd[i].fd); + } + } + + return descList; + } +} diff --git a/Platform/Unix/Poller.h b/Platform/Unix/Poller.h new file mode 100644 index 0000000..131e469 --- /dev/null +++ b/Platform/Unix/Poller.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_Poller +#define TC_HEADER_Platform_Unix_Poller + +#include "Platform/PlatformBase.h" + +namespace TrueCrypt +{ + class Poller + { + public: + Poller (int fileDescriptor1, int fileDescriptor2 = -1, int fileDescriptor3 = -1, int fileDescriptor4 = -1); + virtual ~Poller () { } + + list WaitForData (int timeOut = -1) const; + + protected: + vector FileDescriptors; + + private: + Poller (const Poller &); + Poller &operator= (const Poller &); + }; +} + +#endif // TC_HEADER_Platform_Unix_Poller diff --git a/Platform/Unix/Process.cpp b/Platform/Unix/Process.cpp new file mode 100644 index 0000000..d99dff8 --- /dev/null +++ b/Platform/Unix/Process.cpp @@ -0,0 +1,202 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include +#include "Process.h" +#include "Platform/Exception.h" +#include "Platform/FileStream.h" +#include "Platform/ForEach.h" +#include "Platform/MemoryStream.h" +#include "Platform/SystemException.h" +#include "Platform/StringConverter.h" +#include "Platform/Unix/Pipe.h" +#include "Platform/Unix/Poller.h" + +namespace TrueCrypt +{ + string Process::Execute (const string &processName, const list &arguments, int timeOut, ProcessExecFunctor *execFunctor, const Buffer *inputData) + { + char *args[32]; + if (array_capacity (args) <= arguments.size()) + throw ParameterTooLarge (SRC_POS); + +#if 0 + stringstream dbg; + dbg << "exec " << processName; + foreach (const string &at, arguments) + dbg << " " << at; + trace_msg (dbg.str()); +#endif + + Pipe inPipe, outPipe, errPipe, exceptionPipe; + + int forkedPid = fork(); + throw_sys_if (forkedPid == -1); + + if (forkedPid == 0) + { + try + { + try + { + int argIndex = 0; + if (!execFunctor) + args[argIndex++] = const_cast (processName.c_str()); + + foreach (const string &arg, arguments) + { + args[argIndex++] = const_cast (arg.c_str()); + } + args[argIndex] = nullptr; + + if (inputData) + { + throw_sys_if (dup2 (inPipe.GetReadFD(), STDIN_FILENO) == -1); + } + else + { + inPipe.Close(); + int nullDev = open ("/dev/null", 0); + throw_sys_sub_if (nullDev == -1, "/dev/null"); + throw_sys_if (dup2 (nullDev, STDIN_FILENO) == -1); + } + + throw_sys_if (dup2 (outPipe.GetWriteFD(), STDOUT_FILENO) == -1); + throw_sys_if (dup2 (errPipe.GetWriteFD(), STDERR_FILENO) == -1); + exceptionPipe.GetWriteFD(); + + if (execFunctor) + { + (*execFunctor)(argIndex, args); + } + else + { + execvp (args[0], args); + throw SystemException (SRC_POS, args[0]); + } + } + catch (Exception &) + { + throw; + } + catch (exception &e) + { + throw ExternalException (SRC_POS, StringConverter::ToExceptionString (e)); + } + catch (...) + { + throw UnknownException (SRC_POS); + } + } + catch (Exception &e) + { + try + { + shared_ptr outputStream (new FileStream (exceptionPipe.GetWriteFD())); + e.Serialize (outputStream); + } + catch (...) { } + } + + _exit (1); + } + + throw_sys_if (fcntl (outPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + throw_sys_if (fcntl (errPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + throw_sys_if (fcntl (exceptionPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + + vector buffer (4096), stdOutput (4096), errOutput (4096), exOutput (4096); + buffer.clear (); + stdOutput.clear (); + errOutput.clear (); + exOutput.clear (); + + Poller poller (outPipe.GetReadFD(), errPipe.GetReadFD(), exceptionPipe.GetReadFD()); + int status, waitRes; + + if (inputData) + throw_sys_if (write (inPipe.GetWriteFD(), inputData->Ptr(), inputData->Size()) == -1 && errno != EPIPE); + + inPipe.Close(); + + int timeTaken = 0; + do + { + const int pollTimeout = 200; + try + { + ssize_t bytesRead = 0; + foreach (int fd, poller.WaitForData (pollTimeout)) + { + bytesRead = read (fd, &buffer[0], buffer.capacity()); + if (bytesRead > 0) + { + if (fd == outPipe.GetReadFD()) + stdOutput.insert (stdOutput.end(), buffer.begin(), buffer.begin() + bytesRead); + else if (fd == errPipe.GetReadFD()) + errOutput.insert (errOutput.end(), buffer.begin(), buffer.begin() + bytesRead); + else if (fd == exceptionPipe.GetReadFD()) + exOutput.insert (exOutput.end(), buffer.begin(), buffer.begin() + bytesRead); + } + } + + if (bytesRead == 0) + { + waitRes = waitpid (forkedPid, &status, 0); + break; + } + } + catch (TimeOut&) + { + timeTaken += pollTimeout; + if (timeOut >= 0 && timeTaken >= timeOut) + throw; + } + } while ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0); + throw_sys_if (waitRes == -1); + + if (!exOutput.empty()) + { + auto_ptr deserializedObject; + Exception *deserializedException = nullptr; + + try + { + shared_ptr stream (new MemoryStream (ConstBufferPtr ((byte *) &exOutput[0], exOutput.size()))); + deserializedObject.reset (Serializable::DeserializeNew (stream)); + deserializedException = dynamic_cast (deserializedObject.get()); + } + catch (...) { } + + if (deserializedException) + deserializedException->Throw(); + } + + int exitCode = (WIFEXITED (status) ? WEXITSTATUS (status) : 1); + if (exitCode != 0) + { + string strErrOutput; + + if (!errOutput.empty()) + strErrOutput.insert (strErrOutput.begin(), errOutput.begin(), errOutput.end()); + + throw ExecutedProcessFailed (SRC_POS, processName, exitCode, strErrOutput); + } + + string strOutput; + + if (!stdOutput.empty()) + strOutput.insert (strOutput.begin(), stdOutput.begin(), stdOutput.end()); + + return strOutput; + } +} diff --git a/Platform/Unix/Process.h b/Platform/Unix/Process.h new file mode 100644 index 0000000..dd878dd --- /dev/null +++ b/Platform/Unix/Process.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_Process +#define TC_HEADER_Platform_Unix_Process + +#include "Platform/PlatformBase.h" +#include "Platform/Buffer.h" +#include "Platform/Functor.h" + +namespace TrueCrypt +{ + struct ProcessExecFunctor + { + virtual ~ProcessExecFunctor () { } + virtual void operator() (int argc, char *argv[]) = 0; + }; + + class Process + { + public: + Process (); + virtual ~Process (); + + static string Execute (const string &processName, const list &arguments, int timeOut = -1, ProcessExecFunctor *execFunctor = nullptr, const Buffer *inputData = nullptr); + + protected: + + private: + Process (const Process &); + Process &operator= (const Process &); + }; +} + +#endif // TC_HEADER_Platform_Unix_Process diff --git a/Platform/Unix/SyncEvent.cpp b/Platform/Unix/SyncEvent.cpp new file mode 100644 index 0000000..fbf8300 --- /dev/null +++ b/Platform/Unix/SyncEvent.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/Exception.h" +#include "Platform/SyncEvent.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + SyncEvent::SyncEvent () + { + int status = pthread_cond_init (&SystemSyncEvent, nullptr); + if (status != 0) + throw SystemException (SRC_POS, status); + + Signaled = false; + Initialized = true; + } + + SyncEvent::~SyncEvent () + { +#ifdef DEBUG + int status = +#endif + pthread_cond_destroy (&SystemSyncEvent); + +#ifdef DEBUG + if (status != 0) + SystemLog::WriteException (SystemException (SRC_POS, status)); +#endif + + Initialized = false; + } + + void SyncEvent::Signal () + { + assert (Initialized); + + ScopeLock lock (EventMutex); + + Signaled = true; + + int status = pthread_cond_signal (&SystemSyncEvent); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void SyncEvent::Wait () + { + assert (Initialized); + + ScopeLock lock (EventMutex); + + while (!Signaled) + { + int status = pthread_cond_wait (&SystemSyncEvent, EventMutex.GetSystemHandle()); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + Signaled = false; + } +} diff --git a/Platform/Unix/System.h b/Platform/Unix/System.h new file mode 100644 index 0000000..63d565b --- /dev/null +++ b/Platform/Unix/System.h @@ -0,0 +1,12 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_System +#define TC_HEADER_Platform_Unix_System + +#endif // TC_HEADER_Platform_Unix_System diff --git a/Platform/Unix/SystemException.cpp b/Platform/Unix/SystemException.cpp new file mode 100644 index 0000000..b29c9b5 --- /dev/null +++ b/Platform/Unix/SystemException.cpp @@ -0,0 +1,66 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include "Platform/SerializerFactory.h" +#include "Platform/SystemException.h" +#include "Platform/StringConverter.h" + +namespace TrueCrypt +{ + SystemException::SystemException () + : ErrorCode (errno) + { + } + + SystemException::SystemException (const string &message) + : Exception (message), ErrorCode (errno) + { + } + + SystemException::SystemException (const string &message, const string &subject) + : Exception (message, StringConverter::ToWide (subject)), ErrorCode (errno) + { + } + + SystemException::SystemException (const string &message, const wstring &subject) + : Exception (message, subject), ErrorCode (errno) + { + } + + void SystemException::Deserialize (shared_ptr stream) + { + Exception::Deserialize (stream); + Serializer sr (stream); + sr.Deserialize ("ErrorCode", ErrorCode); + } + + bool SystemException::IsError () const + { + return ErrorCode != 0; + } + + void SystemException::Serialize (shared_ptr stream) const + { + Exception::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("ErrorCode", ErrorCode); + } + + wstring SystemException::SystemText () const + { + return StringConverter::ToWide (strerror ((int) ErrorCode)); + } + +#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +#undef TC_EXCEPTION_NODECL +#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SystemException); +} diff --git a/Platform/Unix/SystemInfo.cpp b/Platform/Unix/SystemInfo.cpp new file mode 100644 index 0000000..d0ea6e6 --- /dev/null +++ b/Platform/Unix/SystemInfo.cpp @@ -0,0 +1,69 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/SystemException.h" +#include "Platform/SystemInfo.h" +#include + +namespace TrueCrypt +{ + wstring SystemInfo::GetPlatformName () + { +#ifdef TC_LINUX + return L"Linux"; +#elif defined (TC_MACOSX) + return L"Mac OS X"; +#elif defined (TC_FREEBSD) + return L"FreeBSD"; +#elif defined (TC_SOLARIS) + return L"Solaris"; +#else +# error GetPlatformName() undefined +#endif + + } + + vector SystemInfo::GetVersion () + { + struct utsname unameData; + throw_sys_if (uname (&unameData) == -1); + + vector versionStrings = StringConverter::Split (unameData.release, "."); + vector version; + + for (size_t i = 0; i < versionStrings.size(); ++i) + { + string s = versionStrings[i]; + + size_t p = s.find_first_not_of ("0123456789"); + if (p != string::npos) + s = s.substr (0, p); + + if (s.empty()) + break; + + version.push_back (StringConverter::ToUInt32 (s)); + } + + return version; + } + + bool SystemInfo::IsVersionAtLeast (int versionNumber1, int versionNumber2, int versionNumber3) + { + vector osVersionNumbers = GetVersion(); + + if (osVersionNumbers.size() < 2) + throw ParameterIncorrect (SRC_POS); + + if (osVersionNumbers.size() < 3) + osVersionNumbers[2] = 0; + + return (osVersionNumbers[0] * 10000000 + osVersionNumbers[1] * 10000 + osVersionNumbers[2]) >= + (versionNumber1 * 10000000 + versionNumber2 * 10000 + versionNumber3); + } +} diff --git a/Platform/Unix/SystemLog.cpp b/Platform/Unix/SystemLog.cpp new file mode 100644 index 0000000..eea94e0 --- /dev/null +++ b/Platform/Unix/SystemLog.cpp @@ -0,0 +1,27 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "Platform/SystemLog.h" + +namespace TrueCrypt +{ + void SystemLog::WriteDebug (const string &debugMessage) + { + openlog ("truecrypt", LOG_PID, LOG_USER); + syslog (LOG_DEBUG, "%s", debugMessage.c_str()); + closelog(); + } + + void SystemLog::WriteError (const string &errorMessage) + { + openlog ("truecrypt", LOG_PID, LOG_USER); + syslog (LOG_ERR, "%s", errorMessage.c_str()); + closelog(); + } +} diff --git a/Platform/Unix/Thread.cpp b/Platform/Unix/Thread.cpp new file mode 100644 index 0000000..7afe683 --- /dev/null +++ b/Platform/Unix/Thread.cpp @@ -0,0 +1,54 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include "Platform/SystemException.h" +#include "Platform/Thread.h" +#include "Platform/SystemLog.h" + +namespace TrueCrypt +{ + void Thread::Join () const + { + int status = pthread_join (SystemHandle, nullptr); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void Thread::Start (ThreadProcPtr threadProc, void *parameter) + { + pthread_attr_t attr; + size_t stackSize = 0; + int status; + + status = pthread_attr_init (&attr); + if (status != 0) + throw SystemException (SRC_POS, status); + + status = pthread_attr_getstacksize (&attr, &stackSize); + if (status != 0) + throw SystemException (SRC_POS, status); + + if (stackSize < MinThreadStackSize) + { + status = pthread_attr_setstacksize (&attr, MinThreadStackSize); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + status = pthread_create (&SystemHandle, nullptr, threadProc, parameter); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void Thread::Sleep (uint32 milliSeconds) + { + ::usleep (milliSeconds * 1000); + } +} diff --git a/Platform/Unix/Time.cpp b/Platform/Unix/Time.cpp new file mode 100644 index 0000000..01313d5 --- /dev/null +++ b/Platform/Unix/Time.cpp @@ -0,0 +1,23 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/Time.h" +#include +#include + +namespace TrueCrypt +{ + uint64 Time::GetCurrent () + { + struct timeval tv; + gettimeofday (&tv, NULL); + + // Unix time => Windows file time + return ((uint64) tv.tv_sec + 134774LL * 24 * 3600) * 1000LL * 1000 * 10; + } +} diff --git a/Platform/User.h b/Platform/User.h new file mode 100644 index 0000000..8215b80 --- /dev/null +++ b/Platform/User.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_User +#define TC_HEADER_Platform_User + +#include "PlatformBase.h" + +#ifdef TC_UNIX +#include +#include +#endif + +namespace TrueCrypt +{ + struct UserId + { + UserId () { } +#ifdef TC_UNIX + UserId (uid_t systemId) : SystemId (systemId) { } + + uid_t SystemId; +#endif + }; +} + +#endif // TC_HEADER_Platform_User -- cgit