pril 1 (663671), страница 4
Текст из файла (страница 4)
if (fileMode == DISABLE_ARC)
compressionLevel = 1; // min compression level
else
compressionLevel = 0; // default
unsigned long sizeOut;
BYTE *bufOut;
EIAB_ErrorNum err;
if (!Pack(compressionLevel, buffer->GetSize(),
static_cast(buffer->GetBuf()), &sizeOut, &bufOut, &err))
ArcExcept(err);
_ASSERT(sizeOut && bufOut);
pure_com_mem packet(bufOut);
buffer->Clear();
buffer->Write(&sizeOut, sizeof(unsigned));
buffer->Write(bufOut, sizeOut);
unsigned needAdd = static_cast(
(ROUND_SATA_SIZE - (sizeOut % ROUND_SATA_SIZE)) % ROUND_SATA_SIZE);
_ASSERT(needAdd != ROUND_SATA_SIZE);
for (unsigned i = 0; i < needAdd; i++)
{
int rnd = CoolRand();
Write(&rnd, 1);
}
_ASSERT((buffer->GetSize() - sizeof(unsigned)) % ROUND_SATA_SIZE == 0);
CryptData(*(static_cast(buffer->GetBuf()) + sizeof(unsigned)),
buffer->GetSize() - sizeof(unsigned),
*static_cast(uptFileNameForWrite));
}
//-----------------------------------------------------------------------------
void ObjectFile::DecryptBuf()
{
WriteToLog(_T("ObjectFile::DecryptBuf()"));
if (buffer->GetSize() < sizeof(TitleArcData) + sizeof(unsigned))
CkgExcept(ERROR_FILE_FORMAT);
unsigned packSize = *(static_cast(buffer->GetBuf()));
DecryptData(*(static_cast(buffer->GetBuf()) + sizeof(unsigned)),
buffer->GetSize() - sizeof(unsigned),
*static_cast(uptFileNameForRead));
unsigned long sizeOut;
BYTE *bufOut;
EIAB_ErrorNum err;
if(!Unpacking(packSize,
static_cast(buffer->GetBuf()) + sizeof(unsigned),
&sizeOut, &bufOut, &err))
ArcExcept(err);
_ASSERT(sizeOut && bufOut);
pure_com_mem unpacket(bufOut);
buffer->Clear();
buffer->Write(bufOut, sizeOut);
}
//-----------------------------------------------------------------------------
ObjectFile &ObjectFile::Create(BSTR name, BSTR uptFileNameForWrite,
CreateMode mode)
{
WriteToLog(_T("ObjectFile::Create()"));
USES_CONVERSION;
if ((mode != DEFAULT && mode != DISABLE_ARC) || !uptFileNameForWrite ||
!name)
CkgExcept(ERROR_INVALID_ARGUMENT);
CkgString fileName(W2T(name));
if (fileName.IsEmpty())
CkgExcept(ERROR_OPEN_FILE);
if (!TestFilePresent(uptFileNameForWrite))
CkgExcept(_T("UPT-файл для шифрования файла не найден."));
cpp_ptr obj(new ObjectFile);
TestPtr(obj);
obj->fileMode = mode;
obj->mode = EF_READWRITE;
obj->uptFileNameForWrite = W2T(uptFileNameForWrite);
obj->buffer = &CkgBuffer::Create(4096);
obj->f = _tfopen(fileName, _T("wb"));
if (!obj->f)
CkgExcept(ERROR_OPEN_FILE);
obj->isOpened = true;
return *obj.Detach();
}
//-----------------------------------------------------------------------------
ObjectFile &ObjectFile::Open(BSTR name, BSTR uptFileNameForWrite,
BSTR uptFileNameForRead)
{
WriteToLog(_T("ObjectFile::Open()"));
USES_CONVERSION;
if (!name)
CkgExcept(ERROR_INVALID_ARGUMENT);
CkgString fileName(W2T(name));
if (fileName.IsEmpty())
CkgExcept(ERROR_OPEN_FILE);
if (!TestFilePresent(uptFileNameForWrite, true))
CkgExcept(_T("UPT-файл для шифрования файла не найден."));
if (!TestFilePresent(uptFileNameForRead))
CkgExcept(_T("UPT-файл для расшифровки файла не найден."));
cpp_ptr obj(new ObjectFile);
TestPtr(obj);
if (uptFileNameForWrite)
obj->uptFileNameForWrite = W2T(uptFileNameForWrite);
if (uptFileNameForRead)
obj->uptFileNameForRead = W2T(uptFileNameForRead);
obj->mode = (!uptFileNameForWrite || CkgString(obj->uptFileNameForWrite).IsEmpty()) ?
EF_READONLY : EF_READWRITE;
obj->f = _tfopen(fileName, _T("r+b"));
if (!obj->f)
CkgExcept(ERROR_OPEN_FILE);
if (fread(&obj->fileMode, sizeof(BYTE), sizeof(CreateMode), obj->f) != sizeof(CreateMode))
CkgExcept(ERROR_READ_FILE);
unsigned fileSize;
if (fread(&fileSize, sizeof(BYTE), sizeof(unsigned), obj->f) != sizeof(unsigned))
CkgExcept(ERROR_READ_FILE);
cpp_arr_ptr buf(new BYTE[fileSize]);
TestPtr(buf);
if (fread(buf, sizeof(BYTE), fileSize, obj->f) != fileSize)
CkgExcept(ERROR_READ_FILE);
BYTE tmp;
if (fread(&tmp, sizeof(BYTE), 1, obj->f) == 1)
CkgExcept(ERROR_READ_FILE);
obj->buffer = &CkgBuffer::Create(4096);
obj->buffer->Write(buf, fileSize);
obj->DecryptBuf();
obj->buffer->LSeek(0);
obj->isOpened = true;
return *obj.Detach();
}
//-----------------------------------------------------------------------------
void ObjectFile::Write(const void *buf, unsigned size)
{
WriteToLog(_T("ObjectFile::Write()"));
if (mode == EF_READONLY)
CkgExcept(_T("Файл открыт только для чтения."));
if (!size)
{
buffer->SetSize(buffer->GetPosition());
return;
}
buffer->Write(buf, size);
}
//-----------------------------------------------------------------------------
void ObjectFile::Read(void *buf, unsigned size)
{
_ASSERT(!isClosed);
unsigned position = buffer->GetPosition();
if (buffer->GetSize() - position < size)
CkgExcept(ERROR_INVALID_ARGUMENT);
memcpy(buf, static_cast(buffer->GetBuf()) + position, size);
buffer->LSeek(position + size);
}
//-----------------------------------------------------------------------------
void ObjectFile::Seek(int position, int mode)
{
WriteToLog(_T("ObjectFile::Seek()"));
_ASSERT(!isClosed);
if (mode == SEEK_SET)
buffer->LSeek(position);
else if (mode == SEEK_CUR)
buffer->LSeek(buffer->GetPosition() + position);
else if (mode == SEEK_END)
buffer->LSeek(buffer->GetSize() + position);
else
CkgExcept(ERROR_INVALID_ARGUMENT);
}
//-----------------------------------------------------------------------------
void ObjectFile::Close()
{
WriteToLog(_T("ObjectFile::Close()"));
_ASSERT(!isClosed && isOpened);
isClosed = true; // Даже если и не закроем (возникнет исключение), то больше
// пробовать все равно толку нет
if (mode == EF_READWRITE)
{
if (fseek(f, 0, SEEK_SET))
CkgExcept(ERROR_WRITE_FILE);
if (fwrite(&fileMode, sizeof(BYTE), sizeof(CreateMode), f) != sizeof(CreateMode))
CkgExcept(ERROR_WRITE_FILE);
CryptBuf();
unsigned dataSize = buffer->GetSize();
if (fwrite(&dataSize, sizeof(BYTE), sizeof(unsigned), f) != sizeof(unsigned))
CkgExcept(ERROR_WRITE_FILE);
if (fwrite(buffer->GetBuf(), sizeof(BYTE),
dataSize, f) != dataSize)
CkgExcept(ERROR_WRITE_FILE);
if (fwrite(0, 1, 0, f) != 0)
CkgExcept(ERROR_WRITE_FILE);
}
if (fclose(f))
CkgExcept(ERROR_CLOSE_FILE);
f = NULL;
buffer = 0;
}
//-----------------------------------------------------------------------------
ObjectFile::~ObjectFile()
{
WriteToLog(_T("ObjectFile::~ObjectFile()"));
_ASSERT(isClosed);
if (isOpened && !isClosed)
Close();
if (f)
fclose(f);
}
//-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// CProtect
CkgArray CProtect::files(true);
CkgSimpleContainerArray CProtect::handles;
STDMETHODIMP CProtect::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IProtect
};
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
STDMETHODIMP CProtect::GetInfo(short *version, BSTR *info)
{
try
{
*version = moduleVersionInfo;
CComBSTR str;
str.LoadString(IDS_MODULE_INFO);
*info = str.Copy();
return S_OK;
}
CONVERT_EXCEPTION_TO_COM_EXCEPTION
}
STDMETHODIMP CProtect::GenerateUPTfiles(BSTR algorithmCryptFileName,
BSTR algorithmDecryptFileName)
{
return GenerateTimeLimitUPTfiles(algorithmCryptFileName,
algorithmDecryptFileName,
0);
}
void CProtect::ContinueGenerateTimeLimitUPTfiles(
BSTR algorithmCryptFileName, BSTR algorithmDecryptFileName,
long LimitDaysDecrypt, long LimitDaysCrypt)
{
if (LimitDaysDecrypt)
LimitDaysDecrypt += GetCurrentDayNum();
if (LimitDaysCrypt)
LimitDaysCrypt += GetCurrentDayNum();
USES_CONVERSION;
if (!algorithmCryptFileName || !algorithmDecryptFileName)
CkgExcept(_T("Строка с именем upt-файла пустая."));
LPCTSTR fileNameCrypt(W2T(algorithmCryptFileName));
LPCTSTR fileNameDecrypt(W2T(algorithmDecryptFileName));
if (!_tcslen(fileNameCrypt) || !_tcslen(fileNameDecrypt))
CkgExcept(_T("Строка с именем upt-файла пустая."));
GenerateAlgorithm(*fileNameCrypt, *fileNameDecrypt,
static_cast(LimitDaysDecrypt),
static_cast(LimitDaysCrypt));
}
STDMETHODIMP CProtect::GenerateTimeLimitUPTfiles(BSTR algorithmCryptFileName,
BSTR algorithmDecryptFileName,
long LimitDays)
{
WriteToLog(_T("CProtect::GenerateTimeLimitUPTfiles()"));
try
{
ContinueGenerateTimeLimitUPTfiles(algorithmCryptFileName,
algorithmDecryptFileName,
LimitDays, LimitDays);
return S_OK;
}
CONVERT_EXCEPTION_TO_COM_EXCEPTION
return S_OK;
}
STDMETHODIMP CProtect::GenerateTimeLimitUPTfiles2(BSTR algorithmCryptFileName,
BSTR algorithmDecryptFileName, long LimitDaysDecrypt,
long LimitDaysCrypt)
{
WriteToLog(_T("CProtect::GenerateTimeLimitUPTfiles2()"));
try
{
ContinueGenerateTimeLimitUPTfiles(algorithmCryptFileName,
algorithmDecryptFileName,
LimitDaysCrypt, LimitDaysDecrypt);
return S_OK;
}
CONVERT_EXCEPTION_TO_COM_EXCEPTION
return S_OK;
}
void CProtect::ContinueOpen(ObjectFile &file, short &handle)
{
files.Add(file);
short i;
for (i = 1; i < SHRT_MAX; i++)
{
if (handles.IndexOf(i) == -1)
{
handle = i;
handles.Add(i);
break;
}
}
if (i == SHRT_MAX)
CkgExcept(_T("Нет больше свободных дескипторов."));
_ASSERT(handle);
}
STDMETHODIMP CProtect::Create(BSTR name, CreateMode mode, BSTR uptFileName, short *handle)
{
WriteToLog(_T("CProtect::Create()"));
try
{
_ASSERT(handle);
ContinueOpen(ObjectFile::Create(name, uptFileName, mode),
*handle);
return S_OK;
}
CONVERT_EXCEPTION_TO_COM_EXCEPTION
}
STDMETHODIMP CProtect::Open(BSTR name, BSTR uptFileNameForRead,
BSTR uptFileNameForWrite, short *handle)
{
WriteToLog(_T("CProtect::Open()"));
try
{
_ASSERT(handle);
ContinueOpen(ObjectFile::Open(name, uptFileNameForWrite,
uptFileNameForRead), *handle);
return S_OK;
}
CONVERT_EXCEPTION_TO_COM_EXCEPTION
}
STDMETHODIMP CProtect::Close(short handle)
{
WriteToLog(_T("CProtect::Close()"));
try
{
int index = handles.IndexOf(handle);
if (index == -1)
CkgExcept(_T("Ошибка закрытия файла. (Неверный дескриптор.)"));
handles.Remove(index);
files[index].Close();
files.Remove(index, true);
return S_OK;
}
CONVERT_EXCEPTION_TO_COM_EXCEPTION
}
template
void WriteVariable(ObjectFile &file, const T &var, VARTYPE varType)
{
file.Write(&varType, sizeof(VARTYPE));
file.Write(&var, sizeof(T));
}
STDMETHODIMP CProtect::Write(short handle, VARIANT buffer, long *written)
{
WriteToLog(_T("CProtect::Write()"));
try
{
int index = handles.IndexOf(handle);
if (index == -1)
CkgExcept(_T("Ошибка записи в файл. (Неверный дескриптор.)"));
VARTYPE vt = buffer.vt;
ObjectFile &file = files[index];
unsigned oldSize = file.GetPosition();
if (!(vt & VT_BYREF) && !(vt & VT_ARRAY))
{
if (vt == VT_UI1)
WriteVariable(file, buffer.bVal, VT_UI1);
else if (vt == VT_I2)
WriteVariable(file, buffer.iVal, VT_I2);