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

📄 nfs_svr.cpp

📁 一个普通的mount工具,能过CIFS协议来挂载盘符
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <windows.h>
#include <__trace.h>
#include <dyn.h>
#include <tempory.h>
#include <hashtmp.h>
#include <regkey.h>
#include "nfs.h"
#include "nfp.inl"

#if !defined(TRACE_PRINTF) && !defined(NDEBUG) && defined(TRACE) && defined(_CONSOLE) 
#include <stdio.h>
#define TRACE_PRINTF( expr ) printf expr
#define TRACE_PRINTF_IF( condition, expr )  ( condition? printf expr: (void)0 )
#endif

#ifdef  VERBOSE_TRACE
#define TRACE_VERBOSE_MSG   TRACE_PRINTF
#else
#define TRACE_VERBOSE_MSG   
#endif

namespace namNFS
{
	const size_t MAX_OPENFILES = 0x400;

	unsigned ForST_HashTable_getHashCode(ClServerFileObject * p)
	{
		unsigned uHashCode = (unsigned)p;
		unsigned uGranularity = ( sizeof(ClServerFileObject) + sizeof(PVOID) - 1 )
			/ sizeof(PVOID) * sizeof(PVOID);
		uHashCode = uHashCode/uGranularity;
		uHashCode = uHashCode%MAX_OPENFILES;
		return uHashCode;
	}

	class ClOpenFiles : public ST_HashTable<ClServerFileObject *>
	{
		typedef ST_HashTable<ClServerFileObject *> ClParentClass;
	protected:
		int m_nOpenFiles;
		SOCKET m_Connection;

		ClParentClass::add;
		ClParentClass::remove;

		void clearNode(ClNode & node);
	public:
		ClOpenFiles( SOCKET Connection ) : 
			ClParentClass( MAX_OPENFILES ),
			m_Connection( Connection ),  
			m_nOpenFiles( 0 )
		{}
		~ClOpenFiles();

		BOOL add(ClServerFileObject * pFile)
		{
			if( ClParentClass::add( pFile ) )
			{
				m_nOpenFiles ++;
				return TRUE;
			}

			return FALSE;
		}

		BOOL remove(ClServerFileObject * pFile)
		{
			if( ClParentClass::remove( pFile ) )
			{
				m_nOpenFiles --;
				return TRUE;
			}

			return FALSE;
		}

	};

	void ClOpenFiles::clearNode(ClNode & node)
	{
		ClServerFileObject * pFileObject = node.m_data;

		if( pFileObject )
		{
			if( pFileObject->isValid() )
			{
				delete pFileObject;
				node.m_data = NULL;
			}
			else
			{
				::OutputDebugString( "!!!Fatal Error: A open file list of a connection is corrupted!!!\n" );
			}
		}
	}

	ClOpenFiles::~ClOpenFiles()
	{
		if( m_nOpenFiles )
		{
			size_t nItems = m_Table;

			//	Close all open files in this connection
			for(unsigned i = 0; i < nItems; i ++)
			{
				if( m_Table[i].m_isUsed )
				{
					clearNode( m_Table[i] );
				}

				ClNode * p = m_Table[i].m_pNext;
				while( p )
				{	
					clearNode( *p );
					p = p->m_pNext;
				}
			}	//	for

			TRACE_PRINTF( ("Closed %d files open in connection %d\n", m_nOpenFiles, m_Connection ) );
		}
	}

	BOOL matchAlias( LPCSTR szName, LPSTR szLocalPath )
	{
		CHAR szDir[MAX_PATH];

		LPCSTR szRest = ::strchr( szName, '\\' );
		if( szRest == NULL )
		{	//	There is no alias because there is not subdirectory name
			return FALSE;
		}

		size_t n = szRest - szName;
		::strncpy( szDir, szName, n );
		szDir[n] = 0;

		try
		{
			ClRegKey keyAliases( HKEY_LOCAL_MACHINE, "Software\\TodaySoft\\NfpService\\ShareAlias" );

			DWORD dwValueCount;
			if( ::RegQueryInfoKey( keyAliases,
					NULL, NULL,	//	Class
					NULL, //	Reserved
					NULL, NULL, NULL,
					&dwValueCount,
					NULL, NULL, NULL, NULL
					) != ERROR_SUCCESS ||
				dwValueCount == 0
			  )
			{
				return FALSE;
			}

			for( int i = 0; i < (int)dwValueCount; i ++ )
			{
				CHAR szAlias[MAX_PATH];
				CHAR szLocalDir[MAX_PATH];

				DWORD dwValueSize = MAX_PATH;
				DWORD dwDataSize = MAX_PATH;
				DWORD dwType = REG_SZ;

				if( ::RegEnumValue( keyAliases,
						i, szAlias, &dwValueSize, 
						NULL, &dwType, 
						(LPBYTE)szLocalDir, &dwDataSize ) == ERROR_SUCCESS )
				{
					if( ::stricmp( szAlias, szDir ) == 0 )
					{
						::strcpy( szLocalPath, szLocalDir );
						::strcat( szLocalPath, szRest );
						return TRUE;
					}
				}
			}

			return FALSE;
		}
		catch( ClRegKey::XFailedToCreate & )
		{
			return FALSE;
		}
	}
}

static void PutErrorMsg(void)
{
    DWORD dwLastError = ::GetLastError();
    LPVOID lpMsgBuf;

    if( ::FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dwLastError,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
      ) )
    {
        TRACE_PRINTF( ("GetLastError: Error code: %#x, reason: %s\n", dwLastError, lpMsgBuf) );

        // Free the buffer.
        LocalFree( lpMsgBuf );
    }
    else
    {
        TRACE_PRINTF( ("GetLastError: Error code: %#x\n", dwLastError) );
    }
}
 
using namespace namNFS;

ClNFSFileSysAgent::ClNFSFileSysAgent( const char * szServerIP ) :
	ClServerSocket( szServerIP, namNFS::FILE_SYS_PORT ) 
{}

void ClNFSFileSysAgent::OnConnect( SOCKET Connection )
{
	ClOpenFiles OpenFiles( Connection );
	//	Above object will make sure all open files in this connection can be
	//	closed if this connection is disconnected abnormally.

    TRACE_PRINTF( ("ClNFSFileSysAgent::OnConnect( %d )\n", Connection) );

    DYN<St_FileSysRequest> pRequest = new (MAX_PATH) St_FileSysRequest;

    if( (St_FileSysRequest *)pRequest == NULL )
    {
        TRACE_PRINTF( ("ClNFSFileSysAgent::OnConnect: Failed to allocate a St_FileSysRequest\n") );
        return;
    }

    while( TRUE )
    {
        //  Receive the file system request
        int nReceived = ::recv( Connection, 
            (LPSTR)(St_FileSysRequest *)pRequest, sizeof(St_FileSysRequest)+MAX_PATH, 0 );

        if( !nReceived )
        {
            TRACE_PRINTF( ("ClNFSFileSysAgent::OnConnect - Connection %d has been closed\n", Connection) );
            return;
        }

		if( nReceived == SOCKET_ERROR )
		{
			int nReason = ::WSAGetLastError();
			if( nReason == WSAECONNRESET )
			{   //  This connection has been closed, so quit this function
				TRACE_PRINTF( ("ClNFSFileSysAgent::OnConnect - Connection %d has been closed\n", Connection) );
				return;
			}

			TRACE_PRINTF( ("Failed to receive a file system request\n") );
			return;
		}

        switch( pRequest->eRequest )
        {
        case St_FileSysRequest::enOpen:
            {
                TRACE_PRINTF( ("Receive St_FileSysRequest::enOpen\n") );

                LPCSTR szFile;
				CHAR szLocalPath[MAX_PATH];

				if( matchAlias( (LPCSTR)pRequest->aryData, szLocalPath ) )
				{
					szFile = szLocalPath;
				}
				else
				{
					szFile = (LPCSTR)pRequest->aryData;
				}
					
				HANDLE hFile = ::CreateFile( szFile, 
                    pRequest->dwPara, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, 
                    OPEN_EXISTING, 
                    FILE_ATTRIBUTE_NORMAL, 
                    NULL );

                if( hFile != INVALID_HANDLE_VALUE )
                {
                    ClServerFileObject * pFileObject = new ClServerFileObject( hFile );
                    
                    if( pFileObject == NULL )
                    {
                        TRACE_PRINTF( ("ClNFSFileSysAgent::OnConnect: Failed to new a ClServerFileObject( %#x )\n", hFile) );
                        ::CloseHandle( hFile );
                        return;
                    }

					if( OpenFiles.add( pFileObject ) )
					{
						hFile = (HANDLE)pFileObject;
					}
					else
					{
						::OutputDebugString( "!!!Fatal Error: A connection is corrupted!!!\n" );
						hFile = INVALID_HANDLE_VALUE;
						delete pFileObject;
					}
                }
                else
                {
                    PutErrorMsg();
                    TRACE_PRINTF( ("Failed to open file \'%s\'\n", (LPCSTR)pRequest->aryData) );
                }

                //  Send back the handle of the open file
                int nSent = ::send( Connection, (LPCSTR)&hFile, sizeof(hFile), 0 );
                if( nSent != sizeof(hFile) )
                {
                    TRACE_PRINTF( ("Failed to send back the handle\n") );

                    //  Close the file and delete the file object
                    if( hFile != INVALID_HANDLE_VALUE )
                    {
                        ClServerFileObject * pFileObject = (ClServerFileObject *)hFile;
						if( !OpenFiles.remove( pFileObject ) )
						{
							::OutputDebugString( "!!!Fatal Error: A connection is corrupted!!!\n" );
						}

                        delete pFileObject;
                    }

                    return; //  An unhandled error, so close this connection

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -