Files
interactive/application/sp-console(down)/ConsoleTransfer(DN)/TransferDlg.cpp
T
2026-08-07 17:38:18 +09:00

1800 lines
46 KiB
C++

// TransferDlg.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include <direct.h>
#include "ConsoleTransfer.h"
#include "TransferDlg.h"
#include "Options.h"
#include "FileExistsDlg.h"
#include "EnterSomethingDlg.h"
#include "TransLogger.h"
#include "ne_socket.h"
#include "ne_uri.h"
#include "ne_request.h"
#include "ne_xml.h"
#include "ne_string.h"
#define RETRY_CNT 5
typedef struct COMMLIB_HANDLE {
ne_session* pnsess;
ne_uri nuri;
string sUserId;
string sPassword;
string sDavAuth;
DWORD dwError;
string sError;
// 업/다운 관련
HANDLE hThread;
HANDLE hWaitEvent;
UINT32 uJob;
string sJobParam;
cl_callback proc;
void* pParam;
HANDLE hTranFile;
__int64 nExFileSize;
__int64 iTranPos;
__int64 nFileSize;
DWORD dwOldTick;
int nTranStop;
string sRedirect;
string sDomain2;
// set<PCLSERVICE_STRUCT> setServiceList;
// set<PCLPATHINFO_STRUCT> setPathInfoList;
// set<PCLFILE_STRUCT> setFileList;
} COMMLIB_STRUCT, *PCOMMLIB_STRUCT;
CString GetErrorMessage(DWORD dwError);
CString BYTE2KMBYTE(__int64 nBytes, int nFlag, BOOL bShowDecimalPoint);
CString BYTE2KMBIT(__int64 nBytes, int nFlag, BOOL bShowDecimalPoint);
CString NumericFormat(__int64 nNumeric);
bool CreateDirectory(CString sDirectory);
bool DeleteDirectory(CString sDirectory);
// CTransferDlg 대화 상자입니다.
PCOMMLIB_STRUCT m_pcl;
IMPLEMENT_DYNAMIC(CTransferDlg, CDialog)
CTransferDlg::CTransferDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTransferDlg::IDD, pParent)
, m_szTargetPath(_T(""))
{
m_hcl = NULL;
m_bPaused = false;
m_bResume = false;
m_bStop = false;
m_pause_disabled = false;
m_pthread = NULL;
m_bUpdating = false;
m_bUpdateMode = false;
m_nTotalCount = 0;
m_nTotalSize = 0;
m_nTotalTransferred = 0;
m_iTransfer = 0;
m_nElapsed = 0;
m_nGapTransfer = 0.5;
m_nSelectedCount = 0;
m_nSelectedSize = 0;
m_sSkippedFolder = "";
m_retry_file = new TRANFILE_STRUCT;
m_retry_tfinfo =new RETRY_TFINFO;
m_retry_tfinfo->retryFile = m_retry_file;
m_retry_tfinfo->doRetry = false;
m_retry_tfinfo->retryCnt = 0;
m_nFailedFileCount = 0;
}
CTransferDlg::~CTransferDlg()
{
for (int i = 0; i < m_paTranFile.GetCount(); i++)
delete (PTRANFILE_STRUCT)m_paTranFile[i];
delete m_retry_tfinfo->retryFile;
delete m_retry_tfinfo;
}
void CTransferDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_WB_ADVERT, m_wbAdvert);
DDX_Control(pDX, IDC_TAB, m_tab);
DDX_Control(pDX, IDC_BTN_DELFILE, m_btnDelFile);
DDX_Control(pDX, IDC_LIST, m_list);
DDX_Control(pDX, IDC_STC_STATUS, m_stcStatus);
DDX_Control(pDX, IDC_GRP_NOW, m_grpNow);
DDX_Control(pDX, IDC_STC_SPEED_TITLE, m_stcSpeedTitle);
DDX_Control(pDX, IDC_STC_SPEED, m_stcSpeed);
DDX_Control(pDX, IDC_STC_SAVEFILE_TITLE, m_stcSaveFileTitle);
DDX_Control(pDX, IDC_STC_SAVEFILE, m_stcSaveFile);
DDX_Control(pDX, IDC_PRS_NOW, m_prsNow);
DDX_Control(pDX, IDC_GRP_TOTAL, m_grpTotal);
DDX_Control(pDX, IDC_STC_ETIME_TITLE, m_stcETimeTitle);
DDX_Control(pDX, IDC_STC_ETIME, m_stcETime);
DDX_Control(pDX, IDC_STC_LTIME_TITLE, m_stcLTimeTitle);
DDX_Control(pDX, IDC_STC_LTIME, m_stcLTime);
DDX_Control(pDX, IDC_STC_FILE_COUNT_TITLE, m_stcFileCountTitle);
DDX_Control(pDX, IDC_STC_FILE_COUNT, m_stcFileCount);
DDX_Control(pDX, IDC_PRS_TOTAL, m_prsTotal);
DDX_Control(pDX, ID_START, m_btnStart);
DDX_Control(pDX, ID_PAUSE, m_btnPause);
DDX_Control(pDX, ID_CLOSE, m_btnClose);
}
BEGIN_MESSAGE_MAP(CTransferDlg, CDialog)
ON_WM_CLOSE()
ON_WM_TIMER()
ON_WM_SETCURSOR()
ON_BN_CLICKED(IDC_BTN_DELFILE, OnBtnDelfile)
ON_BN_CLICKED(ID_START, OnBtnStart)
ON_BN_CLICKED(ID_PAUSE, OnBtnPause)
ON_BN_CLICKED(ID_CLOSE, OnBtnClose)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnListItemChanged)
ON_NOTIFY(LVN_KEYDOWN, IDC_LIST, OnListKeydown)
ON_MESSAGE(WMU_TRANSFER_IS_READY, OnTransferIsReady)
ON_MESSAGE(WMU_TRANSFER, OnTransfer)
ON_MESSAGE(WMU_TRANSFER_COMPLETED, OnTransferCompleted)
ON_MESSAGE(WMU_TRANSFER_ERROR, OnTransferError)
END_MESSAGE_MAP()
// CTransferDlg 메시지 처리기입니다.
BOOL CTransferDlg::OnInitDialog()
{
typedef std::pair<CString,int> pairTranFile;
CDialog::OnInitDialog();
HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
SetIcon(hIcon, TRUE);
SetIcon(hIcon, FALSE);
// X버튼 삭제
ModifyStyle(NULL, WS_SYSMENU | WS_MINIMIZEBOX);
CMenu *menu = GetSystemMenu(FALSE);
RemoveMenu(menu->m_hMenu, 6, MF_BYPOSITION);
BeginWaitCursor();
for (int i = IDC_BTN_DELFILE; i <= IDC_PRS_TOTAL; i++)
GetDlgItem(i)->SetParent(&m_tab);
m_tab.SetWindowPos(&CWnd::wndBottom, 4, 4, 469, 321, NULL);
m_tab.SetItemSize(CSize(130, 17));
m_prsNow.SetRange(0, 100);
m_prsNow.SetStep(1);
m_prsNow.SetShowText(TRUE);
m_prsNow.SetText(" ");
m_prsTotal.SetRange(0, 100);
m_prsTotal.SetStep(1);
m_prsTotal.SetShowText(TRUE);
m_prsTotal.SetText(" ");
m_list.InsertColumn(0, "이름", LVCFMT_LEFT, 237);
m_list.InsertColumn(1, "크기", LVCFMT_RIGHT, 80);
m_list.InsertColumn(2, "종류", LVCFMT_CENTER, 60);
m_list.InsertColumn(3, "상태", LVCFMT_CENTER, 60);
m_list.SetExtendedStyle(LVS_EX_INFOTIP | LVS_EX_FULLROWSELECT);
SHFILEINFO shfi;
HIMAGELIST hil = (HIMAGELIST)SHGetFileInfo("C:\\", 0, &shfi, sizeof(shfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
m_list.SetImageList(CImageList::FromHandle(hil), LVSIL_SMALL);
if (m_tp.nAction == TPA_UPLOAD) {
m_tab.InsertItem(0, "올리기 윈도우");
m_sTitle = "파일 업로드";
}
else {
m_tab.InsertItem(0, "내리기 윈도우");
m_sTitle = "파일 다운로드";
}
SetWindowText(m_sTitle);
for (int i = 0; i < m_tp.nFileListSize; ) {
m_mapTranFile.insert(pairTranFile(&m_pszFileList[i], 0));
i += ((int)strlen(&m_pszFileList[i]) + 1);
}
OutputDebugString(m_tp.szPassword);
OutputDebugString(m_tp.szUserId);
#ifdef _OLD
m_hcl = cl_init(m_tp.szHost, m_tp.szUserId, m_tp.szPassword, m_tp.szProxyHost, m_tp.nProxyPort);
#else
m_hcl = cl_init(m_tp.szHost, "" , m_tp.szUserId, m_tp.szPassword, m_tp.szProxyHost, m_tp.nProxyPort);
#endif
if (!m_hcl) {
AfxMessageBox(GetErrorMessage(GetLastError()), MB_ICONERROR);
return FALSE;
}
m_wbAdvert.ShowWindow(SW_HIDE);
DocumentCompleteWBAdvert(NULL, NULL);
CenterWindow();
ShowWindow(SW_SHOW);
m_btnDelFile.EnableWindow(FALSE);
m_btnStart.EnableWindow(FALSE);
m_btnPause.EnableWindow(FALSE);
m_btnClose.SetWindowText("취소");
m_pthread = AfxBeginThread(LoadTransferFile, this);
cl_set_write_log_dir(m_tp.bLogDir);
cl_set_write_log_upload(m_tp.bLogUpload);
cl_create_log_file();
EndWaitCursor();
return TRUE; // return TRUE unless you set the focus to a control
// 예외: OCX 속성 페이지는 FALSE를 반환해야 합니다.
}
void CTransferDlg::OnClose()
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
if (m_pthread) {
m_bStop = true;
m_nTimer = (UINT)SetTimer(TIMER_ID_CLOSE, 100, 0);
return;
}
if (m_hcl)
{
cl_free(m_hcl);
m_hcl = NULL;
}
cl_destroy_log_file();
if(!m_dlgResult.GetSafeHwnd())
m_dlgResult.Create(IDD_RESULT_DLG, this);
if(m_dlgResult.IsAlreadyShow())
CDialog::OnClose();
else
{
m_dlgResult.SetResult(m_nTotalCount, m_nFailedFileCount, m_strFailedFiles);
m_dlgResult.ShowWindow(SW_SHOW);
m_dlgResult.UpdateData(FALSE);
}
}
BOOL CTransferDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
SetCursor(LoadCursor(NULL, m_pthread ? IDC_APPSTARTING : IDC_ARROW));
return TRUE;
// return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
void CTransferDlg::OnTimer(UINT nIDEvent)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
KillTimer(m_nTimer);
m_nTimer = 0;
if (nIDEvent == TIMER_ID_CLOSE) {
PostMessage(WM_CLOSE);
}
if (nIDEvent == TIMER_ID_UPDATESTATUS) {
ShowStatus(TRUE);
}
else if (nIDEvent == TIMER_ID_TRANSFER) {
PostMessage(WMU_TRANSFER, CLWRITEPOLICY_NONE);
}
CDialog::OnTimer(nIDEvent);
}
void CTransferDlg::OnBtnDelfile()
{
m_bUpdating = true;
CDWordArray daSelected;
int i, nLastItem = -1;
BOOL bFoundTransferred = FALSE;
POSITION pos = m_list.GetFirstSelectedItemPosition();
while (pos) {
int iItem = m_list.GetNextSelectedItem(pos);
if (iItem <= nLastItem)
continue;
if ((iItem > 0 && iItem <= m_iTransfer)
|| (iItem == 0 && ((PTRANFILE_STRUCT)m_paTranFile[iItem])->nState != TFS_READY)) {
bFoundTransferred = TRUE;
continue;
}
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[iItem];
daSelected.Add(iItem);
if (ptf->bFolder) {
CString sPath = ptf->sSrcPath;
sPath += "\\";
int nLength = sPath.GetLength();
for (i = iItem + 1; i < m_paTranFile.GetCount(); i++) {
CString sSrcPath = ((PTRANFILE_STRUCT)m_paTranFile[i])->sSrcPath;
if (sPath != sSrcPath.Left(nLength))
break;
daSelected.Add(i);
}
nLastItem = i - 1;
}
}
if (bFoundTransferred)
AfxMessageBox("전송중이거나 전송완료된 폴더 또는 파일은 삭제할 수 없습니다.", MB_ICONINFORMATION);
for (int i = (int)daSelected.GetCount() - 1; i >= 0; i--) {
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[daSelected[i]];
if (strncmp(ptf->sText, " ", 3) != 0)
m_mapTranFile.erase(ptf->sSrcPath);
for (std::map<CString,int>::iterator iter = m_mapTranFile.begin(); iter != m_mapTranFile.end(); iter++) {
if (iter->second >= (int)daSelected[i])
iter->second--;
}
delete ptf;
m_list.DeleteItem(daSelected[i]);
m_paTranFile.RemoveAt(daSelected[i]);
}
m_bUpdating = FALSE;
ShowStatus();
if (m_nTotalCount > 0 && ((PTRANFILE_STRUCT)m_paTranFile[0])->nState != TFS_READY) {
ShowFileCount();
ShowTotalProgress();
}
else {
AfxMessageBox("전송 할 파일이 없습니다.");
PostMessage(WM_CLOSE);
}
}
void CTransferDlg::OnBtnStart()
{
m_btnStart.EnableWindow(FALSE);
m_btnPause.EnableWindow(TRUE);
m_btnPause.SetFocus();
Pause(false);
InitTransferEnv();
ShowStatus();
PostMessage(WMU_TRANSFER, CLWRITEPOLICY_NONE);
}
void CTransferDlg::OnBtnPause()
{
if(!m_pause_disabled)
{
if (m_bPaused) {
Pause(false);
InitTransferEnv();
ShowStatus();
m_nBaseFileSize = m_nTransferredSize;
PostMessage(WMU_TRANSFER, CLWRITEPOLICY_APPEND);
}
else {
m_btnPause.EnableWindow(FALSE);
m_bPaused = TRUE;
WriteDebugLog("" , "" ,"cl_stop_transfer(m_hcl)#0");
cl_stop_transfer(m_hcl);
}
}
}
void CTransferDlg::OnBtnClose()
{
if (TPA_UPLOAD == m_tp.nAction)
{
/////////////////////////////////////////////////////
///전송창 닫을때, 이 전송트랙젠셕이 끝났음을 알린다.
CConsoleTransferApp* pwp = (CConsoleTransferApp*) AfxGetApp();
pwp->NoticeLastFileTransComplete();
////////////////////////////////////////////////////
}
PostMessage(WM_CLOSE);
}
void CTransferDlg::OnListItemChanged(NMHDR *pNMHDR, LRESULT *pResult)
{
if (m_pthread)
return;
if (m_tp.nAction != TPA_UPLOAD || m_bUpdating)
return;
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
if (!(pNMLV->uChanged & LVIS_DROPHILITED))
return;
if (pNMLV->uNewState & LVIS_SELECTED && !(pNMLV->uOldState & LVIS_SELECTED)) {
m_nSelectedCount++;
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[pNMLV->iItem];
if (!ptf->bFolder)
m_nSelectedSize += ptf->nSize;
}
else if (!(pNMLV->uNewState & LVIS_SELECTED) && pNMLV->uOldState & LVIS_SELECTED) {
m_nSelectedCount--;
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[pNMLV->iItem];
if (!ptf->bFolder)
m_nSelectedSize -= ptf->nSize;
}
if (m_nTimer != 0)
KillTimer(m_nTimer);
m_nTimer = (UINT)SetTimer(TIMER_ID_UPDATESTATUS, 10, 0);
*pResult = 0;
}
void CTransferDlg::OnListKeydown(NMHDR *pNMHDR, LRESULT *pResult)
{
if (m_pthread)
return;
LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
if (GetKeyState(VK_CONTROL) & 128 && pLVKeyDow->wVKey == VK_A) {
m_bUpdating = true;
for (int i = 0; i < m_list.GetItemCount(); i++)
m_list.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
m_bUpdating = false;
ShowStatus(true, false, true);
}
*pResult = 0;
}
LRESULT CTransferDlg::OnTransferIsReady(WPARAM wParam, LPARAM)
{
if (m_bStop)
return S_FALSE;
m_btnStart.EnableWindow(TRUE);
m_btnPause.EnableWindow(TRUE);
m_btnClose.SetWindowText("닫기");
LoadWritePolicy();
ShowStatus();
if (m_list.GetItemCount() == 0) {
AfxMessageBox("전송할 파일이 없습니다.");
PostMessage(WM_CLOSE);
return S_FALSE;
}
#ifndef _DEBUG
OnBtnStart();
#endif
return S_OK;
}
LRESULT CTransferDlg::OnTransfer(WPARAM wParam, LPARAM)
{
int recvFailCnt=0;
m_pause_disabled = false;
if (m_bPaused) {
Pause();
return S_OK;
}
DWORD dwTick = GetTickCount();
PTRANFILE_STRUCT ptf;
if (false == m_retry_tfinfo->doRetry)
{
m_retry_tfinfo->retryCnt = 0;
ptf = NULL;
for (int i = m_iTransfer; i < m_paTranFile.GetCount(); i++) {
ptf = (PTRANFILE_STRUCT)m_paTranFile[m_iTransfer];
if (ptf->nState == TFS_TRANSFERRING)
return S_FALSE;
if (ptf->nState >= TFS_COMPLETE && ptf->nState <= TFS_STOP)
continue;
m_iTransfer = i;
m_retry_tfinfo->retryFile->bFolder = ptf->bFolder;
m_retry_tfinfo->retryFile->nSize = ptf->nSize;
m_retry_tfinfo->retryFile->nState = ptf->nState;
m_retry_tfinfo->retryFile->nTransferredSize = ptf->nTransferredSize;
m_retry_tfinfo->retryFile->sLastModified = ptf->sLastModified;
m_retry_tfinfo->retryFile->sSrcPath = ptf->sSrcPath;
m_retry_tfinfo->retryFile->sDstPath = ptf->sDstPath; // 이거 왜 지우셨더랬나용!! -pizon : sorry...ㅠㅠ
m_retry_tfinfo->retryFile->sText = ptf->sText;
//memcpy( m_retry_tfinfo->retryFile , ptf , sizeof(TRANFILE_STRUCT));
break;
}
}
else
{
(m_retry_tfinfo->retryCnt)++;
ptf = m_retry_tfinfo->retryFile;
}
// add by rokmc777...
// m_iTransfer가 m_nTotalCount보다 커질경우에도 계속 돈다(특히 강제로 네트웍을 끊을때).. 원인찾기전에 임시로...
if(!ptf)
{
PostMessage(WM_CLOSE);
return S_FALSE;
}
m_bUpdating = true;
if (m_iTransfer > 0)
m_list.SetItemState(m_iTransfer - 1, 0, LVIS_SELECTED | LVIS_FOCUSED);
m_list.SetItemState(m_iTransfer, LVIS_SELECTED, LVIS_SELECTED);
m_list.SetItemText(m_iTransfer, 3, "전송중");
m_list.EnsureVisible(m_iTransfer, TRUE);
m_bUpdating = false;
if (m_sSkippedFolder != "")
{
CString m_sSrcPath = ptf->sSrcPath;
if (m_sSkippedFolder == m_sSrcPath.Left(m_sSkippedFolder.GetLength())) {
if (!ptf->bFolder)
m_nTotalTransferred += ptf->nSize;
ptf->nState = TFS_SKIPED;
m_list.SetItemText(m_iTransfer, 3, "건너뜀");
m_iTransfer++;
//if (m_iTransfer < m_nTotalCount) {
if (m_iTransfer <= m_nTotalCount) {
m_bResume = false;
m_nTimer = (UINT)SetTimer(TIMER_ID_TRANSFER, 100, 0);
}
else {
PostMessage(WM_CLOSE);
}
ShowProgressStatus(m_nTotalTransferred);
return S_OK;
}
else
m_sSkippedFolder = "";
}
if (m_bPaused) {
Pause();
return S_OK;
}
ptf->nState = TFS_TRANSFERRING;
CString sFileName, sDstPath;
if (m_tp.nAction == TPA_UPLOAD)
{
sFileName = ptf->sSrcPath;
m_szTargetPath = m_tp.szDstPath + ptf->sDstPath;
m_szTargetPath.Replace("//", "/");
if( (m_nWriteAction == FILEEXISTS_UPDATE || m_bUpdateMode) && (!ptf->bFolder) /*파일일때만 수행 add by pizon*/ )
{
sDstPath = m_tp.szDstPath + GetHashedPath(ptf->sDstPath);
sDstPath.Replace("//", "/");
m_szHashedTargetPath = sDstPath;
}
else
sDstPath = m_szTargetPath;
}
else {
sFileName = m_tp.szDstPath + ptf->sDstPath;
sFileName.Replace("\\\\", "\\");
}
m_stcSaveFile.SetWindowText(sFileName);
ShowFileCount();
int nWritePolicy = (int)wParam;
BOOL bRet = FALSE;
m_nCurrentFileSize = ptf->nSize;
if (nWritePolicy != CLWRITEPOLICY_APPEND) {
m_nBaseFileSize = 0;
m_nTransferredSize = 0;
}
m_dwOldTick = GetTickCount();
if (m_tp.nAction == TPA_UPLOAD) {
if (ptf->bFolder)
{
PCLFILE_STRUCT pclfl = cl_get_file_list(m_hcl, sDstPath, 0, NULL);
if (!pclfl)
{
WriteDebugLog("" , sDstPath ,"bRet = cl_make_directory(m_hcl, sDstPath);#1");
bRet = cl_make_directory(m_hcl, sDstPath);
if (bRet)
PostMessage(WMU_TRANSFER_COMPLETED);
else
{
AddFailedFile(sDstPath, true);
m_sError = cl_get_error_message(m_hcl);
}
}
else
{
bRet = TRUE;
// 폴더에 대해서 writepolicy 를 건너띔으로 설정하면 폴더밑에 파일들에도 같이 정책이 적용되기에
// 폴더에 대해서는 writepolicy 를 묻지않고 completed 시킨다(즉 overwrite)
// if (nWritePolicy != CLWRITEPOLICY_OVERWRITE) {
// m_dwError = CLERRNO_EXISTSFILE;
// PostMessage(WMU_TRANSFER_ERROR);
// }
// else
PostMessage(WMU_TRANSFER_COMPLETED);
}
cl_free_file_list(m_hcl, pclfl);
m_nGapTransfer = (GetTickCount() - dwTick + 100) * 0.001;
ShowProgressStatus(m_nTotalTransferred);
}
else
{
if(m_nWriteAction == FILEEXISTS_UPDATE)
nWritePolicy = CLWRITEPOLICY_OVERWRITE;
WriteDebugLog(sFileName , sDstPath ,"bRet = cl_upload(m_hcl, sFileName, sDstPath, nWritePolicy, m_tp.nFreeBytes, TransferCallbackProc, this );#2");
bRet = cl_upload(m_hcl, sFileName, sDstPath, nWritePolicy, m_tp.nFreeBytes, TransferCallbackProc, this );
}
}
else {
if (ptf->bFolder) {
CFileStatus64 fs;
if (!GetStatus64(sFileName, fs) && GetLastError() == ERROR_FILE_NOT_FOUND) {
bRet = CreateDirectory(sFileName);
if (bRet)
PostMessage(WMU_TRANSFER_COMPLETED);
else
m_sError = GetErrorMessage(m_dwError);
}
else {
if (nWritePolicy != CLWRITEPOLICY_OVERWRITE) {
bRet = TRUE;
m_dwError = CLERRNO_EXISTSFILE;
PostMessage(WMU_TRANSFER_ERROR);
}
else {
if (fs.m_attribute & CFile::directory) {
bRet = TRUE;
PostMessage(WMU_TRANSFER_COMPLETED);
}
else {
bRet = DeleteFile(sFileName);
if (bRet) {
((PTRANFILE_STRUCT)m_paTranFile[m_iTransfer])->nState = TFS_READY;
PostMessage(WMU_TRANSFER);
}
else
m_sError = GetErrorMessage(m_dwError);
}
}
}
m_nGapTransfer = (GetTickCount() - dwTick + 100) * 0.001;
ShowProgressStatus(m_nTotalTransferred);
}
else {
bRet = cl_download(m_hcl, ptf->sSrcPath, sFileName, nWritePolicy, m_tp.nFreeBytes, TransferCallbackProc, this);
if (!bRet)
m_sError = cl_get_error_message(m_hcl);
}
}
if (!bRet) {
m_sError = "에러가 발생했습니다.\n에러내용 : " + m_sError + "\n계속 하시겠습니까?";
if (m_tp.nAction != TPA_UPLOAD) {
if (AfxMessageBox(m_sError, MB_YESNO | MB_ICONERROR) != IDYES) {
PostMessage(WM_CLOSE);
return S_FALSE;
}
}
ptf->nState = TFS_ERROR;
m_list.SetItemText(m_iTransfer, 3, "오류");
m_iTransfer++;
m_nTimer = (UINT)SetTimer(TIMER_ID_TRANSFER, 100, 0);
}
return S_OK;
}
LRESULT CTransferDlg::OnTransferCompleted(WPARAM wParam, LPARAM)
{
if (m_bPaused) {
Pause();
return S_OK;
}
HTREEITEM htiVolume = (HTREEITEM) m_tp.pParam;
CMapPtrToPtr mapHcl;
HCOMMLIB hcl = (HCOMMLIB)mapHcl[htiVolume];
PCOMMLIB_STRUCT m_pcl = (PCOMMLIB_STRUCT)hcl;
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[m_iTransfer];
if (!ptf->bFolder) {
m_nSpeedTransferred += (ptf->nSize - m_nBaseFileSize);
m_nTotalTransferred += ptf->nSize;
m_tp.nFreeBytes -= (ptf->nSize - m_nBaseFileSize);
}
ptf->nState = TFS_COMPLETE;
m_retry_tfinfo->doRetry = false;
if( (!ptf->bFolder /*파일일때만 수행 add by pizon*/ )
&& (ptf->nState == TFS_COMPLETE )
&& (m_nWriteAction == FILEEXISTS_UPDATE || m_bUpdateMode) )
{
m_bUpdateMode = false;
#if 0 /* delete 안하고 , cl_move OVERWRITE add by pizon */
WriteDebugLog("" , m_szTargetPath ,"if(!cl_delete(m_hcl, m_szTargetPath))#3");
if(!cl_delete(m_hcl, m_szTargetPath))
{
if(cl_get_error_number(m_hcl) != CLERRNO_NOEXISTSFILE)
{
//AfxMessageBox(cl_get_error_message(hcl), MB_ICONERROR);
return E_FAIL;
}
}
#endif
FileOptLogsRequest(ptf);
WriteDebugLog(m_szHashedTargetPath , m_szTargetPath ,"if(!cl_move(m_hcl, m_szHashedTargetPath, m_szTargetPath, true))#4");
if(!cl_move(m_hcl, m_szHashedTargetPath, m_szTargetPath, true))
{
//AfxMessageBox(cl_get_error_message(m_hcl), MB_ICONERROR);
return E_FAIL;
}
}
// 파일 분산 배포 요청/////////////////////////////////////////////
if (!ptf->bFolder && TFS_COMPLETE == ptf->nState && TPA_UPLOAD == m_tp.nAction)
// if (TFS_COMPLETE == ptf->nState)
{
// 말그대로 일시정시버튼의 일시정지.
this->m_pause_disabled = true;
CConsoleTransferApp* pwp = (CConsoleTransferApp*) AfxGetApp();
pwp->NoticeTransComplete(m_szTargetPath);
}
//////////////////////////////////////////////////////////////////
else
{
// 폴더일때나 다운로드일때 걍 완료(배포요청안함)
this->TransCompleteWithDistribute();
}
return S_OK;
}
void CTransferDlg::TransCompleteWithDistribute()
{
m_list.SetItemText(m_iTransfer, 3, "완료");
m_iTransfer++;
m_nBaseFileSize = m_nTransferredSize;
// m_nBaseFileSize = 0;
m_nTransferredSize = 0;
//if (m_iTransfer < m_nTotalCount) {
if (m_iTransfer <= m_nTotalCount) {
m_bResume = FALSE;
m_nTimer = (UINT)SetTimer(TIMER_ID_TRANSFER, 100, 0);
}
else {
if (TPA_UPLOAD == m_tp.nAction)
{
/////////////////////////////////////////////////////
///전송창 닫을때, 이 전송트랙젠셕이 끝났음을 알린다.
CConsoleTransferApp* pwp = (CConsoleTransferApp*) AfxGetApp();
pwp->NoticeLastFileTransComplete();
////////////////////////////////////////////////////
}
PostMessage(WM_CLOSE);
}
}
LRESULT CTransferDlg::OnTransferError(WPARAM, LPARAM)
{
UINT nMessage = WMU_TRANSFER_ERROR;
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[m_iTransfer];
if (m_dwError == CLERRNO_EXISTSFILE) {
TRANFILE_STRUCT tfOld;
if (m_tp.nAction == TPA_UPLOAD) {
CString sDstPath = m_tp.szDstPath + ptf->sDstPath;
sDstPath.Replace("//", "/");
PCLFILE_STRUCT pclfl = cl_get_file_list(m_hcl, sDstPath, 0, NULL);
if (!pclfl) {
m_sError = cl_get_error_message(m_hcl);
cl_free_file_list(m_hcl, pclfl);
goto MARK_ERROR;
}
tfOld.sDstPath = pclfl->path;
tfOld.sLastModified = pclfl->lastModified;
tfOld.nSize = pclfl->attr & CLFILEATTR_FOLDER ? -1 : pclfl->size;
cl_free_file_list(m_hcl, pclfl);
}
else {
CFileStatus64 fs;
CString sDstPath = m_tp.szDstPath + ptf->sDstPath;
sDstPath.Replace("\\\\", "\\");
if (!GetStatus64(sDstPath, fs)) {
m_sError = GetErrorMessage(GetLastError());
goto MARK_ERROR;
}
CString sLastModified = fs.m_mtime.Format("%Y-%m-%d %p %I:%M:%S");
if (sLastModified.Replace("AM", "오전") == 0)
sLastModified.Replace("PM", "오후");
tfOld.sDstPath = sDstPath;
tfOld.sLastModified = sLastModified;
tfOld.nSize = fs.m_attribute & CFile::directory ? -1 : fs.m_size;
}
CTimeSpan ts = CTime::GetCurrentTime() - m_tmStart;
m_nElapsed += ts.GetTotalSeconds();
int nAction = GetAction(tfOld.sDstPath, tfOld.sLastModified, tfOld.nSize,
ptf->sSrcPath, ptf->sLastModified, ptf->nSize);
if(nAction == FILEEXISTS_UPDATE)
m_bUpdateMode = true;
else
m_bUpdateMode = false;
m_nSpeedTransferred = 0;
m_nSpeedTick = GetTickCount();
CEnterSomethingDlg dlg(IDS_INPUTDLGTITLE_RENAME, IDS_INPUTDLGTEXT_RENAME, FALSE, this);
switch (nAction) {
case FILEEXISTS_OVERWRITE:
m_nWriteAction = CLWRITEPOLICY_OVERWRITE;
ptf->nState = TFS_READY;
// OVERWRITE 의 경우에는 이전파일 삭제로그를 남김
this->FileOptLogsRequest(ptf);
break;
case FILEEXISTS_UPDATE:
ptf->nState = TFS_READY;
break;
case FILEEXISTS_RESUME:
m_nWriteAction = CLWRITEPOLICY_APPEND;
m_nBaseFileSize = tfOld.nSize;
ptf->nTransferredSize = tfOld.nSize;
ptf->nState = TFS_READY;
break;
case FILEEXISTS_RENAME:
m_nWriteAction = CLWRITEPOLICY_NONE;
dlg.m_String = ptf->sDstPath;
dlg.m_String = dlg.m_String.Mid(dlg.m_String.ReverseFind(m_tp.nAction == TPA_UPLOAD ? '/' : '\\') + 1);
if (dlg.DoModal() != IDOK) {
m_nSpeedTransferred = 0;
m_nSpeedTick = GetTickCount();
goto SKIP_CURRENTFILE;
}
else {
m_nSpeedTransferred = 0;
m_nSpeedTick = GetTickCount();
CString sSeparator = m_tp.nAction == TPA_UPLOAD ? "/" : "\\";
CString sSrcPath = ptf->sDstPath + sSeparator;
CString sDstPath = ptf->sDstPath;
sDstPath = sDstPath.Left(sDstPath.ReverseFind(sSeparator[0]) + 1) + dlg.m_String;
if (ptf->bFolder) {
int nLength = sSrcPath.GetLength();
for (int i = m_iTransfer + 1; i < m_paTranFile.GetCount(); i++) {
PTRANFILE_STRUCT ptfSub = (PTRANFILE_STRUCT)m_paTranFile[i];
CString sSubDstPath = ptfSub->sDstPath;
if (sSrcPath != sSubDstPath.Left(nLength))
break;
sSubDstPath.Replace(sSrcPath, sDstPath + sSeparator);
ptfSub->sDstPath = sSubDstPath;
}
}
ptf->sDstPath = sDstPath;
ptf->nState = TFS_READY;
}
break;
default:
SKIP_CURRENTFILE:
if (!ptf->bFolder)
m_nTotalTransferred += ptf->nSize;
ptf->nState = TFS_SKIPED;
m_list.SetItemText(m_iTransfer, 3, "건너뜀");
if (ptf->bFolder) {
m_sSkippedFolder = ptf->sSrcPath;
m_sSkippedFolder += "\\";
}
nMessage = WMU_TRANSFER_COMPLETED;
m_tmStart = CTime::GetCurrentTime();
goto TRANSFER_NEXTFILE;
break;
}
m_tmStart = CTime::GetCurrentTime();
PostMessage(WMU_TRANSFER, m_nWriteAction);
return S_OK;
}
MARK_ERROR:
m_sError = "에러가 발생했습니다.\n에러내용 : " + m_sError + "\n계속 하시겠습니까?";
// if ((6==this->m_dwError||1==this->m_dwError) && (TPA_UPLOAD == this->m_tp.nAction) )
if ( (TPA_UPLOAD == this->m_tp.nAction) )
{
if ((this->m_retry_tfinfo->retryCnt < RETRY_CNT))
{
this->m_retry_tfinfo->doRetry = true;
this->PostMessage(WMU_TRANSFER, CLWRITEPOLICY_OVERWRITE);
return S_OK;
}
else
{
this->SendMailWhenUploadFail(this->m_retry_tfinfo->retryFile->sSrcPath);
this->WriteWhenUploadFail(this->m_retry_tfinfo->retryFile->sSrcPath , this->m_retry_tfinfo->retryFile->sDstPath);
AddFailedFile(m_retry_tfinfo->retryFile->sSrcPath, false);
this->PostMessage(WMU_TRANSFER_COMPLETED);
return S_OK;
}
}
else
{
if (AfxMessageBox(m_sError, MB_YESNO | MB_ICONERROR) != IDYES) {
PostMessage(WM_CLOSE);
return S_FALSE;
}
}
m_nSpeedTransferred = 0;
m_nSpeedTick = GetTickCount();
ptf->nState = TFS_ERROR;
m_list.SetItemText(m_iTransfer, 3, "오류");
TRANSFER_NEXTFILE:
m_iTransfer++;
//if (m_iTransfer < m_nTotalCount) {
if (m_iTransfer <= m_nTotalCount) {
m_bResume = FALSE;
m_nTimer = (UINT)SetTimer(TIMER_ID_TRANSFER, 100, 0);
}
else {
PostMessage(WM_CLOSE);
}
return S_OK;
}
void CTransferDlg::TransferCallbackProc(LPVOID pParam, __int64 nTransferred)
{
CTransferDlg* pdlg = (CTransferDlg*)pParam;
if (nTransferred == 0) {
pdlg->PostMessage(WMU_TRANSFER_COMPLETED);
return;
}
else if (nTransferred == -1) {
pdlg->m_dwError = cl_get_error_number(pdlg->m_hcl);
pdlg->m_sError = cl_get_error_message(pdlg->m_hcl);
#if 0
if ((6==pdlg->m_dwError||1==pdlg->m_dwError) && (TPA_UPLOAD == pdlg->m_tp.nAction) )
{
if ((pdlg->m_retry_tfinfo->retryCnt < RETRY_CNT))
{
pdlg->m_retry_tfinfo->doRetry = true;
pdlg->PostMessage(WMU_TRANSFER, CLWRITEPOLICY_OVERWRITE);
return;
}
else
{
pdlg->SendMailWhenUploadFail(pdlg->m_retry_tfinfo->retryFile->sSrcPath);
pdlg->WriteWhenUploadFail(pdlg->m_retry_tfinfo->retryFile->sSrcPath);
AddFailedFile(m_retry_tfinfo->retryFile->sSrcPath, false);
pdlg->PostMessage(WMU_TRANSFER_COMPLETED);
return;
}
}
#endif
pdlg->PostMessage(WMU_TRANSFER_ERROR);
return;
}
// 전송속도 구하기
DWORD dwTick = GetTickCount();
DWORD dwGapTick = dwTick - pdlg->m_nSpeedTick;
dwGapTick++;
double nGapSecond = (double)(dwGapTick) / 1000;
INT64 nGapTransferred = pdlg->m_nSpeedTransferred + (nTransferred - pdlg->m_nBaseFileSize);
if (nGapTransferred <= 0)
return;
pdlg->m_nTransferSpeed = nGapTransferred / nGapSecond;
pdlg->m_nTransferredSize = nTransferred;
// 화면 출력하기
// pdlg->m_stcSpeed.SetWindowText(BYTE2KMBYTE((__int64)pdlg->m_nTransferSpeed, 0, TRUE) + "/s");
pdlg->m_stcSpeed.SetWindowText(BYTE2KMBIT((__int64)pdlg->m_nTransferSpeed * 8, 0, TRUE) + "bits/s");
CString sProgress, sTransferred, sTotalSize;
int nPercent;
nPercent = int((nTransferred * 100) / (pdlg->m_nCurrentFileSize == 0 ? 1 : pdlg->m_nCurrentFileSize));
sTransferred = NumericFormat(nTransferred);
sTotalSize = NumericFormat(pdlg->m_nCurrentFileSize);
if (sTransferred == sTotalSize) pdlg->m_pause_disabled = true;
else pdlg->m_pause_disabled = false;
sProgress.Format("%d%% (%s / %s)", nPercent, sTransferred, sTotalSize);
pdlg->m_prsNow.SetPos(nPercent, sProgress);
pdlg->ShowProgressStatus(pdlg->m_nTotalTransferred + nTransferred);
/* 순간 속도
// 전송속도 구하기
DWORD dwTickCount = GetTickCount();
DWORD dwGapTick = dwTickCount - pdlg->m_dwOldTick;
dwGapTick++;
double nGapSecond = (double)(dwGapTick) / 1000;
INT64 nGapTransferred = nTransferred - pdlg->m_nTransferredSize;
if (nGapTransferred <= 0)
return;
pdlg->m_nTransferSpeed = nGapTransferred / nGapSecond;
pdlg->m_dwOldTick = dwTickCount;
pdlg->m_nTransferredSize = nTransferred;
// 화면 출력하기
pdlg->m_stcSpeed.SetWindowText(BYTE2KMBYTE((__int64)pdlg->m_nTransferSpeed, 0, TRUE) + "/s");
CString sProgress, sTransferred, sTotalSize;
int nPercent;
nPercent = int((nTransferred * 100) / (pdlg->m_nCurrentFileSize == 0 ? 1 : pdlg->m_nCurrentFileSize));
sTransferred = NumericFormat(nTransferred);
sTotalSize = NumericFormat(pdlg->m_nCurrentFileSize);
sProgress.Format("%d%% (%s / %s)", nPercent, sTransferred, sTotalSize);
pdlg->m_prsNow.SetPos(nPercent, sProgress);
pdlg->ShowProgressStatus(pdlg->m_nTotalTransferred + nTransferred);
*/
}
void CTransferDlg::ShowProgressStatus(UINT64 nTransferred)
{
// 경과시간
CTime tmCurrent(CTime::GetCurrentTime());
CTimeSpan ts = (tmCurrent - m_tmStart) + m_nElapsed;
m_stcETime.SetWindowText(ts.Format("%H:%M:%S"));
// 남은시간
CString sRemainTime = "??:??:??";
if (m_nTransferSpeed > 0.0) {
int nRemainSec = (int)((double)(m_nTotalSize - nTransferred) / m_nTransferSpeed);
nRemainSec += (int)((m_nTotalCount - m_iTransfer) * m_nGapTransfer) + 1;
sRemainTime.Format("%02d:%02d:%02d", nRemainSec / 60 / 60, nRemainSec / 60 % 60, nRemainSec % 60);
}
else if (m_nTotalSize == 0) {
int nRemainSec = (int)((m_nTotalCount - m_iTransfer) * m_nGapTransfer) + 1;
sRemainTime.Format("%02d:%02d:%02d", nRemainSec / 60 / 60, nRemainSec / 60 % 60, nRemainSec % 60);
}
m_stcLTime.SetWindowText(sRemainTime);
RedrawControl2();
ShowTotalProgress();
CString sTitle;
int nPercent = int((nTransferred * 100) / (m_nTotalSize == 0 ? 1 : m_nTotalSize));
sTitle.Format("(%d%%) %s", nPercent, m_sTitle);
SetWindowText(sTitle);
}
void CTransferDlg::ShowFileCount()
{
if (m_nTotalCount == 0)
return;
m_stcFileCount.SetWindowText(NumericFormat(m_iTransfer + 1) + "/" + NumericFormat(m_nTotalCount));
RedrawControl1();
}
void CTransferDlg::ShowTotalProgress()
{
CString sProgress, sTransferred, sTotalSize;
int nPercent;
if (m_nTotalCount == 0)
return;
UINT64 nTransferred = m_nTotalTransferred + m_nTransferredSize;
nPercent = int((nTransferred * 100) / (m_nTotalSize == 0 ? 1 : m_nTotalSize));
sTransferred = NumericFormat(nTransferred);
sTotalSize = NumericFormat(m_nTotalSize);
sProgress.Format("%d%% (%s / %s)", nPercent, sTransferred, sTotalSize);
m_prsTotal.SetPos(nPercent, sProgress);
}
void CTransferDlg::Pause(bool bPause)
{
if (!m_pause_disabled)
{
m_btnPause.EnableWindow(TRUE);
m_bPaused = bPause;
if (bPause && m_paTranFile.GetCount() > 0 && ((PTRANFILE_STRUCT)m_paTranFile[0])->nState != TFS_READY) {
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[m_iTransfer];
ptf->nState = TFS_PAUSE;
if (m_iTransfer > 0)
m_list.SetItemState(m_iTransfer - 1, 0, LVIS_SELECTED | LVIS_FOCUSED);
m_list.SetItemState(m_iTransfer, LVIS_SELECTED, LVIS_SELECTED);
m_list.SetItemText(m_iTransfer, 3, "일시정지");
m_list.EnsureVisible(m_iTransfer, TRUE);
m_nSelectedCount = 1;
if (!ptf->bFolder)
m_nSelectedSize = ptf->nSize;
ShowStatus(TRUE);
CTimeSpan ts = CTime::GetCurrentTime() - m_tmStart;
m_nElapsed += ts.GetTotalSeconds();
}
m_btnDelFile.EnableWindow(bPause);
m_btnPause.SetWindowText(bPause ? "재시작(&R)" : "일시정지(&C)");
m_btnClose.EnableWindow(bPause);
}
}
void CTransferDlg::Resume()
{
m_btnPause.EnableWindow(TRUE);
InitTransferEnv();
PostMessage(WMU_TRANSFER, CLWRITEPOLICY_NONE);
}
void CTransferDlg::InitTransferEnv()
{
m_bResume = false;
m_nSpeedTransferred = 0;
m_nSpeedTick = GetTickCount();
m_stcLTime.SetWindowText("");
m_stcSpeed.SetWindowText("");
RedrawControl2();
SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
m_tmStart = CTime::GetCurrentTime();
m_dwOldTick = GetTickCount();
}
int CTransferDlg::GetAction(CString sOldObj, CString sOldMTime, UINT64 nOldSize, CString sNewObj, CString sNewMTime, UINT64 nNewSize)
{
int nAction = m_nWriteAction;
// LoadWritePolicy();
if (!m_bWriteApplyAll) {
CFileExistsDlg dlg(this);
dlg.m_bDownload = (m_tp.nAction == TPA_UPLOAD ? FALSE : TRUE);
char cSeparator = sOldObj.Find('/') >= 0 ? '/' : '\\';
dlg.m_sFile1 = sOldObj;
dlg.m_sTime1 = sOldMTime;
dlg.m_sSize1 = nOldSize == (UINT64)-1 ? "" : NumericFormat(nOldSize) + "Bytes";
cSeparator = sNewObj.Find('/') >= 0 ? '/' : '\\';
dlg.m_sFile2 = sNewObj;
dlg.m_sTime2 = sNewMTime;
dlg.m_sSize2 = nNewSize == (UINT64)-1 ? "" : NumericFormat(nNewSize) + "Bytes";
if (dlg.DoModal() == IDOK)
{
switch(dlg.m_nSelectedAction)
{
case 0 : nAction = FILEEXISTS_OVERWRITE; break;
case 1 : nAction = FILEEXISTS_RENAME; break;
case 2 : nAction = FILEEXISTS_RESUME; break;
case 3 : nAction = FILEEXISTS_SKIP; break;
case 4 : nAction = FILEEXISTS_UPDATE; break;
}
//nAction = dlg.m_nSelectedAction + 1;
if (dlg.m_bAlways)
{
m_bWriteApplyAll = TRUE;
m_nWriteAction = nAction;
}
}
else {
nAction = FILEEXISTS_SKIP;
}
}
return nAction;
}
#define UP_MSG "업로드할 파일 목록을 읽는 중... "
#define DN_MSG "다운로드할 파일 목록을 읽는 중... "
UINT CTransferDlg::LoadTransferFile(LPVOID pParam)
{
CTransferDlg* pdlg = (CTransferDlg*)pParam;
pdlg->BeginWaitCursor();
CStringArray saDelete;
pdlg->m_list.DeleteAllItems();
pdlg->m_paTranFile.RemoveAll();
if (pdlg->m_tp.nAction == TPA_UPLOAD) {
typedef std::pair<CString,int> pairTranFile;
pdlg->m_stcStatus.SetWindowText(UP_MSG);
for (map<CString,int>::iterator iter = pdlg->m_mapTranFile.begin(); iter != pdlg->m_mapTranFile.end(); iter++) {
if (pdlg->m_bStop)
break;
if (iter->first.GetLength() == 3 && iter->first[1] == ':' && iter->first[2] == '\\') {
CFileStatus64 fs;
CFileFind finder;
BOOL bFound = finder.FindFile(iter->first + "*");
while (bFound) {
if (pdlg->m_bStop)
break;
bFound = finder.FindNextFile();
CString sFile = finder.GetFilePath();
if (finder.IsDots() || finder.IsSystem() || !sFile.Right(4).Compare(".lnk"))
continue;
int iPos = pdlg->m_list.GetItemCount();
if (finder.IsDirectory())
pdlg->AppendLocalFile(sFile, 0);
else {
if (!GetStatus64(sFile, fs))
continue;
CString sTime = fs.m_mtime.Format("%Y-%m-%d %p %I:%M:%S");
if (sTime.Replace("AM", "오전") == 0)
sTime.Replace("PM", "오후");
pdlg->AppendFile(sFile, fs.m_attribute & CFile::directory ? -1 : fs.m_size, sTime, 0);
}
pdlg->m_mapTranFile.insert(pairTranFile(sFile, iPos));
}
finder.Close();
saDelete.Add(iter->first);
}
else {
int iPos = pdlg->m_list.GetItemCount();
if (pdlg->AppendLocalFile(iter->first, 0))
iter->second = iPos;
}
}
}
else {
pdlg->m_stcStatus.SetWindowText(DN_MSG);
for (map<CString,int>::iterator iter = pdlg->m_mapTranFile.begin(); iter != pdlg->m_mapTranFile.end(); iter++) {
if (pdlg->m_bStop)
break;
int iPos = pdlg->m_list.GetItemCount();
if (pdlg->AppendRemoteFile(iter->first))
iter->second = iPos;
}
}
for (int i = 0; i < saDelete.GetCount(); i++)
pdlg->m_mapTranFile.erase(saDelete[i]);
if (!pdlg->m_bStop)
pdlg->PostMessage(WMU_TRANSFER_IS_READY);
pdlg->EndWaitCursor();
pdlg->m_pthread = NULL;
return 0;
}
bool CTransferDlg::AppendRemoteFile(CString sPath)
{
UINT nFileCount;
PCLFILE_STRUCT pclfl = cl_get_file_list(m_hcl, sPath, 2, &nFileCount);
if (!pclfl)
return false;
if (sPath[0] != '/')
sPath = "/" + sPath;
int nRootCount = sPath.Replace('/', '\\');
for (UINT i = (sPath == "\\" ? 1 : 0); i < nFileCount; i++) {
if (m_bStop)
return 0;
CString sSubPath = pclfl[i].path;
int nDepth = sSubPath.Replace('/', '\\') - nRootCount;
AppendFile(pclfl[i].path, pclfl[i].attr & CLFILEATTR_FOLDER ? -1 : pclfl[i].size, pclfl[i].lastModified, nDepth);
if (pclfl[i].attr & CLFILEATTR_FOLDER) {
CString sName = pclfl[i].path;
m_stcStatus.SetWindowText(DN_MSG + sName.Mid(sName.ReverseFind('/') + 1));
}
}
cl_free_file_list(m_hcl, pclfl);
return true;
}
bool CTransferDlg::AppendLocalFile(CString sPath, int nDepth)
{
CFileStatus64 fs;
if (!GetStatus64(sPath, fs))
return false;
m_stcStatus.SetWindowText(UP_MSG + sPath.Mid(sPath.ReverseFind('\\') + 1));
CString sTime = fs.m_mtime.Format("%Y-%m-%d %p %I:%M:%S");
if (sTime.Replace("AM", "오전") == 0)
sTime.Replace("PM", "오후");
BOOL bFolder = fs.m_attribute & CFile::directory;
AppendFile(sPath, bFolder ? -1 : fs.m_size, sTime, nDepth);
if (bFolder) {
if (sPath.Right(1) != "\\")
sPath += "\\";
nDepth++;
CFileFind finder;
BOOL bFound = finder.FindFile(sPath + "*");
while (bFound) {
if (m_bStop)
return false;
bFound = finder.FindNextFile();
CString sFile = finder.GetFilePath();
if (finder.IsDots() || !sFile.Right(4).Compare(".lnk"))
continue;
if (finder.IsDirectory())
AppendLocalFile(sFile, nDepth);
else {
if (!GetStatus64(sFile, fs))
continue;
sTime = fs.m_mtime.Format("%Y-%m-%d %p %I:%M:%S");
if (sTime.Replace("AM", "오전") == 0)
sTime.Replace("PM", "오후");
AppendFile(sFile, fs.m_attribute & CFile::directory ? -1 : fs.m_size, sTime, nDepth);
}
}
finder.Close();
}
return true;
}
void CTransferDlg::AppendFile(CString sPath, UINT64 nSize, CString sLastModified, int nDepth, int iPos)
{
int i, nReplace;
char cSeparator1;
char cSeparator2;
if (m_tp.nAction == TPA_UPLOAD) {
cSeparator1 = '\\';
cSeparator2 = '/';
}
else {
cSeparator1 = '/';
cSeparator2 = '\\';
}
CString sText = sPath;
nReplace = sText.Replace(cSeparator1, cSeparator2) - nDepth;
for (i = 0; i < nReplace; i++)
sText = sText.Mid(sText.Find(cSeparator2) + 1);
PTRANFILE_STRUCT ptf = new TRANFILE_STRUCT;
for (i = 0; i < nDepth; i++)
ptf->sText += " ";
ptf->bFolder = (nSize == (UINT64)-1);
ptf->sText += sText.Mid(sText.ReverseFind(cSeparator2) + 1);
ptf->sSrcPath = sPath;
ptf->sDstPath = sText;
ptf->sLastModified = sLastModified;
ptf->nSize = nSize;
ptf->nState = TFS_READY;
m_paTranFile.Add(ptf);
if (iPos < 0)
iPos = (int)m_paTranFile.GetCount() - 1;
SHFILEINFO shfi;
if (!SHGetFileInfo(ptf->sText.Mid(ptf->sText.ReverseFind('.')), ptf->bFolder ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL, &shfi, sizeof(shfi), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME)) {
shfi.iIcon = -1;
shfi.szTypeName[0] = NULL;
}
m_list.InsertItem(iPos, ptf->sText, shfi.iIcon);
m_list.SetItemText(iPos, 1, ptf->bFolder ? "" : BYTE2KMBYTE(ptf->nSize, 1, FALSE));
m_list.SetItemText(iPos, 2, shfi.szTypeName);
m_list.SetItemText(iPos, 3, "대기중");
}
void CTransferDlg::ShowStatus(bool bSelected, bool bUpdate, bool bAllSelected)
{
if (!bSelected) {
if (bUpdate) {
m_nTotalCount = (int)m_paTranFile.GetCount();
m_nTotalSize = 0;
m_bUpdating = true;
for (int i = 0; i < m_nTotalCount; i++) {
m_list.SetItemState(i, 0, LVIS_SELECTED);
PTRANFILE_STRUCT ptf = (PTRANFILE_STRUCT)m_paTranFile[i];
if (!ptf->bFolder)
m_nTotalSize += ptf->nSize;
}
m_bUpdating = false;
}
m_nSelectedCount = 0;
m_nSelectedSize = 0;
SHOW_TOTALOBJECTSTATUS:
m_stcStatus.SetWindowText("전체 파일 수 " + NumericFormat(m_nTotalCount) + "건, 전체 파일 용량 " + BYTE2KMBYTE(m_nTotalSize, 0, TRUE));
}
else {
if (bAllSelected) {
m_nSelectedCount = m_nTotalCount;
m_nSelectedSize = m_nTotalSize;
}
if (m_nSelectedCount == 0)
goto SHOW_TOTALOBJECTSTATUS;
m_stcStatus.SetWindowText("선택된 파일 수 " + NumericFormat(m_nSelectedCount) + "건, 선택된 파일 용량 " + BYTE2KMBYTE(m_nSelectedSize, 0, TRUE));
}
}
void CTransferDlg::LoadWritePolicy()
{
// int nWritePolicy = COptions::GetOptionVal(OPTION_WRITEPOLICY);
int nWritePolicy = m_tp.nWritePolicy;
if (nWritePolicy == 0) {
m_bWriteApplyAll = FALSE;
m_nWriteAction = FILEEXISTS_OVERWRITE;
}
else {
m_bWriteApplyAll = TRUE;
m_nWriteAction = nWritePolicy;
}
}
void CTransferDlg::RedrawControl1()
{
/*
static bool bInited = false;
static RECT rc1, rc2;
if (!bInited) {
m_stcSaveFile.GetWindowRect(&rc1);
m_tab.ScreenToClient(&rc1);
m_stcFileCount.GetWindowRect(&rc2);
m_tab.ScreenToClient(&rc2);
bInited = true;
}
m_tab.InvalidateRect(&rc1, FALSE);
m_tab.InvalidateRect(&rc2, FALSE);
*/
m_stcSaveFile.ShowWindow(SW_HIDE);
m_stcSaveFile.ShowWindow(SW_SHOW);
m_stcFileCount.ShowWindow(SW_HIDE);
m_stcFileCount.ShowWindow(SW_SHOW);
}
void CTransferDlg::RedrawControl2()
{
/*
static bool bInited = false;
static RECT rc1, rc2, rc3;
if (!bInited) {
m_stcSpeed.GetWindowRect(&rc1);
m_tab.ScreenToClient(&rc1);
m_stcETime.GetWindowRect(&rc2);
m_tab.ScreenToClient(&rc2);
m_stcLTime.GetWindowRect(&rc3);
m_tab.ScreenToClient(&rc3);
bInited = true;
}
m_tab.InvalidateRect(&rc1, FALSE);
m_tab.InvalidateRect(&rc2, FALSE);
m_tab.InvalidateRect(&rc3, FALSE);
*/
m_stcSpeed.ShowWindow(SW_HIDE);
m_stcSpeed.ShowWindow(SW_SHOW);
m_stcETime.ShowWindow(SW_HIDE);
m_stcETime.ShowWindow(SW_SHOW);
m_stcLTime.ShowWindow(SW_HIDE);
m_stcLTime.ShowWindow(SW_SHOW);
}
BEGIN_EVENTSINK_MAP(CTransferDlg, CDialog)
ON_EVENT(CTransferDlg, IDC_WB_ADVERT, 259, DocumentCompleteWBAdvert, VTS_DISPATCH VTS_PVARIANT)
ON_EVENT(CTransferDlg, IDC_WB_ADVERT, 271, NavigateErrorWBAdvert, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
END_EVENTSINK_MAP()
void CTransferDlg::DocumentCompleteWBAdvert(LPDISPATCH pDisp, VARIANT* URL)
{
}
void CTransferDlg::NavigateErrorWBAdvert(LPDISPATCH pDisp, VARIANT* URL, VARIANT* Frame, VARIANT* StatusCode, BOOL* Cancel)
{
}
void CTransferDlg::FileOptLogsRequest(PTRANFILE_STRUCT ptf)
{
TADDINFO tdi;
ptf->bFolder ? tdi.bFolder='D' : tdi.bFolder='F';
strncpy(tdi.szFileName , m_szTargetPath , 2048-1);
HWND hWnd = m_tp.hwnd;
if (hWnd!=NULL)
{
COPYDATASTRUCT copydata;
copydata.dwData=1000;
copydata.cbData=sizeof(TADDINFO);
copydata.lpData=&tdi;
::SendMessage(hWnd , WM_COPYDATA , (WPARAM)m_hWnd , (LPARAM)&copydata);
}
}
void CTransferDlg::SendMailWhenUploadFail(const char* file_name)
{
char local_file[2048];
strncpy(local_file , file_name , 2048);
HWND hWnd = m_tp.hwnd;
if (hWnd!=NULL)
{
COPYDATASTRUCT copydata;
copydata.dwData=2000;
copydata.cbData=2048;
copydata.lpData=local_file;
::SendMessage(hWnd , WM_COPYDATA , (WPARAM)m_hWnd , (LPARAM)&copydata);
}
}
void CTransferDlg::WriteWhenUploadFail(const char* sfile_name , const char* tfile_name)
{
char log_file_path[256];
char log_contents[4096];
::_mkdir(LOG_PATH1);
::_mkdir(LOG_PATH2);
::sprintf(log_file_path , "%s\\%s" , LOG_PATH2 , LOG_FILE);
::sprintf(log_contents , "%s\r\n" , sfile_name);
FILE* fp;
if (NULL != (fp = ::fopen(log_file_path , "a+")))
{
::fwrite(log_contents , ::strlen(log_contents) , 1 , fp);
}
fclose(fp);
}
void CTransferDlg::WriteDebugLog(const char* sfile_name , const char* tfile_name , const char* action)
{
#if 0
SYSTEMTIME systime;
GetSystemTime(&systime);
CTime ct = CTime( systime );
CString time_str = ct.Format( "%H:%M:%S" );
char log_file_path[256];
char log_contents[8000];
::_mkdir(LOG_PATH1);
::_mkdir(LOG_PATH2);
::sprintf(log_file_path , "%s\\%s" , LOG_PATH2 , DEBUG_FILE);
::sprintf(log_contents , "[%s][%s]%s=>%s\n" , time_str , action ,sfile_name ,tfile_name );
FILE* fp;
if (NULL != (fp = ::fopen(log_file_path , "a+")))
{
::fwrite(log_contents , ::strlen(log_contents) , 1 , fp);
}
fclose(fp);
#endif
}
void CTransferDlg::AddFailedFile(CString strPathName, bool bDirectory)
{
CString str;
str.Format(_T("[%s] %s\r\n"), bDirectory ? _T("디렉토리") : _T("파일"), strPathName);
m_strFailedFiles += str;
m_nFailedFileCount++;
}
CString CTransferDlg::GetHashedPath(CString strPath)
{
CString strHashedPath;
char szHash[1024];
::memset(szHash, NULL, sizeof(szHash));
CMD5::GetHash(strPath.GetBuffer(), szHash);
strHashedPath.Format(_T("%s_%s"), strPath, szHash);
return strHashedPath;
}