/* Copyright (c) 1998-1999 Microsoft Corporation Module Name: blbreg.cpp Abstract: Author: */ #include "stdafx.h" // #include // #include #include #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; }