575 lines
13 KiB
C++
575 lines
13 KiB
C++
/*++
|
||
|
||
Copyright (c) 1994 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ftp.cxx
|
||
|
||
Abstract:
|
||
|
||
Contains methods for FTP_FIND_HANDLE_OBJECT and FTP_FILE_HANDLE_OBJECT classes
|
||
|
||
Contents:
|
||
RMakeFtpFindObjectHandle
|
||
RMakeFtpFileObjectHandle
|
||
RMakeFtpErrorObjectHandle
|
||
FTP_ERROR_HANDLE_OBJECT::SetErrorText
|
||
FTP_ERROR_HANDLE_OBJECT::QueryHtmlDataAvailable
|
||
|
||
Author:
|
||
|
||
Madan Appiah (madana) 16-Nov-1994
|
||
|
||
Environment:
|
||
|
||
User Mode - Win32
|
||
|
||
Revision History:
|
||
|
||
Sophia Chung (sophiac) 14-Feb-1995 (added FTP and Archie class impl.)
|
||
(code adopted from madana)
|
||
|
||
--*/
|
||
|
||
#include <wininetp.h>
|
||
|
||
//
|
||
// functions
|
||
//
|
||
|
||
|
||
DWORD
|
||
RMakeFtpFindObjectHandle(
|
||
IN HINTERNET ParentHandle,
|
||
IN OUT HINTERNET * ChildHandle,
|
||
IN CLOSE_HANDLE_FUNC wCloseFunc,
|
||
IN DWORD_PTR dwContext
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
C-callable wrapper for creating an FTP_FIND_HANDLE_OBJECT
|
||
|
||
Arguments:
|
||
|
||
ParentHandle - mapped address of parent (connect) handle
|
||
|
||
ChildHandle - IN: protocol-specific handle value associated with object
|
||
OUT: mapped address of FTP_FIND_HANDLE_OBJECT
|
||
|
||
wCloseFunc - address of protocol-specific function to be called when
|
||
object is closed
|
||
|
||
dwContext - app-supplied context value
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
Success - ERROR_SUCCESS
|
||
|
||
Failure - ERROR_NOT_ENOUGH_MEMORY
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD error;
|
||
FTP_FIND_HANDLE_OBJECT * hFind;
|
||
|
||
hFind = new FTP_FIND_HANDLE_OBJECT(
|
||
(INTERNET_CONNECT_HANDLE_OBJECT *)ParentHandle,
|
||
*ChildHandle,
|
||
wCloseFunc,
|
||
dwContext
|
||
);
|
||
|
||
if (hFind != NULL) {
|
||
error = hFind->GetStatus();
|
||
if (error == ERROR_SUCCESS) {
|
||
|
||
//
|
||
// inform the app of the new handle
|
||
//
|
||
|
||
error = InternetIndicateStatusNewHandle((LPVOID)hFind);
|
||
|
||
//
|
||
// ERROR_INTERNET_OPERATION_CANCELLED is the only error that we are
|
||
// expecting here. If we get this error then the app has cancelled
|
||
// the operation. Either way, the handle we just generated will be
|
||
// already deleted
|
||
//
|
||
|
||
if (error != ERROR_SUCCESS) {
|
||
|
||
INET_ASSERT(error == ERROR_INTERNET_OPERATION_CANCELLED);
|
||
|
||
hFind = NULL;
|
||
}
|
||
} else {
|
||
delete hFind;
|
||
hFind = NULL;
|
||
}
|
||
} else {
|
||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
|
||
*ChildHandle = (HINTERNET)hFind;
|
||
|
||
return error;
|
||
}
|
||
|
||
|
||
DWORD
|
||
RMakeFtpFileObjectHandle(
|
||
IN HINTERNET ParentHandle,
|
||
IN OUT HINTERNET * ChildHandle,
|
||
IN CLOSE_HANDLE_FUNC wCloseFunc,
|
||
IN DWORD_PTR dwContext
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
C-callable wrapper for creating an FTP_FILE_HANDLE_OBJECT
|
||
|
||
Arguments:
|
||
|
||
ParentHandle - mapped address of parent (connect) handle
|
||
|
||
ChildHandle - IN: protocol-specific handle value associated with object
|
||
OUT: mapped address of FTP_FILE_HANDLE_OBJECT
|
||
|
||
wCloseFunc - address of protocol-specific function to be called when
|
||
object is closed
|
||
|
||
dwContext - app-supplied context value
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
Success - ERROR_SUCCESS
|
||
|
||
Failure - ERROR_NOT_ENOUGH_MEMORY
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD error;
|
||
FTP_FILE_HANDLE_OBJECT * hFile;
|
||
DEBUG_PRINT(FTP,
|
||
INFO,
|
||
("RMakeFtpFileObject(0x%x 0x%x 0x%x 0x%x)\r\n",
|
||
ParentHandle, ChildHandle, wCloseFunc, dwContext));
|
||
|
||
|
||
hFile = new FTP_FILE_HANDLE_OBJECT(
|
||
(INTERNET_CONNECT_HANDLE_OBJECT *)ParentHandle,
|
||
*ChildHandle,
|
||
wCloseFunc,
|
||
dwContext
|
||
);
|
||
|
||
if (hFile != NULL) {
|
||
error = hFile->GetStatus();
|
||
if (error == ERROR_SUCCESS) {
|
||
|
||
//
|
||
// inform the app of the new handle
|
||
//
|
||
|
||
error = InternetIndicateStatusNewHandle((LPVOID)hFile);
|
||
|
||
//
|
||
// ERROR_INTERNET_OPERATION_CANCELLED is the only error that we are
|
||
// expecting here. If we get this error then the app has cancelled
|
||
// the operation. Either way, the handle we just generated will be
|
||
// already deleted
|
||
//
|
||
|
||
if (error != ERROR_SUCCESS) {
|
||
|
||
INET_ASSERT(error == ERROR_INTERNET_OPERATION_CANCELLED);
|
||
|
||
hFile = NULL;
|
||
}
|
||
} else {
|
||
delete hFile;
|
||
hFile = NULL;
|
||
}
|
||
} else {
|
||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
|
||
*ChildHandle = (HINTERNET)hFile;
|
||
|
||
return error;
|
||
}
|
||
|
||
#ifdef EXTENDED_ERROR_HTML
|
||
|
||
DWORD
|
||
RMakeFtpErrorObjectHandle(
|
||
IN HINTERNET hConnect,
|
||
OUT LPHINTERNET lphError
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Creates an FTP_ERROR_HANDLE_OBJECT. Used to return extended error info as
|
||
HTML
|
||
|
||
Arguments:
|
||
|
||
hConnect - pointer to INTERNET_CONNECT_HANDLE_OBJECT
|
||
|
||
lphError - pointer to returned FTP_ERROR_HANDLE_OBJECT
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
|
||
--*/
|
||
|
||
{
|
||
FTP_ERROR_HANDLE_OBJECT * hError;
|
||
|
||
hError = new FTP_ERROR_HANDLE_OBJECT(
|
||
(INTERNET_CONNECT_HANDLE_OBJECT *)hConnect
|
||
);
|
||
|
||
DWORD error;
|
||
|
||
if (hError != NULL) {
|
||
error = hError->GetStatus();
|
||
if (error == ERROR_SUCCESS) {
|
||
|
||
//
|
||
// inform the app of the new handle
|
||
//
|
||
|
||
error = InternetIndicateStatusNewHandle((LPVOID)hError);
|
||
|
||
//
|
||
// ERROR_INTERNET_OPERATION_CANCELLED is the only error that we are
|
||
// expecting here. If we get this error then the app has cancelled
|
||
// the operation. Either way, the handle we just generated will be
|
||
// already deleted
|
||
//
|
||
|
||
if (error != ERROR_SUCCESS) {
|
||
|
||
INET_ASSERT(error == ERROR_INTERNET_OPERATION_CANCELLED);
|
||
|
||
hError = NULL;
|
||
}
|
||
} else {
|
||
delete hError;
|
||
hError = NULL;
|
||
}
|
||
} else {
|
||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
|
||
*lphError = (HINTERNET)hError;
|
||
|
||
return error;
|
||
}
|
||
#endif
|
||
|
||
//
|
||
// FTP_FIND_HANDLE_OJBECT class implementation
|
||
//
|
||
|
||
FTP_FIND_HANDLE_OBJECT::FTP_FIND_HANDLE_OBJECT(
|
||
INTERNET_CONNECT_HANDLE_OBJECT *Parent,
|
||
HINTERNET Child,
|
||
CLOSE_HANDLE_FUNC wCloseFunc,
|
||
DWORD_PTR dwContext
|
||
) : INTERNET_CONNECT_HANDLE_OBJECT(Parent)
|
||
{
|
||
_FindHandle = Child;
|
||
_wCloseFunction = wCloseFunc;
|
||
_dwFtpFindBools = 0;
|
||
_lpszUrl = NULL;
|
||
_lpszDirEntry = NULL;
|
||
_QueryBuffer = NULL;
|
||
_QueryBufferLength = 0;
|
||
_QueryOffset = 0;
|
||
_QueryBytesAvailable = 0;
|
||
_Context = dwContext;
|
||
SetObjectType(TypeFtpFindHandle);
|
||
}
|
||
|
||
FTP_FIND_HANDLE_OBJECT::~FTP_FIND_HANDLE_OBJECT(
|
||
VOID
|
||
)
|
||
{
|
||
//
|
||
// if local internet handle, closed by local close function
|
||
//
|
||
|
||
if (_FindHandle != NULL) {
|
||
_Status = _wCloseFunction(_FindHandle);
|
||
|
||
//INET_ASSERT(_Status == ERROR_SUCCESS);
|
||
|
||
} else {
|
||
_Status = ERROR_SUCCESS;
|
||
}
|
||
|
||
//
|
||
// clear out any strings we allocated
|
||
//
|
||
|
||
if (_lpszUrl != NULL) {
|
||
DEL_STRING(_lpszUrl);
|
||
}
|
||
if (_lpszDirEntry != NULL) {
|
||
DEL_STRING(_lpszDirEntry);
|
||
}
|
||
|
||
//
|
||
// and the query buffer
|
||
//
|
||
|
||
FreeQueryBuffer();
|
||
}
|
||
|
||
HANDLE
|
||
FTP_FIND_HANDLE_OBJECT::GetHandle(
|
||
VOID
|
||
)
|
||
{
|
||
return _FindHandle;
|
||
}
|
||
|
||
DWORD
|
||
FTP_FIND_HANDLE_OBJECT::QueryHtmlDataAvailable(
|
||
OUT LPDWORD lpdwNumberOfBytesAvailable
|
||
)
|
||
{
|
||
DWORD error;
|
||
|
||
if (_QueryBuffer != NULL) {
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
error = AllocateQueryBuffer();
|
||
}
|
||
|
||
INET_ASSERT(_QueryBytesAvailable == 0);
|
||
|
||
if (error == ERROR_SUCCESS) {
|
||
_QueryOffset = 0;
|
||
if (ReadHtmlUrlData((HINTERNET)this,
|
||
_QueryBuffer,
|
||
_QueryBufferLength,
|
||
lpdwNumberOfBytesAvailable
|
||
)) {
|
||
_QueryBytesAvailable = *lpdwNumberOfBytesAvailable;
|
||
//SetAvailableDataLength(_QueryBytesAvailable);
|
||
if (_QueryBytesAvailable == 0) {
|
||
SetEndOfFile();
|
||
}
|
||
} else {
|
||
error = GetLastError();
|
||
}
|
||
}
|
||
return error;
|
||
}
|
||
|
||
//
|
||
// FTP_FILE_HANDLE_OJBECT class implementation
|
||
//
|
||
|
||
FTP_FILE_HANDLE_OBJECT::FTP_FILE_HANDLE_OBJECT(
|
||
INTERNET_CONNECT_HANDLE_OBJECT *Parent,
|
||
HINTERNET Child,
|
||
CLOSE_HANDLE_FUNC wCloseFunc,
|
||
DWORD_PTR dwContext
|
||
) : INTERNET_CONNECT_HANDLE_OBJECT(Parent)
|
||
{
|
||
_FileHandle = Child;
|
||
_wCloseFunction = wCloseFunc;
|
||
_IsHtml = FALSE;
|
||
_lpszFileName = NULL;
|
||
_lpszUrl = NULL;
|
||
_lpszDirEntry = NULL;
|
||
_Context = dwContext;
|
||
SetObjectType(TypeFtpFileHandle);
|
||
}
|
||
|
||
FTP_FILE_HANDLE_OBJECT::~FTP_FILE_HANDLE_OBJECT(
|
||
VOID
|
||
)
|
||
{
|
||
|
||
//
|
||
// if local internet handle, closed by local close function
|
||
//
|
||
|
||
if (_FileHandle != NULL) {
|
||
_Status = _wCloseFunction(_FileHandle);
|
||
|
||
//INET_ASSERT(_Status == ERROR_SUCCESS);
|
||
|
||
} else {
|
||
_Status = ERROR_INVALID_HANDLE;
|
||
}
|
||
|
||
//
|
||
// clear out any strings we allocated
|
||
//
|
||
|
||
if (_lpszUrl != NULL) {
|
||
DEL_STRING(_lpszUrl);
|
||
}
|
||
if (_lpszDirEntry != NULL) {
|
||
DEL_STRING(_lpszDirEntry);
|
||
}
|
||
if (_lpszFileName != NULL) {
|
||
DEL_STRING(_lpszFileName);
|
||
}
|
||
}
|
||
|
||
HINTERNET
|
||
FTP_FILE_HANDLE_OBJECT::GetHandle(
|
||
VOID
|
||
)
|
||
{
|
||
return _FileHandle;
|
||
}
|
||
|
||
#ifdef EXTENDED_ERROR_HTML
|
||
|
||
//
|
||
// FTP_ERROR_HANDLE_OBJECT class implementation
|
||
//
|
||
|
||
FTP_ERROR_HANDLE_OBJECT::FTP_ERROR_HANDLE_OBJECT(
|
||
INTERNET_CONNECT_HANDLE_OBJECT* hConnect
|
||
) : INTERNET_CONNECT_HANDLE_OBJECT(hConnect)
|
||
{
|
||
m_lpszErrorText = NULL;
|
||
m_dwErrorTextLength = 0;
|
||
m_QueryBuffer = NULL;
|
||
m_QueryBufferLength = 0;
|
||
m_QueryOffset = 0;
|
||
m_QueryBytesAvailable = 0;
|
||
m_HtmlState = HTML_STATE_START;
|
||
SetObjectType(TypeFtpFileHandle);
|
||
SetErrorText();
|
||
}
|
||
|
||
FTP_ERROR_HANDLE_OBJECT::~FTP_ERROR_HANDLE_OBJECT(
|
||
VOID
|
||
)
|
||
{
|
||
//
|
||
// clear out any strings we allocated
|
||
//
|
||
|
||
if (m_lpszErrorText != NULL) {
|
||
DEL_STRING(m_lpszErrorText);
|
||
}
|
||
|
||
//
|
||
// and the query buffer
|
||
//
|
||
|
||
FreeQueryBuffer();
|
||
}
|
||
|
||
DWORD
|
||
FTP_ERROR_HANDLE_OBJECT::SetErrorText(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Copies last error info to this handle object
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
Success - ERROR_SUCCESS
|
||
|
||
Failure -
|
||
|
||
--*/
|
||
|
||
{
|
||
INET_ASSERT(m_lpszErrorText == NULL);
|
||
INET_ASSERT(m_dwErrorTextLength == 0);
|
||
|
||
DWORD error;
|
||
DWORD category;
|
||
|
||
if (!InternetGetLastResponseInfo(&category, NULL, &m_dwErrorTextLength)) {
|
||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||
m_lpszErrorText = (LPSTR)ALLOCATE_MEMORY(
|
||
LMEM_FIXED,
|
||
m_dwErrorTextLength
|
||
);
|
||
if (m_lpszErrorText != NULL) {
|
||
if (!InternetGetLastResponseInfo(&category,
|
||
m_lpszErrorText,
|
||
&m_dwErrorTextLength)) {
|
||
m_lpszErrorText[0] = '\0';
|
||
m_dwErrorTextLength = 0;
|
||
}
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
}
|
||
}
|
||
return error;
|
||
}
|
||
|
||
DWORD
|
||
FTP_ERROR_HANDLE_OBJECT::QueryHtmlDataAvailable(
|
||
OUT LPDWORD lpdwNumberOfBytesAvailable
|
||
)
|
||
{
|
||
DWORD error;
|
||
|
||
if (m_QueryBuffer != NULL) {
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
error = AllocateQueryBuffer();
|
||
}
|
||
|
||
INET_ASSERT(m_QueryBytesAvailable == 0);
|
||
|
||
if (error == ERROR_SUCCESS) {
|
||
m_QueryOffset = 0;
|
||
if (ReadHtmlUrlData((HINTERNET)this,
|
||
m_QueryBuffer,
|
||
m_QueryBufferLength,
|
||
lpdwNumberOfBytesAvailable
|
||
)) {
|
||
m_QueryBytesAvailable = *lpdwNumberOfBytesAvailable;
|
||
if (m_QueryBytesAvailable == 0) {
|
||
SetEndOfFile();
|
||
}
|
||
} else {
|
||
error = GetLastError();
|
||
}
|
||
}
|
||
return error;
|
||
}
|
||
|
||
#endif
|