/* * Hillstone Software (www.hillstone-software.com) * HS FTP C Source Library Demo */ #include "stdafx.h" #include #include #include "resource.h" #include #include #include #include "hsftp_if.h" #include #include TCHAR szWindowClass[] = " "; HINSTANCE hInst; TCHAR szTitle[] = "HS FTP C Source Library CLIENT Demo (www.hillstone-software.com) Ver "HS_VERSION; HWND hwnd_main; HWND dlg_main; HBRUSH hbrush1 = NULL; char commercial_msg[] = "This is a demo application for HS FTP C source code library by Hillstone Software. The library is supplied with " "full source code in C and implements the client side of RFC 959 FTP Protocol. Further information:\n" "www.hillstone-software.com/hs_ftp_details.htm\nemail: info@hillstone-software.com; Tel. +353 87 988 1568"; char *m_title = NULL; char *m_prmt = NULL; char *m_err = NULL; char *m_hdr = "Error"; static COLORREF color; static int progress = 0; __int64 rxed_len; __int64 txed_len; static int recursive_operation_in_progress = 0; unsigned char username[100] = "anonymous"; unsigned char password[100] = ""; UINT T1 = 15000; int ip_port = DEF_PORT; unsigned char server_name[256] = "ftp.microsoft.com"; static hstftp_app_cfg_t cfg = {0}; int state = APP_STATE_IDLE; static hsftp_stats_t last_stats = {0}; static DWORD stats_start_tick = 0; long myuserref; static long ftp_session; static unsigned char start_dir[_MAX_PATH]; static unsigned char rxfname[_MAX_PATH]; static unsigned char txfname[_MAX_PATH]; static __int64 local_fsz; static __int64 remote_fsz; static unsigned char rtype[2]; static unsigned char ltype[2]; static FILE *rxfd = NULL; static FILE *txfd = NULL; static unsigned char *syes_hdr = NULL; static unsigned char *syes_text = NULL; static COLORREF syes_color = 0; static int destroy_editbox = 0; static int destroy_overwrite = 1; unsigned char editstr[512]; static int overwrite = TRUE; HIMAGELIST himgList; int index; void CenterWindowInDialog(HWND hDlg) { HWND hwndOwner; RECT rc, rcDlg, rcOwner; if ((hwndOwner = GetParent(hDlg)) == NULL) { hwndOwner = GetDesktopWindow(); } GetWindowRect(hwndOwner, &rcOwner); GetWindowRect(hDlg, &rcDlg); CopyRect(&rc, &rcOwner); // Offset the owner and dialog box rectangles so that right and bottom // values represent the width and height, and then offset the owner again // to discard space taken up by the dialog box. OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); OffsetRect(&rc, -rc.left, -rc.top); OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); // The new position is the sum of half the remaining space and the owner's // original position. SetWindowPos(hDlg, HWND_TOP, rcOwner.left + (rc.right / 2), rcOwner.top + (rc.bottom / 2), 0, 0, // Ignores size arguments. SWP_NOSIZE); } HWND NewDialogWin(HINSTANCE hInst, HWND parent, DLGPROC proc, int dlg_id) { HWND handle; handle = CreateDialog(hInst, (LPCTSTR)dlg_id, parent, proc); ShowWindow (handle, SW_SHOWDEFAULT); UpdateWindow(handle); return handle; } ATOM BlRegisterClass(HINSTANCE hInstance, UINT style, WNDPROC proc, int cursor_id, HBRUSH bkg_brush, LPCTSTR lpszClassName, int icon_id, int menu_id) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = style; wcex.lpfnWndProc = proc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = 0; wcex.hCursor = 0; if (cursor_id) { wcex.hCursor = LoadCursor(0, (const char *)cursor_id); } wcex.hbrBackground = bkg_brush; wcex.lpszMenuName = (LPCSTR)menu_id; wcex.lpszClassName = lpszClassName; wcex.hIconSm = 0; if (icon_id) { wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)icon_id); } return RegisterClassEx(&wcex); } static LRESULT CALLBACK DlgWinYN(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT result = FALSE; switch (message) { case WM_INITDIALOG: SendMessage(hDlg, WM_SETTEXT, 0, (long)syes_hdr); SetDlgItemText(hDlg, IDC_STATIC_YN, syes_text); if (destroy_editbox) { DestroyWindow(GetDlgItem(hDlg, IDC_EDIT1)); } else { SetDlgItemText(hDlg, IDC_EDIT1, editstr); } if (destroy_overwrite) { DestroyWindow(GetDlgItem(hDlg, IDC_CHECK_OVERW)); } else { CheckDlgButton(hDlg, IDC_CHECK_OVERW, overwrite ? BST_CHECKED : BST_UNCHECKED); } CenterWindowInDialog(hDlg); return TRUE; case WM_CTLCOLORSTATIC: if ((HWND)lParam == GetDlgItem(hDlg, IDC_STATIC_YN)) { SetTextColor((HDC)wParam, syes_color); SetBkColor ((HDC)wParam, WHITE); result = (long)hbrush1; } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BUTTON_Y: if (!destroy_editbox) { memset(editstr, 0, sizeof editstr); GetDlgItemText(hDlg, IDC_EDIT1, editstr, (sizeof editstr) - 1); } if (!destroy_overwrite) { overwrite = (IsDlgButtonChecked(hDlg, IDC_CHECK_OVERW) == BST_CHECKED) ? 1 : 0; } EndDialog(hDlg, TRUE); return TRUE; case IDC_BUTTON_N: EndDialog(hDlg, FALSE); return TRUE; } break; default: break; } return result; } INT_PTR ShowYNDialog(HWND hDlg, unsigned char *hdr, unsigned char *text, COLORREF col, int is_edit, int is_overw) { syes_hdr = hdr; syes_text = text; syes_color = col; destroy_editbox = (is_edit) ? 0 : 1; destroy_overwrite = (is_overw) ? 0 : 1; return DialogBox(hInst, (LPCTSTR)IDD_DIALOG_YN, hDlg, (DLGPROC)DlgWinYN); } static void LvInsertCol(HWND hwndListView, int index, unsigned char *hdr, int cx, int fmt) { LV_COLUMN lvColumn = {0}; lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvColumn.pszText = hdr; lvColumn.cx = cx; lvColumn.fmt = fmt; ListView_InsertColumn (hwndListView, index, &lvColumn); } /* seraches from the start of list and return the last item in the list which is NOT a directory */ static int find_first_non_dir_lv(HWND lvhan) { int item_count, i; unsigned char str[2]; item_count = ListView_GetItemCount(lvhan); if (item_count == 0) return 0xffff; for (i=0; i 15)) return FALSE; while (*p) { switch (state) { case IPSTR_FINISHED: return FALSE; case IPSTR_SEG1: case IPSTR_SEG2: case IPSTR_SEG3: if (*p == '.') { if (digits == 0) { return FALSE; } else { digits = 0; state += 2; } } else if (isdigit(*p)) if (++digits == 3) state++; else return FALSE; break; case IPSTR_SEG4: if (isdigit(*p)) if (++digits == 3) state = IPSTR_FINISHED; else return FALSE; break; case IPSTR_SEG1_DOT: case IPSTR_SEG2_DOT: case IPSTR_SEG3_DOT: if (*p == '.') { digits = 0; state++; } else { return FALSE; } break; } p++; } if (state == IPSTR_FINISHED) return TRUE; return FALSE; } /* find substring number n in string src, return in *index * string must be separated by spaces */ static int find_string_start_n(unsigned char *src, int n, int *index) { int i, k; int is_str = FALSE; int len = strlen(src); k = 0; for (i=0; i (sizeof(s) - 1)) break; // if first entry is not "..", we need to manually add it if ((num == 0) && ((strcmp(&line[index], "..") != 0) && (strcmp(&line[index], ".") != 0))) PutLV(lv, "..", "0", "d"); memset(s, 0, sizeof (s)); memcpy(s, &line[index1], k); // if "" is found in place of size, we are dealing with directory if (stricmp(s, "") == 0) { PutLV(lv, &line[index], "0", "d"); } else { PutLV(lv, &line[index], s, s1); } num++; } n = 0; memset(line, 0, sizeof(line)); } else { line[n++] = ch; } i++; } } void write_status(HWND hDlg, COLORREF col, unsigned char *s) { color = col; SetDlgItemText(hDlg, IDC_STATIC_STATUS, s); } void prep_info_string(unsigned char *s1, int s1_size, unsigned char *errstr, int *err_len) { unsigned char *p; memset(s1, 0, s1_size); if ((*err_len) >= s1_size) (*err_len) = (s1_size - 1); memcpy(s1, errstr, (*err_len)); if (strlen(s1) > 1) p = strchr(s1, 13); if (p) *p = 0; } int log_ftp_result(int rc) { unsigned char str[80]; if (rc != HS_FTP_RC_OK) { memset(str, 0, sizeof (str)); sprintf(str, "HS FTP error: %s", HsFtpGetErrStr(rc)); PutLog(dlg_main, str); return FALSE; } return TRUE; } int send_next_file_block(long arg1, long arg2, long arg3) { int *req_sz = (int *)arg2; unsigned char **p_bufp = (unsigned char **)arg1; unsigned char *buf; int read_len; if (!txfd) { txfd = fopen(txfname, "rb"); if (!txfd) return FALSE; } buf = (unsigned char *)malloc(*req_sz); if (!buf) { fclose(txfd); txfd = NULL; return FALSE; } read_len = (int)fread(buf, 1, (*req_sz), txfd); if (read_len != *req_sz) { if (!feof(txfd)) { fclose(txfd); txfd = NULL; free((void *)buf); return FALSE; } fclose(txfd); txfd = NULL; } *req_sz = read_len; *p_bufp = buf; txed_len += read_len; if ((local_fsz) != 0) { progress = (int)((txed_len * 100) / local_fsz); SendMessage(GetDlgItem(dlg_main, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)progress, 0); } return TRUE; } int hs_ftp_callback(void *user_ref, int ev, long arg1, long arg2, long arg3) { unsigned char s[300] = {0}; unsigned char s1[300]; unsigned char *errstr = (unsigned char *)arg1; int len = (int)arg2; int i; int rc; switch (ev) { case HS_FTPCLI_USR_EV_TIMEDOUT: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } i = sprintf(s, "ERROR: TIMEOUT WAITING FOR SERVER REPONSE: (%s)", errstr); if (((sizeof s) - i-1) < (size_t)len) len = ((sizeof s) - i-1); memcpy(&s[i], errstr, len); state = APP_STATE_IDLE; write_status(dlg_main, RED, s); PutLog(dlg_main, s); PutLog(dlg_main, "Disconnected"); ListView_DeleteAllItems(GetDlgItem(dlg_main, IDC_LIST_RFS)); break; case HS_FTPCLI_USR_EV_NOOP_DONE: prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "NOOP complete: %s", s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_PWD_DONE: sprintf(s, "Current Directory=%s", (unsigned char *)arg3); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_RENAME_DONE: PutLog(dlg_main, "File or folder renamed: Success"); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HS_FTPCLI_USR_EV_RENAME_FAILED: prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Rename failed: %s", s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_PWD_FAILED: prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Get current directory failed: %s", s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_SRVERR: case HS_FTPCLI_USR_EV_UNKNOWN: case HS_FTPCLI_USR_EV_UNEXP: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); state = APP_STATE_IDLE; if (ev == HS_FTPCLI_USR_EV_SRVERR) sprintf(s, "(%d) Server Error: %s", (int)arg3, s1); else if (ev == HS_FTPCLI_USR_EV_UNKNOWN) sprintf(s, "(%d) Unknown: %s", (int)arg3, s1); else if (ev == HS_FTPCLI_USR_EV_UNEXP) sprintf(s, "(%d) Unexpected: %s", (int)arg3, s1); write_status(dlg_main, RED, s); PutLog(dlg_main, s); PutLog(dlg_main, "Disconnected"); ListView_DeleteAllItems(GetDlgItem(dlg_main, IDC_LIST_RFS)); break; case HS_FTPCLI_USR_EV_LOGGEDIN: prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Connected to Server. %s", s1); state = APP_STATE_CONNECTED; write_status(dlg_main, GREEN, s); PutLog(dlg_main, s); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HS_FTPCLI_USR_EV_LIST: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } load_remote_directory(dlg_main, (unsigned char *)arg1, (int)arg2); break; case HS_FTPCLI_USR_EV_CWD_FAILED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Change directory failed: %s", s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_MKD_FAILED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Create directory failed: %s", s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_RMD_FAILED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Deleting directory failed: %s", s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_DELE_FAILED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Deleting file failed: %s", s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_CWD_DONE: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Changed Directory: %s", s1); PutLog(dlg_main, s); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HS_FTPCLI_USR_EV_MKD_DONE: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Created Directory: %s", s1); PutLog(dlg_main, s); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HS_FTPCLI_USR_EV_RMD_DONE: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Deleted Directory: %s", s1); PutLog(dlg_main, s); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HS_FTPCLI_USR_EV_DELE_DONE: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "Deleted File: %s", s1); PutLog(dlg_main, s); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HS_FTPCLI_USR_EV_CLOSED: state = APP_STATE_IDLE; if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } sprintf(s, "(%d) FTP Connection Closed", (int)arg3); write_status(dlg_main, RED, s); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_CONNFAIL: state = APP_STATE_IDLE; write_status(dlg_main, RED, "FTP Connection Failed"); PutLog(dlg_main, errstr); break; case HS_FTPCLI_USR_EV_NOCTX: state = APP_STATE_IDLE; if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } sprintf(s, "FTP Connection Closed - No Free Contexts"); write_status(dlg_main, RED, s); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_NOMEM: state = APP_STATE_IDLE; if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } sprintf(s, "(%d) FTP Connection Closed - No Free Memory", (int)arg3); write_status(dlg_main, RED, s); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_STOR_FAILED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } if (errstr == NULL) { sprintf(s, "(%d) File Send Failed", (int)arg3); } else { prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "(%d) File Send Failed: %s", (int)arg3, s1); } PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_RXINCOMPL: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } PutLog(dlg_main, "File receive failed: incomplete"); if (rxfd) fclose(rxfd); rxfd = NULL; load_local_directory(dlg_main); break; case HS_FTPCLI_USR_EV_RXSEG: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } rxed_len += len; if ((remote_fsz) != 0) { progress = (int)((rxed_len * 100) / remote_fsz); SendMessage(GetDlgItem(dlg_main, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)progress, 0); } if (rxfd) fwrite((unsigned char *)arg1, len, 1, rxfd); break; case HS_FTPCLI_USR_EV_RXDONE: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } progress = 100; SendMessage(GetDlgItem(dlg_main, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)progress, 0); sprintf(s, "File receive complete (%d) bytes", rxed_len); PutLog(dlg_main, s); if (rxfd) fclose(rxfd); rxfd = NULL; load_local_directory(dlg_main); break; case HS_FTPCLI_USR_EV_TXDONE: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } progress = 100; SendMessage(GetDlgItem(dlg_main, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)progress, 0); sprintf(s, "File sending complete (%I64d) bytes", txed_len); PutLog(dlg_main, s); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HS_FTPCLI_USR_EV_TYP_FAILED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "(%d) Setting transfer type failed: %s", (int)arg3, s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_TXSEG: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); return TRUE; } return send_next_file_block(arg1, arg2, arg3); case HS_FTPCLI_USR_EV_ABORTED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "(%d) Abort completed: %s", (int)arg3, s1); PutLog(dlg_main, s); break; case HS_FTPCLI_USR_EV_ABOR_FAILED: if (recursive_operation_in_progress) { HsFtpRecursDoEvent(ftp_session, ev, arg1, arg2, arg3); break; } prep_info_string(s1, sizeof (s1), errstr, &len); sprintf(s, "(%d) Abort failed: %s", (int)arg3, s1); PutLog(dlg_main, s); break; } return FALSE; } void DlgCmdConnect(HWND hDlg) { int rc; hs_ftp_conn_t conn; BOOL translated; unsigned char s[80] = {0}; UINT val; hs_ftp_config_t cfg = {0}; if (state != APP_STATE_IDLE) return; val = GetDlgItemInt(hDlg, IDC_EDIT_T1, &translated, FALSE); if (translated) { T1 = val; cfg.t1_timeout = (long)T1; HsFtpSetConfig(&cfg); } memset(&conn, 0, sizeof(hs_ftp_conn_t)); memset(server_name, 0, sizeof server_name); GetDlgItemText(hDlg, IDC_EDIT_NAME, server_name, (sizeof (server_name) -1)); if (is_string_ip_address(server_name)) conn.srv_ip = server_name; else conn.srv_name = server_name; conn.srv_port = (unsigned short)GetDlgItemInt(hDlg, IDC_EDIT_PORT, &translated, FALSE); memset(username, 0, sizeof (username)); memset(password, 0, sizeof (password)); GetDlgItemText(hDlg, IDC_EDIT_USER, username, sizeof(username) - 1); GetDlgItemText(hDlg, IDC_EDIT_PW, password, sizeof(password) - 1); conn.usrname = username; conn.password = password; conn.callback = hs_ftp_callback; conn.user_ref = (void *)&myuserref; rc = HsFtpCliConnect(&conn, &ftp_session); if (rc != HS_FTP_RC_OK) { state = APP_STATE_IDLE; sprintf(s, "HS FTP error: %s", HsFtpGetErrStr(rc)); write_status(hDlg, RED, s); PutLog(hDlg, s); return; } state = APP_STATE_CONNECTING; write_status(hDlg, GREEN, "Connecting"); PutLog(hDlg, "Connecting"); } void DlgCmdDisconnect(HWND hDlg) { int rc; unsigned char s[80] = {0}; HWND lv = GetDlgItem(hDlg, IDC_LIST_RFS); if ((state != APP_STATE_CONNECTING) && (state != APP_STATE_CONNECTED)) return; rc = HsFtpCliDisconnect(ftp_session); if (!log_ftp_result(rc)) return; ListView_DeleteAllItems(lv); state = APP_STATE_IDLE; write_status(hDlg, GREEN, "Not Connected"); PutLog(hDlg, "Disconnected"); } void DlgCmdGetFile(HWND hDlg) { int rc; unsigned char s[300]; if (state != APP_STATE_CONNECTED) return; if (!GetSelectedFilename(IDC_LIST_RFS, rxfname, sizeof (rxfname), &remote_fsz, rtype)) return; if (rtype[0] == 'd') { PutLog(dlg_main, "Remote file is a directory, not proceeding."); return; } if (file_exists(rxfname)) { if (!ShowYNDialog(dlg_main, "Confirm file overwrite", "File already exists. Overwrite?", RED, FALSE, FALSE)) return; } rxfd = fopen(rxfname, "wb"); if (!rxfd) { return; } memset(s, 0, sizeof (s)); sprintf(s, "Getting file %s ...", rxfname); PutLog(dlg_main, s); rc = HsFtpCliGetFile(ftp_session, rxfname, remote_fsz); if (!log_ftp_result(rc)) return; progress = 0; rxed_len = 0; SendMessage(GetDlgItem(hDlg, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)progress, 0); } void DlgCmdPutFile(HWND hDlg) { int rc; unsigned char s[300]; if (state != APP_STATE_CONNECTED) return; if (!GetSelectedFilename(IDC_LIST_LFS, txfname, sizeof (txfname), &local_fsz, ltype)) return; if (ltype[0] == 'd') { PutLog(dlg_main, "Local file is a directory, not proceeding."); return; } if (FileExistsOnRemote(txfname)) { if (!ShowYNDialog(dlg_main, "Confirm file overwrite", "File exists on remote. Overwrite?", RED, FALSE, FALSE)) return; } txfd = NULL; rc = HsFtpCliSendFile(ftp_session, txfname); if (!log_ftp_result(rc)) return; progress = 0; txed_len = 0; SendMessage(GetDlgItem(hDlg, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)progress, 0); memset(s, 0, sizeof (s)); sprintf(s, "Sending file %s ...", txfname); PutLog(dlg_main, s); } /* Abort current file transfer */ void DlgCmdAbort(HWND hDlg) { int rc; if (state != APP_STATE_CONNECTED) return; rc = HsFtpCliAbort(ftp_session); if (!log_ftp_result(rc)) return; PutLog(hDlg, "Abort by user..."); } /* Create Directory */ void DlgCmdMakeDir(HWND hDlg) { int rc; if (state != APP_STATE_CONNECTED) return; memset(editstr, 0, sizeof (editstr)); if (!ShowYNDialog(dlg_main, "Create Directory", "Okay to Create Directory?", RED, TRUE, FALSE)) return; PutLog(hDlg, "Creating Directory.."); rc = HsFtpCliCreateDir(ftp_session, editstr); log_ftp_result(rc); } /* Delete Directory */ void DlgCmdRmDir(HWND hDlg) { int rc; if (state != APP_STATE_CONNECTED) return; if (!GetSelectedFilename(IDC_LIST_RFS, editstr, sizeof (editstr), &remote_fsz, rtype)) return; if (!ShowYNDialog(dlg_main, "Delete Directory", "Okay to Delete Directory?", RED, TRUE, FALSE)) return; PutLog(hDlg, "Removing Directory.."); if (strlen(editstr) == 0) return; rc = HsFtpCliRemoveDir(ftp_session, editstr); log_ftp_result(rc); } /* Rename file or folder */ void DlgCmdRename(HWND hDlg) { int rc; unsigned char str[300]; unsigned char oldpath[300]; if (state != APP_STATE_CONNECTED) return; if (!GetSelectedFilename(IDC_LIST_RFS, editstr, sizeof (editstr), &remote_fsz, rtype)) return; if (strlen(editstr) >= sizeof(oldpath)) return; memset(oldpath, 0, sizeof(oldpath)); memcpy(oldpath, editstr, strlen(editstr)); sprintf(str, "Rename from: %s", editstr); if (!ShowYNDialog(dlg_main, str, "Type pathname to rename to:", RED, TRUE, FALSE)) return; if (strlen(editstr) == 0) return; PutLog(hDlg, str); rc = HsFtpCliRename(ftp_session, oldpath, editstr); log_ftp_result(rc); } /* Delete File */ void DlgCmdDele(HWND hDlg) { int rc; if (state != APP_STATE_CONNECTED) return; if (!GetSelectedFilename(IDC_LIST_RFS, editstr, sizeof (editstr), &remote_fsz, rtype)) return; if (!ShowYNDialog(dlg_main, "Delete File", "Okay to Delete File?", RED, TRUE, FALSE)) return; PutLog(hDlg, "Deleting File.."); if (strlen(editstr) == 0) return; rc = HsFtpCliDeleteFile(ftp_session, editstr); log_ftp_result(rc); } /* NOOP */ void DlgCmdNoop(HWND hDlg) { int rc; if (state != APP_STATE_CONNECTED) return; PutLog(hDlg, "Sending NOOP command.."); rc = HsFtpCliNoop(ftp_session); log_ftp_result(rc); } /* NOOP */ void DlgCmdGetCurrDir(HWND hDlg) { int rc; if (state != APP_STATE_CONNECTED) return; PutLog(hDlg, "Requesting Current Working Direcrory name..."); rc = HsFtpCliGetCurrentDirectory(ftp_session); log_ftp_result(rc); } static int check_recursive_close_event(long arg2) { switch (arg2) { case HS_FTPCLI_USR_EV_TIMEDOUT: state = APP_STATE_IDLE; write_status(dlg_main, RED, "Timeout waiting for server reponse. Session closed."); PutLog(dlg_main, "Disconnected"); return TRUE; case HS_FTPCLI_USR_EV_CLOSED: state = APP_STATE_IDLE; write_status(dlg_main, RED, "Ftp control connection closed. Session closed."); PutLog(dlg_main, "Ftp control connection closed"); return TRUE; case HS_FTPCLI_USR_EV_SRVERR: state = APP_STATE_IDLE; write_status(dlg_main, RED, "Ftp control connection closed. Server Error Received."); PutLog(dlg_main, "Ftp control connection closed"); return TRUE; case HS_FTPCLI_USR_EV_UNKNOWN: state = APP_STATE_IDLE; write_status(dlg_main, RED, "Ftp control connection closed. Unknown Event."); PutLog(dlg_main, "Ftp control connection closed"); return TRUE; case HS_FTPCLI_USR_EV_UNEXP: state = APP_STATE_IDLE; write_status(dlg_main, RED, "Ftp control connection closed. Unexpected Event."); PutLog(dlg_main, "Ftp control connection closed"); return TRUE; case HS_FTPCLI_USR_EV_NOMEM: state = APP_STATE_IDLE; write_status(dlg_main, RED, "Ftp control connection closed. Out of Memory."); PutLog(dlg_main, "Ftp control connection closed"); return TRUE; case HS_FTPCLI_USR_EV_NOCTX: state = APP_STATE_IDLE; write_status(dlg_main, RED, "Ftp control connection closed. No Free Contexts."); PutLog(dlg_main, "Ftp control connection closed"); return TRUE; } return FALSE; } /* callback from recursive operations module */ void hsftp_recursive_callback(long ftp_session, int ev, long arg1, long arg2) { unsigned char str[300]; int rc; switch (ev) { case HSFTP_RECURS_USR_EV_FOLDER_DELETE_FAILED: recursive_operation_in_progress = FALSE; sprintf(str, "Recursive Folder Delete: Failed (RC=%u) (core ev=%u) Requesting remote listing..", arg1, arg2); PutLog(dlg_main, str); if (check_recursive_close_event(arg2)) break; rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HSFTP_RECURS_USR_EV_FOLDER_DOWNLOAD_FAILED: recursive_operation_in_progress = FALSE; sprintf(str, "Recursive Folder Download: Failed (RC=%u) (core ev=%u)", arg1, arg2); PutLog(dlg_main, str); check_recursive_close_event(arg2); load_local_directory(dlg_main); break; case HSFTP_RECURS_USR_EV_FOLDER_UPLOAD_FAILED: recursive_operation_in_progress = FALSE; sprintf(str, "Recursive Folder Upload: Failed (RC=%u) (core ev=%u) Requesting remote listing..", arg1, arg2); PutLog(dlg_main, str); if (check_recursive_close_event(arg2)) break; rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HSFTP_RECURS_USR_EV_FOLDER_DELETE_DONE: recursive_operation_in_progress = FALSE; PutLog(dlg_main, "Recursive Folder Delete: Success. Requesting remote listing.."); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HSFTP_RECURS_USR_EV_FOLDER_DOWNLOAD_DONE: recursive_operation_in_progress = FALSE; PutLog(dlg_main, "Recursive Folder Download: Success."); load_local_directory(dlg_main); break; case HSFTP_RECURS_USR_EV_FOLDER_UPLOAD_DONE: recursive_operation_in_progress = FALSE; PutLog(dlg_main, "Recursive Folder Upload: Success. Requesting remote listing.."); rc = HsFtpCliList(ftp_session); log_ftp_result(rc); break; case HSFTP_RECURS_USR_EV_FOLDER_DELETE_STATUS: if (arg2 == HSFTP_OP_START) { sprintf(str, "Recursive Folder Delete: Deleting: %s", (unsigned char *)arg1); PutLog(dlg_main, str); } else { PutLog(dlg_main, "Recursive Folder Delete: item deleted"); } break; case HSFTP_RECURS_USR_EV_FOLDER_DOWNLOAD_STATUS: if (arg2 == HSFTP_OP_START) { sprintf(str, "Recursive Folder Download: Downloading: %s", (unsigned char *)arg1); PutLog(dlg_main, str); } else { PutLog(dlg_main, "Recursive Folder Download: item downloaded"); } break; case HSFTP_RECURS_USR_EV_FOLDER_UPLOAD_STATUS: if (arg2 == HSFTP_OP_START) { sprintf(str, "Recursive Folder Upload: Uploading: %s", (unsigned char *)arg1); PutLog(dlg_main, str); } else { PutLog(dlg_main, "Recursive Folder Upload: item uploaded"); } break; case HSFTP_RECURS_USR_EV_FOLDER_PROGRESS: SendMessage(GetDlgItem(dlg_main, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)arg1, 0); break; } } void DlgCmdRecursiveDeleteFolder(HWND hDlg) { unsigned char str[300]; int rc; if (state != APP_STATE_CONNECTED) return; if (recursive_operation_in_progress) return; if (!GetSelectedFilename(IDC_LIST_RFS, editstr, sizeof (editstr), &remote_fsz, rtype)) return; if (!ShowYNDialog(dlg_main, "Recursive Delete Folder", "Okay to Delete Folder and all contents?", RED, TRUE, FALSE)) return; sprintf(str, "Recursive Deleting Folder..%s", editstr); PutLog(hDlg, str); if (strlen(editstr) == 0) return; recursive_operation_in_progress = TRUE; rc = HsFtpRecursDeleteFolder(ftp_session, editstr); if (rc != HSFTP_RECURS_RC_OK) { sprintf(str, "Recursive folder delete failed (RC=%u)", rc); PutLog(hDlg, str); recursive_operation_in_progress = FALSE; } } /* recursively doanload folder and all subfolders and files */ void DlgCmdRecursiveDownloadFolder(HWND hDlg) { unsigned char str[300]; int rc; if (state != APP_STATE_CONNECTED) return; if (recursive_operation_in_progress) return; if (!GetSelectedFilename(IDC_LIST_RFS, editstr, sizeof (editstr), &remote_fsz, rtype)) return; if (!ShowYNDialog(dlg_main, "Recursive Download Folder", "Okay to Download Folder and all contents?", RED, TRUE, TRUE)) return; sprintf(str, "Recursive Downloading Folder..%s", editstr); PutLog(hDlg, str); if (strlen(editstr) == 0) return; recursive_operation_in_progress = TRUE; rc = HsFtpRecursDownloadFolder(ftp_session, editstr, overwrite); if (rc != HSFTP_RECURS_RC_OK) { sprintf(str, "Recursive folder download failed (RC=%u)", rc); PutLog(hDlg, str); recursive_operation_in_progress = FALSE; } } /* recursively upload folder and all subfolders and files */ void DlgCmdRecursiveUploadFolder(HWND hDlg) { unsigned char str[300]; int rc; if (state != APP_STATE_CONNECTED) return; if (recursive_operation_in_progress) return; if (!GetSelectedFilename(IDC_LIST_LFS, editstr, sizeof (editstr), &remote_fsz, rtype)) return; if (!ShowYNDialog(dlg_main, "Recursive Upload Folder", "Okay to Upload Folder and all contents?", RED, TRUE, FALSE)) return; sprintf(str, "Recursive Uploading Folder..%s", editstr); PutLog(hDlg, str); if (strlen(editstr) == 0) return; recursive_operation_in_progress = TRUE; rc = HsFtpRecursUploadFolder(ftp_session, editstr); if (rc != HSFTP_RECURS_RC_OK) { sprintf(str, "Recursive folder upload failed (RC=%u)", rc); PutLog(hDlg, str); recursive_operation_in_progress = FALSE; } } /* load configuration */ static void load_config(unsigned char *cfg_filename, hstftp_app_cfg_t *cfg) { FILE *fd; getcwd(start_dir, sizeof(start_dir)); fd = fopen(cfg_filename,"r+b"); if (!fd) { if (!fd) return; } fread(cfg, (sizeof (hstftp_app_cfg_t)) , 1, fd); fclose(fd); memset(server_name, 0, sizeof (server_name)); memcpy(server_name, cfg->server_name, sizeof(cfg->server_name)); memset(username, 0, sizeof (username)); memcpy(username, cfg->username, sizeof (cfg->username)); memset(password, 0, sizeof (password)); memcpy(password, cfg->password, sizeof (cfg->password)); T1 = (UINT)cfg->t1_timeout; if (T1 == 0) T1 = 15000; } /* save configuration */ static void save_config(unsigned char *cfg_filename, hstftp_app_cfg_t *cfg) { FILE *fd; chdir(start_dir); fd = fopen(cfg_filename,"r+b"); if (!fd) { fd = fopen(cfg_filename,"w+b"); if (!fd) return; } memset(cfg, 0, sizeof (hstftp_app_cfg_t)); memcpy(cfg->server_name, server_name, sizeof(cfg->server_name)); memcpy(cfg->username, username, sizeof (cfg->username)); memcpy(cfg->password, password, sizeof (cfg->password)); cfg->t1_timeout = (long)T1; fwrite(cfg, (sizeof (hstftp_app_cfg_t)) , 1, fd); fclose(fd); } /* * Main dialog handler */ LRESULT CALLBACK DlgWin(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT result = FALSE; char windir[_MAX_PATH] = {0}; char expl_path[_MAX_PATH] = {0}; int wmId; HINSTANCE dllhinst; HICON hIcon; unsigned char s[_MAX_PATH]; int rc; switch (message) { case WM_INITDIALOG: SendDlgItemMessage(hDlg, IDC_RADIO_NAME, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hDlg, IDC_EDIT_NAME, EM_LIMITTEXT, MAX_SRVNAME, 0); SendDlgItemMessage(hDlg, IDC_EDIT_PORT, EM_LIMITTEXT, 5, 0); SendDlgItemMessage(hDlg, IDC_EDIT_USER, EM_LIMITTEXT, (sizeof username) -1, 0); SendDlgItemMessage(hDlg, IDC_EDIT_PW, EM_LIMITTEXT, (sizeof password) -1, 0); SetDlgItemInt(hDlg, IDC_EDIT_PORT, ip_port, FALSE); SetDlgItemText(hDlg, IDC_EDIT_NAME, server_name); SetDlgItemText(hDlg, IDC_EDIT_USER, username); SetDlgItemText(hDlg, IDC_EDIT_PW, password); SetDlgItemInt(hDlg, IDC_EDIT_T1, (UINT)T1, FALSE); SendDlgItemMessage(hDlg, IDC_STATIC_CM, WM_SETTEXT, 0, (long)commercial_msg); himgList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 , 4, 4); ImageList_SetBkColor(himgList, GetSysColor(COLOR_WINDOW)); ListView_SetImageList(GetDlgItem(hDlg, IDC_LIST_LFS), himgList, LVSIL_SMALL); ListView_SetImageList(GetDlgItem(hDlg, IDC_LIST_RFS), himgList, LVSIL_SMALL); dllhinst = LoadLibrary("shell32.dll"); hIcon = LoadIcon(dllhinst, MAKEINTRESOURCE(5)); index = ImageList_AddIcon(himgList, hIcon); FreeLibrary(dllhinst); InitLVlog(GetDlgItem(hDlg, IDC_LIST_LOG)); InitLV(GetDlgItem(hDlg, IDC_LIST_RFS)); InitLV(GetDlgItem(hDlg, IDC_LIST_LFS)); load_local_directory(hDlg); write_status(hDlg, GREEN, "Not Connected"); PutLog(hDlg, "Initialised HS FTP C Source Library (Client)"); return TRUE; case WM_CTLCOLORSTATIC: if ((HWND)lParam == GetDlgItem(hDlg, IDC_STATIC_CM)) { SetTextColor((HDC)wParam, BLUE); SetBkColor ((HDC)wParam, WHITE); result = (long)hbrush1; } else if ((HWND)lParam == GetDlgItem(hDlg, IDC_STATIC_STATUS)) { SetTextColor((HDC)wParam, color); SetBkColor ((HDC)wParam, WHITE); result = (long)hbrush1; } else if (((HWND)lParam == GetDlgItem(hDlg, IDC_STATIC_LFS)) || ((HWND)lParam == GetDlgItem(hDlg, IDC_STATIC_RFS)) || ((HWND)lParam == GetDlgItem(hDlg, IDC_STATIC_BYTE_TX)) || ((HWND)lParam == GetDlgItem(hDlg, IDC_STATIC_BYTE_RX))) { SetTextColor((HDC)wParam, 0); SetBkColor ((HDC)wParam, WHITE); result = (long)hbrush1; } break; case WM_NOTIFY: wmId = (int)(wParam); switch (wmId) { case IDC_LIST_LFS: switch (((LPNMHDR)lParam)->code) { case NM_DBLCLK: if (!GetSelectedFilename(IDC_LIST_LFS, s, sizeof (s), &local_fsz, ltype)) break; if (!chdir(s)) { load_local_directory(hDlg); } break; } break; case IDC_LIST_RFS: switch (((LPNMHDR)lParam)->code) { case NM_DBLCLK: if (!GetSelectedFilename(IDC_LIST_RFS, s, sizeof (s), &remote_fsz, rtype)) break; rc = HsFtpCliChDir(ftp_session, s); log_ftp_result(rc); break; } break; } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BUTTON_CONN: DlgCmdConnect(hDlg); break; case IDC_BUTTON_DISC: DlgCmdDisconnect(hDlg); break; case IDC_BUTTON_GET: DlgCmdGetFile(hDlg); break; case IDC_BUTTON_SEND: DlgCmdPutFile(hDlg); break; case IDC_BUTTON_ABORT: DlgCmdAbort(hDlg); break; case IDC_BUTTON_MKDIR: DlgCmdMakeDir(hDlg); break; case IDC_BUTTON_RMDIR: DlgCmdRmDir(hDlg); break; case IDC_BUTTON_DELE: DlgCmdDele(hDlg); break; case IDC_BUTTON_NOOP: DlgCmdNoop(hDlg); break; case IDC_BUTTON_GETDIR: DlgCmdGetCurrDir(hDlg); break; case IDC_BUTTON_RENAME: DlgCmdRename(hDlg); break; case IDC_BUTTON_RECURS_FDEL: DlgCmdRecursiveDeleteFolder(hDlg); break; case IDC_BUTTON_RECURS_GET: DlgCmdRecursiveDownloadFolder(hDlg); break; case IDC_BUTTON_RECURS_PUT: DlgCmdRecursiveUploadFolder(hDlg); break; case IDC_BUTTON_BUY: GetWindowsDirectory(&windir[0], sizeof windir); sprintf(expl_path, "%s\\explorer.exe", windir); _spawnl( _P_NOWAIT, expl_path, BUYLINK, BUYLINK, NULL); break; case IDC_BUTTON_INFO: GetWindowsDirectory(&windir[0], sizeof windir); sprintf(expl_path, "%s\\explorer.exe", windir); _spawnl( _P_NOWAIT, expl_path, INFOLINK, INFOLINK, NULL); break; } break; } return result; } void ProcessMainMenu(HWND hWnd, WORD id) { char windir[_MAX_PATH] = {0}; char expl_path[_MAX_PATH] = {0}; switch(id) { case ID_FILE_CONNECT: DlgCmdConnect(dlg_main); break; case ID_FILE_DISCONNECT: DlgCmdDisconnect(dlg_main); break; case ID_TRANSFER_SENDFILE: DlgCmdPutFile(dlg_main); break; case ID_TRANSFER_GETFILE: DlgCmdGetFile(dlg_main); break; case ID_TOOLS_DELETEFILE: DlgCmdDele(dlg_main); break; case ID_TOOLS_UPLOADFOLDER: DlgCmdRecursiveUploadFolder(dlg_main); break; case ID_TOOLS_DOWNLOADFOLDER: DlgCmdRecursiveDownloadFolder(dlg_main); break; case ID_TOOLS_DELETEFOLDER: DlgCmdRecursiveDeleteFolder(dlg_main); break; case ID_TOOLS_CREATEDIRECTORY: DlgCmdMakeDir(dlg_main); break; case ID_TOOLS_REMOVEDIRECTORY: DlgCmdRmDir(dlg_main); break; case ID_TOOLS_GETCURRENTPATHNAME: DlgCmdGetCurrDir(dlg_main); break; case ID_TOOLS_RENAMEFILEORDIRECTORY: DlgCmdRename(dlg_main); break; case ID_TOOLS_NOOPERATIONNOOP: DlgCmdNoop(dlg_main); break; case ID_TRANSFER_ABORT: DlgCmdAbort(dlg_main); break; case ID_ABOUT_ABOUTHSFTP: GetWindowsDirectory(&windir[0], sizeof windir); sprintf(expl_path, "%s\\explorer.exe", windir); _spawnl( _P_NOWAIT, expl_path, INFOLINK, INFOLINK, NULL); break; case ID_ABOUT_BUYONLINE: GetWindowsDirectory(&windir[0], sizeof windir); sprintf(expl_path, "%s\\explorer.exe", windir); _spawnl( _P_NOWAIT, expl_path, BUYLINK, BUYLINK, NULL); break; case ID_EXIT: DestroyWindow(hWnd); break; } } /* * Main window message handler */ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static INITCOMMONCONTROLSEX icex; switch (message) { case WM_CREATE: icex.dwSize = sizeof(icex); icex.dwICC = ICC_DATE_CLASSES; InitCommonControlsEx(&icex); InitCommonControls(); load_config(CONFIG_FILENAME, &cfg); dlg_main = NewDialogWin(hInst, hWnd, DlgWin, IDD_DIALOG_MAIN); break; case WM_COMMAND: ProcessMainMenu(hWnd, LOWORD(wParam)); break; case WM_MOVE: break; case WM_DESTROY: if (hbrush1) { SelectObject(GetWindowDC(hWnd), hbrush1); DeleteObject(hbrush1); } save_config(CONFIG_FILENAME, &cfg); HsFtpCleanUp(); HsFtpRecurseCleanUp(); ImageList_Destroy(himgList); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } /* * Init Application Instance */ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, HWND *hwnd) { HWND hWnd; hInst = hInstance; hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPED | WS_SYSMENU, 0, 0, MAINWIDTH, MAINDEPTH, NULL, 0/*LoadMenu(hInstance, (LPCTSTR)IDR_MENU1)*/, hInstance, NULL); if (!hWnd) { return FALSE; } *hwnd = hWnd; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } /* undate stats */ static void update_stats(void) { hsftp_stats_t stats = {0}; unsigned char str[100]; DWORD now; now = GetTickCount(); if(now - stats_start_tick >= STATS_UPDATE_INTERVAL_MS) { stats_start_tick = now; HsFtpGetStats(&stats); if (memcmp(&stats, &last_stats, sizeof (hsftp_stats_t)) == 0) return; memcpy(&last_stats, &stats, sizeof (hsftp_stats_t)); sprintf(str, "%I64d", stats.total_bytes_Tx); SetDlgItemText(dlg_main, IDC_STATIC_BYTE_TX, str); sprintf(str, "%I64d", stats.total_bytes_Rx); SetDlgItemText(dlg_main, IDC_STATIC_BYTE_RX, str); } } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; HACCEL hAccelTable; hs_ftp_config_t cfg = {0}; hbrush1 = CreateSolidBrush(RGB(255, 255, 255)); BlRegisterClass(hInstance, CS_HREDRAW | CS_VREDRAW, WndProc, (int)IDC_ARROW, (HBRUSH)(COLOR_APPWORKSPACE+1), szWindowClass, IDI_ICON1, IDR_MENU1); if (!InitInstance (hInstance, nCmdShow, &hwnd_main)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)0); HsFtpInit(); cfg.t1_timeout = (long)T1; HsFtpSetConfig(&cfg); HsFtpRecursInit(hsftp_recursive_callback); stats_start_tick = GetTickCount(); while (1) { if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } else { break; } } else { HsFtpTick(); HsFtpRecursTick(); Sleep(1); update_stats(); } } return msg.wParam; }