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

📄 tapirecv.cpp

📁 tapi3.0实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                                                   VARIANT_TRUE,
                                                   TAPIMEDIATYPE_AUDIO,
                                                   g_nTAPINotificationCookie,
                                                   &ulCallNotificationCookie
                                                   );

    return hr;
}


///////////////////////////////////////////////////////////////////////////////
//
// StartListening
//
// find all addresses that support audio and start listening on them
//
///////////////////////////////////////////////////////////////////////////////

HRESULT StartListening()
{

    HRESULT hr = S_OK;

    LogMessage("StartListening: started");
    

    //
    // enumerate available addresses
    // 
    
    IEnumAddress *pEnumAddress = NULL;

    hr = g_pTapi->EnumerateAddresses( &pEnumAddress );

    if (FAILED(hr))
    {
        LogError("StartListening: Failed to enumerate addresses");

        return hr;
    }


    //
    // this flag remains false until we succeded starting listening on at 
    // least one address
    //

    BOOL bListenStarted = FALSE;


    //
    // walk through all the addresses and start listening on the ones that
    // support audio
    //
    
    while (TRUE)
    {
        //
        // check the next address
        //

        ITAddress *pAddress = NULL;

        hr = pEnumAddress->Next(1, &pAddress, NULL);

        if (S_OK != hr)
        {

            //
            // no more addresses or error
            //

            break;
        }


        //
        // log the name of the address
        //

        BSTR bstrAddressName;
        hr = pAddress->get_AddressName(&bstrAddressName);

        if (SUCCEEDED(hr))
        {

            LogMessage("StartListening: -> found address [%S]",
                        bstrAddressName);

            SysFreeString(bstrAddressName);
        }
        else
        {
            LogError("StartListening: failed to get address name");
        }


        //
        // if the address supports audio and media streaming terminal, 
        // start listening
        //

        if ( AddressSupportsAudio(pAddress) && AddressSupportsMST(pAddress) )
        {

            //
            // start listening on this address
            // 

            LogMessage("StartListening: Starting listening.");

            hr = ListenOnAddress(pAddress);

            if (SUCCEEDED(hr))
            {

                //
                // we are listening on at least one address
                //

                bListenStarted = TRUE;

                LogMessage("StartListening: "
                           "-> started listening on this address");

            }
            else
            {
                //
                // log an error and continue
                //

                LogError("StartListening: -> failed starting listening on this address, "
                         "hr = 0x%lx", hr);
            }
        }
        else
        {
            LogMessage("StartListening: -> no audio or MST support on this address.");
        }


        pAddress->Release();
        pAddress = NULL;

    }


    pEnumAddress->Release();
    pEnumAddress = NULL;


    //
    // depending on whether we started listening or not, log a message and
    // return the appropriate error code.
    //

    if (bListenStarted)
    {
        LogMessage("StartListening: completed. "
                   "Listening on one or more addresses");

        return S_OK;
    }
    else
    {
        LogMessage("StartListening: completed. Not listening on any address.");

        return E_FAIL;
    }
}


///////////////////////////////////////////////////////////////////////////////
//
// InitializeTAPI
//
// create and initialize the tapi object
//
///////////////////////////////////////////////////////////////////////////////

HRESULT InitializeTAPI()
{
    
    LogMessage("InitializeTAPI: started");

    HRESULT hr = E_FAIL;
        

    //
    // cocreate the TAPI object
    //

    hr = CoCreateInstance(
                          CLSID_TAPI,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ITTAPI,
                          (LPVOID *)&g_pTapi
                         );

    if (FAILED(hr))
    {
        LogError("InitializeTAPI: failed to CoCreateInstance TAPI");

        return hr;
    }


    //
    // cannot use tapi until it's initialized
    //

    hr = g_pTapi->Initialize();

    if (FAILED(hr))
    {
        LogError("InitializeTAPI: TAPI failed to initialize");

        g_pTapi->Release();
        g_pTapi = NULL;
        
        return hr;
    }


    //
    // register the callback object that will receive tapi notifications
    //

    hr = RegisterCallback();

    if (FAILED(hr))
    {
        LogError("InitializeTAPI: failed to register callback");

        g_pTapi->Shutdown();
        g_pTapi->Release();
        g_pTapi = NULL;
        
        return hr;
    }


    //
    // we want to be notified of these events:
    //
   
    hr = g_pTapi->put_EventFilter(TE_CALLNOTIFICATION |
                                  TE_CALLSTATE |
                                  TE_CALLMEDIA);

    if (FAILED(hr))
    {
        LogError("InitializeTAPI: Failed to put_EventFilter");

        //
        // unregister callback
        //

        UnRegisterCallBack();

        //
        // shutdown and release TAPI
        //

        g_pTapi->Shutdown();
        g_pTapi->Release();
        g_pTapi = NULL;

        return hr;
    }


    //
    // start listening on the addresses that support audio
    //

    hr = StartListening();

    if (S_OK != hr)
    {
        LogError("InitializeTAPI: Failed to start listening");

        //
        // unregister callback
        //

        UnRegisterCallBack();

        //
        // shutdown and release TAPI
        //

        g_pTapi->Shutdown();
        g_pTapi->Release();
        g_pTapi = NULL;

        return hr;
    }

    LogMessage("InitializeTAPI: succeeded");

    return S_OK;
}



///////////////////////////////////////////////////////////////////////////////
//
// DisconnectAndReleaseCall
// 
// disconnect and release the current call, if we have one
//
///////////////////////////////////////////////////////////////////////////////

void DisconnectAndReleaseCall()
{

    //
    // g_pCurrentCall can be accessed from event-processing thread and
    // needs to be protected
    //

    EnterCriticalSection(&g_CurrentCallCritSection);

    if (NULL != g_pCurrentCall)
    {

        //
        // if the call exists, attempt to disconnect it
        //

        LogMessage("DisconnectAndReleaseCall: disconnecting the call");

        g_pCurrentCall->Disconnect(DC_NORMAL);


        //
        // succeded or failed, release the call
        //

        g_pCurrentCall->Release();
        g_pCurrentCall = NULL;
    }

    
    LeaveCriticalSection(&g_CurrentCallCritSection);
}


///////////////////////////////////////////////////////////////////////////////
//
// ShutdownTapi
//
// - unregister callback object
// - shutdown and release TAPI object
//
///////////////////////////////////////////////////////////////////////////////

void ShutdownTapi()
{

    LogMessage("ShutdownTapi: started");

    
    // 
    // if there is still a call, disconnect it
    //

    HRESULT hr = E_FAIL;


    //
    // by now, the call is released and disconnected.
    // shutdown tapi
    //

    if (NULL != g_pTapi)
    {
        //
        // unregister callback
        //

        UnRegisterCallBack();


        //
        // shutdown and release the TAPI object
        //

        g_pTapi->Shutdown();
        g_pTapi->Release();
        g_pTapi = NULL;

    }

    
    //
    // in the unlikely case another call was received after we released the 
    // call that we had, release the new call.
    //
    
    EnterCriticalSection(&g_CurrentCallCritSection);

    if (NULL != g_pCurrentCall)
    {
        
        g_pCurrentCall->Release();
        g_pCurrentCall = NULL;

    }

    LeaveCriticalSection(&g_CurrentCallCritSection);

    LogMessage("ShutdownTapi: succeeded");
}


///////////////////////////////////////////////////////////////////////////////
//
// CtrlHandler
//
// set shutdown flag when the user requests exit by pressing
// ctrl+break, attempting to log off, close the window, or
// shutdown windows. this will give use a chance to exit gracefully.
//
///////////////////////////////////////////////////////////////////////////////

BOOL CtrlHandler(DWORD nEventType) 
{

    static BOOL bShutdownInProgress = FALSE;

    
    //
    // are we in the middle of shutting down?
    //

    if (TRUE == bShutdownInProgress)
    {
        LogMessage("CtrlHandler: Shutdown already in progress");

        return TRUE;
    }


    //
    // any exit event (close, ctrl+break/C, logoff, shutdown)
    // is a signal for the application to exit.
    //

    switch (nEventType)
    { 
 
        case CTRL_C_EVENT: 
        case CTRL_CLOSE_EVENT: 
        case CTRL_BREAK_EVENT: 
        case CTRL_LOGOFF_EVENT: 
        case CTRL_SHUTDOWN_EVENT:

            LogMessage("CtrlHandler: Initiating shutdown.");
            
            //
            // ignore subsequent shutdown requests...
            //

            bShutdownInProgress = TRUE;
            
            //
            // signal shutdown
            //

            SetEvent(g_hExitEvent);
            break;

        default: 
            break;

    } 

    return TRUE;
}
 

///////////////////////////////////////////////////////////////////////////////
//
// main
// 
///////////////////////////////////////////////////////////////////////////////

int __cdecl main(int argc, char* argv[])
{

    LogMessage("main: started");


    //
    // this event be signalled when it's time to exit
    //

    g_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (NULL == g_hExitEvent)
    {
        LogError("main: Failed to create exit event");

        return 1;
    }

   

    //
    // we want to handle ctrl+c and ctrl+break events so we can cleanup on exit
    // proceed even in case of failure
    //

    SetConsoleCtrlHandler( (PHANDLER_ROUTINE)CtrlHandler, TRUE);


    //
    // initialize COM
    //

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    if ( FAILED(hr))
    {
        LogError("main: Failed to CoInitialize");

        CloseHandle(g_hExitEvent);
        g_hExitEvent = NULL;

        return 1;
    }


    //
    // start worker thread for tapi message processing
    //

    hr = g_WorkerThread.Initialize();

    if (FAILED(hr))
    {
        LogError("main: Failed to initialize worker thread");
        
        CoUninitialize();

        CloseHandle(g_hExitEvent);
        g_hExitEvent = NULL;

        return 1;
    }


    //
    // initialize critical section used to serialize access to global
    // current call
    //
    // note: InitializeCriticalSection can raise STATUS_NO_MEMORY exception
    //

    InitializeCriticalSection(&g_CurrentCallCritSection);

    //
    // create and initialize tapi object, register the callback object 
    // and start listening
    //
    
    hr = InitializeTAPI();

    if (FAILED(hr))
    {
        
        g_WorkerThread.Shutdown();


        CloseHandle(g_hExitEvent);
        g_hExitEvent = NULL;

        DeleteCriticalSection(&g_CurrentCallCritSection);

        CoUninitialize();
        return 1;
    }

    
    //
    // wait until ctrl+break handler or CS_DISCONNECT handler signal exit event
    //

    LogMessage("main: waiting for exit event");

    DWORD nWaitResult = WaitForSingleObject(g_hExitEvent, INFINITE);
    
    LogMessage("main: exit event signaled");


    //
    // disconnect and release call, if it exists
    //

    DisconnectAndReleaseCall();


    //
    // cleanup tapi
    //

    ShutdownTapi();


    //
    // stop the worker thread
    //

    g_WorkerThread.Shutdown();


    //
    // no longer need the critical section
    //

    DeleteCriticalSection(&g_CurrentCallCritSection);


    //
    // release com
    //
    
    CoUninitialize();


    //
    // no longer need the event
    //

    CloseHandle(g_hExitEvent);
    g_hExitEvent = NULL;


    //
    // exiting... we no longer want to handle ctrl+c and ctrl+break
    //
    
    SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, FALSE);


    //
    // was the event signaled, or wait failed?
    //

    if (WAIT_OBJECT_0 != nWaitResult)
    {
        LogError("main: Failed to wait for exit event");
        return 1;
    }


    LogMessage("main: exiting");

	return 0;
}

⌨️ 快捷键说明

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