⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs_cli.cpp

📁 一个普通的mount工具,能过CIFS协议来挂载盘符
💻 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 + -