📄 inet.cpp
字号:
ASSERT_VALID(this);
ASSERT(AfxIsValidAddress(lpBuf, nCount));
ASSERT(m_hFile != NULL);
ASSERT(m_bReadMode);
DWORD dwBytes;
if (!m_bReadMode || m_hFile == NULL)
AfxThrowInternetException(m_dwContext, ERROR_INVALID_HANDLE);
if (m_pbReadBuffer == NULL)
{
if (!InternetReadFile(m_hFile, (LPVOID) lpBuf, nCount, &dwBytes))
AfxThrowInternetException(m_dwContext);
return dwBytes;
}
LPBYTE lpbBuf = (LPBYTE) lpBuf;
// if the requested size is bigger than our buffer,
// then handle it directly
if (nCount >= m_nReadBufferSize)
{
DWORD dwMoved = max(0, (long)m_nReadBufferBytes - (long)m_nReadBufferPos);
memcpy(lpBuf, m_pbReadBuffer + m_nReadBufferPos, dwMoved);
m_nReadBufferPos = m_nReadBufferSize;
if (!InternetReadFile(m_hFile, lpbBuf+dwMoved, nCount-dwMoved, &dwBytes))
AfxThrowInternetException(m_dwContext);
dwBytes += dwMoved;
}
else
{
if (m_nReadBufferPos + nCount >= m_nReadBufferBytes)
{
DWORD dwMoved = max(0, (long)m_nReadBufferBytes - (long)m_nReadBufferPos);
memcpy(lpbBuf, m_pbReadBuffer + m_nReadBufferPos, dwMoved);
DWORD dwRead;
if (!InternetReadFile(m_hFile, m_pbReadBuffer, m_nReadBufferSize,
&dwRead))
AfxThrowInternetException(m_dwContext);
m_nReadBufferBytes = dwRead;
dwRead = min(nCount - dwMoved, m_nReadBufferBytes);
memcpy(lpbBuf + dwMoved, m_pbReadBuffer, dwRead);
m_nReadBufferPos = dwRead;
dwBytes = dwMoved + dwRead;
}
else
{
memcpy(lpbBuf, m_pbReadBuffer + m_nReadBufferPos, nCount);
m_nReadBufferPos += nCount;
dwBytes = nCount;
}
}
return dwBytes;
}
void CInternetFile::Write(const void* lpBuf, UINT nCount)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
ASSERT(m_bReadMode == FALSE || m_bReadMode == -1);
if (m_bReadMode == TRUE || m_hFile == NULL)
AfxThrowInternetException(m_dwContext, ERROR_INVALID_HANDLE);
DWORD dwBytes;
if (m_pbWriteBuffer == NULL)
{
if (!InternetWriteFile(m_hFile, lpBuf, nCount, &dwBytes))
AfxThrowInternetException(m_dwContext);
if (dwBytes != nCount)
AfxThrowInternetException(m_dwContext);
}
else
{
if ((m_nWriteBufferPos + nCount) >= m_nWriteBufferSize)
{
// write what is in the buffer just now
if (!InternetWriteFile(m_hFile, m_pbWriteBuffer,
m_nWriteBufferPos, &dwBytes))
AfxThrowInternetException(m_dwContext);
// reset the buffer position since it is now clean
m_nWriteBufferPos = 0;
}
// if we can't hope to buffer the write request,
// do it immediately ... otherwise, buffer it!
if (nCount >= m_nWriteBufferSize)
{
if (!InternetWriteFile(m_hFile, (LPVOID) lpBuf, nCount, &dwBytes))
AfxThrowInternetException(m_dwContext);
}
else
{
memcpy(m_nWriteBufferPos + m_pbWriteBuffer, lpBuf, nCount);
m_nWriteBufferPos += nCount;
}
}
}
void CInternetFile::WriteString(LPCTSTR pstr)
{
ASSERT(m_bReadMode == TRUE || m_bReadMode == -1);
ASSERT(AfxIsValidString(pstr));
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
if (m_bReadMode == TRUE)
AfxThrowInternetException(m_dwContext, ERROR_INVALID_HANDLE);
Write(pstr, lstrlen(pstr));
}
LPTSTR CInternetFile::ReadString(LPTSTR pstr, UINT nMax)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
ASSERT(AfxIsValidAddress(pstr, nMax*sizeof(TCHAR)));
DWORD dwRead;
// if we're reading line-by-line, we must have a buffer
if (m_pbReadBuffer == NULL)
{
if (!SetReadBufferSize(4096)) // arbitrary but reasonable
return NULL;
if (!InternetReadFile(m_hFile, m_pbReadBuffer, m_nReadBufferSize,
&dwRead))
AfxThrowInternetException(m_dwContext);
m_nReadBufferBytes = dwRead;
m_nReadBufferPos = 0;
}
LPTSTR pstrChar = (LPTSTR) (m_pbReadBuffer + m_nReadBufferPos);
LPTSTR pstrTarget = pstr;
while (--nMax)
{
if (m_nReadBufferPos >= m_nReadBufferBytes)
{
if (!InternetReadFile(m_hFile, m_pbReadBuffer, m_nReadBufferSize,
&dwRead))
AfxThrowInternetException(m_dwContext);
m_nReadBufferBytes = dwRead;
if (m_nReadBufferBytes == 0)
{
*pstrTarget = '\0';
if (pstrTarget == pstr)
return NULL;
else
return pstr;
}
else
{
m_nReadBufferPos = 0;
pstrChar = (LPTSTR) m_pbReadBuffer;
}
}
if (*pstrChar != '\r')
*pstrTarget++ = *pstrChar;
m_nReadBufferPos++;
if (*pstrChar++ == '\n')
break;
}
*pstrTarget = '\0';
return pstr;
}
BOOL CInternetFile::ReadString(CString& rString)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
rString = _T(""); // empty string without deallocating
const int nMaxSize = 128;
LPTSTR pstrPlace = rString.GetBuffer(nMaxSize);
LPTSTR pstrResult;
int nLen;
do
{
pstrResult = ReadString(pstrPlace, nMaxSize);
rString.ReleaseBuffer();
// if string is read completely or EOF
if (pstrResult == NULL ||
(nLen = lstrlen(pstrPlace)) < (nMaxSize-1) ||
pstrPlace[nLen-1] == '\n')
break;
nLen = rString.GetLength();
pstrPlace = rString.GetBuffer(nMaxSize + nLen) + nLen;
} while (1);
// remove '\n' from end of string if present
pstrPlace = rString.GetBuffer(0);
nLen = rString.GetLength();
if (nLen != 0 && pstrPlace[nLen-1] == '\n')
pstrPlace[nLen-1] = '\0';
rString.ReleaseBuffer();
return (pstrResult != NULL);
}
DWORD CInternetFile::GetLength() const
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
DWORD dwRet = 0;
if (m_hFile != NULL)
{
if (!InternetQueryDataAvailable(m_hFile, &dwRet, 0, 0))
dwRet = 0;
}
return dwRet;
}
void CInternetFile::LockRange(DWORD /* dwPos */, DWORD /* dwCount */)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
AfxThrowNotSupportedException();
}
void CInternetFile::UnlockRange(DWORD /* dwPos */, DWORD /* dwCount */)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
AfxThrowNotSupportedException();
}
void CInternetFile::SetLength(DWORD)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
AfxThrowNotSupportedException();
}
CFile* CInternetFile::Duplicate() const
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
AfxThrowNotSupportedException();
return NULL;
}
#ifdef _DEBUG
void CInternetFile::AssertValid() const
{
// Don't call CStdioFile's AsssertValid()
CFile::AssertValid();
ASSERT(m_hConnection != NULL);
// make sure we really have a decent handle
if (m_hFile != NULL)
{
DWORD dwResult = AfxGetInternetHandleType(m_hFile);
if (IsKindOf(RUNTIME_CLASS(CHttpFile)))
{
ASSERT(dwResult == INTERNET_HANDLE_TYPE_HTTP_REQUEST);
}
else if (IsKindOf(RUNTIME_CLASS(CGopherFile)))
{
ASSERT(dwResult == INTERNET_HANDLE_TYPE_GOPHER_FILE ||
dwResult == INTERNET_HANDLE_TYPE_GOPHER_FIND_HTML ||
dwResult == INTERNET_HANDLE_TYPE_GOPHER_FILE_HTML ||
dwResult == INTERNET_HANDLE_TYPE_HTTP_REQUEST);
}
else if (IsKindOf(RUNTIME_CLASS(CInternetFile)))
{
ASSERT(dwResult == INTERNET_HANDLE_TYPE_FTP_FILE ||
dwResult == INTERNET_HANDLE_TYPE_FTP_FILE_HTML ||
dwResult == INTERNET_HANDLE_TYPE_FTP_FIND_HTML ||
dwResult == INTERNET_HANDLE_TYPE_HTTP_REQUEST);
}
else
ASSERT(FALSE); // some bogus object!
}
}
void CInternetFile::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << "\na " << GetRuntimeClass()->m_lpszClassName;
dc << " with handle " << (UINT)m_hFile;
}
#endif
/////////////////////////////////////////////////////////////////////////////
// CInternetConnection
CInternetConnection::CInternetConnection(CInternetSession* pSession,
LPCTSTR pstrServerName,
INTERNET_PORT nPort /* = INTERNET_INVALID_PORT_NUMBER */,
DWORD dwContext /* = 1 */)
: m_strServerName(pstrServerName)
{
ASSERT(pSession != NULL);
ASSERT_VALID(pSession);
ASSERT(pstrServerName != NULL);
m_nPort = nPort;
m_pSession = pSession;
m_hConnection = NULL;
if (dwContext == 1)
dwContext = pSession->GetContext();
m_dwContext = dwContext;
}
CInternetConnection::~CInternetConnection()
{
if (m_hConnection != NULL)
{
#ifdef _DEBUG
USES_CONVERSION;
LPCTSTR pszName = A2CT(GetRuntimeClass()->m_lpszClassName);
TRACE3("Warning: Disconnecting %s handle %8.8X in context %8.8X at destruction.\n",
pszName, m_hConnection, m_dwContext);
#endif
Close();
}
}
BOOL CInternetConnection::SetOption(DWORD dwOption, LPVOID lpBuffer,
DWORD dwBufferLength, DWORD dwFlags /* = 0 */)
{
ASSERT(dwOption >= INTERNET_FIRST_OPTION &&
dwOption <= INTERNET_LAST_OPTION);
ASSERT(AfxIsValidAddress(lpBuffer, dwBufferLength, FALSE));
ASSERT(dwBufferLength != 0);
ASSERT((dwFlags & INTERNET_FLAG_ASYNC) == 0);
// bogus flag?
ASSERT(dwFlags == 0 || ((dwFlags & ISO_VALID_FLAGS) == dwFlags));
return InternetSetOptionEx(m_hConnection, dwOption,
lpBuffer, dwBufferLength, dwFlags);
}
BOOL CInternetConnection::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_hConnection, dwOption,
lpBuffer, lpdwBufferLength);
}
BOOL CInternetConnection::QueryOption(DWORD dwOption, DWORD& dwValue) const
{
DWORD dwLen = sizeof(DWORD);
return InternetQueryOption(m_hConnection, dwOption,
&dwValue, &dwLen);
}
BOOL CInternetConnection::QueryOption(DWORD dwOption, CString& refString) const
{
ASSERT(dwOption >= INTERNET_FIRST_OPTION &&
dwOption <= INTERNET_LAST_OPTION);
return _AfxQueryCStringInternetOption(m_hConnection, dwOption, refString);
}
void CInternetConnection::Close()
{
if (m_hConnection != NULL)
{
InternetCloseHandle(m_hConnection);
_afxSessionMap.RemoveKey(m_hConnection);
m_hConnection = NULL;
}
}
#ifdef _DEBUG
void CInternetConnection::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << "m_hConnection = " << m_hConnection;
}
void CInternetConnection::AssertValid() const
{
CObject::AssertValid();
}
#endif
/////////////////////////////////////////////////////////////////////////////
// CFtpConnection
CFtpConnection::~CFtpConnection()
{
}
CFtpConnection::CFtpConnection(CInternetSession* pSession,
HINTERNET hConnected, LPCTSTR pstrServer, DWORD dwContext)
: CInternetConnection(pSession, pstrServer, INTERNET_INVALID_PORT_NUMBER,
dwContext)
{
ASSERT(pSession != NULL);
ASSERT(AfxIsValidString(pstrServer));
BOOL bBadType = FALSE;
if (AfxGetInternetHandleType(hConnected) != INTERNET_HANDLE_TYPE_CONNECT_FTP)
{
ASSERT(FALSE); // used the wrong handle type
bBadType = TRUE;
}
m_strServerName = pstrServer;
m_hConnection = hConnected;
if (m_hConnection == NULL || bBadType)
AfxThrowInternetException(m_dwContext, ERROR_INVALID_HANDLE);
else
_afxSessionMap.SetAt(m_hConnection, m_pSession);
}
CFtpConnection::CFtpConnection(CInternetSession* pSession,
LPCTSTR pstrServer, LPCTSTR pstrUserName /* = NULL */,
LPCTSTR pstrPassword /* = NULL */, DWORD dwContext /* = 0 */,
INTERNET_PORT nPort /* = INTERNET_INVALID_PORT_NUMBER */,
BOOL bPassive /* = FALSE */)
: CInternetConnection(pSession, pstrServer, nPort, dwContext)
{
ASSERT(pSession != NULL);
ASSERT_KINDOF(CInternetSession, pSession);
ASSERT(AfxIsValidString(pstrServer));
m_strServerName = pstrServer;
m_hConnection = InternetConnect((HINTERNET) *pSession, pstrServer,
nPort, pstrUserName, pstrPassword, INTERNET_SERVICE_FTP,
(bPassive ? INTERNET_FLAG_PASSIVE : 0), m_dwContext);
if (m_hConnection == NULL)
AfxThrowInternetException(m_dwContext, ::GetLastError());
else
_afxSessionMap.SetAt(m_hConnection, m_pSession);
}
void CFtpConnection::Close()
{
CInternetConnection::Close();
}
BOOL CFtpConnection::Remove(LPCTSTR pstrFileName)
{
ASSERT_VALID(this);
ASSERT(m_hConnection != NULL);
ASSERT(AfxIsValidString(pstrFileName));
return FtpDeleteFile(m_hConnection, pstrFileName);
}
BOOL CFtpConnection::Rename(LPCTSTR pstrExisting, LPCTSTR pstrNew)
{
ASSERT_VALID(this);
ASSERT(m_hConnection != NULL);
ASSERT(AfxIsValidString(pstrExisting));
ASSERT(AfxIsValidString(pstrNew));
return FtpRenameFile(m_hConnection, pstrExisting, pstrNew);
}
BOOL CFtpConnection::CreateDirectory(LPCTSTR pstrDirName)
{
ASSERT_VALID(this);
ASSERT(m_hConnection != NULL);
ASSERT(AfxIsValidString(pstrDirName));
return FtpCreateDirectory(m_hConnection, pstrDirName);
}
BOOL CFtpConnection::RemoveDirectory(LPCTSTR pstrDirName)
{
ASSERT_VALID(this);
ASSERT(m_hConnection != NULL);
ASSERT(AfxIsValidString(pstrDirName));
return FtpRemoveDirectory(m_hConnection, pstrDirName);
}
BOOL CFtpConnection::SetCurrentDirectory(LPCTSTR pstrDirName)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -