Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
12 KiB

  1. /*
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. blbreg.cpp
  5. Abstract:
  6. Author:
  7. */
  8. #include "stdafx.h"
  9. // #include <windows.h>
  10. // #include <wtypes.h>
  11. #include <winsock2.h>
  12. #include "blbreg.h"
  13. const TCHAR TCHAR_BLANK = _T(' ');
  14. const TCHAR gsz_SdpRoot[] =
  15. _T("Software\\Microsoft\\Windows\\CurrentVersion\\Dynamic Directory\\Conference\\Sdp");
  16. const TCHAR gsz_ConfInstRoot[] =
  17. _T("Software\\Microsoft\\Windows\\CurrentVersion\\Dynamic Directory\\Conference");
  18. const TCHAR gsz_CharNewLine = _T('\n');
  19. const TCHAR gsz_CharRegNewLine = _T('#');
  20. DWORD REG_READER::ms_ErrorCode = ERROR_INTERNAL_ERROR;
  21. TCHAR SDP_REG_READER::ms_TimeTemplate[MAX_REG_TSTR_SIZE];
  22. TCHAR SDP_REG_READER::ms_MediaTemplate[MAX_REG_TSTR_SIZE];
  23. TCHAR SDP_REG_READER::ms_ConfBlobTemplate[MAX_BLOB_TEMPLATE_SIZE];
  24. USHORT SDP_REG_READER::ms_TimeTemplateLen;
  25. USHORT SDP_REG_READER::ms_MediaTemplateLen;
  26. USHORT SDP_REG_READER::ms_ConfBlobTemplateLen;
  27. DWORD SDP_REG_READER::ms_StartTimeOffset;
  28. DWORD SDP_REG_READER::ms_StopTimeOffset;
  29. BOOL SDP_REG_READER::ms_fInitCalled;
  30. BOOL SDP_REG_READER::ms_fWinsockStarted;
  31. IP_ADDRESS SDP_REG_READER::ms_HostIpAddress;
  32. static REG_INFO const gs_SdpRegInfoArray[] =
  33. {
  34. {TIME_TEMPLATE,
  35. sizeof(SDP_REG_READER::ms_TimeTemplate) - 1, // -1 for the newline
  36. &SDP_REG_READER::ms_TimeTemplateLen,
  37. SDP_REG_READER::ms_TimeTemplate},
  38. {MEDIA_TEMPLATE,
  39. sizeof(SDP_REG_READER::ms_MediaTemplate) - 1, // -1 for the newline
  40. &SDP_REG_READER::ms_MediaTemplateLen,
  41. SDP_REG_READER::ms_MediaTemplate},
  42. {CONFERENCE_BLOB_TEMPLATE,
  43. sizeof(SDP_REG_READER::ms_ConfBlobTemplate),
  44. &SDP_REG_READER::ms_ConfBlobTemplateLen,
  45. SDP_REG_READER::ms_ConfBlobTemplate}
  46. };
  47. inline void
  48. AppendTchar(
  49. IN OUT TCHAR *Tstr,
  50. IN OUT USHORT &TstrLen,
  51. IN TCHAR AppendChar
  52. )
  53. {
  54. ASSERT(lstrlen(Tstr) == TstrLen);
  55. Tstr[TstrLen++] = AppendChar;
  56. Tstr[TstrLen] = TCHAR_EOS;
  57. }
  58. BOOL
  59. REG_READER::ReadRegValues(
  60. IN HKEY Key,
  61. IN DWORD NumValues,
  62. IN REG_INFO const RegInfoArray[]
  63. )
  64. {
  65. DWORD ValueType = REG_SZ;
  66. DWORD BufferSize = 0;
  67. // for each value field, retrieve the value
  68. for (UINT i=0; i < NumValues; i++)
  69. {
  70. // determine the size of the buffer
  71. ms_ErrorCode = RegQueryValueEx(
  72. Key,
  73. RegInfoArray[i].msz_ValueName,
  74. 0,
  75. &ValueType,
  76. NULL,
  77. &BufferSize
  78. );
  79. if ( ERROR_SUCCESS != ms_ErrorCode )
  80. {
  81. return FALSE;
  82. }
  83. // check if the reqd buffer is bigger than the max acceptable size
  84. if ( RegInfoArray[i].m_MaxSize < BufferSize )
  85. {
  86. ms_ErrorCode = ERROR_OUTOFMEMORY;
  87. return FALSE;
  88. }
  89. // retrieve the value into the allocated buffer
  90. ms_ErrorCode = RegQueryValueEx(
  91. Key,
  92. RegInfoArray[i].msz_ValueName,
  93. 0,
  94. &ValueType,
  95. (BYTE *)RegInfoArray[i].msz_Tstr,
  96. &BufferSize
  97. );
  98. if ( ERROR_SUCCESS != ms_ErrorCode )
  99. {
  100. return FALSE;
  101. }
  102. // the reqd buffer size is > 1
  103. ASSERT(1 > BufferSize );
  104. // jump over any trailing blank characters - start at the last but one char
  105. for(UINT j=BufferSize-2; (TCHAR_BLANK == RegInfoArray[i].msz_Tstr[j]); j--)
  106. {
  107. }
  108. // if trailing blank chars, set the EOS beyond the last non-blank char
  109. if ( j < (BufferSize-2) )
  110. {
  111. RegInfoArray[i].msz_Tstr[j+1] = TCHAR_EOS;
  112. }
  113. // set the length of the tstr
  114. *RegInfoArray[i].m_TstrLen = j+1;
  115. }
  116. // return success
  117. return TRUE;
  118. }
  119. // static method
  120. BOOL
  121. IP_ADDRESS::GetLocalIpAddress(
  122. OUT DWORD &LocalIpAddress
  123. )
  124. {
  125. CHAR LocalHostName[MAXHOSTNAME];
  126. LPHOSTENT Hostent;
  127. int WsockErrorCode;
  128. // get the local host name
  129. WsockErrorCode = gethostname(LocalHostName, MAXHOSTNAME);
  130. if ( SOCKET_ERROR != WsockErrorCode)
  131. {
  132. // resolve host name for local address
  133. Hostent = gethostbyname((LPSTR)LocalHostName);
  134. if ( Hostent )
  135. {
  136. LocalIpAddress = ntohl(*((u_long *)Hostent->h_addr));
  137. return TRUE;
  138. }
  139. }
  140. const CHAR *LOOPBACK_ADDRESS_STRING = "127.0.0.1";
  141. SOCKADDR_IN LocalAddress;
  142. SOCKADDR_IN RemoteAddress;
  143. INT AddressSize = sizeof(sockaddr_in);
  144. SOCKET Socket;
  145. // initialize it to 0 to use it as a check later
  146. LocalIpAddress = 0;
  147. // initialize the local address to 0
  148. LocalAddress.sin_addr.s_addr = INADDR_ANY;
  149. // if still not resolved try the (horrible) second strategy
  150. Socket = socket(AF_INET, SOCK_DGRAM, 0);
  151. if ( INVALID_SOCKET != Socket )
  152. {
  153. // connect to arbitrary port and address (NOT loopback)
  154. // if connect is not performed, the provider may not return
  155. // a valid ip address
  156. RemoteAddress.sin_family = AF_INET;
  157. RemoteAddress.sin_port = htons(IPPORT_ECHO);
  158. // this address should ideally be an address that is outside the
  159. // intranet - but no harm if the address is inside
  160. RemoteAddress.sin_addr.s_addr = inet_addr(LOOPBACK_ADDRESS_STRING);
  161. WsockErrorCode = connect(Socket, (sockaddr *)&RemoteAddress, sizeof(sockaddr_in));
  162. if ( SOCKET_ERROR != WsockErrorCode )
  163. {
  164. // get local address
  165. getsockname(Socket, (sockaddr *)&LocalAddress, (int *)&AddressSize);
  166. LocalIpAddress = ntohl(LocalAddress.sin_addr.s_addr);
  167. }
  168. // close the socket
  169. closesocket(Socket);
  170. }
  171. if ( 0 == LocalIpAddress )
  172. {
  173. SetLastError(WSAGetLastError());
  174. return FALSE;
  175. }
  176. return TRUE;
  177. }
  178. BOOL
  179. SDP_REG_READER::ReadTimeValues(
  180. IN HKEY SdpKey
  181. )
  182. {
  183. DWORD ValueType = REG_DWORD;
  184. DWORD BufferSize = sizeof(DWORD);
  185. // read the start and stop time offsets
  186. ms_ErrorCode = RegQueryValueEx(
  187. SdpKey,
  188. START_TIME_OFFSET,
  189. 0,
  190. &ValueType,
  191. (BYTE *)&ms_StartTimeOffset,
  192. &BufferSize
  193. );
  194. if ( ERROR_SUCCESS != ms_ErrorCode )
  195. {
  196. return FALSE;
  197. }
  198. ms_ErrorCode = RegQueryValueEx(
  199. SdpKey,
  200. STOP_TIME_OFFSET,
  201. 0,
  202. &ValueType,
  203. (BYTE *)&ms_StopTimeOffset,
  204. &BufferSize
  205. );
  206. if ( ERROR_SUCCESS != ms_ErrorCode )
  207. {
  208. return FALSE;
  209. }
  210. return TRUE;
  211. }
  212. BOOL
  213. SDP_REG_READER::CheckIfCorrectVersion(
  214. )
  215. {
  216. WORD wVersionRequested;
  217. WSADATA WsaData;
  218. wVersionRequested = MAKEWORD(2, 0);
  219. // call winsock startup
  220. int ms_ErrorCode = WSAStartup( wVersionRequested, &WsaData );
  221. if ( 0 != ms_ErrorCode )
  222. {
  223. return FALSE;
  224. }
  225. // we'll take any version - no need to check if the requested version is supported
  226. ms_fWinsockStarted = TRUE;
  227. return TRUE;
  228. }
  229. void SDP_REG_READER::Init(
  230. )
  231. {
  232. ms_fInitCalled = TRUE;
  233. if ( !CheckIfCorrectVersion() )
  234. {
  235. return;
  236. }
  237. // try to determine the host ip address
  238. // ignore, if failed (255.255.255.255)
  239. DWORD LocalIpAddress;
  240. IP_ADDRESS::GetLocalIpAddress(LocalIpAddress);
  241. ms_HostIpAddress.SetIpAddress((0==LocalIpAddress)?(-1):LocalIpAddress);
  242. // open sdp key
  243. HKEY SdpKey;
  244. ms_ErrorCode = RegOpenKeyEx(
  245. HKEY_LOCAL_MACHINE,
  246. gsz_SdpRoot,
  247. 0,
  248. KEY_READ, // ZoltanS was: KEY_ALL_ACCESS
  249. &SdpKey
  250. );
  251. if ( ERROR_SUCCESS != ms_ErrorCode )
  252. {
  253. return;
  254. }
  255. // ZoltanS: NO NEED TO CLOSE THE ABOVE KEY because it is
  256. // wrapped in the class and closed "automatically."
  257. KEY_WRAP RendKeyWrap(SdpKey);
  258. // read the template registry info (tstr values) under the key
  259. if ( !ReadRegValues(
  260. SdpKey,
  261. sizeof(gs_SdpRegInfoArray)/ sizeof(REG_INFO),
  262. gs_SdpRegInfoArray
  263. ) )
  264. {
  265. return;
  266. }
  267. // Insert the "a:charset:%s#" into the sdp conference template
  268. AddCharacterSetAttribute();
  269. // replace the registry newline with the real newline character
  270. // NOTE - this is being done because we don't know how to enter the newline character
  271. // into a registry string
  272. for (UINT i=0; TCHAR_EOS != ms_ConfBlobTemplate[i]; i++)
  273. {
  274. if ( gsz_CharRegNewLine == ms_ConfBlobTemplate[i] )
  275. {
  276. ms_ConfBlobTemplate[i] = gsz_CharNewLine;
  277. }
  278. }
  279. // append newline after the media and time templates
  280. AppendTchar(ms_MediaTemplate, ms_MediaTemplateLen, gsz_CharNewLine);
  281. AppendTchar(ms_TimeTemplate, ms_TimeTemplateLen, gsz_CharNewLine);
  282. if ( !ReadTimeValues(SdpKey) )
  283. {
  284. return;
  285. }
  286. // success
  287. ms_ErrorCode = ERROR_SUCCESS;
  288. return;
  289. }
  290. /*++
  291. AddCharacterSetAttribute
  292. This methd it's called by SDP_REG_READER::Init
  293. Try to add the "a:charset:%s#" into ms_ConfBlobTemplate
  294. This atribute represents the character sets
  295. --*/
  296. void SDP_REG_READER::AddCharacterSetAttribute()
  297. {
  298. if( _tcsstr( ms_ConfBlobTemplate, _T("a=charset:")))
  299. {
  300. // The attribute is already into the Blob template
  301. return;
  302. }
  303. // The attribute charset is not in Blob Template
  304. // Try to find aut the "m=" (media attribute)
  305. TCHAR* szMediaTemplate = _tcsstr( ms_ConfBlobTemplate, _T("m="));
  306. if( szMediaTemplate == NULL)
  307. {
  308. // Add at the end of the template
  309. _tcscat( ms_ConfBlobTemplate, _T("a=charset:%s#"));
  310. return;
  311. }
  312. // We have to insert the
  313. TCHAR szBuffer[2000];
  314. _tcscpy( szBuffer, szMediaTemplate );
  315. // We concatenate the charset attribute
  316. szMediaTemplate[0] = (TCHAR)0;
  317. _tcscat( ms_ConfBlobTemplate, _T("a=charset:%s#"));
  318. // We add the media atrributes
  319. _tcscat( ms_ConfBlobTemplate, szBuffer);
  320. return;
  321. }