📄 nfs_svr.cpp
字号:
}
TRACE_PRINTF_IF( hFile != INVALID_HANDLE_VALUE, ("Open file \'%s\' successfully\n", (LPCSTR)pRequest->aryData) );
}
break;
case St_FileSysRequest::enClose:
{
TRACE_PRINTF( ("Receive St_FileSysRequest::enClose\n") );
BOOL isDone;
ClServerFileObject * pFileObject = (ClServerFileObject *)pRequest->dwPara;
if( !pFileObject->isValid() )
{
TRACE_PRINTF( ("Failed to close an invalid file handle %#x\n", pFileObject) );
isDone = FALSE;
}
else
{
// query if this pointer is valid in another way
if( OpenFiles( pFileObject ) )
{
if( !OpenFiles.remove( pFileObject ) )
{
::OutputDebugString( "!!!Fatal Error: A connection is corrupted!!!\n" );
}
delete pFileObject;
isDone = TRUE;
}
else
{
TRACE_PRINTF( ("Failed to locate an file handle %#x\n", pFileObject) );
::OutputDebugString( "!!!Fatal Error: A connection is corrupted!!!\n" );
isDone = FALSE;
}
}
// Send back the result of the closed file
int nSent = ::send( Connection, (LPCSTR)&isDone, sizeof(isDone), 0 );
if( nSent != sizeof(isDone) )
{
TRACE_PRINTF( ("Failed to send back the result of the closed file\n") );
return; // An unhandled error, so close this connection
}
else
{
TRACE_PRINTF( ("Close a file successfully\n") );
}
}
break;
default:
TRACE_PRINTF( ("Received an unknown file system request %#x\n", pRequest->eRequest) );
} // switch
} // while
}
ClNFSFileAgent::ClNFSFileAgent( const char * szServerIP ) :
ClServerSocket( szServerIP, namNFS::FILE_AGENT_PORT )
{}
void ClNFSFileAgent::OnConnect( SOCKET Connection )
{
TRACE_PRINTF( ("ClNFSFileAgent::OnConnect( %d )\n", Connection) );
St_FileOperation stFileOperation;
while( TRUE )
{
// Receive the file system request
int nReceived = ::recv( Connection,
(LPSTR)&stFileOperation, sizeof(stFileOperation), 0 );
if( !nReceived )
{
TRACE_PRINTF( ("ClNFSFileAgent::OnConnect - Connection %d has been closed\n", Connection) );
return;
}
if( nReceived != sizeof(stFileOperation) )
{
if( nReceived == SOCKET_ERROR )
{
int nReason = ::WSAGetLastError();
if( nReason == WSAECONNRESET )
{
TRACE_PRINTF( ("ClNFSFileAgent::OnConnect - Connection %d has been closed\n", Connection) );
return;
}
}
TRACE_PRINTF( ("Failed to receive a file operation\n") );
return;
}
#if 0
TRACE_PRINTF( ("File Request Transaction: %#x\n", stFileOperation.nTransactionId) );
#endif
switch( stFileOperation.eOperation )
{
case St_FileOperation::enRead:
{
int nSent;
St_IntegerHolder stVerfication = { stFileOperation.nTransactionId + 1, TRUE };
// increase TransactionId for ensuring the transaction consistency
TRACE_PRINTF( ( "Receive St_FileOperation::enRead, Handle %#x, Size:%#x\n",
stFileOperation.hFileObject, stFileOperation.u64Data.LowPart ) );
ClServerFileObject * pFileObject = (ClServerFileObject *)stFileOperation.hFileObject;
if( !pFileObject->isValid() )
{
stVerfication.nValue = FALSE;
TRACE_PRINTF( ("Failed to execute reading for an invalid file handle %#x\n", pFileObject) );
}
// Tell the client if the requested handle is valid
nSent = ::send( Connection, (LPCSTR)&stVerfication, sizeof(stVerfication), 0 );
if( nSent != sizeof(stVerfication) )
{
TRACE_PRINTF( ("Unhandled Error: Failed to verify the requested handle with the client\n") );
return; // An unhandled error, so close this connection
}
if( !stVerfication.nValue )
{
continue; // abort this operation
}
DWORD dwSize = TRANSACTION_ID_SIZE + stFileOperation.u64Data.LowPart;
Temporary<BYTE> pBuffer = new BYTE[(size_t)dwSize];
if( (BYTE *)pBuffer == NULL )
{
TRACE_PRINTF( ("ClNFSFileAgent::OnConnect: Failed to allocate %d bytes\n", dwSize) );
return;
}
// Place a TransactionId before the data
// Increase TransactionId for ensuring the transaction consistency
if( !::ReadFile( pFileObject->getHandle(),
(BYTE *)pBuffer + TRANSACTION_ID_SIZE, stFileOperation.u64Data.LowPart, &dwSize, NULL ) )
{
PutErrorMsg();
TRACE_PRINTF( ("Failed to read %d bytes data from the file %#x, local handle %#x\n", stFileOperation.u64Data.LowPart, pFileObject, pFileObject->getHandle() ) );
*(int *)(BYTE *)pBuffer = 0xFF55AA5A;
dwSize = 0;
}
else
{
*(int *)(BYTE *)pBuffer = stFileOperation.nTransactionId + 2;
}
dwSize += TRANSACTION_ID_SIZE;
nSent = ::send( Connection, (LPCSTR)(BYTE *)pBuffer, dwSize, 0 );
if( nSent != (int)dwSize )
{
TRACE_PRINTF( ("Unhandled Error: Failed to send %d bytes data read from a file\n", dwSize - TRANSACTION_ID_SIZE) );
return; // An unhandled error, so close this connection
}
if( dwSize > TRANSACTION_ID_SIZE )
{
TRACE_VERBOSE_MSG( ("Read %d bytes data of handle %#x successfully\n", dwSize - TRANSACTION_ID_SIZE, stFileOperation.hFileObject) );
}
}
break;
case St_FileOperation::enWrite:
{
St_IntegerHolder stVerfication = { stFileOperation.nTransactionId + 1, TRUE };
TRACE_PRINTF( ( "Receive St_FileOperation::enWrite, Handle %#x, Size:%#x\n",
stFileOperation.hFileObject, stFileOperation.u64Data.LowPart ) );
ClServerFileObject * pFileObject = (ClServerFileObject *)stFileOperation.hFileObject;
if( !pFileObject->isValid() )
{
stVerfication.nValue = FALSE;
TRACE_PRINTF( ("Failed to execute writing for an invalid file handle %#x\n", pFileObject) );
}
// Tell the client if the requested handle is valid
int nSent = ::send( Connection, (LPCSTR)&stVerfication, sizeof(stVerfication), 0 );
if( nSent != sizeof(stVerfication) )
{
TRACE_PRINTF( ("Unhandled Error: Failed to verify the requested handle with the client\n") );
return; // An unhandled error, so close this connection
}
if( !stVerfication.nValue )
{
continue; // abort this operation
}
int nSize = TRANSACTION_ID_SIZE + stFileOperation.u64Data.LowPart;
Temporary<BYTE> pBuffer = new BYTE[nSize];
if( (BYTE *)pBuffer == NULL )
{
TRACE_PRINTF( ("ClNFSFileAgent::OnConnect: Failed to allocate %d bytes\n", nSize) );
return;
}
// Receive the data written from the client
int nReceived = ::recv( Connection, (LPSTR)(BYTE *)pBuffer, nSize, 0 );
if( nReceived != nSize )
{
TRACE_PRINTF( ("Unhandled Error: Failed to receive %d bytes data", stFileOperation.u64Data.LowPart) );
return; // An unhandled error, so close this connection
}
int nTransactionId = *(int *)(BYTE *)pBuffer;
if( nTransactionId != stFileOperation.nTransactionId + 2 )
{
TRACE_PRINTF( ("!!!Fatal Error: A transaction is inconsistent, the ID of which is %#x, this one is %#x + 2 !!!\n",
stFileOperation.nTransactionId, nTransactionId - 2) );
return; // An unhandled fatal error, so close this connection
}
DWORD dwWritten;
if( ::WriteFile( pFileObject->getHandle(),
(BYTE *)pBuffer + TRANSACTION_ID_SIZE, nReceived - TRANSACTION_ID_SIZE, &dwWritten, NULL ) )
{
TRACE_VERBOSE_MSG( ("Write %d bytes data of handle %#x successfully\n", dwWritten, stFileOperation.hFileObject) );
}
else
{
PutErrorMsg();
TRACE_PRINTF( ("Failed to write %d bytes data from the file %#x, local handle %#x\n", nReceived - TRANSACTION_ID_SIZE, pFileObject, pFileObject->getHandle() ) );
}
}
break;
case St_FileOperation::enSeek:
{
St_IntegerHolder stResult = { stFileOperation.nTransactionId + 1, TRUE };
TRACE_PRINTF( ( "Receive St_FileOperation::enSeek, Handle:%#x, Offset:%#x\n",
stFileOperation.hFileObject, stFileOperation.u64Data.LowPart ) );
ClServerFileObject * pFileObject = (ClServerFileObject *)stFileOperation.hFileObject;
if( !pFileObject->isValid() )
{
stResult.nValue = FALSE;
TRACE_PRINTF( ("Failed to execute seeking for an invalid file handle %#x\n", pFileObject) );
}
if( stResult.nValue )
{
if( ::SetFilePointer( pFileObject->getHandle(),
stFileOperation.u64Data.LowPart,
(PLONG)&stFileOperation.u64Data.HighPart,
FILE_BEGIN ) == INVALID_FILE_OFFSET )
{
stResult.nValue = FALSE;
PutErrorMsg();
TRACE_PRINTF( ("Failed to seek file %#x at %#x, local handle %#x\n", pFileObject, stFileOperation.u64Data.LowPart, pFileObject->getHandle()) );
}
}
// Tell the client if the requested handle is valid
int nSent = ::send( Connection, (LPCSTR)&stResult, sizeof(stResult), 0 );
if( nSent != sizeof(stResult) )
{
TRACE_PRINTF( ("Unhandled Error: Failed to verify the requested handle with the client\n") );
return; // An unhandled error, so close this connection
}
TRACE_VERBOSE_MSG( ("Seek a file at position %#x of handle %#x successfully\n", stFileOperation.u64Data.LowPart, stFileOperation.hFileObject) );
}
break;
case St_FileOperation::enGetSize:
{
int nSent;
St_IntegerHolder stVerfication = { stFileOperation.nTransactionId + 1, TRUE };
TRACE_VERBOSE_MSG( ( "Receive St_FileOperation::enGetSize, Handle %#x\n", stFileOperation.hFileObject ) );
ClServerFileObject * pFileObject = (ClServerFileObject *)stFileOperation.hFileObject;
if( !pFileObject->isValid() )
{
stVerfication.nValue = FALSE;
TRACE_PRINTF( ("Failed to execute GetSize for an invalid file handle %#x\n", pFileObject) );
}
// Tell the client if the requested handle is valid
nSent = ::send( Connection, (LPCSTR)&stVerfication, sizeof(stVerfication), 0 );
if( nSent != sizeof(stVerfication) )
{
TRACE_PRINTF( ("Unhandled Error: Failed to verify the requested handle with the client\n") );
return; // An unhandled error, so close this connection
}
if( !stVerfication.nValue )
{
continue; // abort this operation
}
St_FileSizeHolder stFileSize = { stFileOperation.nTransactionId + 2 };
stFileSize.u64Size.LowPart = ::GetFileSize( pFileObject->getHandle(), &stFileSize.u64Size.HighPart );
if( stFileSize.u64Size.LowPart == INVALID_FILE_SIZE )
{
stFileSize.u64Size.HighPart = INVALID_FILE_SIZE;
PutErrorMsg();
TRACE_PRINTF( ( "Failed to get size of file %#x, local handle %#x\n", pFileObject, pFileObject->getHandle() ) );
}
nSent = ::send( Connection, (LPCSTR)&stFileSize, sizeof(stFileSize), 0 );
if( nSent != sizeof(stFileSize) )
{
TRACE_PRINTF( ("Unhandled Error: Failed to send the size data\n") );
return; // An unhandled error, so close this connection
}
TRACE_VERBOSE_MSG( ("Get file size of handle %#x successfully\n", stFileOperation.hFileObject) );
}
break;
default:
TRACE_PRINTF( ("Received an unknown file operation %#x\n", stFileOperation.eOperation) );
} // switch
} // while
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -