/*=========================================================================
 * 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);

}
