commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
173
include/platform/filesystem/io_crypto.cpp
Normal file
173
include/platform/filesystem/io_crypto.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "filesystem/io_crypto.h"
|
||||
|
||||
using namespace GS::IO;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint Crypto::GetCaps() const
|
||||
{ return wrapped_io->GetCaps(); }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Crypto::Encrypt(GS::Array <char> &data)
|
||||
{
|
||||
size_t len = key.Len();
|
||||
for (size_t n = 0; n < data.GetSize(); ++n)
|
||||
data[(int)n] = data[(int)n] ^ key[(int)(n % len)];
|
||||
}
|
||||
void Crypto::Decrypt(GS::Array <char> &data)
|
||||
{
|
||||
size_t len = key.Len();
|
||||
for (size_t n = 0; n < data.GetSize(); ++n)
|
||||
data[(int)n] = data[(int)n] ^ key[(int)(n % len)];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Handle *Crypto::Open(const char *path, Mode mode)
|
||||
{
|
||||
/*
|
||||
When opening a file in read mode, the wrapped io file is decrypted and
|
||||
stored in the cached io file system for further access.
|
||||
When opening a file in write mode, the file is first created in clear
|
||||
on the cached io then encrypted and committed to the wrapped io.
|
||||
*/
|
||||
Handle *h = NULL;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ModeRead:
|
||||
{
|
||||
// Load wrapped IO file.
|
||||
AutoPtr <Handle> _h(wrapped_io->Open(path, mode));
|
||||
if (_h.IsNull())
|
||||
break;
|
||||
|
||||
size_t size = _h->GetSize();
|
||||
Array <char> data(size);
|
||||
if (data.IsNull())
|
||||
break;
|
||||
if (_h->Read(data.c_ptr(), size) != size)
|
||||
break;
|
||||
|
||||
// Decrypt buffer.
|
||||
Decrypt(data);
|
||||
|
||||
// Write decrypted content to cache IO.
|
||||
if ((h = cache_io->Open(path, ModeWrite)) != NULL)
|
||||
h->Write(data.c_ptr(), size);
|
||||
_safe_delete(h);
|
||||
|
||||
h = cache_io->Open(path, mode);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModeWrite:
|
||||
h = cache_io->Open(path, mode);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return h ? new CryptoHandle(this, h, path, mode) : NULL;
|
||||
}
|
||||
void Crypto::Close(Handle *_h)
|
||||
{
|
||||
if (CryptoHandle *h = (CryptoHandle *)_h)
|
||||
{
|
||||
h->cached_h = NULL;
|
||||
|
||||
switch (h->io_mode)
|
||||
{
|
||||
case ModeRead:
|
||||
cache_io->Delete(h->path);
|
||||
break;
|
||||
|
||||
case ModeWrite:
|
||||
{
|
||||
// Retrieve the whole cached file content and drop it from the cache IO.
|
||||
h->cached_h = cache_io->Open(h->path);
|
||||
|
||||
size_t size = h->cached_h->GetSize();
|
||||
Array <char> data(size);
|
||||
|
||||
if (data.IsValid())
|
||||
h->cached_h->Read(data.c_ptr(), size);
|
||||
|
||||
h->cached_h = NULL;
|
||||
cache_io->Delete(h->path);
|
||||
|
||||
// Encrypt buffer.
|
||||
Encrypt(data);
|
||||
|
||||
// Commit file to the wrapped IO.
|
||||
AutoPtr <Handle> _h(wrapped_io->Open(h->path, ModeWrite));
|
||||
if (_h.IsValid())
|
||||
_h->Write(data.c_ptr(), size);
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Crypto::Delete(const char *path)
|
||||
{ return wrapped_io->Delete(path); }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
size_t Crypto::Tell(Handle *_h)
|
||||
{
|
||||
if (CryptoHandle *h = (CryptoHandle *)_h)
|
||||
return h->cached_h->Tell();
|
||||
return (size_t)-1;
|
||||
}
|
||||
size_t Crypto::Seek(Handle *_h, ptrdiff_t offset, SeekRef seek)
|
||||
{
|
||||
if (CryptoHandle *h = (CryptoHandle *)_h)
|
||||
return h->cached_h->Seek(offset, seek);
|
||||
return (size_t)-1;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
size_t Crypto::Read(Handle *_h, void *p, size_t s)
|
||||
{
|
||||
if (CryptoHandle *h = (CryptoHandle *)_h)
|
||||
return h->cached_h->Read(p, s);
|
||||
return 0;
|
||||
}
|
||||
size_t Crypto::Write(Handle *_h, const void *p, size_t s)
|
||||
{
|
||||
if (CryptoHandle *h = (CryptoHandle *)_h)
|
||||
return h->cached_h->Write(p, s);
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Crypto::MkDir(const char *path)
|
||||
{ return wrapped_io->MkDir(path); }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Crypto::Crypto(Base *_io, const char *_key) : wrapped_io(_io)
|
||||
{
|
||||
cache_io = new Memory;
|
||||
key = _key;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
CryptoHandle::CryptoHandle(Base *io, Handle *h, const char *_path, Mode mode) : Handle(io), cached_h(h), path(_path), io_mode(mode)
|
||||
{}
|
||||
CryptoHandle::~CryptoHandle()
|
||||
{ GetIOSystem()->Close(this); }
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user