Files
2022-10-26 12:25:11 +08:00

265 lines
6.3 KiB
C++

#include ".\ftpnetwork.h"
CFtpNetwork::CFtpNetwork(void)
{
m_hInetSession = NULL; //인터넷 세션 핸들
m_hFtpConnection = NULL; //Ftp 연결 핸들
ZeroMemory( m_szIP, FTP_ADDRESS_SIZE );
ZeroMemory( m_szID, DEFAULT_BUFFER_SIZE ); //ID
ZeroMemory( m_szPass, DEFAULT_BUFFER_SIZE ); //PASSWORD
m_fnMsgCallBack = NULL;
}
CFtpNetwork::~CFtpNetwork(void)
{
}
BOOL CFtpNetwork::Connect( TCHAR* pszIP, int nPort, TCHAR* pszID, TCHAR* pszPass, DWORD &ErrorCode )
{
m_hInetSession = InternetOpen("UPDATE_FTP", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (m_hInetSession == NULL)
{
ErrorCode = GetLastError();
return FALSE;
}
//IP검증
if ( (strcmp(pszIP, "") == 0) || (pszIP == NULL) )
{
ZeroMemory( m_szIP, FTP_ADDRESS_SIZE );
return FALSE;
}
else
strncpy( m_szIP, pszIP, FTP_ADDRESS_SIZE );
//Port검증
if( nPort <= 0 || nPort > 60000 )
{
m_nPort = 0;
return FALSE;
}
else
m_nPort = nPort;
//ID검증
if ( (strcmp(pszID, "") == 0) || (pszID == NULL) )
{
ZeroMemory( m_szID, DEFAULT_BUFFER_SIZE );
return FALSE;
}
else
strncpy( m_szID, pszID, DEFAULT_BUFFER_SIZE );
//PASSWORD 검증
if ( (strcmp(pszPass, "") == 0) || (pszPass == NULL) )
{
ZeroMemory( m_szPass, DEFAULT_BUFFER_SIZE );
return FALSE;
}
else
strncpy( m_szPass, pszPass, DEFAULT_BUFFER_SIZE );
//FTP 연결
m_hFtpConnection =InternetConnect(m_hInetSession, m_szIP, m_nPort, m_szID, m_szPass,
INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
if(m_hFtpConnection == NULL)
{
ErrorCode = GetLastError();
return FALSE;
}
return TRUE;
}
void CFtpNetwork::DisConnect()
{
if( !m_hFtpConnection ) InternetCloseHandle( m_hFtpConnection );
if( !m_hInetSession ) InternetCloseHandle( m_hInetSession );
m_hFtpConnection = NULL;
m_hInetSession = NULL;
}
//현재 설정된 FTP의 디렉토리 내에서 파일을 찾아서, 파일의 크기와 시간정보를 얻는다.
//리턴값이 FALSE이면, 파일을 찾지 못한경우이다.
BOOL CFtpNetwork::GetFileInfo( const TCHAR* pszFile, WIN32_FIND_DATA& info )
{
if( !m_hFtpConnection )
return FALSE;
if( (strcmp( pszFile, "" ) == 0) || (pszFile == NULL) )
return FALSE;
HINTERNET hFind;
BOOL bResult = TRUE;
hFind = FtpFindFirstFile( m_hFtpConnection, "*.*", &info, 0, 0 );
if( hFind != NULL )
{
//NULL이 아니면 최초의 파일(또는 폴더)를 찾았다..
do
{
if( strcmp( info.cFileName, pszFile ) == 0 ) //찾는 파일이면..
{
InternetCloseHandle( hFind );
return TRUE;
}
}
while( bResult = InternetFindNextFile( hFind, &info ) );
}
else
{
DWORD dwError = GetLastError();
if( dwError == ERROR_INTERNET_EXTENDED_ERROR )
{
char buf[DEFAULT_BUFFER_SIZE];
DWORD dwLen = DEFAULT_BUFFER_SIZE;
InternetGetLastResponseInfo( &dwError, buf, &dwLen );
}
}
InternetCloseHandle( hFind );
return FALSE;
}
BOOL CFtpNetwork::SetDirectory( const TCHAR* pszDir ) //FTP의 디렉토리를 설정한다.
{
return FtpSetCurrentDirectory( m_hFtpConnection, pszDir );
}
BOOL CFtpNetwork::GetDirectory( TCHAR* pszDir, DWORD dwSize ) //현재 FTP의 디렉토리를 가져온다.
{
return FtpGetCurrentDirectory( m_hFtpConnection, pszDir, &dwSize );
}
HINTERNET CFtpNetwork::OpenFtpFile( TCHAR* pszFile )
{
HINTERNET hRemoteFile;
INT iCount = MAX_RETRY_OPENFILE;
while(iCount--)
{
hRemoteFile = ::FtpOpenFile( m_hFtpConnection, pszFile, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY |
INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0);//(DWORD)this);
if( hRemoteFile == NULL )
Sleep(100);
else
break;
}
if( iCount < 1 ) //파일을 찾을수 없으면..
return NULL;
return hRemoteFile;
}
// 원격지의 파일의 내용을 로컬 파일에 기록한다.
// hRemoteFile : 다운받을 FTP서버의 파일 이름
// hRemoteFileLength : 원격지 파일 크기.
// hLocalFile : 로컬에 기록할 파일의 이름
// 파일의 다운로드 진행상황을 알기 위해서, hLocalFile에 쓰는 방법을 택했다.
BOOL CFtpNetwork::DownloadFile( const HINTERNET hRemoteFile, DWORD dwRemoteFileLength, HANDLE hLocalFile )
{
DWORD dwNowRecvBytes, dwNowWrittenBytes, dwTotalWrittenBytes;
dwNowRecvBytes = dwNowWrittenBytes = dwTotalWrittenBytes = 0;
//1. 파일 다운로드
//파일이 원격서버에 존재하는데, 크기가 0인경우는 TRUE를 리턴하는것으로 한다.
if( dwRemoteFileLength > 0 )
{
while(TRUE)
{
if ( !InternetReadFile( hRemoteFile, m_szFtpBuffer, sizeof(m_szFtpBuffer), &dwNowRecvBytes) )
return FALSE;
if ( !WriteFile( hLocalFile, m_szFtpBuffer, dwNowRecvBytes, &dwNowWrittenBytes, NULL ) )
return FALSE;
dwTotalWrittenBytes += dwNowWrittenBytes;
// 현재까지 쓰여진 파일의 용량이 전체 파일의 용량보다 같거나 크다면...
if ( dwTotalWrittenBytes >= dwRemoteFileLength )
break;
}
}
else if( dwRemoteFileLength < 0 )
return FALSE;
return TRUE;
}
//해당 윈도우로 정보 출력 코드 포함하는 함수
BOOL CFtpNetwork::DownloadFile( const HINTERNET hRemoteFile, WIN32_FIND_DATA& RemoteInfo, HANDLE hLocalFile )
{
DWORD dwNowRecvBytes, dwNowWrittenBytes, dwTotalWrittenBytes;
dwNowRecvBytes = dwNowWrittenBytes = dwTotalWrittenBytes = 0;
//1. 파일 다운로드
//파일이 원격서버에 존재하는데, 크기가 0인경우는 TRUE를 리턴하는것으로 한다.
if( RemoteInfo.nFileSizeLow > 0 )
{
while(TRUE)
{
if ( !InternetReadFile( hRemoteFile, m_szFtpBuffer, sizeof(m_szFtpBuffer), &dwNowRecvBytes) )
return FALSE;
if ( !WriteFile( hLocalFile, m_szFtpBuffer, dwNowRecvBytes, &dwNowWrittenBytes, NULL ) )
return FALSE;
dwTotalWrittenBytes += dwNowWrittenBytes;
//현재 파일의 다운로드 정보 출력
m_UpdateFileInfo.SetFileName( RemoteInfo.cFileName );
m_UpdateFileInfo.SetNowFileSize( dwTotalWrittenBytes );
m_UpdateFileInfo.SetWholeFileSize( RemoteInfo.nFileSizeLow );
AddMessage( WM_FILE_DOWNLOAD_WORKING, &m_UpdateFileInfo );
// 현재까지 쓰여진 파일의 용량이 전체 파일의 용량보다 같거나 크다면...
if ( dwTotalWrittenBytes >= RemoteInfo.nFileSizeLow )
break;
}
}
else if( RemoteInfo.nFileSizeLow < 0 )
return FALSE;
return TRUE;
}
void CFtpNetwork::GetIP( TCHAR* pszIP, int nSize )
{
ZeroMemory( pszIP, nSize );
strncpy( pszIP, m_szIP, nSize );
}
void CFtpNetwork::AddMessage( UINT uMsg, VOID* pData )
{
if( !m_fnMsgCallBack ) return;
m_fnMsgCallBack( uMsg, (VOID*)pData );
}
BOOL CFtpNetwork::IsConnectFTP()
{
if( m_hFtpConnection )
return TRUE;
else
return FALSE;
}
VOID CFtpNetwork::SetMsgCallBack( fnMsgCallBack CallBack )
{
if( !CallBack ) return;
m_fnMsgCallBack = CallBack;
}