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

📄 ioapi.cpp

📁 Complete PCAUSA samples including various kernel mode TDI code, TDI filters/redirectors and NDIS fil
💻 CPP
字号:
// IoApi.cpp : TDI Redirector Driver I/O Interface Support.
//

#include "stdafx.h"
#include "winioctl.h"

static OVERLAPPED   m_ovlp;
static HANDLE       m_hFileHandle = INVALID_HANDLE_VALUE; // Open device handle
static DWORD        m_BytesReturned = 0;
static BOOL         m_bIsLoadSuccessfully = FALSE;
static TCHAR        m_DriverName[FILE_NAME_SIZE];


BOOL TcpRedirector_InstallDriver( IN LPCTSTR DriverName )
{
    SC_HANDLE   schSCManager, schService;
    TCHAR       pszImagePath[ FILE_NAME_SIZE ];

    // Format full file name
    lstrcpy ( pszImagePath, _T("System32\\Drivers\\") );
    lstrcat ( pszImagePath, TDIREDIR_BASE_NAME );
    lstrcat ( pszImagePath, _T(".sys") );

    schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

    if ( schSCManager == NULL )
        return FALSE;

    schService = CreateService(
        schSCManager,          // SCManager database
        DriverName,           // name of service
        DriverName,           // name to display
        SERVICE_ALL_ACCESS,    // desired access
        SERVICE_KERNEL_DRIVER, // service type
        SERVICE_DEMAND_START,  // start type
        SERVICE_ERROR_NORMAL,  // error control type
        pszImagePath,          // service's binary
        _T("PNP_TDI"),         // no load ordering group
        NULL,                  // no tag identifier
        NULL,                  // no dependencies
        NULL,                  // LocalSystem account
        NULL                   // no password
        );

    if ( schService == NULL )
    {
        CloseServiceHandle( schSCManager );
        return FALSE;
    }

    CloseServiceHandle( schService );
    CloseServiceHandle( schSCManager );

    return TRUE;
}


BOOL TcpRedirector_RemoveDriver( IN LPCTSTR DriverName )
{
    SC_HANDLE  schService, SchSCManager;
    BOOL       ret;

    SchSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

    if ( SchSCManager == NULL )
        return FALSE;

    schService = OpenService( SchSCManager,
        DriverName,
        SERVICE_ALL_ACCESS
        );

    if ( schService == NULL )
    {
        CloseServiceHandle( SchSCManager );
        return FALSE;
    }

    ret = DeleteService( schService );

    CloseServiceHandle( schService );

    CloseServiceHandle( SchSCManager );

    return ret;
}

static BOOL TcpRedirector_StartDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName )
{
    SC_HANDLE  schService;
    BOOL       ret;

    schService = OpenService( SchSCManager,
        DriverName,
        SERVICE_ALL_ACCESS
        );
    if ( schService == NULL )
        return FALSE;

    ret = StartService( schService, 0, NULL )
        || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING 
        || GetLastError() == ERROR_SERVICE_DISABLED;

    CloseServiceHandle( schService );

    return ret;
}

static BOOL TcpRedirector_LoadDeviceDriver( const TCHAR * Name )
{
    SC_HANDLE   schSCManager;
    BOOL        okay;

    schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

    // Ignore success of start: it may already be started.
    okay = TcpRedirector_StartDriver( schSCManager, Name );

    CloseServiceHandle( schSCManager );

    return TRUE;
}

static BOOL TcpRedirector_DeviceIoControl(
    DWORD dwService, void *BuffIn, int SizeIn, void *BuffOut, int SizeOut, DWORD *SizeRet, LPOVERLAPPED povlp)
{
    BOOL Ret = 0;

    // Supports overlapped and nonoverlapped IO

    if ( !SizeRet )
      SizeRet = &m_BytesReturned;

    if( m_hFileHandle != INVALID_HANDLE_VALUE )
    {
        if( povlp == NULL )
            Ret = DeviceIoControl( m_hFileHandle, dwService, BuffIn, SizeIn, BuffOut, SizeOut, (unsigned long*)SizeRet, &m_ovlp);
        else 
            Ret = DeviceIoControl( m_hFileHandle, dwService, BuffIn, SizeIn, BuffOut, SizeOut, (unsigned long*)SizeRet, povlp);

    }

    return Ret;
}

BOOL TcpRedirector_SetRedirectRules(
   PTCP_REDIR_RULE_BUFFER pRuleBuffer,
   DWORD RuleBufferSize     // Total Number of Bytes at pRuleBuffer
   )
{
    BOOL bIOResult = FALSE;
    DWORD dwBytesReturned = 0;

    // Sanity Checks
    if( pRuleBuffer != NULL )
    {
        // Check Total Buffer Size
        if( RuleBufferSize != pRuleBuffer->TotalBufferSize )
        {
            SetLastError( ERROR_BAD_LENGTH );
            return FALSE;
        }

        // Make Sure Buffer Contains At Least One Port Rule
        if( pRuleBuffer->RuleCount == 0 )
        {
            SetLastError( ERROR_INVALID_DATA );
            return FALSE;
        }

        // Make Sure Port Rule Size Is Correct
        if( pRuleBuffer->RedirectRuleSize != sizeof( TCP_REDIR_RULE ) )
        {
            SetLastError( ERROR_INVALID_DATA );
            return FALSE;
        }
    }

    bIOResult = TcpRedirector_DeviceIoControl(
        IOCTL_SET_REDIRECTION_RULES,
        pRuleBuffer,
        pRuleBuffer != NULL ? RuleBufferSize : 0,
        NULL,
        0,
        &dwBytesReturned,   // Bytes Returned
        NULL
        );

    if( bIOResult == FALSE )
    {
//        printf( "Error: %d\n", GetLastError() );
    }

    return bIOResult;
}

BOOL TcpRedirector_ClearRedirectRules()
{
    return TcpRedirector_SetRedirectRules ( (PTCP_REDIR_RULE_BUFFER )NULL, 0 );
}

BOOL TcpRedirector_GetRedirectRules(
   PTCP_REDIR_RULE_BUFFER pRuleBuffer,
   DWORD RuleBufferSize     // Total Number of Bytes at pRuleBuffer
   )
{
    BOOL bIOResult = FALSE;
    DWORD dwBytesReturned = 0;

    // Sanity Checks
    if( pRuleBuffer == NULL )
    {
        return FALSE;
    }

    bIOResult = TcpRedirector_DeviceIoControl(
        IOCTL_GET_REDIRECTION_RULES,
        NULL,
        0,
        pRuleBuffer,
        pRuleBuffer != NULL ? RuleBufferSize : 0,
        &dwBytesReturned,   // Bytes Returned
        NULL
        );

    if( bIOResult == FALSE )
    {
//        printf( "Error: %d\n", GetLastError() );
    }

    return bIOResult;
}

BOOL TcpRedirector_GetOriginalDestination(
   PTCP_ORIGINAL_INFO pOriginalInfo,
   DWORD BufferSize,        // Total Number of Bytes at pOriginalInfo
   USHORT RedirectToPort    // The Proxy Local Port
   )
{
    BOOL bIOResult = FALSE;
    DWORD dwBytesReturned = 0;

    // Sanity Checks
    if( pOriginalInfo == NULL )
    {
        return FALSE;
    }

    if( BufferSize != sizeof(TCP_ORIGINAL_INFO) )
    {
        return FALSE;
    }

    memset( pOriginalInfo, 0x00, BufferSize );

    pOriginalInfo->OriginalInfoSize = BufferSize;

    pOriginalInfo->RemotePort = RedirectToPort;

    bIOResult = TcpRedirector_DeviceIoControl(
        IOCTL_GET_ORIGINAL_DESTINATION,
        pOriginalInfo,
        BufferSize,
        pOriginalInfo,
        BufferSize,
        &dwBytesReturned,   // Bytes Returned
        NULL
        );

    if( bIOResult == FALSE )
    {
//        printf( "Error: %d\n", GetLastError() );
    }

    return bIOResult;
}

BOOL TcpRedirector_Startup()
{
    TCHAR pszFullName [ FILE_NAME_SIZE ];

    // Format full file name
    lstrcpy ( pszFullName, _T("\\\\.\\") );
    lstrcat ( pszFullName, TDIREDIR_BASE_NAME );

    // Save driver name (in our case driver name equals device symbolic link)
    memset ( m_DriverName, 0, FILE_NAME_SIZE*sizeof(TCHAR) );
    _tcscpy ( m_DriverName, TDIREDIR_BASE_NAME );

    m_bIsLoadSuccessfully = FALSE;

    m_hFileHandle   = CreateFile ( pszFullName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 );

    if(m_hFileHandle == INVALID_HANDLE_VALUE)
    {
        // Install and load driver
        TcpRedirector_LoadDeviceDriver ( m_DriverName );
    }

    if(m_hFileHandle == INVALID_HANDLE_VALUE)
        m_hFileHandle   = CreateFile ( pszFullName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 );

    if( m_hFileHandle == INVALID_HANDLE_VALUE )
    {
        DWORD err = GetLastError ();
        m_ovlp.hEvent = 0;
    }
    else
    {
        m_ovlp.hEvent = 0;

        m_ovlp.hEvent = CreateEvent ( 0, TRUE, FALSE, NULL );

        if( m_ovlp.hEvent )
        {
            m_bIsLoadSuccessfully = TRUE;
        }
    }

    m_BytesReturned = 0;

    return m_bIsLoadSuccessfully;
}


void TcpRedirector_Shutdown()
{
    if( m_hFileHandle != INVALID_HANDLE_VALUE )
    {
        CloseHandle ( m_hFileHandle );
    }

    if( m_ovlp.hEvent != INVALID_HANDLE_VALUE )
    {
        CloseHandle ( m_ovlp.hEvent );
    }
}


BOOL TcpRedirector_IsDriverLoaded()
{
    if( !m_bIsLoadSuccessfully )
    {
        TcpRedirector_Startup();
    }

    return m_bIsLoadSuccessfully;
}

PTCP_REDIR_RULE_BUFFER TcpRedirector_AllocateRuleBuffer()
{
    PTCP_REDIR_RULE_BUFFER pRuleBuffer = NULL;

    pRuleBuffer = (PTCP_REDIR_RULE_BUFFER )malloc( sizeof( TCP_REDIR_RULE_BUFFER ) );

    if( pRuleBuffer != NULL )
    {
        pRuleBuffer->Reserved = 0;
        pRuleBuffer->TotalBufferSize = sizeof( TCP_REDIR_RULE_BUFFER );
        pRuleBuffer->RedirectRuleSize = sizeof( TCP_REDIR_RULE );
        pRuleBuffer->RuleCount = 0;
    }

    return pRuleBuffer;
}

void TcpRedirector_FreeRuleBuffer( PTCP_REDIR_RULE_BUFFER pRuleBuffer )
{
    free( (void * )pRuleBuffer );
}

static int TcpRedirector_PortRuleCompare( const void *arg1, const void *arg2 )
{
    PTCP_REDIR_RULE pKeyRule = (PTCP_REDIR_RULE )arg1;
    PTCP_REDIR_RULE pComparandRule = (PTCP_REDIR_RULE )arg2;

    if( pKeyRule->RemotePort == pComparandRule->RemotePort )
    {
        return 0;
    }

    if( pKeyRule->RemotePort < pComparandRule->RemotePort )
    {
        return -1;
    }

    return 1;
}

PTCP_REDIR_RULE TcpRedirector_FindPortRule(
    PTCP_REDIR_RULE_BUFFER pRuleBuffer,
    USHORT  RemotePort           // Port Number in Host Byte Order
    )
{
    TCP_REDIR_RULE KeyRule;

    KeyRule.RemotePort = RemotePort;

    return (PTCP_REDIR_RULE )bsearch( (void * )&KeyRule, &pRuleBuffer->RuleArray[0], pRuleBuffer->RuleCount, pRuleBuffer->RedirectRuleSize,
        TcpRedirector_PortRuleCompare );
}


PTCP_REDIR_RULE_BUFFER TcpRedirector_AddPortRule(
    PTCP_REDIR_RULE_BUFFER  pRuleBuffer,                // Previously Allocated Rule Buffer
    ULONG                   RemoteAddressRangeStart,
    ULONG                   RemoteAddressRangeEnd,
    ULONG                   RemoteNetMask,
    USHORT                  RemotePort,                 // Port Number in Host Byte Order
    PCHAR                   ProcessNameToRedirect,
    PCHAR                   ProcessNameToIgnore,
    HANDLE                  ProcessIdToIgnore,
    ULONG                   RedirectToAddress,
    USHORT                  RedirectToPort              // Host Byte Order
    )
{
    PTCP_REDIR_RULE pFoundRule = NULL;

    // Sanity Checks
    if( pRuleBuffer == NULL )
    {
        pRuleBuffer = TcpRedirector_AllocateRuleBuffer();
    }

    if( pRuleBuffer == NULL )
    {
        return pRuleBuffer;
    }

    if( htonl( RemoteAddressRangeStart ) > htonl( RemoteAddressRangeEnd ) )
    {
        return pRuleBuffer;
    }

    // Find Existing Rule, If Any
    pFoundRule = TcpRedirector_FindPortRule( pRuleBuffer, RemotePort );

    if( pFoundRule == NULL )
    {
        // Allocate Space for New Rule
        pRuleBuffer = (PTCP_REDIR_RULE_BUFFER )realloc( (void * )pRuleBuffer, pRuleBuffer->TotalBufferSize + sizeof( TCP_REDIR_RULE ) );

        if( pRuleBuffer == NULL )
        {
            return pRuleBuffer;
        }

        // Initialize Rule
        pRuleBuffer->TotalBufferSize = pRuleBuffer->TotalBufferSize + sizeof( TCP_REDIR_RULE );
        pRuleBuffer->RedirectRuleSize = sizeof( TCP_REDIR_RULE );

        ++pRuleBuffer->RuleCount;

        pFoundRule = &pRuleBuffer->RuleArray[ pRuleBuffer->RuleCount - 1 ];

        memset( pFoundRule, 0x00, sizeof( TCP_REDIR_RULE ) );
    }

    pFoundRule->RemoteAddressRangeStart = RemoteAddressRangeStart;
    pFoundRule->RemoteAddressRangeEnd = RemoteAddressRangeEnd;
    pFoundRule->RemoteNetMask = RemoteNetMask;
    pFoundRule->RemotePort = RemotePort;

    memset( pFoundRule->ProcessNameToRedirect, 0x00, sizeof( pFoundRule->ProcessNameToRedirect ) );

    if( ( ProcessNameToRedirect != NULL ) && ( *ProcessNameToRedirect != 0 ) )
    {
        strncpy( pFoundRule->ProcessNameToRedirect, ProcessNameToRedirect, sizeof( pFoundRule->ProcessNameToRedirect ) - 1 );
        _strupr( pFoundRule->ProcessNameToRedirect );
    }
    
    memset( pFoundRule->ProcessNameToIgnore, 0x00, sizeof( pFoundRule->ProcessNameToIgnore ) );

    if( ( ProcessNameToIgnore != NULL ) && ( *ProcessNameToIgnore != 0 ) )
    {
        strncpy( pFoundRule->ProcessNameToIgnore, ProcessNameToIgnore, sizeof( pFoundRule->ProcessNameToIgnore ) - 1 );
        _strupr( pFoundRule->ProcessNameToIgnore );
    }

    pFoundRule->ProcessIdToIgnore = ProcessIdToIgnore;

    pFoundRule->RedirectToAddress = RedirectToAddress;
    pFoundRule->RedirectToPort = RedirectToPort;

    // Quick Sort the Rule Buffer
    qsort( (void * )&pRuleBuffer->RuleArray[0], pRuleBuffer->RuleCount, pRuleBuffer->RedirectRuleSize,
        TcpRedirector_PortRuleCompare );

    return pRuleBuffer;
}




⌨️ 快捷键说明

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