windows-nt/Source/XPSP1/NT/net/tapi/server/event.c
2020-09-26 16:20:57 +08:00

1325 lines
34 KiB
C

/*++ BUILD Version: 0000 // Increment this if a change has global effects
Copyright (c) 1999-2001 Microsoft Corporation
Module Name:
event.c
Abstract:
Src module for tapi event filtering funcs
Author:
Xiaohai Zhang (xzhang) 24-Nov-1999
Revision History:
--*/
#include "windows.h"
#include "tapi.h"
#include "tspi.h"
#include "client.h"
#include "loc_comn.h"
#include "server.h"
#include "private.h"
#include "tapihndl.h"
#include "utils.h"
extern BOOL gbNTServer;
//
// GetSubMaskIndex
// Description:
// Get the index into the submask array in vairous TAPI server object
// from the event mask, there should be one and only one bit set in
// ulEventMask
// Parameters:
// ulEventMask : the mask whose submask index to be returned
// Return Value:
// The index of the message mask in ulEventMask
//
DWORD
GetSubMaskIndex (ULONG64 ulEventMask)
{
DWORD dwSubMaskIndex;
// Assert that there is one and only one bit set in ulEventMask
ASSERT (ulEventMask !=0 && (ulEventMask & (ulEventMask - 1)) == 0);
dwSubMaskIndex = 0;
while (ulEventMask > 1)
{
ulEventMask >>= 1;
++dwSubMaskIndex;
}
return dwSubMaskIndex;
}
//
// GetMsgMask
// Description:
// Utility function to get corresponding msg mask and its submask index
// Parameters:
// Msg : whose mask and submask index to be returned
// pulMask : address to hold the returned mask
// pdwSubMaskIndex : address to hold the returned submask index
// Return Value:
// TRUE if there exists a mask defined for the Msg, otherwise FALSE
//
BOOL
GetMsgMask (DWORD Msg, ULONG64 * pulMask, DWORD *pdwSubMaskIndex)
{
ULONG64 ulMask;
DWORD dwSubMaskIndex;
if (NULL == pulMask ||
NULL == pdwSubMaskIndex)
{
ASSERT (0);
return FALSE;
}
switch (Msg)
{
case LINE_ADDRESSSTATE:
ulMask = EM_LINE_ADDRESSSTATE;
break;
case LINE_LINEDEVSTATE:
ulMask = EM_LINE_LINEDEVSTATE;
break;
case LINE_CALLINFO:
ulMask = EM_LINE_CALLINFO;
break;
case LINE_CALLSTATE:
ulMask = EM_LINE_CALLSTATE;
break;
case LINE_APPNEWCALL:
ulMask = EM_LINE_APPNEWCALL;
break;
case LINE_CREATE:
ulMask = EM_LINE_CREATE;
break;
case LINE_REMOVE:
ulMask = EM_LINE_REMOVE;
break;
case LINE_CLOSE:
ulMask = EM_LINE_CLOSE;
break;
// case LINE_PROXYREQUEST:
// ulMask = EM_LINE_PROXYREQUEST;
// break;
case LINE_DEVSPECIFIC:
ulMask = EM_LINE_DEVSPECIFIC;
break;
case LINE_DEVSPECIFICFEATURE:
ulMask = EM_LINE_DEVSPECIFICFEATURE;
break;
case LINE_AGENTSTATUS:
ulMask = EM_LINE_AGENTSTATUS;
break;
case LINE_AGENTSTATUSEX:
ulMask = EM_LINE_AGENTSTATUSEX;
break;
case LINE_AGENTSPECIFIC:
ulMask = EM_LINE_AGENTSPECIFIC;
break;
case LINE_AGENTSESSIONSTATUS:
ulMask = EM_LINE_AGENTSESSIONSTATUS;
break;
case LINE_QUEUESTATUS:
ulMask = EM_LINE_QUEUESTATUS;
break;
case LINE_GROUPSTATUS:
ulMask = EM_LINE_GROUPSTATUS;
break;
// case LINE_PROXYSTATUS:
// ulMask = EM_LINE_PROXYSTATUS;
// break;
case LINE_APPNEWCALLHUB:
ulMask = EM_LINE_APPNEWCALLHUB;
break;
case LINE_CALLHUBCLOSE:
ulMask = EM_LINE_CALLHUBCLOSE;
break;
case LINE_DEVSPECIFICEX:
ulMask = EM_LINE_DEVSPECIFICEX;
break;
case LINE_QOSINFO:
ulMask = EM_LINE_QOSINFO;
break;
case PHONE_CREATE:
ulMask = EM_PHONE_CREATE;
break;
case PHONE_REMOVE:
ulMask = EM_PHONE_REMOVE;
break;
case PHONE_CLOSE:
ulMask = EM_PHONE_CLOSE;
break;
case PHONE_STATE:
ulMask = EM_PHONE_STATE;
break;
case PHONE_DEVSPECIFIC:
ulMask = EM_PHONE_DEVSPECIFIC;
break;
case PHONE_BUTTON:
ulMask = EM_PHONE_BUTTONMODE;
break;
default:
ulMask = 0;
}
if (ulMask != 0)
{
*pulMask = ulMask;
*pdwSubMaskIndex = GetSubMaskIndex(ulMask);
}
return (ulMask ? TRUE : FALSE);
}
//
// FMsgDisabled
// Description:
// Utility function used throughout tapisrv to check if a message
// is allowed to be sent or not.
// Parameters:
// dwAPIVersion : the object API version
// adwEventSubMasks: the object submasks array
// Msg : the message to be checked
// dwParam1 : the sub message of Msg to be checked
// Return Value:
// TRUE if the message should NOT be sent, otherwise FALSE
//
BOOL
FMsgDisabled (
DWORD dwAPIVersion,
DWORD *adwEventSubMasks,
DWORD Msg,
DWORD dwParam1
)
{
BOOL fRet;
ULONG64 ulMsgMask;
DWORD dwSubMaskIndex;
if (dwAPIVersion <= TAPI_VERSION3_0)
{
LOG((TL_INFO, "FMsgDisbled: dwAPIVersion<= TAPI_VERSION3_0, msg will be enabled"));
fRet = FALSE;
goto ExitHere;
}
//
// The message is allowed to be sent if
// (1). No event mask defined for Msg, i.e LINE_REPLY
// (2). Msg is enabled for all submasks adwEventSubMasks[index] = (-1)
// (3). SubMask enabled: adwEventSubMask[index] & dwParam1 != 0
//
if (!GetMsgMask(Msg, &ulMsgMask, &dwSubMaskIndex) ||
adwEventSubMasks[dwSubMaskIndex] == (-1) ||
((adwEventSubMasks[dwSubMaskIndex] & dwParam1) != 0))
{
fRet = FALSE;
}
else
{
fRet = TRUE;
}
ExitHere:
LOG((TL_TRACE, "FMsgDisabled return %x", fRet));
return (fRet);
}
//
// SetEventMasksOrSubMasks
// Description:
// Utility function used to apply masks or submasks to a certain objects
// submasks array.
// Parameters:
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// adwEventSubMasks: the submasks array from the object
// Return Value:
// Always succeed.
//
LONG
SetEventMasksOrSubMasks (
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks,
DWORD *adwTargetSubMasks
)
{
ULONG64 ulMask = 1;
LONG lResult = S_OK;
DWORD dwIndex = 0;
if (NULL == adwTargetSubMasks)
{
ASSERT (0);
return LINEERR_INVALPOINTER;
}
if (fSubMask)
{
dwIndex = GetSubMaskIndex(ulEventMasks);
adwTargetSubMasks[dwIndex] = dwEventSubMasks;
}
else
{
for (dwIndex = 0; dwIndex < EM_NUM_MASKS; ++dwIndex)
{
adwTargetSubMasks[dwIndex] = ((ulMask & ulEventMasks) ? (-1) : 0);
ulMask <<= 1;
}
}
return lResult;
}
//
// SettCallClientEventMasks
// Description:
// Apply the masks or submasks on a call object.
// Parameters:
// ptCallClient : the call object to apply the masking
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// Return Value:
//
LONG
SettCallClientEventMasks (
PTCALLCLIENT ptCallClient,
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks
)
{
LONG lResult = S_OK;
BOOL bLocked = TRUE;
if (!WaitForExclusivetCallAccess (ptCallClient->ptCall, TCALL_KEY))
{
bLocked = FALSE;
lResult = LINEERR_OPERATIONFAILED;
goto ExitHere;
}
if (ptCallClient->ptLineClient->ptLineApp->dwAPIVersion <= TAPI_VERSION3_0)
{
goto ExitHere;
}
lResult = SetEventMasksOrSubMasks (
fSubMask,
ulEventMasks,
dwEventSubMasks,
ptCallClient->adwEventSubMasks
);
ExitHere:
if (bLocked)
{
UNLOCKTCALL (ptCallClient->ptCall);
}
return lResult;
}
//
// SettLineClientEventMasks
// Description:
// Apply the masks or submasks on a tLineClient object.
// Parameters:
// ptLineClient : the line object to apply the masking
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// Return Value:
//
LONG
SettLineClientEventMasks (
PTLINECLIENT ptLineClient,
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks
)
{
LONG lResult = S_OK;
PTCALLCLIENT ptCallClient;
LOCKTLINECLIENT (ptLineClient);
if (ptLineClient->dwKey != TLINECLIENT_KEY)
{
lResult = LINEERR_OPERATIONFAILED;
goto ExitHere;
}
if (ptLineClient->ptLineApp->dwAPIVersion <= \
TAPI_VERSION3_0)
{
goto ExitHere;
}
lResult = SetEventMasksOrSubMasks (
fSubMask,
ulEventMasks,
dwEventSubMasks,
ptLineClient->adwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptCallClient = ptLineClient->ptCallClients;
while (ptCallClient)
{
lResult = SettCallClientEventMasks (
ptCallClient,
fSubMask,
ulEventMasks,
dwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptCallClient = ptCallClient->pNextSametLineClient;
}
ExitHere:
UNLOCKTLINECLIENT (ptLineClient);
return lResult;
}
//
// SettLineAppEventMasks
// Description:
// Apply the masks or submasks on a tLineApp object.
// Parameters:
// ptLineApp : the tLineApp object to apply the masking
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// Return Value:
//
LONG
SettLineAppEventMasks (
PTLINEAPP ptLineApp,
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks
)
{
PTLINECLIENT ptLineClient;
LONG lResult = S_OK;
LOCKTLINEAPP (ptLineApp);
if (ptLineApp->dwKey != TLINEAPP_KEY)
{
lResult = LINEERR_OPERATIONFAILED;
goto ExitHere;
}
if (ptLineApp->dwAPIVersion <= TAPI_VERSION3_0)
{
lResult = LINEERR_OPERATIONUNAVAIL;
goto ExitHere;
}
lResult = SetEventMasksOrSubMasks (
fSubMask,
ulEventMasks,
dwEventSubMasks,
ptLineApp->adwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptLineClient = ptLineApp->ptLineClients;
while (ptLineClient)
{
lResult = SettLineClientEventMasks (
ptLineClient,
fSubMask,
ulEventMasks,
dwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptLineClient = ptLineClient->pNextSametLineApp;
}
ExitHere:
UNLOCKTLINEAPP (ptLineApp);
return lResult;
}
//
// SettPhoneClientEventMasks
// Description:
// Apply the masks or submasks on a tPhoneClient object.
// Parameters:
// ptPhoneClient : the tPhoneClient object to apply the masking
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// Return Value:
//
LONG
SettPhoneClientEventMasks (
PTPHONECLIENT ptPhoneClient,
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks
)
{
LONG lResult = S_OK;
LOCKTPHONECLIENT (ptPhoneClient);
if (ptPhoneClient->dwKey != TPHONECLIENT_KEY)
{
lResult = PHONEERR_OPERATIONFAILED;
goto ExitHere;
}
if (ptPhoneClient->ptPhoneApp->dwAPIVersion <= TAPI_VERSION3_0)
{
goto ExitHere;
}
lResult = SetEventMasksOrSubMasks (
fSubMask,
ulEventMasks,
dwEventSubMasks,
ptPhoneClient->adwEventSubMasks
);
ExitHere:
UNLOCKTPHONECLIENT (ptPhoneClient);
return lResult;
}
//
// SettPhoneAppEventMasks
// Description:
// Apply the masks or submasks on a tPhoneApp object.
// Parameters:
// ptPhoneApp : the tPhoneApp object to apply the masking
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// Return Value:
//
LONG
SettPhoneAppEventMasks (
PTPHONEAPP ptPhoneApp,
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks
)
{
LONG lResult = S_OK;
PTPHONECLIENT ptPhoneClient;
LOCKTPHONEAPP (ptPhoneApp);
if (ptPhoneApp->dwKey != TPHONEAPP_KEY)
{
lResult = PHONEERR_OPERATIONFAILED;
goto ExitHere;
}
if (ptPhoneApp->dwAPIVersion <= TAPI_VERSION3_0)
{
lResult = PHONEERR_OPERATIONUNAVAIL;
goto ExitHere;
}
lResult = SetEventMasksOrSubMasks (
fSubMask,
ulEventMasks,
dwEventSubMasks,
ptPhoneApp->adwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptPhoneClient = ptPhoneApp->ptPhoneClients;
while (ptPhoneClient)
{
lResult = SettPhoneClientEventMasks (
ptPhoneClient,
fSubMask,
ulEventMasks,
dwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptPhoneClient = ptPhoneClient->pNextSametPhoneApp;
}
ExitHere:
UNLOCKTPHONEAPP (ptPhoneApp);
return lResult;
}
//
// SettClientEventMasks
// Description:
// Apply the masks or submasks client wide.
// Parameters:
// ptClient : the client object to apply the masking
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// Return Value:
//
LONG
SettClientEventMasks (
PTCLIENT ptClient,
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks
)
{
LONG lResult = S_OK;
PTLINEAPP ptLineApp;
PTPHONEAPP ptPhoneApp;
BOOL fLocked = TRUE;
if (!WaitForExclusiveClientAccess (ptClient))
{
lResult = LINEERR_OPERATIONFAILED;
fLocked = FALSE;
goto ExitHere;
}
lResult = SetEventMasksOrSubMasks (
fSubMask,
ulEventMasks,
dwEventSubMasks,
ptClient->adwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptLineApp = ptClient->ptLineApps;
while (ptLineApp)
{
lResult = SettLineAppEventMasks (
ptLineApp,
fSubMask,
ulEventMasks,
dwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptLineApp = ptLineApp->pNext;
}
ptPhoneApp = ptClient->ptPhoneApps;
while (ptPhoneApp)
{
lResult = SettPhoneAppEventMasks (
ptPhoneApp,
fSubMask,
ulEventMasks,
dwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptPhoneApp = ptPhoneApp->pNext;
}
ExitHere:
if (fLocked)
{
UNLOCKTCLIENT (ptClient);
}
return lResult;
}
//
// SettClientEventMasks
// Description:
// Apply the masks or submasks server wide.
// Parameters:
// fSubMask : this function is called for submasks
// ulEventMasks : the masks to be set if fSubMask is true or the mask
// whose submasks is to be set
// dwEventSubMasks : the submasks to be set, ignored if fSubMask is FALSE
// Return Value:
//
LONG
SetGlobalEventMasks (
BOOL fSubMask,
ULONG64 ulEventMasks,
DWORD dwEventSubMasks
)
{
LONG lResult = S_OK;
PTCLIENT ptClient;
TapiEnterCriticalSection (&TapiGlobals.CritSec);
ptClient = TapiGlobals.ptClients;
while (ptClient)
{
lResult = SettClientEventMasks (
ptClient,
fSubMask,
ulEventMasks,
dwEventSubMasks
);
if (lResult)
{
goto ExitHere;
}
ptClient = ptClient->pNext;
}
ExitHere:
TapiLeaveCriticalSection (&TapiGlobals.CritSec);
return lResult;
}
//
// TSetEventMasksOrSubMasks
// Description:
// The RPC function used for seting Masks/SubMasks on various different
// types of objects
// Parameters:
// Return Value:
//
void
WINAPI
TSetEventMasksOrSubMasks (
PTCLIENT ptClient,
PTSETEVENTMASK_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
ULONG64 ulEventMasks;
// Assemble the two DWORD into 64 bit masks
ulEventMasks = pParams->dwHiMasks;
ulEventMasks <<= 32;
ulEventMasks |= pParams->dwLowMasks;
// Mask sure we do not violate the permissible mask setting
TapiEnterCriticalSection (&TapiGlobals.CritSec);
if (ulEventMasks & (~TapiGlobals.ulPermMasks))
{
pParams->lResult = LINEERR_INVALPARAM;
TapiLeaveCriticalSection (&TapiGlobals.CritSec);
goto ExitHere;
}
// Call the corresponding function to apply masking on different
// type of objects
switch (pParams->dwObjType)
{
case TAPIOBJ_NULL:
{
pParams->lResult = (LONG) SettClientEventMasks (
ptClient,
pParams->fSubMask,
ulEventMasks,
pParams->dwEventSubMasks
);
}
break;
case TAPIOBJ_HLINEAPP:
{
PTLINEAPP ptLineApp;
ptLineApp = ReferenceObject (
ghHandleTable,
pParams->hLineApp,
TLINEAPP_KEY
);
if (ptLineApp)
{
pParams->lResult = (LONG) SettLineAppEventMasks (
ptLineApp,
pParams->fSubMask,
ulEventMasks,
pParams->dwEventSubMasks
);
DereferenceObject (
ghHandleTable,
pParams->hLineApp,
1
);
}
else
{
pParams->lResult = LINEERR_INVALAPPHANDLE;
}
}
break;
case TAPIOBJ_HPHONEAPP:
{
PTPHONEAPP ptPhoneApp;
ptPhoneApp = ReferenceObject (
ghHandleTable,
pParams->hPhoneApp,
TPHONEAPP_KEY
);
if (ptPhoneApp)
{
pParams->lResult = (LONG) SettPhoneAppEventMasks (
ptPhoneApp,
pParams->fSubMask,
ulEventMasks,
pParams->dwEventSubMasks
);
DereferenceObject (
ghHandleTable,
pParams->hPhoneApp,
1
);
}
else
{
pParams->lResult = PHONEERR_INVALAPPHANDLE;
}
}
break;
case TAPIOBJ_HLINE:
{
PTLINECLIENT ptLineClient;
ptLineClient = ReferenceObject (
ghHandleTable,
pParams->hLine,
TLINECLIENT_KEY
);
if (ptLineClient)
{
pParams->lResult = (LONG) SettLineClientEventMasks (
ptLineClient,
pParams->fSubMask,
ulEventMasks,
pParams->dwEventSubMasks
);
DereferenceObject (
ghHandleTable,
pParams->hLine,
1
);
}
else
{
pParams->lResult = LINEERR_INVALLINEHANDLE;
}
}
break;
case TAPIOBJ_HCALL:
{
PTCALLCLIENT ptCallClient;
ptCallClient = ReferenceObject (
ghHandleTable,
pParams->hCall,
TCALLCLIENT_KEY
);
if (ptCallClient)
{
pParams->lResult = (LONG) SettCallClientEventMasks (
ptCallClient,
pParams->fSubMask,
ulEventMasks,
pParams->dwEventSubMasks
);
DereferenceObject (
ghHandleTable,
pParams->hCall,
1
);
}
else
{
pParams->lResult = LINEERR_INVALCALLHANDLE;
}
}
break;
case TAPIOBJ_HPHONE:
{
PTPHONECLIENT ptPhoneClient;
ptPhoneClient = ReferenceObject (
ghHandleTable,
pParams->hPhone,
TPHONECLIENT_KEY
);
if (ptPhoneClient)
{
pParams->lResult = (LONG) SettPhoneClientEventMasks (
ptPhoneClient,
pParams->fSubMask,
ulEventMasks,
pParams->dwEventSubMasks
);
DereferenceObject (
ghHandleTable,
pParams->hPhone,
1
);
}
else
{
pParams->lResult = PHONEERR_INVALPHONEHANDLE;
}
}
break;
default:
pParams->lResult = LINEERR_OPERATIONFAILED;
break;
}
TapiLeaveCriticalSection (&TapiGlobals.CritSec);
ExitHere:
*pdwNumBytesReturned = sizeof (TSETEVENTMASK_PARAMS);
}
//
// GetEventsMasksOrSubMasks
// Description:
// Utility function used by TGetEventMasksOrSubMasks to retrieve
// Masks/SubMasks from various Tapisrv objects
// Parameters:
// fSubMask Masks or SubMasks are to be retrieved
// ulEventMasksIn Indicates which submask to get if fSubMask
// pulEventMasksOut Hold the returned masks if(!fSubMask),
// corresponding bit is set as long as at least
// one submask bit is set
// pdwEventSubMasksOut Hold the returned submask if(fSubMask)
// adwEventSubMasks the submasks array to work on
// Return Value:
//
LONG
GetEventMasksOrSubMasks (
BOOL fSubMask,
ULONG64 ulEventMasksIn, // Needs to be set if fSubMask
ULONG64 *pulEventMasksOut,
DWORD *pdwEventSubMasksOut,
DWORD *adwEventSubMasks
)
{
DWORD dwIndex;
ULONG64 ulMask;
if (NULL == adwEventSubMasks ||
NULL == pulEventMasksOut ||
NULL == pdwEventSubMasksOut)
{
ASSERT (0);
return LINEERR_INVALPOINTER;
}
if (fSubMask)
{
ASSERT (pdwEventSubMasksOut != NULL);
ASSERT (ulEventMasksIn != 0 &&
(ulEventMasksIn & (ulEventMasksIn - 1)) == 0);
*pdwEventSubMasksOut =
adwEventSubMasks[GetSubMaskIndex(ulEventMasksIn)];
}
else
{
ASSERT (pulEventMasksOut);
ulMask = 1;
*pulEventMasksOut = 0;
for (dwIndex = 0; dwIndex < EM_NUM_MASKS; ++dwIndex)
{
if (adwEventSubMasks[dwIndex])
{
*pulEventMasksOut |= ulMask;
}
ulMask <<= 1;
}
}
return S_OK;
}
//
// TGetEventMasksOrSubMasks
// Description:
// The RPC function used for geting Masks/SubMasks on various different
// types of objects
// Parameters:
// Return Value:
//
void
WINAPI
TGetEventMasksOrSubMasks (
PTCLIENT ptClient,
PTGETEVENTMASK_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
ULONG64 ulEventMasksIn;
ULONG64 ulEventMasksOut;
// Assember the 64 bit mask from the two DWORD
if (pParams->fSubMask)
{
ulEventMasksIn = pParams->dwHiMasksIn;
ulEventMasksIn <<= 32;
ulEventMasksIn += pParams->dwLowMasksIn;
}
TapiEnterCriticalSection (&TapiGlobals.CritSec);
// Retrieve the masking from various objects by calling
// the corresponding functions
switch (pParams->dwObjType)
{
case TAPIOBJ_NULL:
{
if (WaitForExclusiveClientAccess (ptClient))
{
pParams->lResult = (LONG) GetEventMasksOrSubMasks (
pParams->fSubMask,
ulEventMasksIn,
&ulEventMasksOut,
&pParams->dwEventSubMasks,
ptClient->adwEventSubMasks
);
UNLOCKTCLIENT (ptClient);
}
else
{
pParams->lResult = LINEERR_INVALPARAM;
}
}
break;
case TAPIOBJ_HLINEAPP:
{
PTLINEAPP ptLineApp;
ptLineApp = ReferenceObject (
ghHandleTable,
pParams->hLineApp,
TLINEAPP_KEY
);
if (ptLineApp && ptLineApp->dwKey == TLINEAPP_KEY)
{
LOCKTLINEAPP (ptLineApp);
pParams->lResult = GetEventMasksOrSubMasks (
pParams->fSubMask,
ulEventMasksIn,
&ulEventMasksOut,
&pParams->dwEventSubMasks,
ptLineApp->adwEventSubMasks
);
UNLOCKTLINEAPP (ptLineApp);
DereferenceObject (
ghHandleTable,
pParams->hLineApp,
1
);
}
else
{
pParams->lResult = LINEERR_INVALAPPHANDLE;
}
}
break;
case TAPIOBJ_HPHONEAPP:
{
PTPHONEAPP ptPhoneApp;
ptPhoneApp = ReferenceObject (
ghHandleTable,
pParams->hPhoneApp,
TPHONEAPP_KEY
);
if (ptPhoneApp && ptPhoneApp->dwKey == TPHONEAPP_KEY)
{
LOCKTPHONEAPP (ptPhoneApp);
pParams->lResult = GetEventMasksOrSubMasks (
pParams->fSubMask,
ulEventMasksIn,
&ulEventMasksOut,
&pParams->dwEventSubMasks,
ptPhoneApp->adwEventSubMasks
);
UNLOCKTPHONEAPP (ptPhoneApp);
DereferenceObject (
ghHandleTable,
pParams->hPhoneApp,
1
);
}
else
{
pParams->lResult = PHONEERR_INVALAPPHANDLE;
}
}
break;
case TAPIOBJ_HLINE:
{
PTLINECLIENT ptLineClient;
ptLineClient = ReferenceObject (
ghHandleTable,
pParams->hLine,
TLINECLIENT_KEY
);
if (ptLineClient && ptLineClient->dwKey == TLINECLIENT_KEY)
{
LOCKTLINECLIENT (ptLineClient);
pParams->lResult = GetEventMasksOrSubMasks (
pParams->fSubMask,
ulEventMasksIn,
&ulEventMasksOut,
&pParams->dwEventSubMasks,
ptLineClient->adwEventSubMasks
);
UNLOCKTLINECLIENT (ptLineClient);
DereferenceObject (
ghHandleTable,
pParams->hLine,
1
);
}
else
{
pParams->lResult = LINEERR_INVALLINEHANDLE;
}
}
break;
case TAPIOBJ_HCALL:
{
PTCALLCLIENT ptCallClient;
ptCallClient = ReferenceObject (
ghHandleTable,
pParams->hCall,
TCALLCLIENT_KEY
);
if (ptCallClient && ptCallClient->dwKey == TCALLCLIENT_KEY)
{
LOCKTLINECLIENT (ptCallClient);
pParams->lResult = GetEventMasksOrSubMasks (
pParams->fSubMask,
ulEventMasksIn,
&ulEventMasksOut,
&pParams->dwEventSubMasks,
ptCallClient->adwEventSubMasks
);
UNLOCKTLINECLIENT (ptCallClient);
DereferenceObject (
ghHandleTable,
pParams->hCall,
1
);
}
else
{
pParams->lResult = LINEERR_INVALCALLHANDLE;
}
}
break;
case TAPIOBJ_HPHONE:
{
PTPHONECLIENT ptPhoneClient;
ptPhoneClient = ReferenceObject (
ghHandleTable,
pParams->hPhone,
TPHONECLIENT_KEY
);
if (ptPhoneClient && ptPhoneClient->dwKey == TPHONECLIENT_KEY)
{
LOCKTPHONECLIENT (ptPhoneClient);
pParams->lResult = GetEventMasksOrSubMasks (
pParams->fSubMask,
ulEventMasksIn,
&ulEventMasksOut,
&pParams->dwEventSubMasks,
ptPhoneClient->adwEventSubMasks
);
UNLOCKTPHONECLIENT (ptPhoneClient);
DereferenceObject (
ghHandleTable,
pParams->hPhone,
1
);
}
else
{
pParams->lResult = PHONEERR_INVALPHONEHANDLE;
}
}
break;
default:
pParams->lResult = LINEERR_OPERATIONFAILED;
break;
}
TapiLeaveCriticalSection (&TapiGlobals.CritSec);
// Seperating the returned 64 bit masks into two DWORD for RPC purpose
if (pParams->lResult == 0 && !pParams->fSubMask)
{
pParams->dwLowMasksOut = (DWORD)(ulEventMasksOut & 0xffffffff);
pParams->dwHiMasksOut = (DWORD)(ulEventMasksOut >> 32);
}
*pdwNumBytesReturned = sizeof (TGETEVENTMASK_PARAMS);
}
//
// TSetPermissibleMasks
// Description:
// Set the global PermissibleMasks, this operation is only
// allowed for admins
// Parameters:
// Return Value:
//
void
WINAPI
TSetPermissibleMasks (
PTCLIENT ptClient,
PTSETPERMMASKS_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
BOOL bAdmin;
ULONG64 ulPermMasks;
// Check the Admin status
LOCKTCLIENT (ptClient);
bAdmin = IS_FLAG_SET(ptClient->dwFlags, PTCLIENT_FLAG_ADMINISTRATOR);
UNLOCKTCLIENT (ptClient);
// Allow the operation to go ahead if the caller is an Admin or
// this machine is not configured to function as a server
if (!(TapiGlobals.dwFlags & TAPIGLOBALS_SERVER) || bAdmin)
{
ulPermMasks = pParams->dwHiMasks;
ulPermMasks <<= 32;
ulPermMasks += pParams->dwLowMasks;
TapiEnterCriticalSection (&TapiGlobals.CritSec);
TapiGlobals.ulPermMasks = ulPermMasks & EM_ALL;
TapiLeaveCriticalSection (&TapiGlobals.CritSec);
pParams->lResult = (LONG) SetGlobalEventMasks (
FALSE,
ulPermMasks,
0
);
}
else
{
pParams->lResult = TAPIERR_NOTADMIN;
}
*pdwNumBytesReturned = sizeof (TSETPERMMASKS_PARAMS);
return;
}
//
// TGetPermissibleMasks
// Description:
// Get the global PermissibleMasks
// Parameters:
// Return Value:
//
void
WINAPI
TGetPermissibleMasks (
PTCLIENT ptClient,
PTGETPERMMASKS_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
TapiEnterCriticalSection (&TapiGlobals.CritSec);
pParams->dwLowMasks = (DWORD)(TapiGlobals.ulPermMasks & 0xffffffff);
pParams->dwHiMasks = (DWORD)(TapiGlobals.ulPermMasks >> 32);
TapiLeaveCriticalSection (&TapiGlobals.CritSec);
*pdwNumBytesReturned = sizeof (TGETPERMMASKS_PARAMS);
}