📄 ceinet.cpp
字号:
{
Flush();
InternetCloseHandle(m_hFile);
_CESessionMap.RemoveKey(m_hFile);
m_hFile = NULL;
if (m_pbWriteBuffer != NULL)
{
delete [] m_pbWriteBuffer;
m_pbWriteBuffer = NULL;
}
if (m_pbReadBuffer != NULL)
{
delete [] m_pbReadBuffer;
m_pbReadBuffer = NULL;
}
}
}
UINT CCEInternetFile::Read(LPVOID lpBuf, UINT nCount)
{
ASSERT_VALID(this);
ASSERT(AfxIsValidAddress(lpBuf, nCount));
ASSERT(m_hFile != NULL);
ASSERT(m_bReadMode);
DWORD dwBytes;
if (!m_bReadMode || m_hFile == NULL)
CEThrowInternetException(m_dwContext, ERROR_INVALID_HANDLE);
if (m_pbReadBuffer == NULL)
{
if (!InternetReadFile(m_hFile, (LPVOID) lpBuf, nCount, &dwBytes))
CEThrowInternetException(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);
WCE_FCTN(memcpy)(lpBuf, m_pbReadBuffer + m_nReadBufferPos, dwMoved);
m_nReadBufferPos = m_nReadBufferSize;
if (!InternetReadFile(m_hFile, lpbBuf+dwMoved, nCount-dwMoved, &dwBytes))
CEThrowInternetException(m_dwContext);
dwBytes += dwMoved;
}
else
{
if (m_nReadBufferPos + nCount >= m_nReadBufferBytes)
{
DWORD dwMoved = max(0, (long)m_nReadBufferBytes - (long)m_nReadBufferPos);
WCE_FCTN(memcpy)(lpbBuf, m_pbReadBuffer + m_nReadBufferPos, dwMoved);
DWORD dwRead;
if (!InternetReadFile(m_hFile, m_pbReadBuffer, m_nReadBufferSize,
&dwRead))
CEThrowInternetException(m_dwContext);
m_nReadBufferBytes = dwRead;
dwRead = min(nCount - dwMoved, m_nReadBufferBytes);
WCE_FCTN(memcpy)(lpbBuf + dwMoved, m_pbReadBuffer, dwRead);
m_nReadBufferPos = dwRead;
dwBytes = dwMoved + dwRead;
}
else
{
WCE_FCTN(memcpy)(lpbBuf, m_pbReadBuffer + m_nReadBufferPos, nCount);
m_nReadBufferPos += nCount;
dwBytes = nCount;
}
}
return dwBytes;
}
LPTSTR CCEInternetFile::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))
CEThrowInternetException(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))
CEThrowInternetException(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;
#if defined(_WIN32_WCE)
m_nReadBufferPos += 2; // WinCE: for UNICODE characters
#else // _WIN32_WCE
m_nReadBufferPos++;
#endif // _WIN32_WCE
if (*pstrChar++ == '\n')
break;
}
*pstrTarget = '\0';
return pstr;
}
BOOL CCEInternetFile::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 CCEInternetFile::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 CCEInternetFile::LockRange(DWORD /* dwPos */, DWORD /* dwCount */)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
AfxThrowNotSupportedException();
}
void CCEInternetFile::UnlockRange(DWORD /* dwPos */, DWORD /* dwCount */)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
AfxThrowNotSupportedException();
}
void CCEInternetFile::SetLength(DWORD)
{
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
AfxThrowNotSupportedException();
}
CFile* CCEInternetFile::Duplicate() const
{
ASSERT_VALID(this);
#if !defined(_WIN32_WCE)
ASSERT(m_pStream != NULL);
#endif // _WIN32_WCE
AfxThrowNotSupportedException();
return NULL;
}
#ifdef _DEBUG
void CCEInternetFile::AssertValid() const
{
// Don't call CStdioFile's AsssertValid()
CFile::AssertValid();
#if !defined(_WIN32_WCE)
ASSERT(m_hConnection != NULL);
#endif // _WIN32_WCE
// make sure we really have a decent handle
if (m_hFile != NULL)
{
DWORD dwResult = CEGetInternetHandleType(m_hFile);
if (IsKindOf(RUNTIME_CLASS(CCEInternetFile)))
{
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 CCEInternetFile::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << "\na " << GetRuntimeClass()->m_lpszClassName;
dc << " with handle " << (UINT)m_hFile;
}
#endif
//___________________________________________________________________________
IMPLEMENT_DYNAMIC(CCEFtpFileFind, CObject)
void CCEFtpFileFind::Close()
{
if (m_pFoundInfo != NULL)
{
delete m_pFoundInfo;
m_pFoundInfo = NULL;
}
if (m_pNextInfo != NULL)
{
delete m_pNextInfo;
m_pNextInfo = NULL;
}
if (m_hContext != NULL && m_hContext != INVALID_HANDLE_VALUE)
{
CloseContext();
m_hContext = NULL;
}
}
CCEFtpFileFind::CCEFtpFileFind(CCEFtpConnection* pConnection, DWORD dwContext)
{
ASSERT(pConnection != NULL);
ASSERT_KINDOF(CCEFtpConnection, pConnection);
m_pFoundInfo = NULL;
m_pNextInfo = NULL;
m_hContext = NULL;
m_pConnection = pConnection;
if (dwContext == 1)
dwContext = pConnection->GetContext();
m_dwContext = dwContext;
m_chDirSeparator = '/';
}
CCEFtpFileFind::~CCEFtpFileFind()
{
Close();
}
BOOL CCEFtpFileFind::FindFile(LPCTSTR pstrName /* = NULL */,
DWORD dwFlags /* = INTERNET_FLAG_RELOAD */)
{
ASSERT((dwFlags & INTERNET_FLAG_ASYNC) == 0);
ASSERT(m_pConnection != NULL);
ASSERT_VALID(m_pConnection);
if (m_pConnection == NULL)
return FALSE;
Close();
m_pNextInfo = new WIN32_FIND_DATA;
m_bGotLast = FALSE;
if (pstrName == NULL)
pstrName = _T("*");
wcscpy(((LPWIN32_FIND_DATA) m_pNextInfo)->cFileName, pstrName);
m_hContext = FtpFindFirstFile((HINTERNET) *m_pConnection,
pstrName, (LPWIN32_FIND_DATA) m_pNextInfo, dwFlags, m_dwContext);
if (m_hContext == NULL)
{
Close();
return FALSE;
}
LPCTSTR pstrRoot = wcspbrk(pstrName, _T("\\/"));
CString strCWD;
m_pConnection->GetCurrentDirectory(strCWD);
if (pstrRoot == NULL)
{
if (m_pConnection->SetCurrentDirectory(pstrName))
{
m_pConnection->GetCurrentDirectory(m_strRoot);
m_pConnection->SetCurrentDirectory(strCWD);
}
else
m_strRoot = strCWD;
}
else
{
// find the last forward or backward whack
int nLast;
LPCTSTR pstrOther = _tcsrchr(pstrName, '\\');
pstrRoot = _tcsrchr(pstrName, '/');
if (pstrRoot == NULL)
pstrRoot = pstrName;
if (pstrOther == NULL)
pstrOther = pstrName;
if (pstrRoot >= pstrOther)
nLast = pstrRoot - pstrName;
else
nLast = pstrOther - pstrName;
// from the start to the last whack is the root
if (nLast == 0)
nLast++;
m_strRoot = pstrName;
m_strRoot = m_strRoot.Left(nLast);
}
return TRUE;
}
BOOL CCEFtpFileFind::FindNextFile()
{
ASSERT(m_hContext != NULL);
if (m_hContext == NULL)
return FALSE;
if (m_pFoundInfo == NULL)
m_pFoundInfo = new WIN32_FIND_DATA;
ASSERT_VALID(this);
void* pTemp = m_pFoundInfo;
m_pFoundInfo = m_pNextInfo;
m_pNextInfo = pTemp;
return InternetFindNextFile(m_hContext, m_pNextInfo);
}
void CCEFtpFileFind::CloseContext()
{
if (m_hContext != NULL && m_hContext != INVALID_HANDLE_VALUE)
{
InternetCloseHandle(m_hContext);
m_hContext = NULL;
}
return;
}
CString CCEFtpFileFind::GetFileName() const
{
ASSERT(m_hContext != NULL);
ASSERT_VALID(this);
CString ret;
if (m_pFoundInfo != NULL)
ret = ((LPWIN32_FIND_DATA) m_pFoundInfo)->cFileName;
return ret;
}
CString CCEFtpFileFind::GetFilePath() const
{
ASSERT(m_hContext != NULL);
ASSERT_VALID(this);
CString strResult = m_strRoot;
if (strResult[strResult.GetLength()-1] != '\\' &&
strResult[strResult.GetLength()-1] != '/')
strResult += m_chDirSeparator;
strResult += GetFileName();
return strResult;
}
CString CCEFtpFileFind::GetFileURL() const
{
ASSERT_VALID(this);
ASSERT(m_hContext != NULL);
CString str;
if (m_hContext != NULL)
{
str += _CEURLftp;
str += m_pConnection->GetServerName();
str += GetFilePath();
}
return str;
}
#ifdef _DEBUG
void CCEFtpFileFind::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << "m_hContext = " << m_hContext;
}
void CCEFtpFileFind::AssertValid() const
{
CObject::AssertValid();
}
#endif
/////////////////////////////////////////////////////////////////////////////
// exception handling
void __stdcall CEThrowInternetException(DWORD dwContext, DWORD dwError /* = 0 */)
{
if (dwError == 0)
dwError = ::GetLastError();
CCEInternetException* pException = new CCEInternetException(dwError);
pException->m_dwContext = dwContext;
TRACE1("Warning: throwing CCEInternetException for error %d\n", dwError);
THROW(pException);
}
IMPLEMENT_DYNAMIC(CCEInternetException, CException)
BOOL CCEInternetException::GetErrorMessage(LPTSTR pstrError, UINT nMaxError,
PUINT pnHelpContext)
{
ASSERT(pstrError != NULL && AfxIsValidString(pstrError, nMaxError));
if (pnHelpContext != NULL)
*pnHelpContext = 0;
LPTSTR lpBuffer;
BOOL bRet = TRUE;
HINSTANCE hWinINetLibrary;
hWinINetLibrary = ::WCE_FCTN(LoadLibraryA)(WCE_IF(WCE_WININET_DLL,"WININET.DLL"));
if (hWinINetLibrary == NULL ||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
hWinINetLibrary, m_dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
(LPTSTR) &lpBuffer, 0, NULL) == 0)
{
// it failed! try Windows...
bRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, m_dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
(LPTSTR) &lpBuffer, 0, NULL);
}
if (!bRet)
*pstrError = '\0';
else
{
if (m_dwError == ERROR_INTERNET_EXTENDED_ERROR)
{
LPTSTR lpExtended;
DWORD dwLength = 0;
DWORD dwError;
// find the length of the error
if (!InternetGetLastResponseInfo(&dwError, NULL, &dwLength) &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
lpExtended = (LPTSTR) LocalAlloc(LPTR, dwLength);
InternetGetLastResponseInfo(&dwError, lpExtended, &dwLength);
wcsncpy(pstrError, lpExtended, nMaxError);
pstrError += dwLength;
nMaxError -= dwLength;
if (nMaxError < 0)
nMaxError = 0;
LocalFree(lpExtended);
}
else
TRACE0("Warning: Extended error reported with no response info\n");
bRet = TRUE;
}
else
{
wcsncpy(pstrError, lpBuffer, nMaxError);
bRet = TRUE;
}
LocalFree(lpBuffer);
}
#ifndef _AFXDLL
::FreeLibrary(hWinINetLibrary);
#endif
return bRet;
}
CCEInternetException::CCEInternetException(DWORD dwError)
{
m_dwError = dwError;
}
CCEInternetException::~CCEInternetException()
{
}
#ifdef _DEBUG
void CCEInternetException::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << "m_dwError = " << m_dwError;
dc << "\nm_dwContext = " << m_dwContext;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -