windows-nt/Source/XPSP1/NT/net/tapi/skywalker/sdpblb/blbreg.cpp
2020-09-26 16:20:57 +08:00

405 lines
12 KiB
C++

/*
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
blbreg.cpp
Abstract:
Author:
*/
#include "stdafx.h"
// #include <windows.h>
// #include <wtypes.h>
#include <winsock2.h>
#include "blbreg.h"
const TCHAR TCHAR_BLANK = _T(' ');
const TCHAR gsz_SdpRoot[] =
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Dynamic Directory\\Conference\\Sdp");
const TCHAR gsz_ConfInstRoot[] =
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Dynamic Directory\\Conference");
const TCHAR gsz_CharNewLine = _T('\n');
const TCHAR gsz_CharRegNewLine = _T('#');
DWORD REG_READER::ms_ErrorCode = ERROR_INTERNAL_ERROR;
TCHAR SDP_REG_READER::ms_TimeTemplate[MAX_REG_TSTR_SIZE];
TCHAR SDP_REG_READER::ms_MediaTemplate[MAX_REG_TSTR_SIZE];
TCHAR SDP_REG_READER::ms_ConfBlobTemplate[MAX_BLOB_TEMPLATE_SIZE];
USHORT SDP_REG_READER::ms_TimeTemplateLen;
USHORT SDP_REG_READER::ms_MediaTemplateLen;
USHORT SDP_REG_READER::ms_ConfBlobTemplateLen;
DWORD SDP_REG_READER::ms_StartTimeOffset;
DWORD SDP_REG_READER::ms_StopTimeOffset;
BOOL SDP_REG_READER::ms_fInitCalled;
BOOL SDP_REG_READER::ms_fWinsockStarted;
IP_ADDRESS SDP_REG_READER::ms_HostIpAddress;
static REG_INFO const gs_SdpRegInfoArray[] =
{
{TIME_TEMPLATE,
sizeof(SDP_REG_READER::ms_TimeTemplate) - 1, // -1 for the newline
&SDP_REG_READER::ms_TimeTemplateLen,
SDP_REG_READER::ms_TimeTemplate},
{MEDIA_TEMPLATE,
sizeof(SDP_REG_READER::ms_MediaTemplate) - 1, // -1 for the newline
&SDP_REG_READER::ms_MediaTemplateLen,
SDP_REG_READER::ms_MediaTemplate},
{CONFERENCE_BLOB_TEMPLATE,
sizeof(SDP_REG_READER::ms_ConfBlobTemplate),
&SDP_REG_READER::ms_ConfBlobTemplateLen,
SDP_REG_READER::ms_ConfBlobTemplate}
};
inline void
AppendTchar(
IN OUT TCHAR *Tstr,
IN OUT USHORT &TstrLen,
IN TCHAR AppendChar
)
{
ASSERT(lstrlen(Tstr) == TstrLen);
Tstr[TstrLen++] = AppendChar;
Tstr[TstrLen] = TCHAR_EOS;
}
BOOL
REG_READER::ReadRegValues(
IN HKEY Key,
IN DWORD NumValues,
IN REG_INFO const RegInfoArray[]
)
{
DWORD ValueType = REG_SZ;
DWORD BufferSize = 0;
// for each value field, retrieve the value
for (UINT i=0; i < NumValues; i++)
{
// determine the size of the buffer
ms_ErrorCode = RegQueryValueEx(
Key,
RegInfoArray[i].msz_ValueName,
0,
&ValueType,
NULL,
&BufferSize
);
if ( ERROR_SUCCESS != ms_ErrorCode )
{
return FALSE;
}
// check if the reqd buffer is bigger than the max acceptable size
if ( RegInfoArray[i].m_MaxSize < BufferSize )
{
ms_ErrorCode = ERROR_OUTOFMEMORY;
return FALSE;
}
// retrieve the value into the allocated buffer
ms_ErrorCode = RegQueryValueEx(
Key,
RegInfoArray[i].msz_ValueName,
0,
&ValueType,
(BYTE *)RegInfoArray[i].msz_Tstr,
&BufferSize
);
if ( ERROR_SUCCESS != ms_ErrorCode )
{
return FALSE;
}
// the reqd buffer size is > 1
ASSERT(1 > BufferSize );
// jump over any trailing blank characters - start at the last but one char
for(UINT j=BufferSize-2; (TCHAR_BLANK == RegInfoArray[i].msz_Tstr[j]); j--)
{
}
// if trailing blank chars, set the EOS beyond the last non-blank char
if ( j < (BufferSize-2) )
{
RegInfoArray[i].msz_Tstr[j+1] = TCHAR_EOS;
}
// set the length of the tstr
*RegInfoArray[i].m_TstrLen = j+1;
}
// return success
return TRUE;
}
// static method
BOOL
IP_ADDRESS::GetLocalIpAddress(
OUT DWORD &LocalIpAddress
)
{
CHAR LocalHostName[MAXHOSTNAME];
LPHOSTENT Hostent;
int WsockErrorCode;
// get the local host name
WsockErrorCode = gethostname(LocalHostName, MAXHOSTNAME);
if ( SOCKET_ERROR != WsockErrorCode)
{
// resolve host name for local address
Hostent = gethostbyname((LPSTR)LocalHostName);
if ( Hostent )
{
LocalIpAddress = ntohl(*((u_long *)Hostent->h_addr));
return TRUE;
}
}
const CHAR *LOOPBACK_ADDRESS_STRING = "127.0.0.1";
SOCKADDR_IN LocalAddress;
SOCKADDR_IN RemoteAddress;
INT AddressSize = sizeof(sockaddr_in);
SOCKET Socket;
// initialize it to 0 to use it as a check later
LocalIpAddress = 0;
// initialize the local address to 0
LocalAddress.sin_addr.s_addr = INADDR_ANY;
// if still not resolved try the (horrible) second strategy
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if ( INVALID_SOCKET != Socket )
{
// connect to arbitrary port and address (NOT loopback)
// if connect is not performed, the provider may not return
// a valid ip address
RemoteAddress.sin_family = AF_INET;
RemoteAddress.sin_port = htons(IPPORT_ECHO);
// this address should ideally be an address that is outside the
// intranet - but no harm if the address is inside
RemoteAddress.sin_addr.s_addr = inet_addr(LOOPBACK_ADDRESS_STRING);
WsockErrorCode = connect(Socket, (sockaddr *)&RemoteAddress, sizeof(sockaddr_in));
if ( SOCKET_ERROR != WsockErrorCode )
{
// get local address
getsockname(Socket, (sockaddr *)&LocalAddress, (int *)&AddressSize);
LocalIpAddress = ntohl(LocalAddress.sin_addr.s_addr);
}
// close the socket
closesocket(Socket);
}
if ( 0 == LocalIpAddress )
{
SetLastError(WSAGetLastError());
return FALSE;
}
return TRUE;
}
BOOL
SDP_REG_READER::ReadTimeValues(
IN HKEY SdpKey
)
{
DWORD ValueType = REG_DWORD;
DWORD BufferSize = sizeof(DWORD);
// read the start and stop time offsets
ms_ErrorCode = RegQueryValueEx(
SdpKey,
START_TIME_OFFSET,
0,
&ValueType,
(BYTE *)&ms_StartTimeOffset,
&BufferSize
);
if ( ERROR_SUCCESS != ms_ErrorCode )
{
return FALSE;
}
ms_ErrorCode = RegQueryValueEx(
SdpKey,
STOP_TIME_OFFSET,
0,
&ValueType,
(BYTE *)&ms_StopTimeOffset,
&BufferSize
);
if ( ERROR_SUCCESS != ms_ErrorCode )
{
return FALSE;
}
return TRUE;
}
BOOL
SDP_REG_READER::CheckIfCorrectVersion(
)
{
WORD wVersionRequested;
WSADATA WsaData;
wVersionRequested = MAKEWORD(2, 0);
// call winsock startup
int ms_ErrorCode = WSAStartup( wVersionRequested, &WsaData );
if ( 0 != ms_ErrorCode )
{
return FALSE;
}
// we'll take any version - no need to check if the requested version is supported
ms_fWinsockStarted = TRUE;
return TRUE;
}
void SDP_REG_READER::Init(
)
{
ms_fInitCalled = TRUE;
if ( !CheckIfCorrectVersion() )
{
return;
}
// try to determine the host ip address
// ignore, if failed (255.255.255.255)
DWORD LocalIpAddress;
IP_ADDRESS::GetLocalIpAddress(LocalIpAddress);
ms_HostIpAddress.SetIpAddress((0==LocalIpAddress)?(-1):LocalIpAddress);
// open sdp key
HKEY SdpKey;
ms_ErrorCode = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
gsz_SdpRoot,
0,
KEY_READ, // ZoltanS was: KEY_ALL_ACCESS
&SdpKey
);
if ( ERROR_SUCCESS != ms_ErrorCode )
{
return;
}
// ZoltanS: NO NEED TO CLOSE THE ABOVE KEY because it is
// wrapped in the class and closed "automatically."
KEY_WRAP RendKeyWrap(SdpKey);
// read the template registry info (tstr values) under the key
if ( !ReadRegValues(
SdpKey,
sizeof(gs_SdpRegInfoArray)/ sizeof(REG_INFO),
gs_SdpRegInfoArray
) )
{
return;
}
// Insert the "a:charset:%s#" into the sdp conference template
AddCharacterSetAttribute();
// replace the registry newline with the real newline character
// NOTE - this is being done because we don't know how to enter the newline character
// into a registry string
for (UINT i=0; TCHAR_EOS != ms_ConfBlobTemplate[i]; i++)
{
if ( gsz_CharRegNewLine == ms_ConfBlobTemplate[i] )
{
ms_ConfBlobTemplate[i] = gsz_CharNewLine;
}
}
// append newline after the media and time templates
AppendTchar(ms_MediaTemplate, ms_MediaTemplateLen, gsz_CharNewLine);
AppendTchar(ms_TimeTemplate, ms_TimeTemplateLen, gsz_CharNewLine);
if ( !ReadTimeValues(SdpKey) )
{
return;
}
// success
ms_ErrorCode = ERROR_SUCCESS;
return;
}
/*++
AddCharacterSetAttribute
This methd it's called by SDP_REG_READER::Init
Try to add the "a:charset:%s#" into ms_ConfBlobTemplate
This atribute represents the character sets
--*/
void SDP_REG_READER::AddCharacterSetAttribute()
{
if( _tcsstr( ms_ConfBlobTemplate, _T("a=charset:")))
{
// The attribute is already into the Blob template
return;
}
// The attribute charset is not in Blob Template
// Try to find aut the "m=" (media attribute)
TCHAR* szMediaTemplate = _tcsstr( ms_ConfBlobTemplate, _T("m="));
if( szMediaTemplate == NULL)
{
// Add at the end of the template
_tcscat( ms_ConfBlobTemplate, _T("a=charset:%s#"));
return;
}
// We have to insert the
TCHAR szBuffer[2000];
_tcscpy( szBuffer, szMediaTemplate );
// We concatenate the charset attribute
szMediaTemplate[0] = (TCHAR)0;
_tcscat( ms_ConfBlobTemplate, _T("a=charset:%s#"));
// We add the media atrributes
_tcscat( ms_ConfBlobTemplate, szBuffer);
return;
}