|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
globals.h
Abstract:
Global definitions for H.323 TAPI Service Provider.
Author: Nikhil Bobde (NikhilB)
Revision History:
--*/
// build control defines
#define STRICT
#define UNICODE
#define _UNICODE
#define VC_EXTRALEAN
#define H323_USE_PRIVATE_IO_THREAD 1
//
// Include files:SDK
//
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <winsock2.h>
#include <mswsock.h>
#include <tapi3.h>
#include <tspi.h>
#include <crtdbg.h>
#include <stdio.h>
#include <tchar.h>
#include <rtutils.h>
// Project
#include <h225asn.h>
#include <tspmspif.h>
typedef class CH323Call* PH323_CALL; typedef class H323_CONFERENCE* PH323_CONFERENCE;
#define CALL_ALERTING_TIMEOUT 180000
#define Q931_CALL_PORT 1720 // Endpoint TCP Call Signalling Port
//
// String definitions
//
#define H323_MAXCALLSPERLINE 32768 //limited by 15 bit CRV sent to the Gatekeeper
#define H323_MAXLINENAMELEN 16
#define H323_MAXPORTNAMELEN 16
#define H323_MAXADDRNAMELEN (H323_MAXLINENAMELEN + H323_MAXPORTNAMELEN)
#define H323_MAXPATHNAMELEN 256
#define H323_MAXDESTNAMELEN 256
#define MAX_E164_ADDR_LEN 127
#define MAX_H323_ADDR_LEN 255
#define H323_UIDLL _T("H323.TSP")
#define H323_TSPDLL _T("H323.TSP")
#define H323_WINSOCKVERSION MAKEWORD(2,0)
#define H221_COUNTRY_CODE_USA 0xB5
#define H221_COUNTRY_EXT_USA 0x00
#define H221_MFG_CODE_MICROSOFT 0x534C
#define H323_PRODUCT_ID "Microsoft TAPI\0"
#define H323_PRODUCT_VERSION "Version 3.1\0"
#define MSP_HANDLE_UNKNOWN 0
//
// Registry key definitions
//
#define REGSTR_PATH_WINDOWS_CURRENTVERSION TEXT("Software\\Microsoft\\Windows\\CurrentVersion")
#define TAPI_REGKEY_ROOT REGSTR_PATH_WINDOWS_CURRENTVERSION TEXT("\\Telephony")
#define TAPI_REGKEY_PROVIDERS TAPI_REGKEY_ROOT TEXT("\\Providers")
#define TAPI_REGVAL_NUMPROVIDERS TEXT("NumProviders")
#define H323_SUBKEY TEXT("H323TSP")
#define H323_REGKEY_ROOT REGSTR_PATH_WINDOWS_CURRENTVERSION TEXT("\\") H323_SUBKEY
#define H323_REGVAL_Q931ALERTINGTIMEOUT TEXT("Q931AlertingTimeout")
#define H323_REGVAL_Q931LISTENPORT TEXT("Q931ListenPort")
#define H323_REGVAL_GATEWAYENABLED TEXT("H323GatewayEnabled")
#define H323_REGVAL_GATEWAYADDR TEXT("H323GatewayAddress")
#define H323_REGVAL_PROXYENABLED TEXT("H323ProxyEnabled")
#define H323_REGVAL_PROXYADDR TEXT("H323ProxyAddress")
#define H323_REGVAL_GKENABLED TEXT("H323GatekeeperEnabled")
#define H323_REGVAL_GKLOGON_PHONEENABLED TEXT("H323GKLogOnPhoneNumberEnabled")
#define H323_REGVAL_GKLOGON_ACCOUNTENABLED TEXT("H323GKLogOnAccountNameEnabled")
#define H323_REGVAL_GKADDR TEXT("H323GatekeeperAddress")
#define H323_REGVAL_GKLOGON_PHONE TEXT("H323GatekeeperLogOnPhoneNumber")
#define H323_REGVAL_GKLOGON_ACCOUNT TEXT("H323GatekeeperLogOnAccountName")
#define H323_REGVAL_DEBUGLEVEL TEXT("DebugLevel")
//
// Global Definitions
//
// CCRC_CALL_REJECTED reason codes (includes cause values)
#define H323_REJECT_NO_BANDWIDTH 1
#define H323_REJECT_GATEKEEPER_RESOURCES 2
#define H323_REJECT_UNREACHABLE_DESTINATION 3
#define H323_REJECT_DESTINATION_REJECTION 4
#define H323_REJECT_INVALID_REVISION 5
#define H323_REJECT_NO_PERMISSION 6
#define H323_REJECT_UNREACHABLE_GATEKEEPER 7
#define H323_REJECT_GATEWAY_RESOURCES 8
#define H323_REJECT_BAD_FORMAT_ADDRESS 9
#define H323_REJECT_ADAPTIVE_BUSY 10
#define H323_REJECT_IN_CONF 11
#define H323_REJECT_ROUTE_TO_GATEKEEPER 12
#define H323_REJECT_CALL_FORWARDED 13
#define H323_REJECT_ROUTE_TO_MC 14
#define H323_REJECT_UNDEFINED_REASON 15
#define H323_REJECT_INTERNAL_ERROR 16 // Internal error occured in peer CS stack.
#define H323_REJECT_NORMAL_CALL_CLEARING 17 // Normal call hangup
#define H323_REJECT_USER_BUSY 18 // User is busy with another call
#define H323_REJECT_NO_ANSWER 19 // Callee does not answer
#define H323_REJECT_NOT_IMPLEMENTED 20 // Service has not been implemented
#define H323_REJECT_MANDATORY_IE_MISSING 21 // Pdu missing mandatory ie
#define H323_REJECT_INVALID_IE_CONTENTS 22 // Pdu ie was incorrect
#define H323_REJECT_TIMER_EXPIRED 23 // Own timer expired
#define H323_REJECT_CALL_DEFLECTION 24 // You deflected the call, so lets quit.
#define H323_REJECT_GATEKEEPER_TERMINATED 25 // Gatekeeper terminated call
// unicode character mask contants
#define H323_ALIAS_H323_PHONE_CHARS L"0123456789#*,"
#define H323_ODOTTO_CHARS L".0123456789"
//
//H450 Operation types
//
enum H450_OPERATION_TYPE { H450_INVOKE = 0x00000100, H450_RETURNRESULT = 0x00000200, H450_RETURNERROR = 0x00000400, H450_REJECT = 0x00000800,
};
//
//H450 APDU types
//
enum H450_OPCODE { NO_H450_APDU = 0,
H4503_DUMMYTYPERETURNRESULT_APDU = 50, H4503_RETURNERROR_APDU = 51, H4503_REJECT_APDU = 52,
CHECKRESTRICTION_OPCODE = 18, CALLREROUTING_OPCODE = 19, DIVERTINGLEGINFO1_OPCODE = 20, DIVERTINGLEGINFO2_OPCODE = 21, DIVERTINGLEGINFO3_OPCODE = 22,
CTIDENTIFY_OPCODE = 7, CTINITIATE_OPCODE = 9, CTSETUP_OPCODE = 10,
HOLDNOTIFIC_OPCODE = 101, RETRIEVENOTIFIC_OPCODE = 102, REMOTEHOLD_OPCODE = 103, REMOTERETRIEVE_OPCODE = 104,
CPREQUEST_OPCODE = 106, CPSETUP_OPCODE = 107, GROUPINDON_OPCODE = 108, GROUPINDOFF_OPCODE = 109, PICKREQU_OPCODE = 110, PICKUP_OPCODE = 111, PICKEXE_OPCODE = 112, CPNOTIFY_OPCODE = 113, CPICKUPNOTIFY_OPCODE = 114,
};
#define NO_INVOKEID 0x00000000
//
// Global Data Structures
//
// IP address in conventional 'dot' notation
typedef struct { WORD wPort; // UDP or TCP port (host byte order)
WCHAR cAddr[16]; // UNICODE zstring
} H323_IP_Dot_t;
// IP address in binary format
typedef struct { WORD wPort; // UDP or TCP port (host byte order)
DWORD dwAddr; // binary address (host byte order)
} H323_IP_Binary_t;
typedef enum { H323_ADDR_NOT_DEFINED = 0, H323_IP_DOMAIN_NAME , H323_IP_DOT , H323_IP_BINARY } H323_ADDRTYPE;
typedef struct _ADDR { H323_ADDRTYPE nAddrType; BOOL bMulticast; union { H323_IP_Dot_t IP_Dot; H323_IP_Binary_t IP_Binary; } Addr; } H323_ADDR, *PH323_ADDR;
typedef struct { BYTE *pOctetString; WORD wOctetStringLength;
} H323_OCTETSTRING, *PH323_OCTETSTRING;
typedef struct ENDPOINT_ID { ASN1uint32_t length; ASN1char16_t value[H323_MAXPATHNAMELEN+ 1];
} ENDPOINT_ID;
typedef struct { H323_OCTETSTRING sData; // pointer to Octet data.
BYTE bCountryCode; BYTE bExtension; WORD wManufacturerCode; } H323NonStandardData;
#define H323_MAX_PRODUCT_LENGTH 256
#define H323_MAX_VERSION_LENGTH 256
#define H323_MAX_DISPLAY_LENGTH 82
typedef struct { BYTE bCountryCode; BYTE bExtension; WORD wManufacturerCode; PH323_OCTETSTRING pProductNumber; PH323_OCTETSTRING pVersionNumber; } H323_VENDORINFO, *PH323_VENDORINFO;
typedef struct { PH323_VENDORINFO pVendorInfo; BOOL bIsTerminal; BOOL bIsGateway; // for now, the H323 capability will be hard-coded.
} H323_ENDPOINTTYPE, *PH323_ENDPOINTTYPE;
typedef struct { WORD wType; WORD wPrefixLength; LPWSTR pPrefix; WORD wDataLength; // UNICODE character count
LPWSTR pData; // UNICODE data.
} H323_ALIASITEM, *PH323_ALIASITEM;
typedef struct { WORD wCount; PH323_ALIASITEM pItems;
} H323_ALIASNAMES, *PH323_ALIASNAMES;
typedef struct _H323_FASTSTART { struct _H323_FASTSTART* next; DWORD length; BYTE* value;
} H323_FASTSTART, *PH323_FASTSTART;
struct H323_REGISTRY_SETTINGS { DWORD dwQ931AlertingTimeout; // q931 alerting timeout
DWORD dwQ931ListenPort; // port to listen for incoming calls
BOOL fIsGatewayEnabled; // if true, gateway enabled
BOOL fIsProxyEnabled; // if true, proxy enabled
BOOL fIsGKEnabled; // if true, GK enabled
H323_ADDR gatewayAddr; // H.323 gateway address
H323_ADDR proxyAddr; // H.323 proxy address
SOCKADDR_IN saGKAddr; // H.323 gatekeeper address
WCHAR wszGKLogOnPhone[H323_MAXDESTNAMELEN+1]; // phone number to register with the gatekeeper
WCHAR wszGKLogOnAccount[H323_MAXDESTNAMELEN+1]; // account name to register with the gatekeeper
BOOL fIsGKLogOnPhoneEnabled; // if true, gateway enabled
BOOL fIsGKLogOnAccountEnabled; // if true, proxy enabled
DWORD dwLogLevel; // debug log level
//TCHAR szLogFile[MAX_PATH+1];
};
//
// Global Variables
//
extern WCHAR g_pwszProviderInfo[]; extern WCHAR g_pwszLineName[]; extern LINEEVENT g_pfnLineEventProc; extern HINSTANCE g_hInstance; extern HANDLE g_hCanUnloadDll; extern HANDLE g_hEventLogSource; extern DWORD g_dwLineDeviceIDBase; extern DWORD g_dwPermanentProviderID; extern H323_REGISTRY_SETTINGS g_RegistrySettings;
#define H323TimerQueue NULL // use default process timer queue
//
// I/O callback threaddeclarations.
//
#if H323_USE_PRIVATE_IO_THREAD
BOOL H323BindIoCompletionCallback ( IN HANDLE ObjectHandle, IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine, IN ULONG Flags);
HRESULT H323IoThreadStart(void); void H323IoThreadStop(void);
#else
#define H323BindIoCompletionCallback BindIoCompletionCallback
#endif
enum { DEBUG_LEVEL_FORCE = 0x00000000, // always emit, no matter what
DEBUG_LEVEL_ERROR = 0x00020000, // significant errors only
DEBUG_LEVEL_INFO = 0x00040000, // general information, but not too detailed
DEBUG_LEVEL_TRACE = 0x00080000, // lotsa lotsa trace output
};
#define DEBUG_LEVEL_WARNING DEBUG_LEVEL_INFO
#define DEBUG_LEVEL_FATAL DEBUG_LEVEL_FORCE // big, bad errors, always output
#define DEBUG_LEVEL_VERBOSE DEBUG_LEVEL_INFO
PSTR EventIDToString( DWORD eventID ); PSTR H323CallStateToString( DWORD dwCallState ); PSTR H323AddressTypeToString( DWORD dwAddressType ); PSTR H323TSPMessageToString( DWORD dwMessageType );
#define SOCKADDR_IN_PRINTF(SocketAddress) \
ntohl ((SocketAddress) -> sin_addr.s_addr), \ ntohs ((SocketAddress) -> sin_port)
//
//Debug Output declarations
//
#if DBG
#define H323DBG(_x_) H323DbgPrint _x_
void H323DUMPBUFFER( IN BYTE * pEncoded, IN DWORD cbEncodedSize );
//
// Public prototypes
//
VOID H323DbgPrint( DWORD dwLevel, LPSTR szFormat, ... ); void DumpError( IN DWORD ErrorCode ); BOOL TRACELogRegister(LPCTSTR szName); void TRACELogDeRegister();
static __inline void DumpLastError (void) { DumpError (GetLastError()); }
static DWORD ProcessTAPICallRequest( IN PVOID ContextParameter );
static DWORD ProcessSuppServiceWorkItem( IN PVOID ContextParameter );
DWORD SendMSPMessageOnRelatedCall( IN PVOID ContextParameter );
static DWORD ProcessTAPILineRequest( IN PVOID ContextParam );
#else
// retail build
#define DumpError(ErrorCode) 0
#define DumpLastError() 0
#define H323DBG(_x_) if( 0 != g_RegistrySettings.dwLogLevel ) H323DbgPrintFre _x_
#define H323DUMPBUFFER( x, y)
VOID OpenLogFile(); VOID CloseLogFile(); VOID H323DbgPrintFre(DWORD dwLevel, LPSTR szFormat, ... );
#define ProcessTAPICallRequest ProcessTAPICallRequestFre
#define ProcessSuppServiceWorkItem ProcessSuppServiceWorkItemFre
#define ProcessTAPILineRequest ProcessTAPILineRequestFre
#define SendMSPMessageOnRelatedCall SendMSPMessageOnRelatedCallFre
#endif // DBG
//
// Global Function Declarations
//
void ReportTSPEvent( LPCTSTR wszErrorMessage ); #define H323TSP_EVENT_SOURCE_NAME _T("Microsoft H.323 Telephony Service Provider")
static __inline BOOL IsGuidSet ( IN const GUID * Guid) { return Guid -> Data1 || Guid -> Data2 || Guid -> Data3 || Guid -> Data4; }
static __inline void CopyConferenceID ( OUT GloballyUniqueID * Target, IN const GUID * Value) { CopyMemory (Target -> value, Value, sizeof (GUID)); Target -> length = sizeof (GUID); }
static __inline void CopyConferenceID ( OUT GUID * Target, IN const GloballyUniqueID * Value) { if (Value -> length == sizeof (GUID)) CopyMemory (Target, Value -> value, sizeof (GUID)); else { H323DBG ((DEBUG_LEVEL_ERROR, "GloballyUniqueID was wrong length (%d)\n", Value -> length));
ZeroMemory (Target, sizeof (GUID)); } }
extern ASYNC_COMPLETION g_pfnCompletionProc; #define H323CompleteRequest (*g_pfnCompletionProc)
// notify TAPI of a line event.
void H323PostLineEvent ( IN HTAPILINE TapiLine, IN HTAPICALL TapiCall, IN DWORD MessageID, IN ULONG_PTR Parameter1, IN ULONG_PTR Parameter2, IN ULONG_PTR Parameter3);
static __inline HRESULT GetLastResult (void) { return HRESULT_FROM_WIN32 (GetLastError()); }
BOOL H323ValidateTSPIVersion( IN DWORD dwTSPIVersion ); BOOL H323ValidateExtVersion ( IN DWORD dwExtVersion);
HRESULT RegistryStart (void); void RegistryStop (void);
HANDLE H323CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
BOOL bManualReset, // reset type
BOOL bInitialState, // initial state
LPCTSTR lpName // object name
);
//
// Macros
//
#define H323AddrToString(_dwAddr_) \
(inet_ntoa(H323AddrToAddrIn(_dwAddr_)))
#define H323AddrToAddrIn(_dwAddr_) \
(*((struct in_addr *)&(_dwAddr_)))
#define H323SizeOfWSZ(wsz) \
(((wsz) == NULL) ? 0 : ((wcslen(wsz) + 1) * sizeof(WCHAR)))
//
// Table Class
//
template <class T, DWORD INITIAL = 8, DWORD DELTA = 8> class TSPTable { protected: T* m_aT; int m_nSize; int m_nAllocSize; CRITICAL_SECTION m_CriticalSection;
public:
// Construction/destruction
TSPTable() : m_aT(NULL), m_nSize(0), m_nAllocSize(0) { // No need to check the result of this one since this object is
// always allocated on static memory, right when the DLL is loaded.
InitializeCriticalSectionAndSpinCount( &m_CriticalSection, 0x80000000 ); }
~TSPTable() { if(m_nAllocSize > 0) { free(m_aT); m_aT = NULL; m_nSize = 0; m_nAllocSize = 0; }
DeleteCriticalSection(&m_CriticalSection); } void Lock() { EnterCriticalSection( &m_CriticalSection ); } void Unlock() { LeaveCriticalSection( &m_CriticalSection ); } // Operations
int GetSize() const { return m_nSize; } int GetAllocSize() { return m_nAllocSize; } int Add(T& t) { Lock(); if(m_nSize == m_nAllocSize) { if (!Grow()) return -1; SetAtIndex(m_nSize, t); m_nSize++; Unlock(); return m_nSize - 1; } else { for(int i=0; i<m_nAllocSize; i++) if(m_aT[i] == NULL ) break; SetAtIndex(i, t); m_nSize++; Unlock(); return i; } } void RemoveAt(int nIndex) { Lock(); _ASSERTE( m_aT[nIndex] ); m_aT[nIndex] = NULL; m_nSize--; Unlock(); } T& operator[] (int nIndex) const { static T t1 = (T)NULL; _ASSERTE( (nIndex >= 0) && (nIndex < m_nAllocSize) ); if( (nIndex >= 0) && (nIndex < m_nAllocSize) ) return m_aT[nIndex]; return t1; }
// Implementation
private: void SetAtIndex(int nIndex, T& t) { _ASSERTE(nIndex >= 0 && nIndex < m_nAllocSize); if( (nIndex >= 0) && (nIndex < m_nAllocSize) ) m_aT[nIndex] = t; } BOOL Grow() { T* aT; int nNewAllocSize = (m_nAllocSize == 0) ? INITIAL : (m_nSize + DELTA);
aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T)); if(aT == NULL) return FALSE; ZeroMemory( (PVOID)&aT[m_nAllocSize], sizeof(T)*(nNewAllocSize-m_nAllocSize)); m_nAllocSize = nNewAllocSize; m_aT = aT;
return TRUE; } };
/*++
CTSPArray template Description:
This array should only be used to store simple types. It doesn't call the constructor nor the destructor for each element in the array.
--*/
template <class T, DWORD INITIAL_SIZE = 8, DWORD DELTA_SIZE = 8> class CTSPArray {
protected: T* m_aT; int m_nSize; int m_nAllocSize;
public:
// Construction/destruction
CTSPArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0) { }
~CTSPArray() { RemoveAll(); }
// Operations
int GetSize() const { return m_nSize; } BOOL Grow() { T* aT; int nNewAllocSize = (m_nAllocSize == 0) ? INITIAL_SIZE : (m_nSize + DELTA_SIZE);
aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T)); if(aT == NULL) return FALSE; m_nAllocSize = nNewAllocSize; m_aT = aT; return TRUE; }
BOOL Add(T& t) { if(m_nSize == m_nAllocSize) { if (!Grow()) return FALSE; } m_nSize++; SetAtIndex(m_nSize - 1, t); return TRUE; } BOOL Remove(T& t) { int nIndex = Find(t); if(nIndex == -1) return FALSE; return RemoveAt(nIndex); } BOOL RemoveAt(int nIndex) { if(nIndex != (m_nSize - 1)) memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(T)); m_nSize--; return TRUE; } void RemoveAll() { if(m_nAllocSize > 0) { free(m_aT); m_aT = NULL; m_nSize = 0; m_nAllocSize = 0; } } T& operator[] (int nIndex) const { _ASSERTE(nIndex >= 0 && nIndex < m_nSize); return m_aT[nIndex]; } T* GetData() const { return m_aT; }
// Implementation
void SetAtIndex(int nIndex, T& t) { _ASSERTE(nIndex >= 0 && nIndex < m_nSize); m_aT[nIndex] = t; } int Find(T& t) const { for(int i = 0; i < m_nSize; i++) { if(m_aT[i] == t) return i; } return -1; // not found
} };
//
//Asynchronous I/O definitions.
//
class RAS_CLIENT; class CH323Call;
#define IO_BUFFER_SIZE 0x2000
enum OVERLAPPED_TYPE { OVERLAPPED_TYPE_SEND = 0, OVERLAPPED_TYPE_RECV, };
typedef struct O_OVERLAPPED { LIST_ENTRY ListEntry; OVERLAPPED Overlapped; OVERLAPPED_TYPE Type; union { RAS_CLIENT* RasClient; CH323Call* pCall; }; DWORD BytesTransferred; SOCKADDR_IN Address;
} RAS_OVERLAPPED, CALL_OVERLAPPED;
struct CALL_SEND_CONTEXT : public CALL_OVERLAPPED { WSABUF WSABuf; };
struct RAS_SEND_CONTEXT : public RAS_OVERLAPPED { UCHAR arBuf[IO_BUFFER_SIZE]; };
struct RAS_RECV_CONTEXT : public RAS_OVERLAPPED { UCHAR arBuf[IO_BUFFER_SIZE]; DWORD Flags; BOOL IsPending; INT AddressLength; }; struct CALL_RECV_CONTEXT : public CALL_OVERLAPPED { char arBuf[IO_BUFFER_SIZE]; WSABUF WSABuf; DWORD dwBytesCopied; DWORD dwPDULen; DWORD dwFlags; };
//
// Component Includes
//
#include "h4503pp.h"
#include "q931pdu.h"
|