Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

530 lines
14 KiB

/*******************************************************************************
Module Name:
work.cpp
Abstract:
Implements main function of the bridge test application
Author:
Qianbo Huai (qhuai) Jan 27 2000
*******************************************************************************/
#include "stdafx.h"
// command line
LPSTR glpCmdLine = NULL;
// dialog
HWND ghDlg = NULL;
// true: exit button on dialog was clicked
bool gfExitButton = false;
// bridge
CBridgeApp *gpBridgeApp = NULL;
// callback func in dialog
BOOL
CALLBACK
MainDialogProc (
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
// func to deal with TAPI events
HRESULT
OnTapiEvent (
TAPI_EVENT TapiEvent,
IDispatch *pEvent
);
HRESULT
OnPrivateEvent (IDispatch *pEvent);
// set status message on dialog
void SetStatusMessage (LPWSTR pszMessage);
void DoMessage (LPWSTR pszMessage);
void EnableDisconnectButton (BOOL fYes);
/*//////////////////////////////////////////////////////////////////////////////
WinMain
////*/
int
WINAPI
WinMain (
HINSTANCE hInst,
HINSTANCE hPrevInst,
LPSTR lpCmdLine,
int nShowCmd
)
{
// init com
if (FAILED (CoInitializeEx(NULL, COINIT_MULTITHREADED)))
return 0;
// init debug
BGLOGREGISTER (L"work");
// keep command line which determines which SDP to join
glpCmdLine = lpCmdLine;
// init CBridgeApp
HRESULT hr;
gpBridgeApp = new CBridgeApp (&hr);
if (gpBridgeApp==NULL || FAILED (hr))
{
LOG ((BG_ERROR, "Failed to init CBridgeApp"));
return 0;
}
// start dialog box
if (!DialogBox (hInst, MAKEINTRESOURCE(IDD_MAINDLG), NULL, MainDialogProc))
{
LOG ((BG_TRACE, "Dialog ends"));
}
// dialog finished
delete gpBridgeApp;
BGLOGDEREGISTER ();
CoUninitialize ();
return 1;
}
/*//////////////////////////////////////////////////////////////////////////////
Callback for dialog
////*/
BOOL
CALLBACK
MainDialogProc (
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
ghDlg = hDlg;
EnableDisconnectButton (false);
return 0;
}
case WM_PRIVATETAPIEVENT:
{
OnTapiEvent ((TAPI_EVENT)wParam, (IDispatch *)lParam);
return 0;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_EXIT:
{
gfExitButton = true;
gpBridgeApp->DisconnectAllCalls (DC_NORMAL);
// check if in connection
if (!IsWindowEnabled (GetDlgItem (ghDlg, IDC_DISCONNECT)))
{
// not in connection
EndDialog (ghDlg, 0);
}
// else
// remember exit button is clicked
// do not call EndDialog because a disconnected event is to come
return 1;
}
case IDC_DISCONNECT:
{
gpBridgeApp->DisconnectAllCalls (DC_NORMAL);
// disable disconnect button
EnableDisconnectButton (false);
return 1;
}
}
case IDC_NEXTSUBSTREAM:
{
gpBridgeApp->NextSubStream ();
return 1;
}
return 0;
}
default:
return 0;
}
}
/*//////////////////////////////////////////////////////////////////////////////
Deals with TAPI events
////*/
HRESULT OnTapiEvent (
TAPI_EVENT TapiEvent,
IDispatch *pEvent
)
{
HRESULT hr = S_OK;
// LOGEvent ((BG_TE, TapiEvent));
switch (TapiEvent)
{
case TE_CALLNOTIFICATION:
{
if (BST_CHECKED != IsDlgButtonChecked (ghDlg, IDC_REJECT))
{
// if h323 call and to us, init h323 call
if (FAILED (hr = gpBridgeApp->CreateH323Call (pEvent)));
LOG ((BG_ERROR, "Failed to create h323 call, %x", hr));
}
break;
}
case TE_CALLSTATE:
{
CALL_STATE cs;
ITCallStateEvent *pCallStateEvent = NULL;
// get call state event
hr = pEvent->QueryInterface (
IID_ITCallStateEvent,
(void **)&pCallStateEvent
);
if (FAILED(hr)) break;
// get call state
hr = pCallStateEvent->get_State (&cs);
pCallStateEvent->Release ();
if (FAILED(hr)) break;
// LOGEvent ((BG_CS, cs));
// if offering, connect
if (CS_OFFERING == cs)
{
CBridgeItem *pItem = NULL;
// check if h323 call created successful
hr = gpBridgeApp->HasH323Call (pEvent, &pItem);
if (S_OK != hr || NULL == pItem)
{
LOG ((BG_ERROR, "Failed to check h323 call, %x", hr));
hr = S_OK;
break;
}
// create sdp call
if (FAILED (hr = gpBridgeApp->CreateSDPCall (pItem)))
{
gpBridgeApp->DisconnectCall (pItem, DC_REJECTED);
// delete pItem;
LOG ((BG_ERROR, "Failed to create SDP call, %x", hr));
break;
}
// bridge call
if (FAILED (hr = gpBridgeApp->BridgeCalls (pItem)))
{
gpBridgeApp->DisconnectCall (pItem, DC_REJECTED);
// delete pItem;
LOG ((BG_ERROR, "Failed to bridge calls, %x", hr));
break;
}
// enable disconnect button
EnableDisconnectButton (true);
}
// if disconnect
else if (CS_DISCONNECTED == cs)
{
CBridgeItem *pItem = NULL;
// check if h323 call created successful
hr = gpBridgeApp->HasH323Call (pEvent, &pItem);
if (S_OK == hr && NULL != pItem)
{
// the call already disconnected
// call disconnect here only to remove pItem from the list
gpBridgeApp->RemoveCall (pItem);
delete pItem;
}
// if exit button is clicked and all call disconnected
if (gfExitButton)
{
if (S_OK != gpBridgeApp->HasCalls ())
EndDialog (ghDlg, 0);
}
else
{
if (S_OK != gpBridgeApp->HasCalls ())
EnableDisconnectButton (false);
}
}
break;
}
case TE_CALLMEDIA:
{
CALL_MEDIA_EVENT cme;
ITCallMediaEvent *pCallMediaEvent;
// get call media event
hr = pEvent->QueryInterface (
IID_ITCallMediaEvent,
(void **)&pCallMediaEvent
);
if (FAILED(hr)) break;
// get the event
hr = pCallMediaEvent->get_Event (&cme);
if (FAILED(hr)) break;
// LOGEvent ((BG_CME, cme));
// check media event
switch (cme)
{
case CME_STREAM_FAIL:
hr = E_FAIL;
LOG ((BG_ERROR, "Stream failed"));
break;
case CME_TERMINAL_FAIL:
hr = E_FAIL;
LOG ((BG_ERROR, "Terminal failed"));
break;
default:
break;
}
// we no longer need this interface.
pCallMediaEvent->Release();
break;
}
case TE_PRIVATE:
hr = OnPrivateEvent (pEvent);
break;
default:
break;
}
pEvent->Release(); // we addrefed it CTAPIEventNotification::Event()
return hr;
}
/*//////////////////////////////////////////////////////////////////////////////
////*/
HRESULT OnPrivateEvent (
IDispatch *pEvent
)
{
ENTER_FUNCTION ("OnPrivateEvent");
// LOG ((BG_TRACE, "%s entered", __fxName));
HRESULT hr = S_OK;
ITPrivateEvent *pPrivateEvent = NULL;
IDispatch *pDispatch = NULL;
ITParticipantEvent *pPartEvent = NULL;
ITParticipant *pParticipant = NULL;
PARTICIPANT_EVENT event;
ITCallInfo *pCallInfo = NULL;
ITBasicCallControl *pCallControl = NULL;
// get private event interface
if (FAILED (hr = pEvent->QueryInterface (&pPrivateEvent)))
{
LOG ((BG_ERROR, "%s failed to query ITPrivateEvent", __fxName));
return hr;
}
// get event interface
if (FAILED (hr = pPrivateEvent->get_EventInterface (&pDispatch)))
{
LOG ((BG_ERROR, "%s failed to query event interface", __fxName));
goto Error;
}
// get participant event interface
hr = pDispatch->QueryInterface (&pPartEvent);
pDispatch->Release ();
pDispatch = NULL;
if (FAILED (hr))
{
LOG ((BG_ERROR, "%s failed to query participant interface", __fxName));
goto Error;
}
// get event
if (FAILED (hr = pPartEvent->get_Event (&event)))
{
LOG ((BG_ERROR, "%s failed to get event", __fxName));
goto Error;
}
// LOGEvent ((BG_PE, event));
// check the event
switch (event)
{
case PE_PARTICIPANT_ACTIVE:
{
// get call info
if (FAILED (hr = pPrivateEvent->get_Call (&pCallInfo)))
{
LOG ((BG_ERROR, "%s failed to get call info", __fxName));
goto Error;
}
// get call control
if (FAILED (hr = pCallInfo->QueryInterface (&pCallControl)))
{
LOG ((BG_ERROR, "%s failed to get call control", __fxName));
goto Error;
}
// get participant interface
if (FAILED (hr = pPartEvent->get_Participant (&pParticipant)))
{
LOG ((BG_ERROR, "%s failed to get participant", __fxName));
goto Error;
}
// show participant
hr = gpBridgeApp->ShowParticipant (pCallControl, pParticipant);
if (FAILED (hr))
{
LOG ((BG_ERROR, "%s failed to show participant, %x", __fxName, hr));
}
if (S_FALSE == hr)
{
hr = S_OK;
// *ppszMessage = L"Participant active but call not found in list";
// or no substream found on the stream
}
}
break;
default:
break;
}
Cleanup:
if (pCallInfo) pCallInfo->Release ();
if (pCallControl) pCallControl->Release ();
if (pPrivateEvent) pPrivateEvent->Release ();
if (pPartEvent) pPartEvent->Release ();
if (pParticipant) pParticipant->Release ();
// LOG ((BG_TRACE, "%s exits", __fxName));
return hr;
Error:
goto Cleanup;
}
/*//////////////////////////////////////////////////////////////////////////////
Popup message box
////*/
WCHAR gMsgBoxTitle[] = L"TAPI 3.0 Bridge Test Application";
void
DoMessage (LPWSTR pszMessage)
{
#if POPUP_MESSAGE
MessageBox (
ghDlg,
pszMessage,
gMsgBoxTitle,
MB_OK
);
#endif
}
/*//////////////////////////////////////////////////////////////////////////////
Status message
////*/
void
SetStatusMessage (LPWSTR pszMessage)
{
SetDlgItemText (ghDlg, IDC_STATUS, pszMessage);
}
/*//////////////////////////////////////////////////////////////////////////////
////*/
void
EnableDisconnectButton (BOOL fYes)
{
if (fYes)
{
// enable
SetStatusMessage (L"Bridging calls ...");
SendDlgItemMessage (
ghDlg,
IDC_NEXTSUBSTREAM,
BM_SETSTYLE,
BS_DEFPUSHBUTTON,
0
);
SendDlgItemMessage (
ghDlg,
IDC_DISCONNECT,
BM_SETSTYLE,
BS_DEFPUSHBUTTON,
0
);
EnableWindow (
GetDlgItem (ghDlg, IDC_NEXTSUBSTREAM),
TRUE
);
EnableWindow (
GetDlgItem (ghDlg, IDC_DISCONNECT),
TRUE
);
SetFocus (GetDlgItem (ghDlg, IDC_DISCONNECT));
}
else
{
// disable
SetStatusMessage (L"Waiting for calls ...");
SendDlgItemMessage (
ghDlg,
IDC_NEXTSUBSTREAM,
BM_SETSTYLE,
BS_PUSHBUTTON,
0
);
SendDlgItemMessage (
ghDlg,
IDC_DISCONNECT,
BM_SETSTYLE,
BS_PUSHBUTTON,
0
);
EnableWindow (
GetDlgItem (ghDlg, IDC_NEXTSUBSTREAM),
FALSE
);
EnableWindow (
GetDlgItem (ghDlg, IDC_DISCONNECT),
FALSE
);
}
}