long C_File::FileSize() { C_FileCritSect cCS0( this, CRITSECT0 ); int iFlag = FALSE; if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ if( ReOpen() != OK ){ if( !_xFile ){ return( -1 ); } _xFile->PseudoClose(); ReOpen(); iFlag = TRUE; } } if( _bIs32s ){ long lCurPosAux = CurPos(); Seek( 0, SEEK_END ); long lSize = CurPos(); Seek( lCurPosAux, SEEK_SET ); if( iFlag ){ PseudoClose(); _xFile->ReOpen(); } return( lSize ); } // guarda a posicao corrente // long lCurPosAux = CurPos(); DWORD dwResult = GetFileSize( hFile, NULL ); /* // vai para o fim do arquivo e pega o numero do ultimo byte dwResult = SetFilePointer( hFile, 0, NULL, FILE_END ); /* if( dwResult == 0XFFFFFFFF ){ DWORD dw = GetLastError(); char szErr[ 500 ]; sprintf( szErr, "Erro no GetFileSize: %d", (int) dw ); MessageBox( NULL, szErr, "DEBUG - LIFILE", MB_OK ); } // volta para a posicao que estava Seek( lCurPosAux, SEEK_SET ); */ if( iFlag ){ PseudoClose(); _xFile->ReOpen(); } return( (long) dwResult ); }
/*** Metodo Release Libera um registro previamente travado Parameters: - pcfControlFile Return: LBS_OK se conseguir liberar ou erro. Comments: ***/ int C_File::Release( long lSize ) { C_FileCritSect cCS0( this, CRITSECT0 ); if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ if( ReOpen() != OK ){ return( E_NOTOPEN ); } } LockStruct ls( this, CurPos(), lSize ); return( DelLock( &ls ) ); }
/*** PRIVATE RealLock Realiza um lock em uma regiao do arquivo, utilizando rotinas do Sistema Operacional ***/ int C_File::RealLock( LockStruct *ls, BOOL bWait ) { C_FileCritSect cCS0( this, CRITSECT0 ); if( !bRealLock ){ return( OK ); } int iRet = !OK; int iFlag = FALSE; if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ if( ReOpen() != OK ){ if( !_xFile ){ return( !OK ); } _xFile->PseudoClose(); ReOpen(); iFlag = TRUE; } } if( ls ){ if( _bIs32s ){ long lPos = CurPos(); if( Seek( ls->iPos, SEEK_SET ) == OK ){ iRet = locking( iFile, _LK_LOCK, ls->iSize ); } Seek( lPos, SEEK_SET ); } else { if( Seek( ls->iPos, SEEK_SET ) == OK ){ DWORD dwErr; SetLastError( 0 ); iRet = LockFile( hFile, ls->iPos, 0, ls->iSize, 0 ) ? OK : !OK; dwErr = GetLastError(); while( bWait && ((dwErr == ERROR_LOCK_FAILED) || (dwErr == ERROR_LOCK_VIOLATION)) ){ // esperar e tentar novamente. cCS0.LeaveCriticalSection(); Sleep( 1000 ); // 1 segundo cCS0.EnterCriticalSection(); SetLastError( 0 ); iRet = LockFile( hFile, ls->iPos, 0, ls->iSize, 0 ) ? OK : !OK; dwErr = GetLastError(); } } } } if( iFlag ){ PseudoClose(); _xFile->ReOpen(); } return( iRet ); }
/*** PRIVATE GrowFile Aumenta o tamanho do arquivo para lNewSize bytes. E' possivel que os buffers MMF sejam resetados (pWinView e pHeadView). E' interessante que o chamador deste metodo reavalie a necessidade de fazer um novo mapeamento do arquivo em MMF (refazer pWinView e pHeadView). ***/ int C_File::GrowFile( long lNewSize ) { // guarda posicao atual long lCPos = CurPos(); // o seek abaixo ja' faz o arquivo crescer int iRet = Seek( lNewSize, SEEK_SET ); // volta para a posicao que estava Seek( lCPos, SEEK_SET ); return( iRet ); }
/*** Retorna TRUE se houve tentativa de lock em uma regiao depois que a mesma ja' estava travada. ***/ BOOL C_File::TryUse() { LockStruct ls( this, CurPos(), 0L ); C_FileCritSect cCS0( this, CRITSECT0 ); LockList &l = *(_LockTable[ iLine ]); for( int i = 0; i < l.NumElem(); i++ ){ LockStruct *lsAux = l [ i ]; if( lsAux->pcfFile == ls.pcfFile && lsAux->iPos == ls.iPos && lsAux->bTryUse == TRUE ){ return( TRUE ); } } return( FALSE ); }
int C_File::PseudoClose( void ) { C_FileCritSect cCS0( this, CRITSECT0 ); if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ return( OK ); } #ifdef _USE_PRINTF_ if( this == _xFile ){ Printf( "C_File: Estou (pseudo) fechando o _xFile****************************" ); } #endif lCurPos = CurPos(); Close(); bReOpen = TRUE; return( OK ); }
/*** Metodo Lock Trava o registro Parameters: - pcfControlFile Return: LBS_OK se conseguir travar ou erro. Comments: ***/ int C_File::Lock( long lSize, BOOL bWait ) { // C_FileCritSect cCS0( this, CRITSECT0 ); if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ if( ReOpen() != OK ){ return( E_NOTOPEN ); } } LockStruct *ls = new LockStruct( this, CurPos(), lSize ); if( ls ){ if( AddLock( ls, bWait ) == OK ){ return( OK ); } delete ls; } return( !OK ); }
bool DirectShowVideoWrapper::seek(Real64 SeekPos) { if(isInitialized()) { HRESULT hr; TCHAR szErr[MAX_ERROR_TEXT_LEN]; Real64 CurPos(getPosition()); if((SeekPos < CurPos) && (!canSeekBackward())) { SWARNING << "Unable to seek backwards on this type of media." << std::endl; return false; } if((SeekPos > CurPos) && (!canSeekForward())) { SWARNING << "Unable to seek forwards on this type of media." << std::endl; return false; } CComPtr<IMediaPosition> mediaPosition; hr = _pGraphBuilder->QueryInterface(&mediaPosition); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to get IMediaPosition, error: " << szErr << std::endl; return false; } hr = mediaPosition->put_CurrentPosition(SeekPos); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to set position to value: " << SeekPos << ", error: " << szErr << std::endl; return false; } return true; } return false; }
/*** PRIVATE RealRelease Realiza um unlock em uma regiao do arquivo, utilizando rotinas do Sistema Operacional ***/ int C_File::RealRelease( LockStruct *ls ) { C_FileCritSect cCS0( this, CRITSECT0 ); if( !bRealLock ){ return( OK ); } int iRet = !OK; int iFlag = FALSE; if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ if( ReOpen() != OK ){ if( !_xFile ){ return( !OK ); } _xFile->PseudoClose(); ReOpen(); iFlag = TRUE; } } if( ls ){ if( _bIs32s ){ long lPos = CurPos(); if( Seek( ls->iPos, SEEK_SET ) == OK ){ iRet = locking( iFile, _LK_UNLCK, ls->iSize ); } Seek( lPos, SEEK_SET ); } else { if( Seek( ls->iPos, SEEK_SET ) == OK ){ iRet = UnlockFile( hFile, ls->iPos, 0, ls->iSize, 0 ) ? OK : !OK; } } } if( iFlag ){ PseudoClose(); _xFile->ReOpen(); } return( iRet ); }
/*** Write bytes in a file from a given buffer. Parameters: - pvBuf: User buffer with data to write in file - tsSize: Size of iten to write - tsNumItens: Number of itens to write Return: Number of writtem itens in succes or E_NOTOPEN, E_BUFFNULL or E_WRITE. ***/ size_t C_File::Write( void FAR *pvBuf, size_t tsSize, size_t tsNumItens ) { C_FileCritSect cCS0( this, CRITSECT0 ); size_t i = 0; BOOL bContinue = TRUE; #ifdef _USE_PRINTF_ Printf( "C_File: Estou em Write. (arq %s)", szFileName ); #endif int iFlag = FALSE; if( !pvBuf ){ return( (size_t) E_BUFFNULL ); } if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ if( ReOpen() != OK ){ if( !_xFile ){ return( 0 ); } _xFile->PseudoClose(); ReOpen(); iFlag = TRUE; } } LockStruct ls( this, CurPos(), (tsSize * tsNumItens) ); if( IsLocked( &ls ) ){ if( iFlag ){ PseudoClose(); _xFile->ReOpen(); } #ifdef _USE_PRINTF_ Printf( "C_File: Write: IsLocked." ); #endif return( (size_t) E_WRITE ); } if( cCriptoOn ){ Encrypt( pvBuf, szKey, tsSize ); } // MMF BOOL bWriteHeader = FALSE; if( !_bIs32s && hMMF ){ // preparar gravacao a partir do MMF long lFSize = FileSize(); long lCPos = CurPos(); if( ( lCPos + (int) (tsNumItens * tsSize) ) > lFSize ){ // este write vai exceder os limites do arquivo. vamos aumentar-lo. if( GrowFile( lCPos + (tsNumItens * tsSize) ) != OK ){ // nao foi possivel aumentar o arquivo. bContinue = FALSE; } } if( bContinue ){ if( (lCPos == iHeadInit) && (((int) tsSize) == iHeadSize) ){ bWriteHeader = TRUE; // vamos fazer write no header do arquivo. if( !pHeadView ){ // o header ainda nao esta' mapeado. vamos fazer isso. CreateViewOfHead(); } } else { if( !pWinView ){ // o arquivo ainda nao esta' mapeado. vamos fazer isso. CreateViewOfFile(); } } } } if( bContinue ){ for( i = 0; i < tsNumItens; i++ ){ if( _bIs32s ){ if( write( iFile, pvBuf, (unsigned) tsSize ) < (int) tsSize ){ break; } } else { if( bWriteHeader ){ // gravar header no MMF. memcpy( pHeadView, pvBuf, tsSize ); } else { if( pWinView ){ // gravar no MMF. int iNumBytes = ((iMMFWinSize * iPageSize) - iSeekWin) - (iHeadSize + 1); memcpy( (void*) ((char*) PWINVIEW + iSeekWin), pvBuf, min( iNumBytes, ((int) tsSize) ) ); if( iNumBytes < ((int) tsSize) ){ // precisamos mapear outra janela e continuar a gravacao ++iWinNum; // proxima janela CreateViewOfFile(); if( !pWinView ){ // mapeamento nao foi feito. fudeu. break; } // gravacao do restante memcpy( (void*) ((char*) PWINVIEW + iSeekWin), (void*) ((char*) pvBuf + iNumBytes), (tsSize - iNumBytes) ); iSeekWin += (tsSize - iNumBytes); } else { iSeekWin += tsSize; } } else { DWORD dwWrittenBytes; BOOL bResult = WriteFile( hFile, pvBuf, (unsigned) tsSize, &dwWrittenBytes, NULL ); if( !bResult || ( dwWrittenBytes < tsSize ) ){ DWORD dwErr = GetLastError(); break; } } } } } } // if( ::GetTypeInt() == PE_REDE ){ // Flush(); // } dwLastUse = GetTickCount(); if( cCriptoOn ){ Decrypt( pvBuf, szKey, tsSize ); } if( i < tsNumItens ){ #ifdef _USE_PRINTF_ Printf( "C_File: Write: E_WRITE." ); #endif i = (size_t) E_WRITE; } if( iFlag ){ PseudoClose(); _xFile->ReOpen(); } #ifdef _USE_PRINTF_ Printf( "C_File: Write: Vou retornar %d.", i ); #endif return( i ); }
/*** Read bytes from a file to a buffer. Parameters: - pvBuf: User buffer. Contains the result of a read. - tsSize: Size of iten to read - tsNumItens: Number of itens to read Return: - O numero de itens lidos (nao o numero de bytes). Em caso de erro: E_NOTOPEN or E_BUFFNULL or EOF. ***/ size_t C_File::Read( void FAR *pvBuf, size_t tsSize, size_t tsNumItens ) { C_FileCritSect cCS0( this, CRITSECT0 ); int iFlag = FALSE; if( !pvBuf ){ return( (size_t) E_BUFFNULL ); } if( (_bIs32s && iFile == -1) || (!_bIs32s && hFile == INVALID_HANDLE_VALUE) ){ if( ReOpen() != OK ){ if( !_xFile ){ return( 0 ); } _xFile->PseudoClose(); ReOpen(); iFlag = TRUE; } } // MMF BOOL bReadHeader = FALSE; if( !_bIs32s && hMMF ){ // preparar leitura a partir do MMF if( (CurPos() == iHeadInit) && ((int) tsSize == iHeadSize) ){ bReadHeader = TRUE; // vamos fazer read no header do arquivo. if( !pHeadView ){ // o header ainda nao esta' mapeado. vamos fazer isso. CreateViewOfHead(); } } else { if( !pWinView ){ // o arquivo ainda nao esta' mapeado. vamos fazer isso. CreateViewOfFile(); } } } for( size_t i = 0; i < tsNumItens; i++ ){ if( _bIs32s ){ if( read( iFile, ( char *) pvBuf + tsSize * i, tsSize ) < (int) tsSize ){ break; } } else { if( bReadHeader ){ // ler header a partir do MMF. memcpy( pvBuf, pHeadView, tsSize ); } else { if( pWinView ){ // ler a partir do MMF. int iNumBytes = ((iMMFWinSize * iPageSize) - iSeekWin) - (iHeadSize + 1); memcpy( (void*) (( char *) pvBuf + tsSize * i), (void*) ((char*) PWINVIEW + iSeekWin), min( iNumBytes, ((int) tsSize) ) ); if( iNumBytes < ((int) tsSize) ){ // precisamos mapear outra janela e continuar a leitura ++iWinNum; // proxima janela CreateViewOfFile(); if( !pWinView ){ // mapeamento nao foi feito. vamos assumir fim-de-arquivo. break; } // ler o restante memcpy( (void*) ((( char *) pvBuf + tsSize * i) + iNumBytes), (void*) ((char*) PWINVIEW + iSeekWin), (tsSize - iNumBytes) ); iSeekWin += (tsSize - iNumBytes); } else { iSeekWin += tsSize; } } else { // ler direto do arquivo DWORD dwReadBytes; BOOL bResult = ReadFile( hFile, ( char *) pvBuf + tsSize * i, tsSize, &dwReadBytes, NULL ); if( !bResult || ( dwReadBytes < tsSize ) ){ break; } } } } } dwLastUse = GetTickCount(); if( cCriptoOn && i >= tsNumItens ){ Decrypt( pvBuf, szKey, tsSize * tsNumItens ); } if( i < tsNumItens ){ i = (size_t) EOF; } if( iFlag ){ PseudoClose(); _xFile->ReOpen(); } return( i ); }