From c606f0866c3a2a5db3ef9bc41738ef33eb9612a9 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 22 Jun 2013 16:16:13 +0200 Subject: Add original TrueCrypt 7.1a sources --- src/Platform/Buffer.cpp | 142 ++++++++++++++ src/Platform/Buffer.h | 115 ++++++++++++ src/Platform/Directory.h | 29 +++ src/Platform/Event.cpp | 47 +++++ src/Platform/Event.h | 86 +++++++++ src/Platform/Exception.cpp | 52 ++++++ src/Platform/Exception.h | 110 +++++++++++ src/Platform/File.h | 110 +++++++++++ src/Platform/FileCommon.cpp | 87 +++++++++ src/Platform/FileStream.h | 58 ++++++ src/Platform/FilesystemPath.h | 73 ++++++++ src/Platform/Finally.h | 46 +++++ src/Platform/ForEach.h | 118 ++++++++++++ src/Platform/Functor.h | 29 +++ src/Platform/Memory.cpp | 58 ++++++ src/Platform/Memory.h | 174 ++++++++++++++++++ src/Platform/MemoryStream.cpp | 47 +++++ src/Platform/MemoryStream.h | 36 ++++ src/Platform/Mutex.h | 61 ++++++ src/Platform/Platform.h | 28 +++ src/Platform/Platform.make | 35 ++++ src/Platform/PlatformBase.h | 134 ++++++++++++++ src/Platform/PlatformTest.cpp | 350 +++++++++++++++++++++++++++++++++++ src/Platform/PlatformTest.h | 43 +++++ src/Platform/Serializable.cpp | 39 ++++ src/Platform/Serializable.h | 82 +++++++++ src/Platform/Serializer.cpp | 299 ++++++++++++++++++++++++++++++ src/Platform/Serializer.h | 74 ++++++++ src/Platform/SerializerFactory.cpp | 54 ++++++ src/Platform/SerializerFactory.h | 93 ++++++++++ src/Platform/SharedPtr.h | 162 ++++++++++++++++ src/Platform/SharedVal.h | 71 +++++++ src/Platform/Stream.h | 34 ++++ src/Platform/StringConverter.cpp | 367 +++++++++++++++++++++++++++++++++++++ src/Platform/StringConverter.h | 60 ++++++ src/Platform/SyncEvent.h | 47 +++++ src/Platform/System.h | 16 ++ src/Platform/SystemException.h | 46 +++++ src/Platform/SystemInfo.h | 28 +++ src/Platform/SystemLog.h | 42 +++++ src/Platform/TextReader.cpp | 37 ++++ src/Platform/TextReader.h | 35 ++++ src/Platform/Thread.h | 74 ++++++++ src/Platform/Time.h | 30 +++ src/Platform/User.h | 32 ++++ 45 files changed, 3790 insertions(+) create mode 100644 src/Platform/Buffer.cpp create mode 100644 src/Platform/Buffer.h create mode 100644 src/Platform/Directory.h create mode 100644 src/Platform/Event.cpp create mode 100644 src/Platform/Event.h create mode 100644 src/Platform/Exception.cpp create mode 100644 src/Platform/Exception.h create mode 100644 src/Platform/File.h create mode 100644 src/Platform/FileCommon.cpp create mode 100644 src/Platform/FileStream.h create mode 100644 src/Platform/FilesystemPath.h create mode 100644 src/Platform/Finally.h create mode 100644 src/Platform/ForEach.h create mode 100644 src/Platform/Functor.h create mode 100644 src/Platform/Memory.cpp create mode 100644 src/Platform/Memory.h create mode 100644 src/Platform/MemoryStream.cpp create mode 100644 src/Platform/MemoryStream.h create mode 100644 src/Platform/Mutex.h create mode 100644 src/Platform/Platform.h create mode 100644 src/Platform/Platform.make create mode 100644 src/Platform/PlatformBase.h create mode 100644 src/Platform/PlatformTest.cpp create mode 100644 src/Platform/PlatformTest.h create mode 100644 src/Platform/Serializable.cpp create mode 100644 src/Platform/Serializable.h create mode 100644 src/Platform/Serializer.cpp create mode 100644 src/Platform/Serializer.h create mode 100644 src/Platform/SerializerFactory.cpp create mode 100644 src/Platform/SerializerFactory.h create mode 100644 src/Platform/SharedPtr.h create mode 100644 src/Platform/SharedVal.h create mode 100644 src/Platform/Stream.h create mode 100644 src/Platform/StringConverter.cpp create mode 100644 src/Platform/StringConverter.h create mode 100644 src/Platform/SyncEvent.h create mode 100644 src/Platform/System.h create mode 100644 src/Platform/SystemException.h create mode 100644 src/Platform/SystemInfo.h create mode 100644 src/Platform/SystemLog.h create mode 100644 src/Platform/TextReader.cpp create mode 100644 src/Platform/TextReader.h create mode 100644 src/Platform/Thread.h create mode 100644 src/Platform/Time.h create mode 100644 src/Platform/User.h (limited to 'src/Platform') diff --git a/src/Platform/Buffer.cpp b/src/Platform/Buffer.cpp new file mode 100644 index 00000000..17dbb7ac --- /dev/null +++ b/src/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/src/Platform/Buffer.h b/src/Platform/Buffer.h new file mode 100644 index 00000000..d4972015 --- /dev/null +++ b/src/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/src/Platform/Directory.h b/src/Platform/Directory.h new file mode 100644 index 00000000..b2eb8027 --- /dev/null +++ b/src/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/src/Platform/Event.cpp b/src/Platform/Event.cpp new file mode 100644 index 00000000..662ca478 --- /dev/null +++ b/src/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/src/Platform/Event.h b/src/Platform/Event.h new file mode 100644 index 00000000..de85a4bc --- /dev/null +++ b/src/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/src/Platform/Exception.cpp b/src/Platform/Exception.cpp new file mode 100644 index 00000000..13b09ac9 --- /dev/null +++ b/src/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/src/Platform/Exception.h b/src/Platform/Exception.h new file mode 100644 index 00000000..8e52b454 --- /dev/null +++ b/src/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/src/Platform/File.h b/src/Platform/File.h new file mode 100644 index 00000000..ef9a5c87 --- /dev/null +++ b/src/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/src/Platform/FileCommon.cpp b/src/Platform/FileCommon.cpp new file mode 100644 index 00000000..d76e5c19 --- /dev/null +++ b/src/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/src/Platform/FileStream.h b/src/Platform/FileStream.h new file mode 100644 index 00000000..1fe6b2ff --- /dev/null +++ b/src/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/src/Platform/FilesystemPath.h b/src/Platform/FilesystemPath.h new file mode 100644 index 00000000..2c85d2ce --- /dev/null +++ b/src/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/src/Platform/Finally.h b/src/Platform/Finally.h new file mode 100644 index 00000000..b8c692b1 --- /dev/null +++ b/src/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/src/Platform/ForEach.h b/src/Platform/ForEach.h new file mode 100644 index 00000000..786ff56b --- /dev/null +++ b/src/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/src/Platform/Functor.h b/src/Platform/Functor.h new file mode 100644 index 00000000..6840b3a1 --- /dev/null +++ b/src/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/src/Platform/Memory.cpp b/src/Platform/Memory.cpp new file mode 100644 index 00000000..3a032467 --- /dev/null +++ b/src/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/src/Platform/Memory.h b/src/Platform/Memory.h new file mode 100644 index 00000000..3a17ba7b --- /dev/null +++ b/src/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/src/Platform/MemoryStream.cpp b/src/Platform/MemoryStream.cpp new file mode 100644 index 00000000..42d38427 --- /dev/null +++ b/src/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/src/Platform/MemoryStream.h b/src/Platform/MemoryStream.h new file mode 100644 index 00000000..30e26400 --- /dev/null +++ b/src/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/src/Platform/Mutex.h b/src/Platform/Mutex.h new file mode 100644 index 00000000..bdeef260 --- /dev/null +++ b/src/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/src/Platform/Platform.h b/src/Platform/Platform.h new file mode 100644 index 00000000..eb6c2076 --- /dev/null +++ b/src/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/src/Platform/Platform.make b/src/Platform/Platform.make new file mode 100644 index 00000000..de44a037 --- /dev/null +++ b/src/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/src/Platform/PlatformBase.h b/src/Platform/PlatformBase.h new file mode 100644 index 00000000..c63f975e --- /dev/null +++ b/src/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/src/Platform/PlatformTest.cpp b/src/Platform/PlatformTest.cpp new file mode 100644 index 00000000..26d07495 --- /dev/null +++ b/src/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/src/Platform/PlatformTest.h b/src/Platform/PlatformTest.h new file mode 100644 index 00000000..9ca842e5 --- /dev/null +++ b/src/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/src/Platform/Serializable.cpp b/src/Platform/Serializable.cpp new file mode 100644 index 00000000..8e3ef582 --- /dev/null +++ b/src/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/src/Platform/Serializable.h b/src/Platform/Serializable.h new file mode 100644 index 00000000..50787547 --- /dev/null +++ b/src/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/src/Platform/Serializer.cpp b/src/Platform/Serializer.cpp new file mode 100644 index 00000000..cd41b3c1 --- /dev/null +++ b/src/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/src/Platform/Serializer.h b/src/Platform/Serializer.h new file mode 100644 index 00000000..71521341 --- /dev/null +++ b/src/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/src/Platform/SerializerFactory.cpp b/src/Platform/SerializerFactory.cpp new file mode 100644 index 00000000..1aae92d5 --- /dev/null +++ b/src/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/src/Platform/SerializerFactory.h b/src/Platform/SerializerFactory.h new file mode 100644 index 00000000..bad68d34 --- /dev/null +++ b/src/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/src/Platform/SharedPtr.h b/src/Platform/SharedPtr.h new file mode 100644 index 00000000..3221265d --- /dev/null +++ b/src/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/src/Platform/SharedVal.h b/src/Platform/SharedVal.h new file mode 100644 index 00000000..64298f0d --- /dev/null +++ b/src/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/src/Platform/Stream.h b/src/Platform/Stream.h new file mode 100644 index 00000000..338d0f51 --- /dev/null +++ b/src/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/src/Platform/StringConverter.cpp b/src/Platform/StringConverter.cpp new file mode 100644 index 00000000..164a218e --- /dev/null +++ b/src/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/src/Platform/StringConverter.h b/src/Platform/StringConverter.h new file mode 100644 index 00000000..51047784 --- /dev/null +++ b/src/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/src/Platform/SyncEvent.h b/src/Platform/SyncEvent.h new file mode 100644 index 00000000..30dcd419 --- /dev/null +++ b/src/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/src/Platform/System.h b/src/Platform/System.h new file mode 100644 index 00000000..cb21e2bd --- /dev/null +++ b/src/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/src/Platform/SystemException.h b/src/Platform/SystemException.h new file mode 100644 index 00000000..630703b1 --- /dev/null +++ b/src/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/src/Platform/SystemInfo.h b/src/Platform/SystemInfo.h new file mode 100644 index 00000000..e70137a9 --- /dev/null +++ b/src/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/src/Platform/SystemLog.h b/src/Platform/SystemLog.h new file mode 100644 index 00000000..06d45367 --- /dev/null +++ b/src/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/src/Platform/TextReader.cpp b/src/Platform/TextReader.cpp new file mode 100644 index 00000000..cc55db1b --- /dev/null +++ b/src/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/src/Platform/TextReader.h b/src/Platform/TextReader.h new file mode 100644 index 00000000..a537907d --- /dev/null +++ b/src/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/src/Platform/Thread.h b/src/Platform/Thread.h new file mode 100644 index 00000000..122d9344 --- /dev/null +++ b/src/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/src/Platform/Time.h b/src/Platform/Time.h new file mode 100644 index 00000000..2a17f9ea --- /dev/null +++ b/src/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/src/Platform/User.h b/src/Platform/User.h new file mode 100644 index 00000000..d3aa9766 --- /dev/null +++ b/src/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 v1.2.3