📄 nfs_cli.cpp
字号:
#ifndef WINNT
#include <portable.h>
#include <__trace.h>
#else
#define WIN_KERNEL_MODE
extern "C"
{
#include <ntddk.h>
}
#include <KWin32.h>
#include <unisock.h>
#endif
#include <dyn.h>
#include <tempory.h>
#include "server/nfs.h"
#include "server/nfp.inl"
#ifdef TRACE_TRANS
#define TRACE_PRINT_TRANS TRACE_PRINTF
#else
#define TRACE_PRINT_TRANS
#endif
namespace namNFS
{
static ST_ListContainer<ClHostConnection> * s_plstHostConnections;
static ClCriticalSection * s_pConnectionsLock;
BOOL ClHostAgent::connect( struct sockaddr_in SocketAddr )
{
return m_FileSys.connect( SocketAddr, FILE_SYS_PORT ) &&
m_FileAgent.connect( SocketAddr, FILE_AGENT_PORT );
}
ClHostConnection::ClHostConnection( LPCSTR szHostIP ) :
m_isCreated( FALSE )
{
strcpy( m_szHostAddr, szHostIP );
if( namWinSocket::GetSocketAddress( szHostIP, m_HostAddr ) &&
m_HostAgent.connect( m_HostAddr ) )
{
m_isCreated = TRUE;
}
}
ClHostConnection * QueryConnection( LPCSTR szHostIP );
void AddConnection( ClHostConnection * pConnection );
BOOL RemoveConnection( ClHostConnection * pConnection );
ClHostConnection * QueryConnection( LPCSTR szHostIP )
{
ClMutualExclusiveAccess AccessNow(*s_pConnectionsLock);
for( ST_ListContainerIt<ClHostConnection> it = *s_plstHostConnections;
it; it ++ )
{
if( **it == szHostIP )
{
return *it;
}
}
return NULL;
}
/*
void AddConnection( ClHostConnection * pConnection )
{
ClMutualExclusiveAccess AccessNow(*s_pConnectionsLock);
s_plstHostConnections->add( pConnection );
}
BOOL RemoveConnection( ClHostConnection * pConnection )
{
ClMutualExclusiveAccess AccessNow(*s_pConnectionsLock);
for( ST_ListContainerIt<ClHostConnection> it = *s_plstHostConnections;
it; it ++ )
{
if( *it == pConnection )
{
it.remove();
return TRUE;
}
}
return FALSE;
}
*/
} // namespace NFS
using namespace namNFS;
using namespace namWinSocket;
extern "C"
{
BOOL NFS_Initialize(void)
{
s_plstHostConnections = new ST_ListContainer<ClHostConnection>;
s_pConnectionsLock = new ClCriticalSection;
return TRUE;
}
BOOL NFS_Uninitialize(void)
{
delete s_plstHostConnections;
s_plstHostConnections = NULL;
delete s_pConnectionsLock;
s_pConnectionsLock = NULL;
return TRUE;
}
NFS_FILEHANDLE NFS_OpenFile( LPCSTR szHostIP, LPCSTR szFilePath, DWORD dwAccess )
{
ClHostConnection * pConnection = QueryConnection( szHostIP );
if( !pConnection )
{
pConnection = new ClHostConnection( szHostIP );
if( !pConnection->isCreated() )
{
TRACE_PRINTF( ("NFS_OpenFile: Failed to open ( %s, %s )\n", szHostIP, szFilePath) );
delete pConnection;
return (NFS_FILEHANDLE)INVALID_HANDLE_VALUE;
}
}
size_t n = strlen( szFilePath ) + 1;
DYN<St_FileSysRequest> pRequest = new (n) St_FileSysRequest;
pRequest->eRequest = St_FileSysRequest::enOpen;
pRequest->dwPara = dwAccess;
::strcpy( pRequest->aryData, szFilePath );
ClMutualExclusiveAccess AccessNow( *pConnection );
SOCKET Host = pConnection->getFileSysSocket();
// Send the request packet to the host for opening the file in the host side
if( !SendStream( Host, (St_FileSysRequest *)pRequest, sizeof(St_FileSysRequest) + n ) )
{
TRACE_PRINTF( ("NFS_OpenFile: Failed to open ( %s, %s ) for failing to send the request\n", szHostIP, szFilePath) );
return (NFS_FILEHANDLE)INVALID_HANDLE_VALUE;
}
NFS_REL_REMOTE_HANDLE hFile;
// Receive the file handle relative to the host
if( !ReceiveStream( Host, &hFile, sizeof(hFile) ) || hFile == INVALID_HANDLE_VALUE )
{
TRACE_PRINTF( ("NFS_OpenFile: Failed to open ( %s, %s ) for failing to receive the result\n", szHostIP, szFilePath) );
return (NFS_FILEHANDLE)INVALID_HANDLE_VALUE;
}
ClClientFileObject * pFileObject = new ClClientFileObject( pConnection, hFile );
return (NFS_FILEHANDLE)pFileObject;
}
BOOL NFS_CloseFile( NFS_FILEHANDLE hFile )
{
ClClientFileObject * pFileObject = (ClClientFileObject *)hFile;
if( !pFileObject->isValid() )
{
TRACE_PRINTF( ("NFS_CloseFile: Failed to close a file\n") );
return FALSE;
}
size_t n = sizeof(NFS_REL_REMOTE_HANDLE);
St_FileSysRequest Request;
Request.eRequest = St_FileSysRequest::enClose;
Request.dwPara = (DWORD)pFileObject->m_Handle;
ClMutualExclusiveAccess AccessNow( *pFileObject->m_pHost );
SOCKET Host = pFileObject->m_pHost->getFileSysSocket();
// Send the request packet to the host for closing the file in the host side
if( !SendStream( Host, &Request, sizeof(Request) ) )
{
TRACE_PRINTF( ("NFS_CloseFile: Failed to close a file for failing to send the request\n") );
return FALSE;
}
BOOL isDone;
// Receive the result of the previous operation.
if( !ReceiveStream( Host, &isDone, sizeof(isDone) ) )
{
TRACE_PRINTF( ("NFS_CloseFile: Failed to close a file for failing to receive the result\n") );
return FALSE;
}
if( isDone )
{
delete pFileObject;
}
return isDone;
}
size_t NFS_ReadFile(NFS_FILEHANDLE hFile, PVOID pBuffer, size_t n)
{
ClClientFileObject * pFileObject = (ClClientFileObject *)hFile;
if( !pFileObject->isValid() )
{
TRACE_PRINTF( ("NFS_ReadFile: An invalid handle\n") );
return 0;
}
St_FileOperation stFileOperation( St_FileOperation::enRead, pFileObject->m_Handle );
stFileOperation.u64Data.LowPart = n;
stFileOperation.u64Data.HighPart = 0;
ClHostConnection & Connection = *pFileObject->m_pHost;
ClMutualExclusiveAccess AccessNow( Connection );
// Begin to access this connection
// Above object makes sure this transaction not been interrupted or preempted
SOCKET Host = Connection.getFileSocket();
// Send the read command to the host for executing file reading.
if( !SendStream( Host, &stFileOperation, sizeof(stFileOperation) ) )
{
TRACE_PRINTF( ("NFS_ReadFile: Failed to send the request\n") );
return 0;
}
TRACE_PRINT_TRANS( ("NFS_ReadFile: Transaction %#x\n", stFileOperation.nTransactionId ) );
St_IntegerHolder stVerfication;
// Verify the requested handle is valid
if( !ReceiveStream( Host, &stVerfication, sizeof(stVerfication) ) )
{
TRACE_PRINTF( ("NFS_ReadFile: Failed to receive the handle verification\n") );
return 0;
}
if( stVerfication.nTransactionId != stFileOperation.nTransactionId + 1 )
{ // This transaction is inconsistent, that means it is interrupted and preempted.
TRACE_PRINTF( ("!!!NFS_ReadFile: The transaction is inconsistent, the ID of which is %#x, this one is %#x + 1 !!!\n",
stFileOperation.nTransactionId, stVerfication.nTransactionId - 1) );
return 0;
}
if( !stVerfication.nValue )
{
TRACE_PRINTF( ("NFS_ReadFile: The requested handle is invalid\n") );
return 0;
}
// Receive the data read from the host
Temporary<BYTE> pRecvBuffer = new BYTE[TRANSACTION_ID_SIZE+n];
if( !ReceiveStream( Host, (BYTE*)pRecvBuffer, TRANSACTION_ID_SIZE+n ) )
{
TRACE_PRINTF( ("NFS_ReadFile: Failed to receive the data\n") );
return 0;
}
int nTransactionId = *(int *)(BYTE *)pRecvBuffer;
if( nTransactionId != stFileOperation.nTransactionId + 2 )
{ // This transaction is inconsistent, that means it is interrupted and preempted.
TRACE_PRINTF( ("!!!NFS_ReadFile: The transaction is inconsistent, the ID of which is %#x, this one is %#x + 2 !!!\n",
stFileOperation.nTransactionId, nTransactionId - 2) );
return 0;
}
::memcpy( pBuffer, (BYTE*)pRecvBuffer + TRANSACTION_ID_SIZE, n );
return n;
}
size_t NFS_WriteFile(NFS_FILEHANDLE hFile, PVOID pBuffer, size_t n)
{
ClClientFileObject * pFileObject = (ClClientFileObject *)hFile;
if( !pFileObject->isValid() )
{
TRACE_PRINTF( ("NFS_WriteFile: An invalid handle\n") );
return 0;
}
St_FileOperation stFileOperation( St_FileOperation::enWrite, pFileObject->m_Handle );
stFileOperation.u64Data.LowPart = n;
stFileOperation.u64Data.HighPart = 0;
ClHostConnection & Connection = *pFileObject->m_pHost;
ClMutualExclusiveAccess AccessNow( Connection );
// Begin to access this connection
// Above object makes sure this transaction not been interrupted or preempted
SOCKET Host = Connection.getFileSocket();
// Send the read command to the host for executing file reading.
if( !SendStream( Host, &stFileOperation, sizeof(stFileOperation) ) )
{
TRACE_PRINTF( ("NFS_WriteFile: Failed to send the request\n") );
return 0;
}
TRACE_PRINT_TRANS( ("NFS_WriteFile: Transaction %#x\n", stFileOperation.nTransactionId ) );
St_IntegerHolder stVerfication;
// Verify the requested handle is valid
if( !ReceiveStream( Host, &stVerfication, sizeof(stVerfication) ) )
{
TRACE_PRINTF( ("NFS_WriteFile: Failed to receive the handle verification\n") );
return 0;
}
if( stVerfication.nTransactionId != stFileOperation.nTransactionId + 1 )
{ // This transaction is inconsistent, that means it is interrupted and preempted.
TRACE_PRINTF( ("!!!NFS_WriteFile: The transaction is inconsistent, the ID of which is %#x, this one is %#x + 1 !!!\n",
stFileOperation.nTransactionId, stVerfication.nTransactionId - 1) );
return 0;
}
if( !stVerfication.nValue )
{
TRACE_PRINTF( ("NFS_WriteFile: The requested handle is invalid\n") );
return 0;
}
Temporary<BYTE> pSendBuffer = new BYTE[TRANSACTION_ID_SIZE+n];
*(int *)(BYTE *)pSendBuffer = stFileOperation.nTransactionId + 2;
::memcpy( (BYTE *)pSendBuffer + TRANSACTION_ID_SIZE, pBuffer, n );
// Send the data read from the host
if( !SendStream( Host, (BYTE *)pSendBuffer, TRANSACTION_ID_SIZE+n ) )
{
TRACE_PRINTF( ("NFS_WriteFile: Failed to send the data\n") );
return 0;
}
return n;
}
BOOL NFS_SeekFile(NFS_FILEHANDLE hFile, DWORDLONG u64Offset)
{
#ifdef TRACE_VERBOSE
TRACE_PRINTF( ("NFS_SeekFile( , %#x)\n", (int)u64Offset) );
#endif
ClClientFileObject * pFileObject = (ClClientFileObject *)hFile;
if( !pFileObject->isValid() )
{
TRACE_PRINTF( ("NFS_SeekFile: An invalid handle\n") );
return FALSE;
}
St_FileOperation stFileOperation( St_FileOperation::enSeek, pFileObject->m_Handle );
stFileOperation.u64Data.QuadPart = u64Offset;
ClHostConnection & Connection = *pFileObject->m_pHost;
ClMutualExclusiveAccess AccessNow( Connection );
// Begin to access this connection
// Above object makes sure this transaction not been interrupted or preempted
SOCKET Host = Connection.getFileSocket();
// Send the read command to the host for executing file reading.
if( !SendStream( Host, &stFileOperation, sizeof(stFileOperation) ) )
{
TRACE_PRINTF( ("NFS_SeekFile: Failed to send the request\n") );
return FALSE;
}
TRACE_PRINT_TRANS( ("NFS_SeekFile: Transaction %#x\n", stFileOperation.nTransactionId ) );
St_IntegerHolder stResult;
// Verify the requested handle is valid
if( !ReceiveStream( Host, &stResult, sizeof(stResult) ) )
{
TRACE_PRINTF( ("NFS_SeekFile: Failed to receive the result\n") );
return FALSE;
}
if( stResult.nTransactionId != stFileOperation.nTransactionId + 1 )
{ // This transaction is inconsistent, that means it is interrupted and preempted.
TRACE_PRINTF( ("!!!NFS_SeekFile: The transaction is inconsistent, the ID of which is %#x, this one is %#x + 1 !!!\n",
stFileOperation.nTransactionId, stResult.nTransactionId - 1) );
return FALSE;
}
return stResult.nValue;
}
BOOL NFS_GetFileSize( NFS_FILEHANDLE hFile, DWORDLONG * pSize )
{
ClClientFileObject * pFileObject = (ClClientFileObject *)hFile;
if( !pFileObject->isValid() )
{
TRACE_PRINTF( ("NFS_GetFileSize: An invalid handle\n") );
return FALSE;
}
St_FileOperation stFileOperation( St_FileOperation::enGetSize, pFileObject->m_Handle );
ClHostConnection & Connection = *pFileObject->m_pHost;
ClMutualExclusiveAccess AccessNow( Connection );
// Begin to access this connection
// Above object makes sure this transaction not been interrupted or preempted
SOCKET Host = Connection.getFileSocket();
// Send the read command to the host for executing file reading.
if( !SendStream( Host, &stFileOperation, sizeof(stFileOperation) ) )
{
TRACE_PRINTF( ("NFS_GetFileSize: Failed to send the request\n") );
return FALSE;
}
TRACE_PRINT_TRANS( ("NFS_GetFileSize: Transaction %#x\n", stFileOperation.nTransactionId ) );
St_IntegerHolder stVerfication;
// Verify the requested handle is valid
if( !ReceiveStream( Host, &stVerfication, sizeof(stVerfication) ) )
{
TRACE_PRINTF( ("NFS_GetFileSize: Failed to receive the handle verification\n") );
return FALSE;
}
if( stVerfication.nTransactionId != stFileOperation.nTransactionId + 1 )
{ // This transaction is inconsistent, that means it is interrupted and preempted.
TRACE_PRINTF( ("!!!NFS_GetFileSize: The transaction is inconsistent, the ID of which is %#x, this one is %#x + 1 !!!\n",
stFileOperation.nTransactionId, stVerfication.nTransactionId - 1) );
return FALSE;
}
if( !stVerfication.nValue )
{
TRACE_PRINTF( ("NFS_GetFileSize: The requested handle is invalid\n") );
return FALSE;
}
// Receive the data read from the host
St_FileSizeHolder stFileSize;
if( !ReceiveStream( Host, &stFileSize, sizeof(stFileSize) ) )
{
TRACE_PRINTF( ("NFS_GetFileSize: Failed to receive the result\n") );
return FALSE;
}
if( stFileSize.nTransactionId != stFileOperation.nTransactionId + 2 )
{ // This transaction is inconsistent, that means it is interrupted and preempted.
TRACE_PRINTF( ("!!!NFS_GetFileSize: The transaction is inconsistent, the ID of which is %#x, this one is %#x + 2 !!!\n",
stFileOperation.nTransactionId, stFileSize.nTransactionId - 2) );
return FALSE;
}
*pSize = stFileSize.u64Size.QuadPart;
return TRUE;
}
} // extern "C"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -