/* START CONFIDENTIAL */

/*******************************************************************/
/*******************************************************************/
/*  DEBUT DU MODULE VARIABLE.C                                     */
/*******************************************************************/

#include <ctype.h>
#include <conio.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <alloc.h>
#include "defs.h"
#include "variable.h"

#include "..\LibUrne\LibUrne.h"

/***********************************************/
#define _SIZE_TMP     12
/**********************************************/
char FERMETURE;
char SUPPORT;
char OUVERTURE;
char TEST;
char RECOMPTAGE;
char NC;

/* Vote counters */
int  *piNOMBRE_VOTES1, *piNOMBRE_VOTES2, *piNOMBRE_VOTES3;
int  *piNOMBRE_NATIO_VOTES1, *piNOMBRE_NATIO_VOTES2, *piNOMBRE_NATIO_VOTES3;
int  *piNOMBRE_STR_VOTES1, *piNOMBRE_STR_VOTES2, *piNOMBRE_STR_VOTES3;
int  *piERROR_COUNT_VOTE, *piERROR_COUNT_VAL;

int Table[_E_NB_MAX_VOTE], Table_Val[_E_TABLE_VAL_PLACE];

long EPROM_TAILLE; /* EPROM size */

unsigned char *pszplainData;
unsigned char *pszcipherData;

int  GLOBAL_NATIO,GLOBAL_EURO,GLOBAL_STR;
int  DEMANDE_FERMETURE;
char JETON_ETENDU[_JETON_ETENDU_MAX_BYTE+1];
char JETON[_JETON_MAX_BYTE+1];

int  USER;
int  POSITION_VOTE;
int  FILE_EPROM;
int  SAUVE_TO_EPROM;
int  NOMBRE_SCRUTIN;
int  *TABLE_PCC;

unsigned int timing;
unsigned int EPROM_SEG;

size_t TAILLE_TABLE_PCC;
szMessage *pszMessage_Point;

extern char Chemin_R[25], Chemin_D[25];
extern char System_Used[9];
extern int iDiskId;
extern int iMAXDISK;
/*<< 9.01c*/
extern char CMinipassword[12];
/*>>*/
extern boolean bErrWrite;
extern boolean bErrRead;
extern boolean bEncodeV;
extern boolean bErrWrite_Ram;
extern boolean bErrRead_Ram;
extern boolean bNoSupMode;
extern boolean bReading_Loop;
extern boolean bWriteData_Ram;


/***********************************************/
/*
   <FUNCTION>
		<NAME>Encode_E_Variable</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Write data in the EPROM, file FE_RAM, file FE_DSK
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Position, Valeur</NAME>
			<TYPE>long, char</TYPE>
			<IO>IN,IN</IO>
			<DESCRIPTION>Data position, data to be written</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Encode_E_Variable(long Position, char Valeur)

{
  char szMsgError[80];
  int iRes;

  bErrWrite = false;
  bErrRead = false;
  bErrRead_Ram = false;
  bErrWrite_Ram = false;

  if ((Position == _E_FERMETURE) || (Position == _E_OUVERTURE))
  {
	    /*Using open because FEram is used into Ram_Write function*/
		FEram = open(Chemin_R, O_RDWR | O_BINARY);
		if (FEram == -1)
		{
			sprintf(szMsgError,"Error opening file %s in Encode_E_Variable function.\nFile source %s\n",Chemin_R, __FILE__);
			Erreur(szMsgError);
			bErrRead_Ram = true;
		}
		else
		{
			iRes = Ram_Write(Valeur, Position);
			if(iRes != 1)
			{
				sprintf(szMsgError,"Error writing to the file %s in Encode_E_Variable function.\nFile source %s\n",Chemin_R, __FILE__);
				Erreur(szMsgError);
				bErrWrite_Ram = true;
			}
			close(FEram);
		}


	  if(SUPPORT == 'E')
	  {
			iRes = Eprom_Write(Valeur, Position);
			if(iRes != true)
			{
				sprintf(szMsgError,"Error writing to the EPROM in Encode_E_Variable function.\nFile source: %s\n",
								__FILE__);
				Erreur(szMsgError);
			}
	  }
	  else if(SUPPORT == 'R')
	  {
			FEdsk = open(Chemin_D, O_RDWR | O_BINARY);
			if (FEdsk == -1)
			{
				sprintf(szMsgError,"Error opening file %s in Encode_E_Variable function.\nFile source %s\n",Chemin_D, __FILE__);
				Erreur(szMsgError);
				bErrRead = true;
			}
			else
			{
				iRes = Disk_Write(Valeur, Position);
				if(iRes != 1)
				{
					sprintf(szMsgError,"Error writing to the file %s in Encode_E_Variable function.\nFile source: %s\n",
								Chemin_D, __FILE__);
					Erreur(szMsgError);
					bErrWrite = true;
				}
				close(FEdsk);
			}
	  }
  }

}  /* Encode_E_Variable */

/***********************************************/
/*
   <FUNCTION>
		<NAME>Recupere_E_Variable</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Recover a data of the EPROM, file FE_RAM, file FE_DSK
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Position, Valeur</NAME>
			<TYPE>long, char *</TYPE>
			<IO>IN,INOUT</IO>
			<DESCRIPTION>Data position, data to be recovered</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Recupere_E_Variable(long Position, char *Valeur, boolean bReadMem)
{
  int iRes;
  boolean bError_L = false;
  char szMsgError[90];


  if ((Position == _E_FERMETURE) || (Position == _E_OUVERTURE))
  {
		if(SUPPORT == 'E')
			Eprom_Read(Valeur, Position);

        if(SUPPORT == 'R')
        {
			if(bReadMem)
			{
				FEram = open(Chemin_R, O_RDWR | O_BINARY);
				if (FEram == -1)
				{
					sprintf(szMsgError,"Error opening file %s in Recupere_E_Variable function.\nFile source: %s\n",
									Chemin_R, __FILE__);
					Erreur(szMsgError);
					bError_L = true;
				}
				else
				{
					iRes = Ram_Read(Valeur, Position);
					if(iRes == -1)
					{
						sprintf(szMsgError,"Error reading from the file %s in Recupere_E_Variable function.\nFile source: %s\n",
									Chemin_R, __FILE__);
						Erreur(szMsgError);
						bError_L = true;
					}
					close(FEram);
				}
			}

			if(bError_L || !bReadMem)
			{
				 FEdsk = open(Chemin_D, O_RDWR | O_BINARY);
				 if (FEdsk == -1)
				 {
					sprintf(szMsgError,"Error opening file %s in Recupere_E_Variable function.\nFile source: %s\n",
											Chemin_D, __FILE__);
					Erreur(szMsgError);
					SUPPORT = 'N'; /*switch to the mode without recording*/
					bNoSupMode = true;
				 }
				 else
				 {
					 iRes = Disk_Read(Valeur, Position);
					 if(iRes == -1)
					 {
						sprintf(szMsgError,"Error reading from the file %s in Recupere_E_Variable function.\nFile source: %s\n",
									Chemin_D, __FILE__);
						Erreur(szMsgError);
						SUPPORT = 'N'; /*switch to the mode without recording*/
						bNoSupMode = true;
					 }
					 close(FEdsk);
				 }

				 if(SUPPORT != 'N')
					Disk_Ram_Load();
				 else
				 {
				    if(!bReading_Loop)
					{
						Lcd_Affiche(0,0,pszMessage_Point[60]);
						Lcd_Affiche(1,0,pszMessage_Point[14]);
						Getch(COLOR);
					}
				 }
			}

        }
  }
} /* Recupere_E_Variable */
/********************************************************************************/

/*
   <FUNCTION>
		<NAME>Encode_Data_Disk</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Write data on the file FE_DSK</DESCRIPTION>
        <PARAMETER>
			<NAME>iPosition,pzDataValue,iDataSize, cSelect</NAME>
			<TYPE>int , char *, int, char</TYPE>
			<IO>IN,IN,IN,IN</IO>
			<DESCRIPTION>Data position, data to be written, data size, select flag </DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Encode_Data_Disk(int iPosition, char *pzDataValue, int iDataSize ,char cSelect)
{
	int iCpt, iRes ;
	char szMsgError[90];
	long E_Position;

	switch(cSelect)
	{
	case 'V' :
		E_Position = (long)_E_TABLE;
		E_Position +=(long)((long)((long)C_VOTE_MAX_BYTE + 5L) * (long)iPosition);
		break;

	case 'C' :
		E_Position = (long)(_E_TABLE_VAL + iPosition);
		break;
	}

	/*<< 9.01c*/
	if(bWriteData_Ram)
	{
		FEram = open(Chemin_R, O_RDWR | O_BINARY);
		if (FEram == -1)
		{
			sprintf(szMsgError,"Error opening file %s in Encode_Data_Disk function.\nFile source %s\n",Chemin_R, __FILE__);
			Erreur(szMsgError);
			SUPPORT = 'N'; /*switch to the mode without recording*/
			bNoSupMode = true;
		}
		else
		{
			for (iCpt = 0, iRes = true;(iCpt < iDataSize) && (iRes == true); iCpt++)
			{
				iRes = Ram_Write(*pzDataValue++, E_Position++);
			}
			close(FEram);
			if(iRes != true)
			{
				sprintf(szMsgError,"Error writing to the file %s in Encode_Data_Disk function.\nFile source %s\n",
							Chemin_R, __FILE__);
				Erreur(szMsgError);
				SUPPORT = 'N'; /*switch to the mode without recording*/
				bNoSupMode = true;
			}
		}

      bWriteData_Ram = false;
	}

	if(SUPPORT != 'N')
	/*>>*/
	{
		FEdsk = open(Chemin_D, O_RDWR | O_BINARY);
		if (FEdsk == -1)
		{
			sprintf(szMsgError,"Error opening file %s in Encode_Data_Disk function.\nFile source: %s\n",
									Chemin_D, __FILE__);
			Erreur(szMsgError);
			SUPPORT = 'N'; /*switch to the mode without recording*/
			bNoSupMode = true;
		}
		else
		{
			for (iCpt = 0, iRes = true;(iCpt < iDataSize) && (iRes == true); iCpt++)
			{
				iRes = Disk_Write(*pzDataValue++, E_Position++);
			}
			close(FEdsk);

			if(iRes != true)
			{
				sprintf(szMsgError,"Error writing to the file %s in Encode_Data_Disk function.\nFile source: %s\n",
									Chemin_D, __FILE__);
				Erreur(szMsgError);
				SUPPORT = 'N'; /*switch to the mode without recording*/
				bNoSupMode = true;
			}
		}
	}

	if((SUPPORT == 'N') && (!bReading_Loop))
	{
		Lcd_Affiche(0,0,pszMessage_Point[60]);
		Lcd_Affiche(1,0,pszMessage_Point[14]);
		Getch(COLOR);
	}
}


/*******************************************************************************/
/*
   <FUNCTION>
		<NAME>Encode_E_Var_String</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Write data of the string type in the EPROM, file FE_RAM, file FE_DSK
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Position, Valeur, Longueur</NAME>
			<TYPE>long, char *, int</TYPE>
			<IO>IN,IN,IN</IO>
			<DESCRIPTION>Data position, data to be written, data size </DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Encode_E_Var_String(long Position, char *Valeur, int Longueur)
{
  int i, iRes ;
  char *Valeur1;
  long Position1;
  char szMsgError[90], szMsgTemp[21], szFileName[11];
  sRecVote Buffer;
  FILE *Fichier;

  Valeur1   = Valeur;
  Position1 = Position;
  bErrWrite = false;
  bErrRead = false;
  bErrRead_Ram = false;
  bErrWrite_Ram = false;

  if(bEncodeV)
  {
		strcpy(szFileName,szCtrlFile);
		Buffer.lpos = Position;
		memcpy(Buffer.szContent,Valeur,Longueur);
  }

   /*Using open because FEram is used into Ram_Write function*/
	FEram = open(Chemin_R, O_RDWR | O_BINARY);
	if (FEram == -1)
	{
		sprintf(szMsgError,"Error opening file %s in Encode_E_Var_String function.\nFile source %s\n",Chemin_R, __FILE__);
		Erreur(szMsgError);
		bErrRead_Ram = true;
	}
	else
	{
		for (i = 0, iRes = true;(i < Longueur) && (iRes == true); i++)
		{
			iRes = Ram_Write(*Valeur1++, Position1++);
		}
		close(FEram);
		if(iRes != true)
		{
			sprintf(szMsgError,"Error writing to the file %s in Encode_E_Var_String function.\nFile source %s\n",
						Chemin_R, __FILE__);
			Erreur(szMsgError);
			bErrWrite_Ram = true;
		}
	}

  if(SUPPORT == 'E')
  {
		for (i = 0, iRes = true;(i < Longueur) && (iRes == true); i++)
        {
			iRes = Eprom_Write(*Valeur++, Position++);
        }

		if(iRes != true)
		{
			sprintf(szMsgError,"Error writing to the EPROM in Encode_E_Var_String function.\nFile source: %s\n",
								__FILE__);
			Erreur(szMsgError);
		}
  }
  else if(SUPPORT == 'R')
  {
	 FEdsk = open(Chemin_D, O_RDWR | O_BINARY);
	 if (FEdsk == -1)
	 {
		sprintf(szMsgError,"Error opening file %s in Encode_E_Var_String function.\nFile source: %s\n",
								Chemin_D, __FILE__);
		Erreur(szMsgError);
		bErrRead = true;
	 }
	 else
	 {
		if(bEncodeV)
		{
			if((Fichier = fopen(szFileName, "wb")) == NULL)
			{
				sprintf(szMsgError,"Error opening file %s in Encode_E_Var_String function.\nFile source: %s\n",
								szFileName, __FILE__);
				Erreur(szMsgError);
			}
			else
			{
				iRes = fwrite(&Buffer, sizeof(Buffer),1, Fichier);
				if(iRes != 1)
				{
					sprintf(szMsgError,"Error writing to the file %s in Encode_E_Var_String function.\nFile source: %s\n",
								szFileName, __FILE__);
					Erreur(szMsgError);
					fclose(Fichier);
					remove(szFileName);
				}
				else
					fclose(Fichier);
			}

			bEncodeV = false;
		}

		for (i = 0, iRes = true;(i < Longueur) && (iRes == true); i++)
		{
			iRes = Disk_Write(*Valeur++, Position++);
		}
		close(FEdsk);

		if(iRes != true)
		{
			sprintf(szMsgError,"Error writing to the file %s in Encode_E_Var_String function.\nFile source: %s\n",
								Chemin_D, __FILE__);
			Erreur(szMsgError);
			bErrWrite = true;
		}
	 }
  }

}  /* Encode_E_Var_String */

/***********************************************/
/*
   <FUNCTION>
		<NAME>Recupere_E_Var_String</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Recover a data of the string type from the EPROM, file FE_RAM, file FE_DSK
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Position, Valeur, Longueur</NAME>
			<TYPE>long, char *, int</TYPE>
			<IO>IN,INOUT,IN</IO>
			<DESCRIPTION>Data position, data to be recovered, data size</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Recupere_E_Var_String(long Position, char *Valeur, int Longueur, boolean bReadMem)
{
  int i, iRes;
  char szMsgError[90];
  boolean bError_L = false;

  if(SUPPORT == 'R')
  {
      if(bReadMem)
	  {
		  FEram = open(Chemin_R, O_RDWR | O_BINARY);
		  if (FEram == -1)
		  {
				sprintf(szMsgError,"Error opening file %s in Recupere_E_Var_String function.\nFile source: %s\n",
										Chemin_R, __FILE__);
				Erreur(szMsgError);
				bError_L = true;
		  }
		  else
		  {
				for (i = 0; i < Longueur; i++)
				{
					iRes = Ram_Read(Valeur++, Position++);
					if(iRes == -1)
					{
						sprintf(szMsgError,"Error reading from the file %s in Recupere_E_Var_String function.\nFile source: %s\n",
										Chemin_R, __FILE__);
						Erreur(szMsgError);
						bError_L = true;
						break;
					}
				}
				close(FEram);
		  }
	  }

	  if(bError_L || !bReadMem)
	  {
		 FEdsk = open(Chemin_D, O_RDWR | O_BINARY);
		 if (FEdsk == -1)
		 {
			sprintf(szMsgError,"Error opening file %s in Recupere_E_Variable function.\nFile source: %s\n",
									Chemin_D, __FILE__);
			Erreur(szMsgError);
			SUPPORT = 'N'; /*switch to the mode without recording*/
			bNoSupMode = true;
		 }
		 else
		 {
			 for (i = 0; i < Longueur; i++)
			 {
				iRes = Disk_Read(Valeur++, Position++);
				if(iRes == -1)
				{
					sprintf(szMsgError,"Error reading from the file %s in Recupere_E_Var_String function.\nFile source: %s\n",
									Chemin_D, __FILE__);
					Erreur(szMsgError);
					SUPPORT = 'N'; /*switch to the mode without recording*/
					bNoSupMode = true;
					break;
				}
			 }
			 close(FEdsk);
		 }

		 if(SUPPORT != 'N')
			Disk_Ram_Load();
		 else
		 {
			if(!bReading_Loop)
			{
				Lcd_Affiche(0,0,pszMessage_Point[60]);
				Lcd_Affiche(1,0,pszMessage_Point[14]);
				Getch(COLOR);
			}
		 }
	  }

  }
  else if(SUPPORT == 'E')
    for (i = 0; i < Longueur; i++)
        Eprom_Read(Valeur++, Position++);

  *Valeur = '\0';

}  /* Recupere_E_Var_String */

/*****************************************************************************/
/*
   <FUNCTION>
		<NAME>Recupere_E_Vote</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Recover vote contents</DESCRIPTION>
        <PARAMETER>
			<NAME>Position, Valeur, Longueur</NAME>
			<TYPE>long, char *, int</TYPE>
			<IO>IN,INOUT,IN</IO>
			<DESCRIPTION>Data position, data to be recovered, data size</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Recupere_E_Vote(int Position, char *Valeur, int Longueur)
{
  long E_Position;


  E_Position = (long)_E_TABLE;
  E_Position +=(long)((long)((long)C_VOTE_MAX_BYTE + 5L) * (long)Position);
  Recupere_E_Var_String(E_Position, Valeur, Longueur,true);

} /* Recupere_E_Vote */

/***********************************************/
/*
   <FUNCTION>
		<NAME>Encode_E_Vote</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Write vote contents</DESCRIPTION>
        <PARAMETER>
			<NAME>Position, Valeur, Longueur</NAME>
			<TYPE>long, char *, int</TYPE>
			<IO>IN,IN,IN</IO>
			<DESCRIPTION>Data position, data to be written, data size</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Encode_E_Vote(int Position, char *Valeur, int Longueur)
{
	  long E_Position;

	  if(SUPPORT == 'R')
			bEncodeV = true;

	  E_Position = (long)_E_TABLE;
	  E_Position +=(long)((long)((long)C_VOTE_MAX_BYTE + 5L) * (long)Position);

	  Encode_E_Var_String(E_Position, Valeur, Longueur);
	  Check_Read_Write();
} /* Encode_E_Vote */

/**************************************************************************/
/*
   <FUNCTION>
		<NAME>Write_Counter</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Write vote counter</DESCRIPTION>
        <PARAMETER>
			<NAME>pzCounter,iSize</NAME>
			<TYPE>char *, int</TYPE>
			<IO>IN,IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Write_Counter(char * pzCounter, int iSize)
{
	long E_Position;

	E_Position = (long)_E_TABLE_VAL;

	Encode_E_Var_String(E_Position, pzCounter, iSize);
	Check_Read_Write();
}
/**************************************************************************/
/*
   <FUNCTION>
		<NAME>Read_Counter</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Read vote counters from FERAM and FEDSK files and compare them
		</DESCRIPTION>
        <PARAMETER>
			<NAME>bReadMem</NAME>
			<TYPE>boolean</TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Read_Counter(boolean bReadMem)
{
	long E_Position;
	char szMsgError[90], szRam_Counter[5], szDsk_Counter[5];
	unsigned char val;
	int iCpt, iRes, iRam, iDsk;
	boolean bError_L = false;

	if(SUPPORT == 'R')
	{
		if(bReadMem)
		{
		  FEram = open(Chemin_R, O_RDWR | O_BINARY);
		  if (FEram == -1)
		  {
			sprintf(szMsgError,"Error opening file %s in Read_Counter function.\nFile source: %s\n",
									Chemin_R, __FILE__);
			Erreur(szMsgError);
			SUPPORT = 'N';/*switch to the mode without recording*/
			bNoSupMode = true;
			iRes = -1;
		  }
		  else
		  {
			E_Position = (long)_E_TABLE_VAL;
			for (iCpt = 0; iCpt < 4; iCpt++, E_Position++)
			{
				lseek(FEram,E_Position,0);
				iRes = read(FEram,&val,1);
				if(iRes == -1)
				{
					sprintf(szMsgError,"Error reading from the file %s in Read_Counter function.\nFile source: %s\n",
									Chemin_R, __FILE__);
					Erreur(szMsgError);
					SUPPORT = 'N';
					bNoSupMode = true;
					break;
				}
				else
				{
					if (val == 255) val = 0;
					szRam_Counter[iCpt] = val;
				}
			}
			szRam_Counter[iCpt] = '\0';
			close(FEram);
		  }
		}

		  if(SUPPORT != 'N')
		  {
				FEdsk = open(Chemin_D, O_RDWR | O_BINARY);
				 if (FEdsk == -1)
				 {
					if(!bReadMem)
					{
						sprintf(szMsgError,"Error opening file %s in Read_Counter function.\nFile source: %s\n",
												Chemin_D, __FILE__);
						Erreur(szMsgError);
					}

					bError_L = true;
					iRes = -1;
				 }
				 else
				 {
					 E_Position = (long)_E_TABLE_VAL;
					 for (iCpt = 0; iCpt < 4; iCpt++, E_Position++)
					 {
						 lseek(FEdsk,E_Position,0);
						 iRes = read(FEdsk,&val,1);
						 if(iRes == -1)
						 {
							if(!bReadMem)
							{
								sprintf(szMsgError,"Error reading from the file %s in Read_Counter function.\nFile source: %s\n",
										Chemin_D, __FILE__);
								Erreur(szMsgError);
							}

							bError_L = true;
							break;
						 }
						 else
						 {
							if (val == 255) val = 0;
							szDsk_Counter[iCpt] = val;
						 }
					 }
					 szDsk_Counter[iCpt] = '\0';
					 close(FEdsk);
				 }

				 if(bReadMem)
				 {
					 if(!bError_L)
					 {
						iRam = atoi(szRam_Counter);
						iDsk = atoi(szDsk_Counter);
						iRes = iDsk;

						if(iRam != iDsk)
						{
							Ram_Disk_Load();
							/*<< 9.01c*/
							iRes = iRam;
							/*>>*/
						}
					 }
					 else
					 {
						 Ram_Disk_Load();
						 /*<< 9.01c*/
						 iRam = atoi(szRam_Counter);
						 iRes = iRam;
						 /*>>*/
					 }
				 }
				 else
				 {
					 if(!bError_L)
					 {
						iDsk = atoi(szDsk_Counter);
						iRes = iDsk;
					 }
				 }
		  }
	}

  return iRes;

}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Check_Read_Write</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Check if reading or writing data failed and try to repair error
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>void</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/

void Check_Read_Write()
{
	if(SUPPORT == 'E')
	{
		if((bErrRead_Ram || bErrWrite_Ram) && (bErrWrite || bErrRead))
		{
			/*switch to the mode without recording*/
			SUPPORT = 'N';
			bNoSupMode = true;
			Lcd_Affiche(0,0,pszMessage_Point[60]);
			Lcd_Affiche(1,0,pszMessage_Point[14]);
			Getch(COLOR);
		}
		else if(bErrRead_Ram || bErrWrite_Ram)
			Eprom_Ram_Load();
		else if (bErrWrite || bErrRead)
			Ram_Eprom_Load();
	}

	if(SUPPORT == 'R')
	{
		if((bErrRead_Ram || bErrWrite_Ram) && (bErrWrite || bErrRead))
		{
			/*switch to the mode without recording*/
			SUPPORT = 'N';
			bNoSupMode = true;
			if(!bReading_Loop)
			{
				Lcd_Affiche(0,0,pszMessage_Point[60]);
				Lcd_Affiche(1,0,pszMessage_Point[14]);
				Getch(COLOR);
			}
		}
		else if(bErrRead_Ram || bErrWrite_Ram)
			Disk_Ram_Load();
		else if (bErrWrite || bErrRead)
			Ram_Disk_Load();
	}
}
/**************************************************************************/
/*
   <FUNCTION>
		<NAME>Est_Valide_E_Vote</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Determine if a vote is valid</DESCRIPTION>
        <PARAMETER>
			<NAME>Position</NAME>
			<TYPE>int</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>vote position</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>boolean</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
boolean Est_Valide_E_Vote(int Position)
{
  long E_Position;
  unsigned char Valide;
  char szMsgError[90], szTempVote[76], /*<< 9.01c*/szPassword[16]/* >> */; 
  int iRes;
  /*<< 9.01c*/
  unsigned int iVoteSize;
  /* >> */

  E_Position = (long)_E_TABLE + _C_CRC_MAX_BYTE;
  E_Position +=(long)((long)((long)C_VOTE_MAX_BYTE + 5L) * (long)Position);

  if(SUPPORT == 'E')
        Eprom_Read(&Valide, E_Position);

  if(SUPPORT == 'R')
  {
      FEram = open(Chemin_R, O_RDWR | O_BINARY);
	  if (FEram == -1)
	  {
			sprintf(szMsgError,"Error opening file %s in Est_Valide_E_Vote function.\nFile source: %s\n",
									Chemin_R, __FILE__);
			Erreur(szMsgError);
			SUPPORT = 'N';//switch to the mode without recording
			bNoSupMode = true;
	  }
	  else
	  {
			iRes = Ram_Read(&Valide, E_Position);
			if(iRes == -1)
			{
				sprintf(szMsgError,"Error reading from the file %s in Est_Valide_E_Vote function.\nFile source: %s\n",
									Chemin_R, __FILE__);
				Erreur(szMsgError);
				SUPPORT = 'N';
				bNoSupMode = true;
			}
			close(FEram);
	  }
  }

  /*<< 9.01c*/
  if(Valide)
  {
	iVoteSize = C_VOTE_MAX_BYTE + _C_CRC_MAX_BYTE + _C_TEST_MAX_BYTE;
	Recupere_E_Vote(Position,szTempVote,iVoteSize);
	Generate_Password(szPassword,Position,true);
	Encrypt_Decrypt(szTempVote,szPassword,iVoteSize);
	Valide = szTempVote[_C_CRC_MAX_BYTE];
  }
  /* >> */

  return(Valide);

} /* Est_Valide_E_Vote */
/***********************************************/
/*
   <FUNCTION>
		<NAME>Est_Libre_E_Position</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Determine if an entry of the votes table is available
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Position</NAME>
			<TYPE>int</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>boolean</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
boolean Est_Libre_E_Position(int Position)
{
  long E_Position;
  char c;

  E_Position = (long)_E_TABLE;
  E_Position +=(long)((long)((long)C_VOTE_MAX_BYTE + 5L) * (long)Position);

  if(SUPPORT == 'E')
       c = (! Eprom_Writed(E_Position));

  else if(SUPPORT == 'R')
       c = (! Disk_Writed(E_Position));
  return(c);

} /* Est_Libre_E_Position */

/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Alloc_Mem</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Carry out the memory allocation of pointers
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>boolean</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
boolean Alloc_Mem()
{
   if ((piNOMBRE_VOTES1 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_VOTES2 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_VOTES3 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_NATIO_VOTES1 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_NATIO_VOTES2 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_NATIO_VOTES3 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_STR_VOTES1 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_STR_VOTES2 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piNOMBRE_STR_VOTES3 = (int *)malloc(sizeof(int))) == NULL)
      return(0);

   if ((piERROR_COUNT_VOTE = (int *)malloc(sizeof(int))) != NULL)
     *piERROR_COUNT_VOTE = 0;
   else
      return(0);
   
    if ((pszplainData = (unsigned char *)malloc(PlainDataLen * sizeof(unsigned char))) == NULL)
	   return(0);

	if ((pszcipherData = (unsigned char *)malloc(CipherDataLen * sizeof(unsigned char))) == NULL)
	   return(0);

	if ((pszMessage_Point = (szMessage *)malloc(MAX_MSG * sizeof(szMessage))) == NULL)
	   return(0);

   return(1);
}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Free_Mem</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		deallocates a memory block allocated
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Free_Mem()
{
   if (piNOMBRE_VOTES1)
      free(piNOMBRE_VOTES1);

   if (piNOMBRE_VOTES2)
      free(piNOMBRE_VOTES2);

   if (piNOMBRE_VOTES3)
      free(piNOMBRE_VOTES3);

   if (piNOMBRE_NATIO_VOTES1)
      free(piNOMBRE_NATIO_VOTES1);

   if (piNOMBRE_NATIO_VOTES2)
      free(piNOMBRE_NATIO_VOTES2);

   if (piNOMBRE_NATIO_VOTES3)
      free(piNOMBRE_NATIO_VOTES3);

   if (piNOMBRE_STR_VOTES1)
      free(piNOMBRE_STR_VOTES1);

   if (piNOMBRE_STR_VOTES2)
      free(piNOMBRE_STR_VOTES2);

   if (piNOMBRE_STR_VOTES3)
      free(piNOMBRE_STR_VOTES3);

   if (piERROR_COUNT_VOTE)
      free(piERROR_COUNT_VOTE);

	if (pszplainData)
		free(pszplainData);

	if (pszcipherData)
		free(pszcipherData);

	if(pszMessage_Point)
	   free(pszMessage_Point);
}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Init_Vote_Counters</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Initialize vote counters
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Init_Vote_Counters()
{
     *piNOMBRE_VOTES1 = 0;
     *piNOMBRE_VOTES2 = 0;
     *piNOMBRE_VOTES3 = 0;

     *piNOMBRE_NATIO_VOTES1 = 0;
     *piNOMBRE_NATIO_VOTES2 = 0;
     *piNOMBRE_NATIO_VOTES3 = 0;

     *piNOMBRE_STR_VOTES1 = 0;
     *piNOMBRE_STR_VOTES2 = 0;
     *piNOMBRE_STR_VOTES3 = 0;

}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Init_Vote_Counters</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Check vote counters</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Check_Vote_Counters()
{

    short int sIndic1, sIndic2, sIndic3, sIndic4;

    if ((*piNOMBRE_VOTES1 == *piNOMBRE_VOTES2) && (*piNOMBRE_VOTES2 == *piNOMBRE_VOTES3))
    {
	sIndic1 = 1;
    }
    else
    {
	sIndic1 = 0;
    }

	if (sIndic1 == 0)
    {
       if (*piNOMBRE_VOTES1 == *piNOMBRE_VOTES2)
       {
	  *piNOMBRE_VOTES3 = *piNOMBRE_VOTES1;
	  sIndic1 = 1;
       }
       else
       if (*piNOMBRE_VOTES1 == *piNOMBRE_VOTES3)
       {
	  *piNOMBRE_VOTES2 = *piNOMBRE_VOTES1;
	  sIndic1 = 1;
       }
       else
       if (*piNOMBRE_VOTES2 == *piNOMBRE_VOTES3)
       {
	  *piNOMBRE_VOTES1 = *piNOMBRE_VOTES2;
	  sIndic1 = 1;
       }
	   else
	   {
			*piERROR_COUNT_VOTE += 1;
	   }
    }

	if(MULTI_ELEC == 'P')
	{

		if ((*piNOMBRE_NATIO_VOTES1 == *piNOMBRE_NATIO_VOTES2) && (*piNOMBRE_NATIO_VOTES2 == *piNOMBRE_NATIO_VOTES3))
		{
		sIndic2 = 1;
		}
		else
		{
		sIndic2 = 0;
		}

		if ((*piNOMBRE_STR_VOTES1 == *piNOMBRE_STR_VOTES2) && (*piNOMBRE_STR_VOTES2 == *piNOMBRE_STR_VOTES3))
		{
		sIndic3 = 1;
		}
		else
		{
		sIndic3 = 0;
		}


		if (sIndic2 == 0)
		{
		   if (*piNOMBRE_NATIO_VOTES1 == *piNOMBRE_NATIO_VOTES2)
		   {
		  *piNOMBRE_NATIO_VOTES3 = *piNOMBRE_NATIO_VOTES1;
		  sIndic2 = 1;
		   }
		   else
		   if (*piNOMBRE_NATIO_VOTES1 == *piNOMBRE_NATIO_VOTES3)
		   {
		  *piNOMBRE_NATIO_VOTES2 = *piNOMBRE_NATIO_VOTES1;
		  sIndic2 = 1;
		   }
		   else
		   if (*piNOMBRE_NATIO_VOTES2 == *piNOMBRE_NATIO_VOTES3)
		   {
		  *piNOMBRE_NATIO_VOTES1 = *piNOMBRE_NATIO_VOTES2;
		  sIndic2 = 1;
		   }
		   else
		   {
				*piERROR_COUNT_VOTE += 1;
		   }
		}


		if (sIndic3 == 0)
		{
		   if (*piNOMBRE_STR_VOTES1 == *piNOMBRE_STR_VOTES2)
		   {
		  *piNOMBRE_STR_VOTES3 = *piNOMBRE_STR_VOTES1;
		  sIndic3 = 1;
		   }
		   else
		   if (*piNOMBRE_STR_VOTES1 == *piNOMBRE_STR_VOTES3)
		   {
		  *piNOMBRE_STR_VOTES2 = *piNOMBRE_STR_VOTES1;
		  sIndic3 = 1;
		   }
		   else
		   if (*piNOMBRE_STR_VOTES2 == *piNOMBRE_STR_VOTES3)
		   {
		  *piNOMBRE_STR_VOTES1 = *piNOMBRE_STR_VOTES2;
		  sIndic3 = 1;
		   }
		   else
		   {
				*piERROR_COUNT_VOTE += 1;
		   }
		}

		if(*piNOMBRE_VOTES1 == (*piNOMBRE_NATIO_VOTES1 + *piNOMBRE_STR_VOTES1))
		{
			sIndic4 = 1;
		}
		else
		{
			sIndic4 = 0;
			*piERROR_COUNT_VOTE += 1;
		}
	}
	else
	{
		sIndic2 = 1;
		sIndic3 = 1;
		sIndic4 = 1;

	}

    if ((sIndic1 == 0) || (sIndic2 == 0) || (sIndic3 == 0) || (sIndic4 == 0))
    {
		Lcd_Affiche(0, 0, pszMessage_Point[12]);
		Lcd_Affiche(1,0,  "");
		if(((SUPPORT == 'R') && (access(Chemin_D, 0) == 0)) || (SUPPORT == 'E'))
			Recupere_Nb_Cartes();
    }



}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Recupere_Nb_Cartes</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Calculate the number of validated votes
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Recupere_Nb_Cartes()
{
  int Position, i;
  char szMsgError[80];

  Init_Vote_Counters();

  for (i = 0; i < _E_NB_MAX_VOTE;i++)
                        Table[i] = 0;
  if(SUPPORT == 'R')
  {
		FEdsk = open(Chemin_D, O_RDWR | O_BINARY);
		if (FEdsk == -1)
		{
			sprintf(szMsgError,"Error opening file %s in Recupere_Nb_Cartes function.\nFile source: %s\n",
								Chemin_D, __FILE__);
			Erreur(szMsgError);
			SUPPORT = 'N';
			bNoSupMode = true;
		}
  }

  if(SUPPORT != 'N')
  {
	Lcd_Affiche(0,0,pszMessage_Point[12]);
	Lcd_Affiche(1,0," ");

	for (Position = 0; Position < _E_NB_MAX_VOTE; Position++)
      if (!Est_Libre_E_Position(Position))
      {
		  if(SUPPORT != 'N')
		  {
			*piNOMBRE_VOTES1 += 1;
			*piNOMBRE_VOTES2 += 1;
			*piNOMBRE_VOTES3 += 1;

			Table[Position] = 1;
			if(MULTI_ELEC == 'P')
			{
				if(Est_Valide_E_Vote(Position) == 'N')
				{
					*piNOMBRE_NATIO_VOTES1 += 1;
					*piNOMBRE_NATIO_VOTES2 += 1;
					*piNOMBRE_NATIO_VOTES3 += 1;

				}
				else if(Est_Valide_E_Vote(Position) == 'S')
				{
					*piNOMBRE_STR_VOTES1 += 1;
					*piNOMBRE_STR_VOTES2 += 1;
					*piNOMBRE_STR_VOTES3 += 1;
				}
			}
		  }
      }

	if(SUPPORT == 'R')
		close(FEdsk);
	Lcd_Affiche(0,0," ");
  }

} /* Recupre_Nb_Cartes */
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Encrypt_Decrypt</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Encrypt or decrypt vote contents</DESCRIPTION>
        <PARAMETER>
			<NAME>pzInputData,pzPassword,iSize</NAME>
			<TYPE>char *,char *,unsigned int</TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>void</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
/*<< 9.01c*/
void Encrypt_Decrypt(char *pzInputData, char *pzPassword, unsigned int iSize)
{
	unsigned int i, iKeySize;

	iKeySize = strlen(pzPassword);

	for (i= 0; i < iSize; i++)
    {
		pzInputData[i] ^=  pzPassword[i % iKeySize];
    }
    pzInputData[iSize] = 0x00;
}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Generate_Password</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Generate password to encrypt or decrypt vote contents</DESCRIPTION>
        <PARAMETER>
			<NAME>pzPassword,Position,bIndic</NAME>
			<TYPE>char *,long,boolean</TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>void</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Generate_Password(char *pzPassword, long Position, boolean bIndic)
{
	long E_Position;
	char szPos[8];

	if(bIndic)
	{
		E_Position = (long)_E_TABLE;
		E_Position +=(long)((long)((long)C_VOTE_MAX_BYTE + 5L) * (long)Position);
	}
	else
		E_Position = Position;

	sprintf(szPos,"%07ld",E_Position);
	if(szPos[0] == '-')
		szPos[0] = '0';

	pzPassword[0] = CMinipassword[0];
	pzPassword[1] = szPos[3];
	pzPassword[2] = CMinipassword[2];
	pzPassword[3] = szPos[4];
	pzPassword[4] = CMinipassword[7];
	pzPassword[5] = szPos[5];
	pzPassword[6] = CMinipassword[4];
	pzPassword[7] = szPos[6];
	pzPassword[8] = szPos[0];
	pzPassword[9] = CMinipassword[1];
	pzPassword[10] = CMinipassword[3];
	pzPassword[11] = szPos[2];
	pzPassword[12] = CMinipassword[6];
	pzPassword[13] = szPos[1];
	pzPassword[14] = CMinipassword[5];
    pzPassword[15] = 0x00;

}
/*>>*/
/****************************************************************************/
/*                      END OF MODULE VARIABLE.C                            */
/****************************************************************************/


