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.

373 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. connect.cxx
  5. Abstract:
  6. Contains methods for INTERNET_CONNECT_HANDLE_OBJECT class
  7. Contents:
  8. RMakeInternetConnectObjectHandle
  9. INTERNET_CONNECT_HANDLE_OBJECT::INTERNET_CONNECT_HANDLE_OBJECT
  10. INTERNET_CONNECT_HANDLE_OBJECT::~INTERNET_CONNECT_HANDLE_OBJECT
  11. Author:
  12. Madan Appiah (madana) 16-Nov-1994
  13. Environment:
  14. User Mode - Win32
  15. Revision History:
  16. Sophia Chung (sophiac) 14-Feb-1995 (added FTP and Archie class impl.)
  17. (code adopted from madana)
  18. --*/
  19. #include <wininetp.h>
  20. //
  21. // functions
  22. //
  23. DWORD
  24. RMakeInternetConnectObjectHandle(
  25. IN HINTERNET ParentHandle,
  26. IN OUT HINTERNET * ChildHandle,
  27. IN LPSTR lpszServerName,
  28. IN INTERNET_PORT nServerPort,
  29. IN DWORD dwFlags
  30. )
  31. /*++
  32. Routine Description:
  33. Creates an INTERNET_CONNECT_HANDLE_OBJECT. Wrapper function callable from
  34. C code
  35. Arguments:
  36. ParentHandle - parent InternetOpen() handle
  37. ChildHandle - IN: protocol-specific child handle
  38. OUT: address of handle object
  39. lpszServerName - pointer to server name
  40. nServerPort - server port to connect to
  41. dwFlags - various open flags from InternetConnect()
  42. Return Value:
  43. DWORD
  44. Success - ERROR_SUCCESS
  45. Failure - ERROR_NOT_ENOUGH_MEMORY
  46. --*/
  47. {
  48. DWORD error;
  49. INTERNET_CONNECT_HANDLE_OBJECT * hConnect;
  50. hConnect = New INTERNET_CONNECT_HANDLE_OBJECT(
  51. (INTERNET_HANDLE_BASE *)ParentHandle,
  52. *ChildHandle,
  53. lpszServerName,
  54. nServerPort,
  55. dwFlags
  56. );
  57. if (hConnect != NULL) {
  58. hConnect->Reference(); // claim a reference for the InternetConnectA() API
  59. error = hConnect->GetStatus();
  60. if (error == ERROR_SUCCESS) {
  61. //
  62. // inform the app of the new handle
  63. //
  64. if (!(dwFlags & WINHTTP_CONNECT_FLAG_NO_INDICATION))
  65. {
  66. error = InternetIndicateStatusNewHandle((LPVOID)hConnect);
  67. }
  68. //
  69. // ERROR_WINHTTP_OPERATION_CANCELLED is the only error that we are
  70. // expecting here. If we get this error then the app has cancelled
  71. // the operation. Either way, the handle we just generated will be
  72. // already deleted
  73. //
  74. if (error != ERROR_SUCCESS) {
  75. INET_ASSERT(error == ERROR_WINHTTP_OPERATION_CANCELLED);
  76. BOOL fDeleted = hConnect->Dereference();
  77. INET_ASSERT(fDeleted);
  78. UNREFERENCED_PARAMETER(fDeleted);
  79. hConnect = NULL;
  80. }
  81. } else {
  82. delete hConnect;
  83. hConnect = NULL;
  84. }
  85. } else {
  86. error = ERROR_NOT_ENOUGH_MEMORY;
  87. }
  88. *ChildHandle = (HINTERNET)hConnect;
  89. return error;
  90. }
  91. //
  92. // INTERNET_CONNECT_HANDLE_OBJECT class implementation
  93. //
  94. INTERNET_CONNECT_HANDLE_OBJECT::INTERNET_CONNECT_HANDLE_OBJECT(
  95. INTERNET_CONNECT_HANDLE_OBJECT *InternetConnectObj
  96. ) : INTERNET_HANDLE_BASE((INTERNET_HANDLE_BASE *)InternetConnectObj)
  97. /*++
  98. Routine Description:
  99. Constructor that creates a copy of an INTERNET_CONNECT_HANDLE_OBJECT when
  100. generating a derived handle object, such as a HTTP_REQUEST_HANDLE_OBJECT
  101. Arguments:
  102. InternetConnectObj - INTERNET_CONNECT_HANDLE_OBJECT to copy
  103. Return Value:
  104. None.
  105. --*/
  106. {
  107. DEBUG_ENTER((DBG_OBJECTS,
  108. None,
  109. "INTERNET_CONNECT_HANDLE_OBJECT::INTERNET_CONNECT_HANDLE_OBJECT",
  110. "%#x",
  111. InternetConnectObj
  112. ));
  113. //
  114. // copy the name objects and server port
  115. //
  116. _HostName = InternetConnectObj->_HostName;
  117. _HostNameNoScopeID = InternetConnectObj->_HostNameNoScopeID;
  118. _HostNameFlags = InternetConnectObj->_HostNameFlags;
  119. _HostPort = InternetConnectObj->_HostPort;
  120. //
  121. // _SchemeType is actual scheme we use. May be different than original
  122. // object type when going via CERN proxy. Initially set to default (HTTP)
  123. //
  124. _SchemeType = InternetConnectObj->_SchemeType;
  125. DEBUG_LEAVE(0);
  126. }
  127. INTERNET_CONNECT_HANDLE_OBJECT::INTERNET_CONNECT_HANDLE_OBJECT(
  128. INTERNET_HANDLE_BASE * Parent,
  129. HINTERNET Child,
  130. LPTSTR lpszServerName,
  131. INTERNET_PORT nServerPort,
  132. DWORD dwFlags
  133. ) : INTERNET_HANDLE_BASE(Parent)
  134. /*++
  135. Routine Description:
  136. Constructor for direct-to-net INTERNET_CONNECT_HANDLE_OBJECT
  137. Arguments:
  138. Parent - pointer to parent handle (INTERNET_HANDLE_BASE as
  139. created by InternetOpen())
  140. Child - handle of child object - typically an identifying value
  141. for the protocol-specific code
  142. lpszServerName - name of the server we are connecting to. May also be the
  143. IP address expressed as a string
  144. nServerPort - the port number at the server to which we connect
  145. dwFlags - creation flags from InternetConnect():
  146. Return Value:
  147. None.
  148. --*/
  149. {
  150. UNREFERENCED_PARAMETER(dwFlags);
  151. UNREFERENCED_PARAMETER(Child);
  152. DEBUG_ENTER((DBG_OBJECTS,
  153. None,
  154. "INTERNET_CONNECT_HANDLE_OBJECT::INTERNET_CONNECT_HANDLE_OBJECT",
  155. "%#x, %#x, %q, %d, %#x, %#x",
  156. Parent,
  157. Child,
  158. lpszServerName,
  159. nServerPort,
  160. dwFlags
  161. ));
  162. // _HostName, _HostNameScopeID, _HostNameFlags all handled by SetHostName()
  163. SetHostName(lpszServerName);
  164. _HostPort = nServerPort;
  165. SetSchemeType(INTERNET_SCHEME_HTTP);
  166. SetObjectType(TypeHttpConnectHandle);
  167. _Status = ERROR_SUCCESS; // BUGBUG: what if we fail to allocate _HostName?
  168. DEBUG_LEAVE(0);
  169. }
  170. INTERNET_CONNECT_HANDLE_OBJECT::~INTERNET_CONNECT_HANDLE_OBJECT(VOID)
  171. /*++
  172. Routine Description:
  173. Destructor for INTERNET_CONNECT_HANDLE_OBJECT
  174. Arguments:
  175. None.
  176. Return Value:
  177. None.
  178. --*/
  179. {
  180. // Nothing to see here, people; move along!
  181. }
  182. VOID INTERNET_CONNECT_HANDLE_OBJECT::SetHostName(
  183. LPSTR lpszHostName
  184. )
  185. /*++
  186. Routine Description:
  187. Stores the Host Name in an INTERNET_CONNECT_HANDLE_OBJECT
  188. Arguments:
  189. lpszHostName - name of the server we are connecting to. May also be an
  190. IP address expressed as a string
  191. Return Value:
  192. None.
  193. --*/
  194. {
  195. SOCKADDR_IN6 Address;
  196. INT Error;
  197. INT AddressLength;
  198. _HostNameFlags = 0;
  199. // check if this is a valid IPv4 iteral
  200. AddressLength = sizeof(Address);
  201. Error = _I_WSAStringToAddressA((LPSTR)lpszHostName, AF_INET, NULL, (LPSOCKADDR)&Address, &AddressLength);
  202. if (Error == 0) {
  203. _HostNameFlags |= _IPv4LiteralFlag;
  204. } else {
  205. // not an IPv4 literal, could be an IPv6 literal
  206. AddressLength = sizeof(Address);
  207. Error = _I_WSAStringToAddressA((LPSTR)lpszHostName, AF_INET6, NULL, (LPSOCKADDR)&Address, &AddressLength);
  208. if (Error == 0) {
  209. _HostNameFlags |= _IPv6LiteralFlag;
  210. if (Address.sin6_scope_id != 0) {
  211. _HostNameFlags |= _IPv6ScopeIDFlag;
  212. }
  213. }
  214. }
  215. // If IPv6 literal address, check if it is encapsulated with '[' and ']'
  216. BOOL bracketsNeeded = FALSE;
  217. DWORD len = strlen(lpszHostName);
  218. if ((_HostNameFlags & _IPv6LiteralFlag) != 0)
  219. {
  220. if ((lpszHostName[0] != '[') || (lpszHostName[len-1] != ']'))
  221. {
  222. // no brackets so we have to add them
  223. bracketsNeeded = TRUE;
  224. }
  225. }
  226. if (!bracketsNeeded)
  227. {
  228. _HostName = lpszHostName;
  229. }
  230. else
  231. {
  232. // using ICSTRING efficiently construct string with brackets
  233. _HostName.CreateStringBuffer("[", 1, len+3); // 3 = 2 brackets + 1 null
  234. _HostName.Strncat(lpszHostName, len);
  235. _HostName.Strncat("]", 1);
  236. }
  237. // If IPv6 literal address has a scope ID then build a no-scope-id hostname
  238. if ((_HostNameFlags & _IPv6ScopeIDFlag) != 0)
  239. {
  240. LPSTR lpszPercent = NULL;
  241. if ((lpszPercent = StrChrA(_HostName.StringAddress(), '%')) != NULL)
  242. {
  243. // using ICSTRING efficiently construct substring minus scope ID
  244. len = (DWORD)(lpszPercent - _HostName.StringAddress());
  245. _HostNameNoScopeID.CreateStringBuffer(_HostName.StringAddress(), len, len+2); // 2 = 1 brkt + 1 null
  246. _HostNameNoScopeID.Strncat("]", 1);
  247. }
  248. }
  249. else
  250. {
  251. _HostNameNoScopeID = NULL;
  252. }
  253. //dprintf("_HostName is %q\n", _HostName.StringAddress());
  254. //dprintf("_HostNameNoScopeID is %q\n", _HostNameNoScopeID.StringAddress());
  255. }