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.

272 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. tcputil.cxx
  5. Abstract:
  6. Contains functions to connect to an FTP server
  7. Contents:
  8. FtpOpenServer
  9. ResetSocket
  10. Author:
  11. Heath Hunnicutt (t-hheath) 21-Jun-1994
  12. Environment:
  13. Win32 user-level DLL
  14. Revision History:
  15. --*/
  16. #include <wininetp.h>
  17. #include "ftpapih.h"
  18. //
  19. // functions
  20. //
  21. DWORD
  22. FtpOpenServer(
  23. IN LPFTP_SESSION_INFO SessionInfo
  24. )
  25. /*++
  26. Routine Description:
  27. Resolves a host name and makes a connection to the FTP server at that host.
  28. If successful, the controlSocket field of the FTP_SESSION_INFO object will
  29. contain an opened socket handle
  30. Arguments:
  31. SessionInfo - pointer to FTP_SESSION_INFO describing host to connect to
  32. Return Value:
  33. DWORD
  34. Success - ERROR_SUCCESS
  35. Failure - ERROR_INTERNET_NAME_NOT_RESOLVED
  36. WSA error
  37. --*/
  38. {
  39. DEBUG_ENTER((DBG_FTP,
  40. Dword,
  41. "FtpOpenServer",
  42. "%#x",
  43. SessionInfo
  44. ));
  45. LPINTERNET_THREAD_INFO lpThreadInfo = InternetGetThreadInfo();
  46. DWORD error;
  47. BOOL fUseSocksProxy = FALSE;
  48. INTERNET_CONNECT_HANDLE_OBJECT *pConnect;
  49. AUTO_PROXY_ASYNC_MSG *pProxyInfoQuery = NULL;
  50. if (lpThreadInfo == NULL) {
  51. INET_ASSERT(FALSE);
  52. error = ERROR_INTERNET_INTERNAL_ERROR;
  53. goto quit;
  54. }
  55. DWORD asyncFlags;
  56. asyncFlags = 0;
  57. //asyncFlags = lpThreadInfo->IsAsyncWorkerThread ? SF_NON_BLOCKING : 0;
  58. //
  59. // attempt to resolve the host name, server port, and possibly service GUID
  60. // to socket address(es)
  61. //
  62. SessionInfo->socketControl->SetPort(SessionInfo->Port);
  63. //
  64. // Using the object handle, check to see if we have a socks proxy.
  65. // If so, use it to do our connections.
  66. //
  67. INTERNET_HANDLE_OBJECT * pInternet;
  68. HINTERNET hConnectMapped;
  69. INET_ASSERT(lpThreadInfo != NULL);
  70. INET_ASSERT(lpThreadInfo->hObjectMapped != NULL);
  71. INET_ASSERT(SessionInfo->Host != NULL);
  72. //
  73. // Get the Mapped Connect Handle Object
  74. //
  75. hConnectMapped = lpThreadInfo->hObjectMapped;
  76. INET_ASSERT(hConnectMapped);
  77. //
  78. // Finally get the Internet Object, so we can query proxy information
  79. // out of it.
  80. //
  81. pConnect = (INTERNET_CONNECT_HANDLE_OBJECT *) hConnectMapped;
  82. pInternet = (INTERNET_HANDLE_OBJECT *)
  83. ((INTERNET_CONNECT_HANDLE_OBJECT *)hConnectMapped)->GetParent();
  84. INET_ASSERT(pInternet);
  85. {
  86. CHAR szUrl[INTERNET_MAX_URL_LENGTH + sizeof("ftp:// /")];
  87. PROXY_STATE * pProxyState = NULL;
  88. INTERNET_SCHEME scheme = INTERNET_SCHEME_DEFAULT;
  89. if (lstrlen(SessionInfo->Host)>INTERNET_MAX_URL_LENGTH)
  90. {
  91. error = ERROR_INSUFFICIENT_BUFFER;
  92. goto quit;
  93. }
  94. wsprintf(szUrl, "ftp://%s/", SessionInfo->Host);
  95. AUTO_PROXY_ASYNC_MSG proxyInfoQuery(
  96. INTERNET_SCHEME_FTP,
  97. szUrl,
  98. lstrlen(szUrl),
  99. SessionInfo->Host,
  100. lstrlen(SessionInfo->Host),
  101. (INTERNET_PORT) SessionInfo->Port
  102. );
  103. proxyInfoQuery.SetBlockUntilCompletetion(TRUE);
  104. pProxyInfoQuery = &proxyInfoQuery;
  105. error = pInternet->GetProxyInfo(
  106. &pProxyInfoQuery
  107. );
  108. if ( error != ERROR_SUCCESS)
  109. {
  110. goto quit2;
  111. }
  112. if ( pProxyInfoQuery->IsUseProxy() &&
  113. pProxyInfoQuery->GetProxyScheme() == INTERNET_SCHEME_SOCKS &&
  114. pProxyInfoQuery->_lpszProxyHostName )
  115. {
  116. //
  117. // If Socks is enabled, then turn it on.
  118. //
  119. error = SessionInfo->socketControl->EnableSocks(
  120. pProxyInfoQuery->_lpszProxyHostName,
  121. pProxyInfoQuery->_nProxyHostPort
  122. );
  123. if ( error != ERROR_SUCCESS)
  124. {
  125. goto quit2;
  126. }
  127. error = SessionInfo->socketData->EnableSocks(
  128. pProxyInfoQuery->_lpszProxyHostName,
  129. pProxyInfoQuery->_nProxyHostPort
  130. );
  131. if ( error != ERROR_SUCCESS)
  132. {
  133. goto quit2;
  134. }
  135. //
  136. // Force Passive Mode, since Socks Firewalls may not
  137. // support connections from the outside in.
  138. //
  139. SessionInfo->Flags |= FFTP_PASSIVE_MODE;
  140. }
  141. pConnect->SetServerInfo(SessionInfo->Host,
  142. lstrlen(SessionInfo->Host));
  143. //
  144. // name was resolved ok, now let's try to connect to the server. Here
  145. // we create the control socket
  146. //
  147. error = SessionInfo->socketControl->Connect(
  148. GetTimeoutValue(INTERNET_OPTION_CONNECT_TIMEOUT),
  149. GetTimeoutValue(INTERNET_OPTION_CONNECT_RETRIES),
  150. SF_INDICATE | asyncFlags
  151. );
  152. quit2:
  153. if ( pProxyInfoQuery && pProxyInfoQuery->IsAlloced() )
  154. {
  155. delete pProxyInfoQuery;
  156. pProxyInfoQuery = NULL;
  157. }
  158. }
  159. quit:
  160. DEBUG_LEAVE(error);
  161. return error;
  162. }
  163. BOOL
  164. ResetSocket(
  165. IN ICSocket * Socket
  166. )
  167. /*++
  168. Routine Description:
  169. Sets linger time to zero on a socket, then closes the socket, causing a
  170. "hard" close
  171. Arguments:
  172. Socket - The socket to reset the connection on
  173. Return Value:
  174. BOOL
  175. Success - TRUE
  176. Failure - FALSE
  177. --*/
  178. {
  179. //
  180. // ignore return code from linger - if error, socket is closed or aborted
  181. //
  182. Socket->SetLinger(TRUE, 0);
  183. return (Socket->Close() == ERROR_SUCCESS) ? TRUE : FALSE;
  184. }