Windows-Server-2003/net/tapi/server/tapi.c

401 lines
10 KiB
C

/*++ BUILD Version: 0000 // Increment this if a change has global effects
Copyright (c) 1995-1996 Microsoft Corporation
Module Name:
tapi.c
Abstract:
Src module for tapi server line funcs
Author:
Dan Knudson (DanKn) 01-Apr-1995
Revision History:
--*/
#include "windows.h"
#include "shellapi.h"
#include "tapi.h"
#include "tspi.h"
#include "utils.h"
#include "client.h"
#include "server.h"
#include "tapiperf.h"
#include "tapy.h"
extern TAPIGLOBALS TapiGlobals;
extern CRITICAL_SECTION gPriorityListCritSec;
extern PERFBLOCK PerfBlock;
BOOL
PASCAL
NotifyHighestPriorityRequestRecipient(
void
);
void
WINAPI
TGetLocationInfo(
PTAPIGETLOCATIONINFO_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
//
// This is currently implemented on the client side (should be moved
// back to server side eventually)
//
}
void
WINAPI
TRequestDrop(
PTCLIENT ptClient,
PTAPIREQUESTDROP_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
//
// No media call/drop support right now, since the original
// spec/implementation wasn't very good and made no provision for
// retrieving media stream handle, etc
//
pParams->lResult = TAPIERR_REQUESTFAILED;
}
void
WINAPI
TRequestMakeCall(
PTCLIENT ptClient,
PTAPIREQUESTMAKECALL_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
BOOL bRequestMakeCallListEmpty;
PTREQUESTMAKECALL pRequestMakeCall;
//
// Check to see if the hRequestMakeCall is non-0, because if so
// tapi32.dll failed to exec a proxy app and it's alerting us that
// we need to clean up this request (we'll just nuke 'em all for now)
//
if (pParams->hRequestMakeCallFailed)
{
PTREQUESTMAKECALL pRequestMakeCall, pNextRequestMakeCall;
EnterCriticalSection (&gPriorityListCritSec);
pRequestMakeCall = TapiGlobals.pRequestMakeCallList;
while (pRequestMakeCall)
{
pNextRequestMakeCall = pRequestMakeCall->pNext;
ServerFree (pRequestMakeCall);
pRequestMakeCall = pNextRequestMakeCall;
}
TapiGlobals.pRequestMakeCallList =
TapiGlobals.pRequestMakeCallListEnd = NULL;
LeaveCriticalSection (&gPriorityListCritSec);
LOG((TL_ERROR,
"TRequestMakeCall: couldn't exec proxy, deleting requests"
));
pParams->lResult = TAPIERR_NOREQUESTRECIPIENT;
return;
}
//
// Verify size/offset/string params given our input buffer/size
//
if (IsBadStringParam(
dwParamsBufferSize,
pDataBuf,
pParams->dwDestAddressOffset
) ||
((pParams->dwAppNameOffset != TAPI_NO_DATA) &&
IsBadStringParam(
dwParamsBufferSize,
pDataBuf,
pParams->dwAppNameOffset
)) ||
((pParams->dwCalledPartyOffset != TAPI_NO_DATA) &&
IsBadStringParam(
dwParamsBufferSize,
pDataBuf,
pParams->dwCalledPartyOffset
)) ||
((pParams->dwCommentOffset != TAPI_NO_DATA) &&
IsBadStringParam(
dwParamsBufferSize,
pDataBuf,
pParams->dwCommentOffset
)) ||
(pParams->dwProxyListTotalSize > dwParamsBufferSize))
{
pParams->lResult = TAPIERR_REQUESTFAILED;
return;
}
//
// Alloc & init a request make call object
//
if (!(pRequestMakeCall = ServerAlloc (sizeof (TREQUESTMAKECALL))))
{
pParams->lResult = TAPIERR_REQUESTFAILED;
return;
}
LOG((TL_INFO, "Request: 0x%p", pRequestMakeCall));
wcsncpy(
pRequestMakeCall->LineReqMakeCall.szDestAddress,
(LPCWSTR) (pDataBuf + pParams->dwDestAddressOffset),
TAPIMAXDESTADDRESSSIZE
);
pRequestMakeCall->LineReqMakeCall.szDestAddress[TAPIMAXDESTADDRESSSIZE-1] =
'\0';
LOG((TL_INFO, " DestAddress: [%ls]",
pRequestMakeCall->LineReqMakeCall.szDestAddress));
if (pParams->dwAppNameOffset != TAPI_NO_DATA)
{
wcsncpy(
pRequestMakeCall->LineReqMakeCall.szAppName,
(LPCWSTR) (pDataBuf + pParams->dwAppNameOffset),
TAPIMAXAPPNAMESIZE
);
pRequestMakeCall->LineReqMakeCall.szAppName[TAPIMAXAPPNAMESIZE-1] =
'\0';
LOG((TL_INFO, " AppName: [%ls]",
pRequestMakeCall->LineReqMakeCall.szAppName));
}
if (pParams->dwCalledPartyOffset != TAPI_NO_DATA)
{
wcsncpy(
pRequestMakeCall->LineReqMakeCall.szCalledParty,
(LPCWSTR) (pDataBuf + pParams->dwCalledPartyOffset),
TAPIMAXCALLEDPARTYSIZE
);
pRequestMakeCall->LineReqMakeCall.szCalledParty[TAPIMAXCALLEDPARTYSIZE-1] =
'\0';
LOG((TL_INFO, " CalledParty: [%ls]",
pRequestMakeCall->LineReqMakeCall.szCalledParty));
}
if (pParams->dwCommentOffset != TAPI_NO_DATA)
{
wcsncpy(
pRequestMakeCall->LineReqMakeCall.szComment,
(LPCWSTR) (pDataBuf + pParams->dwCommentOffset),
TAPIMAXCOMMENTSIZE
);
pRequestMakeCall->LineReqMakeCall.szComment[TAPIMAXCOMMENTSIZE-1] =
'\0';
LOG((TL_INFO, " Comment: [%ls]",
pRequestMakeCall->LineReqMakeCall.szComment));
}
//
// Add object to end of global list
//
EnterCriticalSection (&gPriorityListCritSec);
if (TapiGlobals.pRequestMakeCallListEnd)
{
TapiGlobals.pRequestMakeCallListEnd->pNext = pRequestMakeCall;
bRequestMakeCallListEmpty = FALSE;
}
else
{
TapiGlobals.pRequestMakeCallList = pRequestMakeCall;
bRequestMakeCallListEmpty = TRUE;
}
TapiGlobals.pRequestMakeCallListEnd = pRequestMakeCall;
LeaveCriticalSection (&gPriorityListCritSec);
{
LPVARSTRING pProxyList = (LPVARSTRING) pDataBuf;
pProxyList->dwTotalSize = pParams->dwProxyListTotalSize;
pProxyList->dwNeededSize =
pProxyList->dwUsedSize = sizeof (VARSTRING);
pParams->hRequestMakeCallAttempted = 0;
//
// If the request list is currently empty then we need to notify the
// highest priority request recipient that there's requests for it
// to process. Otherwise, we can assume that we already sent this
// msg and the app knows there's requests available for it to process.
//
if (bRequestMakeCallListEmpty)
{
if (TapiGlobals.pHighestPriorityRequestRecipient)
{
NotifyHighestPriorityRequestRecipient();
}
else
{
EnterCriticalSection (&gPriorityListCritSec);
if (TapiGlobals.pszReqMakeCallPriList)
{
//
// Copy the pri list to the buffer & pass it back to
// the client side, so it can try to start the proxy
// app (if it fails it'll call us back to free the
// pRequestMakeCall)
//
pProxyList->dwNeededSize =
pProxyList->dwUsedSize = pProxyList->dwTotalSize;
pProxyList->dwStringSize =
pParams->dwProxyListTotalSize - sizeof (VARSTRING);
pProxyList->dwStringOffset = sizeof (VARSTRING);
pParams->hRequestMakeCallAttempted = 1;
wcsncpy(
(PWSTR)(((LPBYTE) pProxyList) + pProxyList->dwStringOffset),
TapiGlobals.pszReqMakeCallPriList + 1, // no init ','
pProxyList->dwStringSize / sizeof(WCHAR)
);
}
else
{
TapiGlobals.pRequestMakeCallList =
TapiGlobals.pRequestMakeCallListEnd = NULL;
ServerFree (pRequestMakeCall);
pParams->lResult = TAPIERR_NOREQUESTRECIPIENT;
}
LeaveCriticalSection (&gPriorityListCritSec);
}
}
if (pParams->lResult == 0)
{
pParams->dwProxyListOffset = 0;
*pdwNumBytesReturned = sizeof (TAPI32_MSG) +
pProxyList->dwUsedSize;
}
}
//TRequestMakeCall_return:
LOG((TL_TRACE,
"TapiEpilogSync (tapiRequestMakeCall) exit, returning x%x",
pParams->lResult
));
}
void
WINAPI
TRequestMediaCall(
PTCLIENT ptClient,
PTAPIREQUESTMEDIACALL_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
//
// No media call/drop support right now, since the original
// spec/implementation wasn't very good and made no provision for
// retrieving media stream handle, etc
//
pParams->lResult = TAPIERR_REQUESTFAILED;
}
void
WINAPI
TPerformance(
PTCLIENT ptClient,
PTAPIPERFORMANCE_PARAMS pParams,
DWORD dwParamsBufferSize,
LPBYTE pDataBuf,
LPDWORD pdwNumBytesReturned
)
{
LOG((TL_TRACE, "PERF: In TPerformance"));
//
// Verify size/offset/string params given our input buffer/size
//
if (dwParamsBufferSize < sizeof (PERFBLOCK))
{
pParams->lResult = LINEERR_OPERATIONFAILED;
return;
}
CopyMemory (pDataBuf, &PerfBlock, sizeof (PERFBLOCK));
pParams->dwPerfOffset = 0;
*pdwNumBytesReturned = sizeof(TAPI32_MSG) + sizeof(PERFBLOCK);
}