⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ceinet.cpp

📁 这个程序是我编写的从FTP站点下载文件的wince程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:

#include "stdafx.h"
#include <wininet.h>
#include <afxtempl.h>

#include <afxmt.h>
#pragma warning(disable: 4706) 
#pragma warning(disable: 4074)	
#include "ceinet.h"	
typedef struct CEtagServiceTable {
	DWORD dwService;
	LPCTSTR pstrIdentifier;
} CESvcTable;

AFX_STATIC_DATA const TCHAR _CEURLftp[] = _T("ftp://");

class CSessionMapPtrToPtr : public CMapPtrToPtr
{
private:
	CCriticalSection m_sect;

public:
	CSessionMapPtrToPtr() { }
	~CSessionMapPtrToPtr() { }

	void SetAt(HINTERNET hInternet, CCEInternetSession* pSess)
	{
		m_sect.Lock();
		CMapPtrToPtr::SetAt(hInternet, pSess);
		m_sect.Unlock();
	}

	void RemoveKey(HINTERNET hInternet)
	{
		m_sect.Lock();
		CMapPtrToPtr::RemoveKey(hInternet);
		m_sect.Unlock();
	}

	BOOL Lookup(HINTERNET hInternet, CCEInternetSession*& refpSession)
	{
		BOOL bRet;
		m_sect.Lock();
		bRet = CMapPtrToPtr::Lookup(hInternet, (void*&) refpSession);
		m_sect.Unlock();
		return bRet;
	}
};

CSessionMapPtrToPtr _CESessionMap;

/////////////////////////////////////////////////////////////////////////////
// Global Functions

bool __stdcall _CEParseURLWorker(LPCTSTR pstrURL,
	LPURL_COMPONENTS lpComponents, DWORD& dwServiceType,
	INTERNET_PORT& nPort, DWORD dwFlags)
{
	// this function will return bogus stuff if lpComponents
	// isn't set up to copy the components

	ASSERT(lpComponents != NULL && pstrURL != NULL);
	if (lpComponents == NULL || pstrURL == NULL)
		return FALSE;
	ASSERT(lpComponents->dwHostNameLength == 0 ||
			lpComponents->lpszHostName != NULL);
	ASSERT(lpComponents->dwUrlPathLength == 0 ||
			lpComponents->lpszUrlPath != NULL);
	ASSERT(lpComponents->dwUserNameLength == 0 ||
			lpComponents->lpszUserName != NULL);
	ASSERT(lpComponents->dwPasswordLength == 0 ||
			lpComponents->lpszPassword != NULL);

	ASSERT(AfxIsValidAddress(lpComponents, sizeof(URL_COMPONENTS), TRUE));

	LPTSTR pstrCanonicalizedURL;
	TCHAR szCanonicalizedURL[INTERNET_MAX_URL_LENGTH];
	DWORD dwNeededLength = INTERNET_MAX_URL_LENGTH;
	BOOL bRetVal;
	BOOL bMustFree = FALSE;
	DWORD dwCanonicalizeFlags = dwFlags &
		(ICU_NO_ENCODE | ICU_DECODE | ICU_NO_META |
		ICU_ENCODE_SPACES_ONLY | ICU_BROWSER_MODE);
	DWORD dwCrackFlags = dwFlags & (ICU_ESCAPE | ICU_USERNAME);

	bRetVal = InternetCanonicalizeUrl(pstrURL, szCanonicalizedURL,
		&dwNeededLength, dwCanonicalizeFlags);

	if (!bRetVal)
	{
		if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			return FALSE;

		pstrCanonicalizedURL = new TCHAR[dwNeededLength];
		bMustFree = TRUE;
		bRetVal = InternetCanonicalizeUrl(pstrURL, pstrCanonicalizedURL,
			&dwNeededLength, dwCanonicalizeFlags);
		if (!bRetVal)
		{
			delete [] pstrCanonicalizedURL;
			return FALSE;
		}
	}
	else
		pstrCanonicalizedURL = szCanonicalizedURL;

	// now that it's safely canonicalized, crack it

	bRetVal = InternetCrackUrl(pstrCanonicalizedURL, 0,
						dwCrackFlags, lpComponents);
	if (bMustFree)
		delete [] pstrCanonicalizedURL;

	// convert to MFC-style service ID

	if (!bRetVal)
		dwServiceType = AFX_INET_SERVICE_UNK;
	else
	{
		nPort = lpComponents->nPort;
		switch (lpComponents->nScheme)
		{
		case INTERNET_SCHEME_FTP:
			dwServiceType = AFX_INET_SERVICE_FTP;
			break;

		case INTERNET_SCHEME_GOPHER:
			dwServiceType = AFX_INET_SERVICE_GOPHER;
			break;

		case INTERNET_SCHEME_HTTP:
			dwServiceType = AFX_INET_SERVICE_HTTP;
			break;

		case INTERNET_SCHEME_HTTPS:
			dwServiceType = AFX_INET_SERVICE_HTTPS;
			break;

		case INTERNET_SCHEME_FILE:
			dwServiceType = AFX_INET_SERVICE_FILE;
			break;

		case INTERNET_SCHEME_NEWS:
			dwServiceType = AFX_INET_SERVICE_NNTP;
			break;

		case INTERNET_SCHEME_MAILTO:
			dwServiceType = AFX_INET_SERVICE_MAILTO;
			break;

		default:
			dwServiceType = AFX_INET_SERVICE_UNK;
		}
	}

	return bRetVal;
}
BOOL __stdcall CEParseURLEx(LPCTSTR pstrURL, DWORD& dwServiceType,
	CString& strServer, CString& strObject, INTERNET_PORT& nPort,
	CString& strUsername, CString& strPassword, DWORD dwFlags/* = 0*/)
{
	dwServiceType = AFX_INET_SERVICE_UNK;

	ASSERT(pstrURL != NULL);
	if (pstrURL == NULL)
		return FALSE;

	URL_COMPONENTS urlComponents;
	memset(&urlComponents, 0, sizeof(URL_COMPONENTS));
	urlComponents.dwStructSize = sizeof(URL_COMPONENTS);

	urlComponents.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
	urlComponents.lpszHostName = strServer.GetBuffer(INTERNET_MAX_HOST_NAME_LENGTH+1);
	urlComponents.dwUrlPathLength = INTERNET_MAX_PATH_LENGTH;
	urlComponents.lpszUrlPath = strObject.GetBuffer(INTERNET_MAX_PATH_LENGTH+1);
	urlComponents.dwUserNameLength = INTERNET_MAX_USER_NAME_LENGTH;
	urlComponents.lpszUserName = strUsername.GetBuffer(INTERNET_MAX_USER_NAME_LENGTH+1);
	urlComponents.dwPasswordLength = INTERNET_MAX_PASSWORD_LENGTH;
	urlComponents.lpszPassword = strPassword.GetBuffer(INTERNET_MAX_PASSWORD_LENGTH+1);

	BOOL bRetVal = _CEParseURLWorker(pstrURL, &urlComponents,
					dwServiceType, nPort, dwFlags);

	strServer.ReleaseBuffer();
	strObject.ReleaseBuffer();
	strUsername.ReleaseBuffer();
	strPassword.ReleaseBuffer();
	return bRetVal;
}

BOOL __stdcall CEParseURL(LPCTSTR pstrURL, DWORD& dwServiceType,
	CString& strServer, CString& strObject, INTERNET_PORT& nPort)
{
	dwServiceType = AFX_INET_SERVICE_UNK;

	ASSERT(pstrURL != NULL);
	if (pstrURL == NULL)
		return FALSE;

	URL_COMPONENTS urlComponents;
	memset(&urlComponents, 0, sizeof(URL_COMPONENTS));
	urlComponents.dwStructSize = sizeof(URL_COMPONENTS);

	urlComponents.dwHostNameLength = INTERNET_MAX_URL_LENGTH;
	urlComponents.lpszHostName = strServer.GetBuffer(INTERNET_MAX_URL_LENGTH+1);
	urlComponents.dwUrlPathLength = INTERNET_MAX_URL_LENGTH;
	urlComponents.lpszUrlPath = strObject.GetBuffer(INTERNET_MAX_URL_LENGTH+1);

	BOOL bRetVal = _CEParseURLWorker(pstrURL, &urlComponents,
					dwServiceType, nPort, ICU_BROWSER_MODE);

	strServer.ReleaseBuffer();
	strObject.ReleaseBuffer();
	return bRetVal;
}

DWORD __stdcall CEGetInternetHandleType(HINTERNET hQuery)
{
	DWORD dwServiceType;
	DWORD dwTypeLen = sizeof(dwServiceType);
	if (hQuery == NULL ||
		!InternetQueryOption(hQuery, INTERNET_OPTION_HANDLE_TYPE,
			&dwServiceType, &dwTypeLen))
		return AFX_INET_SERVICE_UNK;
	else
		return dwServiceType;
}

BOOL __stdcall 
_CEQueryCStringInternetOption(HINTERNET hHandle, DWORD dwOption, CString& refString)
{
	DWORD dwLength = 0;
	LPTSTR pstrBuffer;

	if (hHandle == NULL)
		return FALSE;

	if (!InternetQueryOption(hHandle, dwOption, NULL, &dwLength) &&
		GetLastError() != ERROR_INSUFFICIENT_BUFFER)
	{
		refString.Empty();
		return FALSE;
	}

	pstrBuffer = refString.GetBuffer(dwLength);
	BOOL bRet = InternetQueryOption(hHandle, dwOption, pstrBuffer, &dwLength);
	refString.ReleaseBuffer();
	return bRet;
}


#ifdef _DEBUG
void __stdcall CEInternetStatusCallbackDebug(HINTERNET hInternet,
	DWORD dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation,
	DWORD dwStatusInformationLength)
{
	UNUSED_ALWAYS(hInternet);
	TRACE1("Internet ctxt=%d: ", dwContext);

	switch (dwInternetStatus)
	{
	case INTERNET_STATUS_RESOLVING_NAME:
		TRACE1("resolving name for %s\n", lpvStatusInformation);
		break;

	case INTERNET_STATUS_NAME_RESOLVED:
		TRACE1("resolved name for %s!\n", lpvStatusInformation);
		break;

	case INTERNET_STATUS_HANDLE_CREATED:
		TRACE1("handle %8.8X created\n", hInternet);
		break;

	case INTERNET_STATUS_CONNECTING_TO_SERVER:
		{
		sockaddr* pSockAddr = (sockaddr*) lpvStatusInformation;
		TRACE1("connecting to socket address \"%s\"\n", pSockAddr->sa_data);
		}
		break;

	case INTERNET_STATUS_REQUEST_SENT:
		TRACE0("request sent!\n");
		break;

	case INTERNET_STATUS_SENDING_REQUEST:
		TRACE0("sending request...\n");
		break;

	case INTERNET_STATUS_CONNECTED_TO_SERVER:
		TRACE0("connected to socket address!\n");
		break;

	case INTERNET_STATUS_RECEIVING_RESPONSE:
		TRACE0("receiving response...\n");
		break;

	case INTERNET_STATUS_RESPONSE_RECEIVED:
		TRACE0("response received!\n");
		break;

	case INTERNET_STATUS_CLOSING_CONNECTION:
		TRACE1("closing connection %8.8X\n", hInternet);
		break;

	case INTERNET_STATUS_CONNECTION_CLOSED:
		TRACE1("connection %8.8X closed!\n", hInternet);
		break;

	case INTERNET_STATUS_HANDLE_CLOSING:
		TRACE1("handle %8.8X closed!\n", hInternet);
		break;

	case INTERNET_STATUS_REQUEST_COMPLETE:
		if (dwStatusInformationLength == sizeof(INTERNET_ASYNC_RESULT))
		{
			INTERNET_ASYNC_RESULT* pResult = (INTERNET_ASYNC_RESULT*) lpvStatusInformation;
			TRACE2("request complete, dwResult = %8.8X, dwError = %8.8X\n",
				pResult->dwResult, pResult->dwError);
		}
		else
			TRACE0("request complete.\n");
		break;

	case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
	case INTERNET_STATUS_REDIRECT:
	default:
		TRACE1("Unknown status: %d\n", dwInternetStatus);
		break;
	}

	return;
}
#endif // _DEBUG

void __stdcall CEInternetStatusCallback(HINTERNET hInternet, DWORD dwContext,
	DWORD dwInternetStatus, LPVOID lpvStatusInformation,
	DWORD dwStatusInformationLength)
{
	CCEInternetSession* pSession;

	if (_CESessionMap.Lookup(hInternet, pSession))
	{
		pSession->OnStatusCallback(dwContext, dwInternetStatus,
			lpvStatusInformation, dwStatusInformationLength);
	}

	// note that an entry we can't match is simply ignored as
	// WININET can send notifications for handles that we can't
	// see -- such as when using InternetOpenURL()
}

/////////////////////////////////////////////////////////////////////////////
/////CCEInternetSession
//

IMPLEMENT_DYNAMIC(CCEInternetSession, CObject)
CCEInternetSession::~CCEInternetSession()
{
	Close();
}
CCEInternetSession::CCEInternetSession(LPCTSTR pstrAgent /* = NULL */,
	DWORD dwContext /* = 1 */,
	DWORD dwAccessType /* = PRE_CONFIG_INTERNET_ACCESS */,
	LPCTSTR pstrProxyName /* = NULL */,
	LPCTSTR pstrProxyBypass /* = NULL */,
	DWORD dwFlags /* = 0 */)
{
#if defined(_WIN32_WCE)
	ASSERT(dwFlags == 0);
#else // _WIN32_WCE
	ASSERT((dwFlags & INTERNET_FLAG_ASYNC) == 0);
#endif // _WIN32_WCE
	m_bCallbackEnabled = FALSE;
	m_pOldCallback = NULL;

	m_dwContext = dwContext;
	if (pstrAgent == NULL)
		pstrAgent = AfxGetAppName();
	m_hSession = InternetOpen(pstrAgent, dwAccessType,
		pstrProxyName, pstrProxyBypass, dwFlags);

	if (m_hSession == NULL)
		CEThrowInternetException(m_dwContext);
	else
		_CESessionMap.SetAt(m_hSession, this);

#if defined(_WIN32_WCE)
	if((dwContext != 0) && (m_hSession != NULL))
		EnableStatusCallback(TRUE);
#endif // _WIN32_WCE
}

CCEInternetSession::operator HINTERNET() const
{
  return this->m_hSession;
}
void CCEInternetSession::Close()
{
	if (m_bCallbackEnabled)
		EnableStatusCallback(FALSE);

	if (m_hSession != NULL)
	{
		InternetCloseHandle(m_hSession);
		_CESessionMap.RemoveKey(m_hSession);
		m_hSession = NULL;
	}
}
DWORD CCEInternetSession::GetContext() const
{
	return m_dwContext;
}

CCEFtpConnection* CCEInternetSession::GetFtpConnection(LPCTSTR pstrServer,
	LPCTSTR pstrUserName /* = NULL */, LPCTSTR pstrPassword /* = NULL */,
	INTERNET_PORT nPort /* = INTERNET_INVALID_PORT_NUMBER */,
	BOOL bPassive /* = FALSE */)
{
	ASSERT(AfxIsValidString(pstrServer));

	CCEFtpConnection* pReturn = new CCEFtpConnection(this,
		pstrServer, pstrUserName, pstrPassword, m_dwContext,
		nPort, bPassive);
	return pReturn;
}

CStdioFile* CCEInternetSession::OpenURL(LPCTSTR pstrURL,
	DWORD dwContext /* = 0 */, DWORD dwFlags /* = INTERNET_FLAG_TRANSFER_BINARY */,
	LPCTSTR pstrHeaders /* = NULL */, DWORD dwHeadersLength /* = 0 */)
{
	ASSERT(AfxIsValidString(pstrURL));
	ASSERT(dwHeadersLength == 0 || pstrHeaders != NULL);
	ASSERT((dwFlags & INTERNET_FLAG_ASYNC) == 0);

	// must have TRANSFER_BINARY or TRANSFER_ASCII but not both
#define _AFX_TRANSFER_MASK (INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_TRANSFER_ASCII)
	ASSERT((dwFlags & _AFX_TRANSFER_MASK) != 0);
	ASSERT((dwFlags & _AFX_TRANSFER_MASK) != _AFX_TRANSFER_MASK);
#if defined(_WIN32_WCE)
	ASSERT( (dwFlags & ~(_AFX_TRANSFER_MASK | INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_AUTO_REDIRECT)) == 0 );
#endif
	if (dwContext == 1)
		dwContext = m_dwContext;

	DWORD dwServiceType;
	CString strServer;
	CString strObject;
	INTERNET_PORT nPort;
	CStdioFile* pReturn;

	BOOL bParsed = CEParseURL(pstrURL, dwServiceType, strServer, strObject, nPort);

	// if it turns out to be a file...
	if (bParsed && dwServiceType == AFX_INET_SERVICE_FILE)
	{
		int nMode = CFile::modeRead | CFile::shareCompat;
		if (dwFlags & INTERNET_FLAG_TRANSFER_BINARY)
			nMode |= CFile::typeBinary;
		else
			nMode |= CFile::typeText;

		pReturn = new CStdioFile(strObject, nMode);
	}
	else
	{
		HINTERNET hOpener;

		dwFlags &= ~(INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_TRANSFER_ASCII);
		hOpener = InternetOpenUrl(m_hSession, pstrURL, pstrHeaders,
			dwHeadersLength, dwFlags, dwContext);

		if (hOpener == NULL)
			CEThrowInternetException(m_dwContext);

		if (!bParsed)
			dwServiceType = CEGetInternetHandleType(hOpener);

		switch (dwServiceType)
		{

/*
#if !defined(_WIN32_WCE_NO_FTP)
			case INTERNET_HANDLE_TYPE_FTP_FILE:
			case AFX_INET_SERVICE_FTP:
				pReturn = new CCEInternetFile(hOpener, m_hSession, strObject,
					strServer, dwContext, TRUE);
				_CESessionMap.SetAt(hOpener, this);
				break;
#endif // _WIN32_WCE_NO_FTP
*/

			case INTERNET_HANDLE_TYPE_HTTP_REQUEST:
			case AFX_INET_SERVICE_HTTP:
			case AFX_INET_SERVICE_HTTPS:
				pReturn = NULL;
				break;

			default:
				TRACE1("Error: Unidentified service type: %8.8X\n", dwServiceType);
				pReturn = NULL;
		}
	}

	return pReturn;
}

BOOL CCEInternetSession::SetOption(DWORD dwOption, LPVOID lpBuffer,
	DWORD dwBufferLength, DWORD dwFlags /* = 0 */)
{
	ASSERT(AfxIsValidAddress(lpBuffer, dwBufferLength, FALSE));
	ASSERT(dwOption >= INTERNET_FIRST_OPTION &&
		dwOption <= INTERNET_LAST_OPTION);
	ASSERT(dwBufferLength != 0);
	ASSERT((dwFlags & INTERNET_FLAG_ASYNC) == 0);

	// bogus flag?
	ASSERT(dwFlags == 0 || WCE_IF(FALSE, ((dwFlags & ISO_VALID_FLAGS) == dwFlags)));

	return WCE_FCTN(InternetSetOptionEx)(m_hSession, dwOption,
		lpBuffer, dwBufferLength, dwFlags);
}

BOOL CCEInternetSession::QueryOption(DWORD dwOption, LPVOID lpBuffer,
	LPDWORD lpdwBufferLength) const
{
	ASSERT(dwOption >= INTERNET_FIRST_OPTION &&
		dwOption <= INTERNET_LAST_OPTION);
	ASSERT_POINTER(lpdwBufferLength, DWORD);
	ASSERT(AfxIsValidAddress(lpBuffer, *lpdwBufferLength));
	ASSERT(*lpdwBufferLength != 0);

	return InternetQueryOption(m_hSession, dwOption,
		lpBuffer, lpdwBufferLength);
}

BOOL CCEInternetSession::QueryOption(DWORD dwOption, DWORD& dwValue) const
{
	DWORD dwLen = sizeof(DWORD);
	return InternetQueryOption(m_hSession, dwOption,
		&dwValue, &dwLen);
}

BOOL CCEInternetSession::QueryOption(DWORD dwOption, CString& refString) const
{
	ASSERT(dwOption >= INTERNET_FIRST_OPTION &&
		dwOption <= INTERNET_LAST_OPTION);

	return _CEQueryCStringInternetOption(m_hSession, dwOption, refString);
}

void CCEInternetSession::OnStatusCallback(DWORD dwContext,
	DWORD dwInternetStatus, LPVOID lpvStatusInformation,
	DWORD dwStatusInformationLength)
{
	ASSERT(m_bCallbackEnabled != NULL);

	if (m_pOldCallback != NULL)
	{
		(*m_pOldCallback)(m_hSession, dwContext, dwInternetStatus,
			lpvStatusInformation, dwStatusInformationLength);
	}
}

BOOL CCEInternetSession::EnableStatusCallback(BOOL bEnable /* = TRUE */)
{
	ASSERT(!bEnable || m_hSession != NULL);
	if (m_hSession == NULL)
		return FALSE;

	BOOL bResult = TRUE;

	if (bEnable)
	{
#if !defined(_WIN32_WCE)
		ASSERT(!m_bCallbackEnabled);
#endif // _WIN32_WCE
		if (!m_bCallbackEnabled)
		{
			INTERNET_STATUS_CALLBACK pRet =
				InternetSetStatusCallback(m_hSession, CEInternetStatusCallback);

			if (pRet != INTERNET_INVALID_STATUS_CALLBACK)
			{
				m_pOldCallback = pRet;
				m_bCallbackEnabled = TRUE;
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -