614 lines
19 KiB
C
614 lines
19 KiB
C
/*=========================================================================
|
|
* SnaFile.c : Manage files with checksums and basic encryption.
|
|
*
|
|
* The checksum is a simple xor check.
|
|
* To use files w/ checksums you must open, close, read and write to a file
|
|
* using SNA_fn_bFOpen, SNA_fn_bFClose, etc.
|
|
*
|
|
* The functions automatically compute the checksum and/or crypt the datas upon reading or writing.
|
|
*
|
|
* How to create a file :
|
|
* Open it with SNA_fn_bFOpen (specify if you want to use checksum and/or encryption)
|
|
* Write data with SNA_fn_ulFWrite (you may call for it several times)
|
|
* When ALL datas are written, call SNA_fn_bWriteChecksum,
|
|
* then SNA_fn_bFClose
|
|
*
|
|
*
|
|
* How to read a file :
|
|
* Open it with SNA_fn_bFOpen
|
|
* Read data with SNA_fn_ulFRead (you may call for it several times)
|
|
* When ALL datas are read, call SNA_fn_bReadChecksum,
|
|
* then SNA_fn_bFClose
|
|
* Now, you can check if checksum is good with SNA_fn_bTestChecksum.
|
|
*
|
|
* You can put several checksums in one file.
|
|
* Simply call SNA_fn_bWriteChecksum when you want to add a checksum
|
|
* for datas allready written.
|
|
* Checksums only control datas written BETWEEN two consecutive SNA_fn_bWriteChecksum.
|
|
* Be sure to read checksums at the same place you wrote them.
|
|
*
|
|
* Do NOT use fseek when writing or reading, it would make the checksum useless.
|
|
* You can use other file functions like ftell like this: ftell( stSNAFile->p_xFile );
|
|
*
|
|
* Version 1.0
|
|
* Creation date 25/09/98
|
|
* Revision date
|
|
*
|
|
* (c) Ubi R&D 1998
|
|
*=========================================================================
|
|
*/
|
|
|
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
|
|
|
#include <stdio.h>
|
|
#include <memory.h>
|
|
#include <string.h>
|
|
//#include "acp_opfi.h"
|
|
#include "snafile.h"
|
|
#include "TMP.h"
|
|
|
|
#include "mmg.h"
|
|
#include "snammg.h"
|
|
#include "snarlt.h"
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
/**
|
|
* SNA_fn_vSetXorCode
|
|
* Sets the xor key for encryption of a file.
|
|
* To call after SNA_fn_bFOpen(..).
|
|
*/
|
|
void SNA_fn_vSetCryptKey( unsigned char _ulCryptKey, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
_p_stFile->ulCryptKey = _ulCryptKey;
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
/**
|
|
* SNA_fn_vResetChecksum
|
|
* Sets the checksum of a file to 0.
|
|
* To use after reading and testing it's value, before further reading.
|
|
*/
|
|
void SNA_fn_vResetChecksum( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
_p_stFile->ulChecksum = 0;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
|
|
/**
|
|
* SNA_fn_bTestChecksum
|
|
* Tests if checksum is ok (==0).
|
|
* Tu use JUST AFTER SNA_bReadChecksum
|
|
*/
|
|
ACP_tdxBool SNA_fn_bTestChecksum( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
return (_p_stFile->ulChecksum == 0);
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
/**
|
|
* SNA_fn_bWriteChecksum
|
|
* Write the computed checksum in the file.
|
|
* The written checksum checks datas between the current position and
|
|
* the beginning of the file or the position of the last call to SNA_fn_bWriteChecksum
|
|
*/
|
|
ACP_tdxBool SNA_fn_bWriteChecksum( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
if( SNA_fn_bFileUseChecksum( _p_stFile ) )
|
|
{
|
|
unsigned long ulTempChecksum = _p_stFile->ulChecksum;
|
|
|
|
DWORD dwlNumberOfBytesWriten;
|
|
|
|
if( _p_stFile->ucBytesInChecksumBuffer )
|
|
{
|
|
memset( &_p_stFile->a4_cChecksumBuffer[_p_stFile->ucBytesInChecksumBuffer], 4-_p_stFile->ucBytesInChecksumBuffer, 0 );
|
|
ulTempChecksum ^= *(unsigned long *)_p_stFile->a4_cChecksumBuffer;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
}
|
|
|
|
_p_stFile->ulChecksum = 0;
|
|
|
|
SNA_M_WRITEFILE(_p_stFile->hFile , &ulTempChecksum , sizeof(ulTempChecksum) , &dwlNumberOfBytesWriten , NULL);
|
|
return (dwlNumberOfBytesWriten != 0);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
/**
|
|
* Read file checksum (if file uses checksums)
|
|
* Return TRUE if checksum was read ok or FALSE if there was a read error.
|
|
* To test the checksum value, use SNA_fn_bTestChecksum
|
|
*/
|
|
ACP_tdxBool SNA_fn_bReadChecksum( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
if( SNA_fn_bFileUseChecksum( _p_stFile ) )
|
|
{
|
|
DWORD dwNbRead;
|
|
unsigned long ulTempChecksum = 0;
|
|
|
|
if( _p_stFile->ucBytesInChecksumBuffer )
|
|
{
|
|
memset( &_p_stFile->a4_cChecksumBuffer[_p_stFile->ucBytesInChecksumBuffer], 4-_p_stFile->ucBytesInChecksumBuffer, 0 );
|
|
_p_stFile->ulChecksum ^= *(unsigned long *)_p_stFile->a4_cChecksumBuffer;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
}
|
|
|
|
if (!SNA_M_READFILE(_p_stFile->hFile , &ulTempChecksum , sizeof(ulTempChecksum) , &dwNbRead , NULL))
|
|
{
|
|
_p_stFile->ulChecksum = -1;
|
|
_p_stFile -> bReadSuccess = FALSE;
|
|
return FALSE;
|
|
}
|
|
_p_stFile -> bReadSuccess = TRUE;
|
|
|
|
_p_stFile->ulChecksum ^= ulTempChecksum;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
/**
|
|
* Opens a file.
|
|
* ucOptions are a bitwise combo of SNA_C_ucUseChecksum and/or SNA_C_ucUseEncryption and/or SNA_C_ucUseMemBuffer
|
|
*/
|
|
|
|
void SNA_fn_vInitFile(unsigned char ucOptions, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
_p_stFile->ulChecksum = 0;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
_p_stFile->ucOptions = ucOptions;
|
|
|
|
_p_stFile->p_fn_bWriteWithoutOptions = SNA_fn_bWriteToFile;
|
|
_p_stFile->p_fn_bReadWithoutOptions = SNA_fn_bReadFromFile;
|
|
if( SNA_fn_bFileUseEncryption( _p_stFile ) )
|
|
{
|
|
_p_stFile->ulCryptKey = 0x6AB5CC79; // Set default encryption key.
|
|
_p_stFile->p_fn_bDefaultWrite = SNA_fn_bCryptAndWriteToFile;
|
|
_p_stFile->p_fn_bDefaultRead = SNA_fn_bReadAndDecryptFromFile;
|
|
}
|
|
else
|
|
{
|
|
_p_stFile->ulCryptKey = 0;
|
|
_p_stFile->p_fn_bDefaultWrite = SNA_fn_bWriteToFile;
|
|
_p_stFile->p_fn_bDefaultRead = SNA_fn_bReadFromFile;
|
|
}
|
|
}
|
|
|
|
ACP_tdxBool SNA_fn_bFOpen(
|
|
char *_p_szfilename,
|
|
unsigned char ucMode,
|
|
unsigned char ucOptions,
|
|
struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
DWORD dwCreate,dwAccess;
|
|
|
|
/*
|
|
_p_stFile->ulChecksum = 0;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
_p_stFile->ucOptions = ucOptions;
|
|
|
|
_p_stFile->p_fn_bWriteWithoutOptions = SNA_fn_bWriteToFile;
|
|
_p_stFile->p_fn_bReadWithoutOptions = SNA_fn_bReadFromFile;
|
|
if( SNA_fn_bFileUseEncryption( _p_stFile ) )
|
|
{
|
|
_p_stFile->ulCryptKey = 0x6AB5CC79; // Set default encryption key.
|
|
_p_stFile->p_fn_bDefaultWrite = SNA_fn_bCryptAndWriteToFile;
|
|
_p_stFile->p_fn_bDefaultRead = SNA_fn_bReadAndDecryptFromFile;
|
|
}
|
|
else
|
|
{
|
|
_p_stFile->ulCryptKey = 0;
|
|
_p_stFile->p_fn_bDefaultWrite = SNA_fn_bWriteToFile;
|
|
_p_stFile->p_fn_bDefaultRead = SNA_fn_bReadFromFile;
|
|
}
|
|
*/
|
|
SNA_fn_vInitFile (ucOptions , _p_stFile);
|
|
|
|
switch(ucMode)
|
|
{
|
|
case SNA_C_ucWrite: dwCreate = CREATE_ALWAYS; dwAccess = GENERIC_WRITE;
|
|
{
|
|
DWORD dwAttrib = GetFileAttributes(_p_szfilename);
|
|
|
|
if(dwAttrib & FILE_ATTRIBUTE_READONLY)
|
|
SetFileAttributes(_p_szfilename , dwAttrib & ~FILE_ATTRIBUTE_READONLY);
|
|
}
|
|
break;
|
|
case SNA_C_ucRead: dwCreate = OPEN_EXISTING; dwAccess = GENERIC_READ; break;
|
|
default:
|
|
_asm {int 3h};
|
|
break;
|
|
}
|
|
|
|
_p_stFile -> hFile = SNA_M_CREATEFILE(_p_szfilename , dwAccess , 0 , NULL , dwCreate , FILE_ATTRIBUTE_NORMAL , NULL);
|
|
|
|
_p_stFile -> bReadSuccess = (_p_stFile -> hFile != INVALID_HANDLE_VALUE);
|
|
|
|
return (_p_stFile -> bReadSuccess);
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
/**
|
|
* Closes a file
|
|
* Be sure to call SNA_fn_bTestChecksum before Close to check the value of the file checksum.
|
|
*/
|
|
ACP_tdxBool SNA_fn_bFClose( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
int iRes;
|
|
// _p_stFile->ulChecksum = 0;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
|
|
iRes = (int) SNA_M_CLOSEHANDLE(_p_stFile->hFile);
|
|
|
|
_p_stFile->hFile = INVALID_HANDLE_VALUE;
|
|
|
|
return (iRes == 0);
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
/**
|
|
* SNA_fn_ulFWrite
|
|
* Write datas into a file with or without encryption and checksum.
|
|
* (it checks the option field in SNA_tdstFile)
|
|
* Returns the number of items written.
|
|
*/
|
|
size_t SNA_fn_ulFWrite( void *_p_vBuffer, size_t _ulSize, size_t _ulCount, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
unsigned long ulTotalSize = _ulSize*_ulCount;
|
|
|
|
// If nothing to write, then nothing to do...
|
|
if( ! ulTotalSize ) return 0;
|
|
|
|
|
|
// Check if this file uses checksums.
|
|
if( SNA_fn_bFileUseChecksum( _p_stFile ) )
|
|
{
|
|
/* It uses checksums. */
|
|
unsigned char ucRest;
|
|
char *p_cBuffer = _p_vBuffer;
|
|
|
|
// If there was some bytes remaining in the checksum buffer, take them into account.
|
|
if( _p_stFile->ucBytesInChecksumBuffer )
|
|
{
|
|
// First, fill the buffer.
|
|
unsigned char ucBytesToCopy = (unsigned char)min( ulTotalSize, (unsigned long)(4-_p_stFile->ucBytesInChecksumBuffer) );
|
|
memcpy( &_p_stFile->a4_cChecksumBuffer[_p_stFile->ucBytesInChecksumBuffer], p_cBuffer, ulTotalSize );
|
|
|
|
// Update buffer info
|
|
_p_stFile->ucBytesInChecksumBuffer += ucBytesToCopy;
|
|
p_cBuffer += ucBytesToCopy;
|
|
ulTotalSize -= ucBytesToCopy;
|
|
|
|
// If buffer is full, compute checksum.
|
|
if( _p_stFile->ucBytesInChecksumBuffer == 4 )
|
|
{
|
|
_p_stFile->ulChecksum ^= *(unsigned long *)_p_stFile->a4_cChecksumBuffer;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
}
|
|
}
|
|
|
|
// Compute number of long integers in the datas.
|
|
ucRest = (unsigned char)(ulTotalSize & 0x03); // =Total Size % 4
|
|
ulTotalSize >>= 2;
|
|
|
|
// For each long integer, update the checksum.
|
|
while( ulTotalSize )
|
|
{
|
|
_p_stFile->ulChecksum ^= *(unsigned long *)p_cBuffer;
|
|
p_cBuffer += 4;
|
|
ulTotalSize--;
|
|
}
|
|
|
|
// Trailing bytes (less than 4 bytes) are put in the checksum buffer.
|
|
if( ucRest )
|
|
{
|
|
memcpy( &_p_stFile->a4_cChecksumBuffer[_p_stFile->ucBytesInChecksumBuffer], p_cBuffer, ucRest );
|
|
_p_stFile->ucBytesInChecksumBuffer += ucRest;
|
|
}
|
|
|
|
} // end of checksum calculation
|
|
|
|
// Then, write the data to the file.
|
|
if( ! _p_stFile->p_fn_bDefaultWrite( _p_vBuffer, ulTotalSize, _p_stFile ) )
|
|
return 0;
|
|
|
|
return _ulCount;
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
/**
|
|
* SNA_fn_ulFRead
|
|
* Read datas from a file with or without encryption and checksum.
|
|
* (it checks the option field in SNA_tdstFile)
|
|
* Returns the number of items read.
|
|
*/
|
|
|
|
size_t SNA_fn_ulFRead( void *_p_vBuffer, size_t _ulSize, size_t _ulCount, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
unsigned long ulTotalSize = _ulSize*_ulCount;
|
|
|
|
// If nothing to read, then nothing to do...
|
|
if( ! ulTotalSize ) return 0;
|
|
|
|
// First, read the datas.
|
|
if( ! _p_stFile->p_fn_bDefaultRead( _p_vBuffer, ulTotalSize, _p_stFile ) )
|
|
return 0;
|
|
|
|
// Check if this file uses checksums.
|
|
if( SNA_fn_bFileUseChecksum( _p_stFile ) )
|
|
{
|
|
unsigned long ulTotalSize = _ulSize*_ulCount;
|
|
unsigned char ucRest;
|
|
char *p_cBuffer = _p_vBuffer;
|
|
|
|
if( _p_stFile->ucBytesInChecksumBuffer )
|
|
{
|
|
unsigned char ucBytesToCopy = (unsigned char)min( ulTotalSize, (unsigned long)(4-_p_stFile->ucBytesInChecksumBuffer) );
|
|
memcpy( &_p_stFile->a4_cChecksumBuffer[_p_stFile->ucBytesInChecksumBuffer], p_cBuffer, ucBytesToCopy );
|
|
|
|
_p_stFile->ucBytesInChecksumBuffer += ucBytesToCopy;
|
|
p_cBuffer += ucBytesToCopy;
|
|
ulTotalSize -= ucBytesToCopy;
|
|
|
|
if( _p_stFile->ucBytesInChecksumBuffer == 4 )
|
|
{
|
|
_p_stFile->ulChecksum ^= *(unsigned long *)_p_stFile->a4_cChecksumBuffer;
|
|
_p_stFile->ucBytesInChecksumBuffer = 0;
|
|
}
|
|
}
|
|
|
|
ucRest = (unsigned char)(ulTotalSize & 0x03); // =Total Size % 4
|
|
ulTotalSize >>= 2;
|
|
|
|
while( ulTotalSize )
|
|
{
|
|
_p_stFile->ulChecksum ^= *(unsigned long *)p_cBuffer;
|
|
p_cBuffer += 4;
|
|
ulTotalSize--;
|
|
}
|
|
|
|
if( ucRest )
|
|
{
|
|
memcpy( &_p_stFile->a4_cChecksumBuffer[_p_stFile->ucBytesInChecksumBuffer], p_cBuffer, ucRest );
|
|
_p_stFile->ucBytesInChecksumBuffer += ucRest;
|
|
}
|
|
} // End of checksum calculation
|
|
|
|
return _ulCount;
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
// For writing datas without encryption nor checksum calculation,
|
|
// even if the file has been opened with such options
|
|
size_t SNA_fn_ulFWriteWithoutOptions( void *_p_vBuffer, size_t _ulSize, size_t _ulCount, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
unsigned long ulTotalSize = _ulSize*_ulCount;
|
|
|
|
// If nothing to write, then nothing to do...
|
|
if( ! ulTotalSize ) return 0;
|
|
// write the data to the file without encryption nor checksum calculation
|
|
if( ! _p_stFile->p_fn_bWriteWithoutOptions( _p_vBuffer, ulTotalSize, _p_stFile ) )
|
|
return 0;
|
|
|
|
return _ulCount;
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
// For reading datas without encryption nor checksum calculation,
|
|
// even if the file has been opened with such options
|
|
// Use this function ONLY if you have written the datas you want to read
|
|
// with SNA_fn_ulFWriteWithoutOptions
|
|
size_t SNA_fn_ulFReadWithoutOptions( void *_p_vBuffer, size_t _ulSize, size_t _ulCount, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
unsigned long ulTotalSize = _ulSize*_ulCount;
|
|
|
|
// If nothing to read, then nothing to do...
|
|
if( ! ulTotalSize ) return 0;
|
|
|
|
// read the datas without encryption nor checksum calculation.
|
|
if( ! _p_stFile->p_fn_bReadWithoutOptions( _p_vBuffer, ulTotalSize, _p_stFile ) )
|
|
return 0;
|
|
|
|
return _ulCount;
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
ACP_tdxBool SNA_fn_bFileUseChecksum( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
return (_p_stFile->ucOptions & SNA_C_ucUseChecksum) != 0;
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
ACP_tdxBool SNA_fn_bFileUseEncryption( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
return (_p_stFile->ucOptions & SNA_C_ucUseEncryption) != 0;
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
///////
|
|
// Handle seek for sna file.
|
|
// WARNING : you'd better not use seek with file with checksum and encryption.
|
|
// Encryption is handled by seek only if the origin is the current position.
|
|
// Checksum calculation is NOT handled by seek.
|
|
// This function does not check the validity of the offset.
|
|
// A bad offset (seek goes out of file) can cause problems in key calculation for files with encryption...
|
|
int SNA_fn_bFseek( struct SNA_tdstFile_ *_p_stFile, long _lOffset, int _lOrigin )
|
|
{
|
|
// fflush( _p_stFile->p_xFile );
|
|
DWORD dwMoveMethod;
|
|
|
|
if( _lOrigin == SEEK_CUR && SNA_fn_bFileUseEncryption( _p_stFile ) )
|
|
{
|
|
unsigned char *p_a_ucCryptKeys = (unsigned char *)&_p_stFile->ulCryptKey;
|
|
unsigned long ulOffset = abs( _lOffset );
|
|
ACP_tdxBool ucForward = (_lOffset>0);
|
|
|
|
if( _lOffset>0 )
|
|
while( ulOffset-- )
|
|
{
|
|
p_a_ucCryptKeys[0] += p_a_ucCryptKeys[2];
|
|
p_a_ucCryptKeys[1] += p_a_ucCryptKeys[3];
|
|
}
|
|
else
|
|
while( ulOffset-- )
|
|
{
|
|
p_a_ucCryptKeys[0] -= p_a_ucCryptKeys[2];
|
|
p_a_ucCryptKeys[1] -= p_a_ucCryptKeys[3];
|
|
}
|
|
}
|
|
|
|
if (_lOrigin == SEEK_SET) dwMoveMethod = FILE_BEGIN;
|
|
else if (_lOrigin == SEEK_END) dwMoveMethod = FILE_END;
|
|
else dwMoveMethod = FILE_CURRENT;
|
|
|
|
return SNA_M_SETFILEPOINTER(_p_stFile->hFile , _lOffset , NULL , dwMoveMethod);
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
int SNA_fn_iFFlush( struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
return (int) SNA_M_FLUSHFILEBUFFERS (_p_stFile->hFile);
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
// Crypt the input data into the file.
|
|
// Return FALSE if an IO error occured
|
|
// To perform this, the datas to be written are copied into a buffer with encryption.
|
|
// Then the buffer is written to the file.
|
|
// Datas are cut into 2048 bytes blocs.
|
|
ACP_tdxBool SNA_fn_bCryptAndWriteToFile( const void *_p_vData, unsigned long _ulSize, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
unsigned char a_ucBuffer[2048];
|
|
unsigned long ulBytesInBuffer;
|
|
const unsigned char *p_ucInput, *p_ucEndInput, *p_ucEndStep;
|
|
unsigned char *p_ucOutput;
|
|
unsigned char *p_a_ucCryptKeys = (unsigned char *)&_p_stFile->ulCryptKey;
|
|
unsigned long ulBytesWritten;
|
|
|
|
// Compute the begining and the end of the input buffer (=datas to be written).
|
|
p_ucInput = _p_vData;
|
|
p_ucEndInput = (char *)_p_vData + _ulSize;
|
|
|
|
// For each 2048 bytes block.
|
|
do
|
|
{
|
|
// Compute amount of data to copy to the buffer (max 2048)
|
|
ulBytesInBuffer = p_ucEndInput - p_ucInput;
|
|
if( ulBytesInBuffer > 2048 ) ulBytesInBuffer = 2048;
|
|
|
|
// Compute the pointer to the end of this bloc.
|
|
p_ucEndStep = p_ucInput + ulBytesInBuffer;
|
|
// Destination = buffer.
|
|
p_ucOutput = a_ucBuffer;
|
|
|
|
// Perform the copy with encryption.
|
|
while( p_ucInput < p_ucEndStep )
|
|
{
|
|
/*
|
|
*p_ucOutput++ = (*p_ucInput++ ^ p_a_ucCryptKeys[1]) + p_a_ucCryptKeys[0];
|
|
p_a_ucCryptKeys[0] += p_a_ucCryptKeys[2];
|
|
p_a_ucCryptKeys[1] += p_a_ucCryptKeys[3];
|
|
*/
|
|
*p_ucOutput++ = (*p_ucInput++ ^ p_a_ucCryptKeys[1]);
|
|
*((DWORD*)p_a_ucCryptKeys) = SNA_fn_dwGetCryptKey(*((DWORD*)p_a_ucCryptKeys));
|
|
}
|
|
|
|
// Writes the buffer to disk.
|
|
SNA_M_WRITEFILE(_p_stFile->hFile , a_ucBuffer , ulBytesInBuffer , &ulBytesWritten, NULL);
|
|
|
|
// If not all datas were written (because of an error), we return FALSE.
|
|
if( ulBytesWritten != ulBytesInBuffer )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// If not end of input, go for the next bloc.
|
|
} while( p_ucInput < p_ucEndInput );
|
|
|
|
// all the datas were written ok, return TRUE.
|
|
return TRUE;
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
// Write the input data into file without encryption.
|
|
// Return FALSE if an IO error occured
|
|
ACP_tdxBool SNA_fn_bWriteToFile( const void *_p_vData, unsigned long _ulSize, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
DWORD dwBytesWritten;
|
|
|
|
SNA_M_WRITEFILE(_p_stFile->hFile , _p_vData , _ulSize , &dwBytesWritten, NULL);
|
|
|
|
return (dwBytesWritten == _ulSize);
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
// Read the data from the IO buffer and decrypt it.
|
|
// Buffer is filled if needed
|
|
// Return FALSE if an IO error occured
|
|
ACP_tdxBool SNA_fn_bReadAndDecryptFromFile( void *_p_vData, unsigned long _ulSize, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
unsigned char *p_ucBuffer = _p_vData;
|
|
unsigned char *p_ucEndBuffer = p_ucBuffer + _ulSize;
|
|
unsigned char *p_a_ucCryptKeys = (unsigned char *)&_p_stFile->ulCryptKey;
|
|
|
|
// First, read the datas.
|
|
DWORD dwBytesRead;
|
|
|
|
_p_stFile -> bReadSuccess = SNA_M_READFILE(_p_stFile->hFile , p_ucBuffer , _ulSize , &dwBytesRead , NULL);
|
|
|
|
if( dwBytesRead != _ulSize )
|
|
return FALSE;
|
|
|
|
// Then, decrypt the datas.
|
|
for( ; p_ucBuffer<p_ucEndBuffer; p_ucBuffer++ )
|
|
{
|
|
/*
|
|
*p_ucBuffer = (*p_ucBuffer - p_a_ucCryptKeys[0]) ^ p_a_ucCryptKeys[1];
|
|
p_a_ucCryptKeys[0] += p_a_ucCryptKeys[2];
|
|
p_a_ucCryptKeys[1] += p_a_ucCryptKeys[3];
|
|
*/
|
|
*p_ucBuffer = (*p_ucBuffer ^ p_a_ucCryptKeys[1]);
|
|
*((DWORD*)p_a_ucCryptKeys) = SNA_fn_dwGetCryptKey(*((DWORD*)p_a_ucCryptKeys));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
// Read the input data from file without encryption.
|
|
// Return FALSE if an IO error occured
|
|
ACP_tdxBool SNA_fn_bReadFromFile( void *_p_vData, unsigned long _ulSize, struct SNA_tdstFile_ *_p_stFile )
|
|
{
|
|
DWORD dwBytesRead;
|
|
|
|
_p_stFile -> bReadSuccess = SNA_M_READFILE(_p_stFile->hFile , _p_vData , _ulSize , &dwBytesRead , NULL);
|
|
|
|
return (dwBytesRead == _ulSize);
|
|
|
|
}
|