/*++ Copyright (c) 1994 Microsoft Corporation Module Name: tcputil.cxx Abstract: Contains functions to connect to an FTP server Contents: FtpOpenServer ResetSocket Author: Heath Hunnicutt (t-hheath) 21-Jun-1994 Environment: Win32 user-level DLL Revision History: --*/ #include #include "ftpapih.h" // // functions // DWORD FtpOpenServer( IN LPFTP_SESSION_INFO SessionInfo ) /*++ Routine Description: Resolves a host name and makes a connection to the FTP server at that host. If successful, the controlSocket field of the FTP_SESSION_INFO object will contain an opened socket handle Arguments: SessionInfo - pointer to FTP_SESSION_INFO describing host to connect to Return Value: DWORD Success - ERROR_SUCCESS Failure - ERROR_INTERNET_NAME_NOT_RESOLVED WSA error --*/ { DEBUG_ENTER((DBG_FTP, Dword, "FtpOpenServer", "%#x", SessionInfo )); LPINTERNET_THREAD_INFO lpThreadInfo = InternetGetThreadInfo(); DWORD error; BOOL fUseSocksProxy = FALSE; INTERNET_CONNECT_HANDLE_OBJECT *pConnect; AUTO_PROXY_ASYNC_MSG *pProxyInfoQuery = NULL; if (lpThreadInfo == NULL) { INET_ASSERT(FALSE); error = ERROR_INTERNET_INTERNAL_ERROR; goto quit; } DWORD asyncFlags; asyncFlags = 0; //asyncFlags = lpThreadInfo->IsAsyncWorkerThread ? SF_NON_BLOCKING : 0; // // attempt to resolve the host name, server port, and possibly service GUID // to socket address(es) // SessionInfo->socketControl->SetPort(SessionInfo->Port); // // Using the object handle, check to see if we have a socks proxy. // If so, use it to do our connections. // INTERNET_HANDLE_OBJECT * pInternet; HINTERNET hConnectMapped; INET_ASSERT(lpThreadInfo != NULL); INET_ASSERT(lpThreadInfo->hObjectMapped != NULL); INET_ASSERT(SessionInfo->Host != NULL); // // Get the Mapped Connect Handle Object // hConnectMapped = lpThreadInfo->hObjectMapped; INET_ASSERT(hConnectMapped); // // Finally get the Internet Object, so we can query proxy information // out of it. // pConnect = (INTERNET_CONNECT_HANDLE_OBJECT *) hConnectMapped; pInternet = (INTERNET_HANDLE_OBJECT *) ((INTERNET_CONNECT_HANDLE_OBJECT *)hConnectMapped)->GetParent(); INET_ASSERT(pInternet); { CHAR szUrl[INTERNET_MAX_URL_LENGTH + sizeof("ftp:// /")]; PROXY_STATE * pProxyState = NULL; INTERNET_SCHEME scheme = INTERNET_SCHEME_DEFAULT; if (lstrlen(SessionInfo->Host)>INTERNET_MAX_URL_LENGTH) { error = ERROR_INSUFFICIENT_BUFFER; goto quit; } wsprintf(szUrl, "ftp://%s/", SessionInfo->Host); AUTO_PROXY_ASYNC_MSG proxyInfoQuery( INTERNET_SCHEME_FTP, szUrl, lstrlen(szUrl), SessionInfo->Host, lstrlen(SessionInfo->Host), (INTERNET_PORT) SessionInfo->Port ); proxyInfoQuery.SetBlockUntilCompletetion(TRUE); pProxyInfoQuery = &proxyInfoQuery; error = pInternet->GetProxyInfo( &pProxyInfoQuery ); if ( error != ERROR_SUCCESS) { goto quit2; } if ( pProxyInfoQuery->IsUseProxy() && pProxyInfoQuery->GetProxyScheme() == INTERNET_SCHEME_SOCKS && pProxyInfoQuery->_lpszProxyHostName ) { // // If Socks is enabled, then turn it on. // error = SessionInfo->socketControl->EnableSocks( pProxyInfoQuery->_lpszProxyHostName, pProxyInfoQuery->_nProxyHostPort ); if ( error != ERROR_SUCCESS) { goto quit2; } error = SessionInfo->socketData->EnableSocks( pProxyInfoQuery->_lpszProxyHostName, pProxyInfoQuery->_nProxyHostPort ); if ( error != ERROR_SUCCESS) { goto quit2; } // // Force Passive Mode, since Socks Firewalls may not // support connections from the outside in. // SessionInfo->Flags |= FFTP_PASSIVE_MODE; } pConnect->SetServerInfo(SessionInfo->Host, lstrlen(SessionInfo->Host)); // // name was resolved ok, now let's try to connect to the server. Here // we create the control socket // error = SessionInfo->socketControl->Connect( GetTimeoutValue(INTERNET_OPTION_CONNECT_TIMEOUT), GetTimeoutValue(INTERNET_OPTION_CONNECT_RETRIES), SF_INDICATE | asyncFlags ); quit2: if ( pProxyInfoQuery && pProxyInfoQuery->IsAlloced() ) { delete pProxyInfoQuery; pProxyInfoQuery = NULL; } } quit: DEBUG_LEAVE(error); return error; } BOOL ResetSocket( IN ICSocket * Socket ) /*++ Routine Description: Sets linger time to zero on a socket, then closes the socket, causing a "hard" close Arguments: Socket - The socket to reset the connection on Return Value: BOOL Success - TRUE Failure - FALSE --*/ { // // ignore return code from linger - if error, socket is closed or aborted // Socket->SetLinger(TRUE, 0); return (Socket->Close() == ERROR_SUCCESS) ? TRUE : FALSE; }