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
272 lines
6.4 KiB
/*++
|
|
|
|
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;
|
|
}
|