/* ************************************************************************************************** * CPA_Ed_1 team * * File Management * ************************************************************************************************** */ #include "Stdinc.h" #include "File.h" #include "Types.h" #ifdef LDT_USE_SINGLE_FILE_BUFFER char* GBuff = NULL; unsigned long GBuffSize = 0; #define GBuffMargin (1024*50) /* 50k above the file size */ #endif /* * OPEN a file for reading * -------------------------------------------------------------- * _pInfoMemFile : the value returned * _Name : Name of the file. * Return : Error code(zero for none) * -------------------------------------------------------------- * Conditions : If the file does not exist or cannot be found, the fopen call fails. * -------------------------------------------------------------- * Comments : If succes, the pointer value not NULL * A null pointer value indicates an error. * If some errors occur, then all space are free */ //#define OVERLAPPED_ #ifdef OVERLAPPED_ #define OVERLAPPED_NO_BUFFERING long f_OpenMem(LDT_tdst_MemFile **_pInfoMemFile,char* _Name) { long Err = LDT_EI_Err_None; *_pInfoMemFile= (LDT_tdst_MemFile *)malloc(sizeof(LDT_tdst_MemFile)); if(*_pInfoMemFile) { HANDLE File; (*_pInfoMemFile)->sPathLength = 0; (*_pInfoMemFile)->pName= (char *)malloc(( strlen(_Name)+1 )); strcpy((*_pInfoMemFile)->pName , _Name); (*_pInfoMemFile)->pBuffer = NULL; #ifdef OVERLAPPED_NO_BUFFERING File = CreateFile( _Name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING, NULL); #else File = CreateFile( _Name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); #endif if(File != INVALID_HANDLE_VALUE) { (*_pInfoMemFile)->Size = GetFileSize( File, NULL); if((*_pInfoMemFile)->Size) { DWORD BoundSize, VolumeSectorsize, SectorsPerCluster, NumberOfFreeClusters, TotalNumberOfClusters ; char Drive[4] = "C:\\"; if(_Name[1] == ':') Drive[0] = _Name[0]; GetDiskFreeSpace(_Name[1] == ':'? Drive: NULL, &SectorsPerCluster, &VolumeSectorsize, &NumberOfFreeClusters, &TotalNumberOfClusters ); #ifdef OVERLAPPED_NO_BUFFERING BoundSize = (*_pInfoMemFile)->Size + 5 + VolumeSectorsize; BoundSize -= BoundSize%VolumeSectorsize; (*_pInfoMemFile)->pBuffer= (char*)VirtualAlloc( NULL, BoundSize, MEM_COMMIT, PAGE_READWRITE ); #else BoundSize = (*_pInfoMemFile)->Size + 5; (*_pInfoMemFile)->pBuffer= (char*)malloc( BoundSize ); #endif if((*_pInfoMemFile)->pBuffer) { OVERLAPPED overlapped; overlapped.Offset = overlapped.OffsetHigh = 0; overlapped.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL); ReadFile( File, (*_pInfoMemFile)->pBuffer, BoundSize, NULL, &overlapped); WaitForSingleObject( overlapped.hEvent, INFINITE); CloseHandle(overlapped.hEvent); (*_pInfoMemFile)->Pos = 0; strcpy((*_pInfoMemFile)->pBuffer+(*_pInfoMemFile)->Size , "\n\"\n\n"); } else Err = LDT_EI_Err_Malloc; } else Err = LDT_EI_Err_SeekFile; CloseHandle(File); } else Err = LDT_EI_Err_OpenFile; } else Err = LDT_EI_Err_Malloc; if( Err != LDT_EI_Err_None && *_pInfoMemFile ) { free((*_pInfoMemFile)->pName); #ifndef LDT_USE_SINGLE_FILE_BUFFER if((*_pInfoMemFile)->pBuffer) free((*_pInfoMemFile)->pBuffer); #endif free((*_pInfoMemFile)); *_pInfoMemFile = NULL; } return Err; } #else long f_OpenMem(LDT_tdst_MemFile **_pInfoMemFile,char* _Name) { long Err = LDT_EI_Err_None; FILE *pFile; /* Pointer of the file */ *_pInfoMemFile= (LDT_tdst_MemFile *)malloc(sizeof(LDT_tdst_MemFile)); if(*_pInfoMemFile) { (*_pInfoMemFile)->sPathLength = 0; (*_pInfoMemFile)->pName= (char *)malloc(( strlen(_Name)+1 )); strcpy((*_pInfoMemFile)->pName , _Name); (*_pInfoMemFile)->pBuffer = NULL; pFile = fopen(_Name, "rb"); if(pFile) { (*_pInfoMemFile)->Size = _filelength (_fileno(pFile)); if((*_pInfoMemFile)->Size) { #ifdef LDT_USE_SINGLE_FILE_BUFFER if(GBuffSize < (*_pInfoMemFile)->Size) { if(GBuff) free(GBuff); GBuff = malloc( GBuffSize = (*_pInfoMemFile)->Size + 5 + GBuffMargin); } (*_pInfoMemFile)->pBuffer = GBuff; #else (*_pInfoMemFile)->pBuffer= (char*) malloc(((*_pInfoMemFile)->Size + 5 )); #endif if((*_pInfoMemFile)->pBuffer) { if(fread((*_pInfoMemFile)->pBuffer,(*_pInfoMemFile)->Size,1,pFile)) { (*_pInfoMemFile)->Pos = 0; strcpy((*_pInfoMemFile)->pBuffer+(*_pInfoMemFile)->Size , "\n\"\n\n"); } else Err = LDT_EI_Err_ReadFile; } else Err = LDT_EI_Err_Malloc; } else Err = LDT_EI_Err_SeekFile; fclose(pFile); } else Err = LDT_EI_Err_OpenFile; } else Err = LDT_EI_Err_Malloc; if( Err != LDT_EI_Err_None && *_pInfoMemFile ) { free((*_pInfoMemFile)->pName); #ifndef LDT_USE_SINGLE_FILE_BUFFER if((*_pInfoMemFile)->pBuffer) free((*_pInfoMemFile)->pBuffer); #endif free((*_pInfoMemFile)); *_pInfoMemFile = NULL; } return Err; } #endif /* * READ a piece of file from memory * -------------------------------------------------------------- * _PointerDest : Address of the destination * _Size : size of data to move (in bytes) * _pInfoMemFile : Source file address in memory * Return : error code if <0 or the Size of data moved(for none error) * -------------------------------------------------------------- * Conditions : * -------------------------------------------------------------- * Comments : If succes, the return value are the Size of data moved * A value<0 indicate an error */ long f_ReadMem(char * _PointerDest,size_t _Size,LDT_tdst_MemFile *_pInfoMemFile ) { long Err; /*if( (_pInfoMemFile->Pos < _pInfoMemFile->Size) && */ if (_pInfoMemFile->Size -_pInfoMemFile->Pos >= _Size) { if(_PointerDest == memmove(_PointerDest,_pInfoMemFile->pBuffer+_pInfoMemFile->Pos,_Size)) { _pInfoMemFile->Pos += _Size; return _Size; } else Err = -LDT_EI_Err_MemMove; } else Err = -LDT_EI_Err_NotEnoughDataForMove; return Err; } /* * CLOSE a file (in memory and stream) * -------------------------------------------------------------- * _pInfoMemFile : Source file address in memory * Return : error code * -------------------------------------------------------------- * Conditions : close an open stream * -------------------------------------------------------------- * Comments : fclose returns 0 if the stream is successfully closed * return EOF to indicate an error.. * Return value must be int */ long f_CloseMem(LDT_tdst_MemFile *_pInfoMemFile) { #ifdef LDT_MULTITHREADED #ifdef OVERLAPPED_NO_BUFFERING VirtualFree( _pInfoMemFile->pBuffer, 0, MEM_RELEASE); #else free( _pInfoMemFile->pBuffer ); #endif #else #ifndef LDT_USE_SINGLE_FILE_BUFFER free(_pInfoMemFile->pBuffer); #endif #endif free(_pInfoMemFile->pName); free(_pInfoMemFile); return LDT_EI_Err_None; } /* * SEEK a file in memory to a given position. * -------------------------------------------------------------- * _File : File to seek. * _Offset : Offset to seek. * _Origin : SEEK_SET or SEEK_END. * Return : error code * -------------------------------------------------------------- * Conditions : The argument origin must be one of the following constant: * -SEEK_CUR Current position of file pointer * -SEEK_END End of file * -SEEK_SET Beginning of file * -------------------------------------------------------------- * Comments : If successful, fseek returns 0 * Return value must be long */ long f_SeekMem(LDT_tdst_MemFile *_pInfoMemFile ,long _Offset,int _Origin) { long Err; Err = LDT_EI_Err_None; switch (_Origin) { case SEEK_SET: if(_Offset>=0 && _pInfoMemFile->Size >= (size_t)_Offset) _pInfoMemFile->Pos = _Offset; else Err = LDT_EI_Err_SeekInMem; break; case SEEK_CUR: if(_Offset>0 && ((_pInfoMemFile->Size-_pInfoMemFile->Pos) >= (size_t)_Offset) ) _pInfoMemFile->Pos += _Offset; else if( _Offset<0 && (_pInfoMemFile->Pos >= (size_t)(-_Offset))) _pInfoMemFile->Pos += _Offset; else Err = LDT_EI_Err_SeekInMem; break; case SEEK_END: if(_Offset <= 0 && (_pInfoMemFile->Size >= (size_t)(-_Offset))) _pInfoMemFile->Pos = _Offset+_pInfoMemFile->Size; else Err = LDT_EI_Err_SeekInMem; break; default: Err = LDT_EI_Err_SeekInMem; } return Err; } long f_TellMem(LDT_tdst_MemFile *_pInfoMemFile ) { return _pInfoMemFile->Pos; }