WindowsXP-SP1/inetcore/wininet/ftp/tcputil.cxx
2020-09-30 16:53:49 +02:00

273 lines
6.4 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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 <wininetp.h>
#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;
}