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