|
RouteTrak API
|
The steps to operate the engine are:
// RTEngineTestDlg.h : header file // #if !defined(AFX_RTENGINETESTDLG_H__54FF921E_41FB_430F_A68B_94FA4FE08B4D__INCLUDED_) #define AFX_RTENGINETESTDLG_H__54FF921E_41FB_430F_A68B_94FA4FE08B4D__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #include "gpsapi.h" #include "compass.h" #include "RTEngine.h" #define WM_STARTGPS (WM_USER + 1) #define ICON_GPS_GOOD 0 #define ICON_GPS_OFF 1 #define ICON_GPS_BAD 2 #define ICON_GPS_MEDIUM 3 #define NO_TIME_CHANGE_LIMIT 10 ///////////////////////////////////////////////////////////////////////////// // CRTEngineTestDlg dialog class CRTEngineTestDlg : public CDialog, CRTEngine { // Construction public: CRTEngineTestDlg(CWnd* pParent = NULL); // standard constructor private: DWORD m_dwNetworkPort; DWORD m_dwTimerCount; DWORD m_dwNoTimeChangeCount; CString m_strMacAddress; CString m_strPort; long m_lBaud; void LoadSettings(); BOOL StartTheGPS(); void SetStatus(LPCTSTR lpszStatus); BOOL TransferToServer(LPCTSTR lpszPath, LPCTSTR lpszURL, LPCTSTR lpszFolder, LPCTSTR lpszUser, LPCTSTR lpszPassword); void OnRTDataChanged(PRTGPSDATA pData); void OnRTDataSaved(DWORD dwSavedRecords); BOOL OnRTLogDataRecord(GPSLOGGER_RECORD * pglrLogData); BOOL OnRTGetExtendedDataRecord(LPBYTE pbExtendedData, DWORD dwSize); BOOL OnRTLoggerDownloadStatus(RTLOGGERDOWNLOAD rldDownload, int iPercentComplete); BOOL OnRTCancelLoggerDownload(); // Dialog Data //{{AFX_DATA(CRTEngineTestDlg) enum { IDD = IDD_RTENGINETEST_DIALOG }; CProgressCtrl m_Progress; CButton m_btnEndOfDay; CButton m_btnCancel; CString m_strStatus; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CRTEngineTestDlg) public: virtual BOOL DestroyWindow(); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; double m_dSpeed; double m_dMiles; double m_dLatitude; double m_dLongitude; double m_dHeading; GPSUTCTIME m_gutcTime; CFont m_cfNormal; CFont m_cfLarge; CRect m_rectCompass; CRect m_rectSpeed; CRect m_rectDist; CRect m_rectGPS; HICON ma_hIcons[4]; HICON m_hGpsStatus; CCompass m_Compass; CBitmap m_bmpLogo; BOOL m_fCanceled; BOOL m_fUseLogger; int m_iLoggerInterval; // Generated message map functions //{{AFX_MSG(CRTEngineTestDlg) virtual BOOL OnInitDialog(); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnPaint(); afx_msg void OnEndofday(); afx_msg void OnCanceldl(); //}}AFX_MSG LRESULT OnStartGPSMessage(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_RTENGINETESTDLG_H__54FF921E_41FB_430F_A68B_94FA4FE08B4D__INCLUDED_)
// RTEngineTestDlg.cpp : implementation file // #include "stdafx.h" #include "RTEngineTest.h" #include "RTEngineTestDlg.h" #include "RTStartDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif typedef struct { WCHAR szMacAddress[18]; GPSLOGGER_RECORD glrData; } GPSDATAMESSAGE, * PGPSDATAMESSAGE; ///////////////////////////////////////////////////////////////////////////// // CRTEngineTestDlg dialog CRTEngineTestDlg::CRTEngineTestDlg(CWnd* pParent /*=NULL*/) : CDialog(CRTEngineTestDlg::IDD, pParent) { //{{AFX_DATA_INIT(CRTEngineTestDlg) m_strStatus = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_dHeading = m_dSpeed = m_dMiles = m_dLatitude = m_dLongitude = 0; m_dwTimerCount = m_dwNoTimeChangeCount = 0; m_fCanceled = FALSE; memset(&m_gutcTime, 0, sizeof(m_gutcTime)); // Load the default settings LoadSettings(); } void CRTEngineTestDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CRTEngineTestDlg) DDX_Control(pDX, IDC_PROGRESS, m_Progress); DDX_Control(pDX, IDC_ENDOFDAY, m_btnEndOfDay); DDX_Control(pDX, IDC_CANCELDL, m_btnCancel); DDX_Text(pDX, IDC_STATUS, m_strStatus); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CRTEngineTestDlg, CDialog) //{{AFX_MSG_MAP(CRTEngineTestDlg) ON_WM_TIMER() ON_WM_PAINT() ON_BN_CLICKED(IDC_ENDOFDAY, OnEndofday) ON_BN_CLICKED(IDC_CANCELDL, OnCanceldl) //}}AFX_MSG_MAP ON_MESSAGE(WM_STARTGPS, OnStartGPSMessage) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRTEngineTestDlg message handlers BOOL CRTEngineTestDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon CenterWindow(GetDesktopWindow()); // center to the hpc screen RTERROR rteError = RTInitialize(1); if (rteError != RTE_NONE) { if (rteError == RTE_GPS_INVALID_PORT) AfxMessageBox(TEXT("Invalid communications port or port currently in use.")); else { CString strError; strError.Format(TEXT("Error initializing GPS Library - Error %ld."), (long)rteError); AfxMessageBox(strError); EndDialog(IDCANCEL); return FALSE; } } // Set screen update timer SetTimer(1, 1000, NULL); LOGFONT lfFont; memset(&lfFont, 0, sizeof(lfFont)); lfFont.lfHeight = 25; lfFont.lfWeight = FW_BOLD; lstrcpy(lfFont.lfFaceName, TEXT("System")); m_cfLarge.CreateFontIndirect(&lfFont); memset(&lfFont, 0, sizeof(lfFont)); lfFont.lfHeight = 15; lfFont.lfWeight = FW_BOLD; lstrcpy(lfFont.lfFaceName, TEXT("System")); m_cfNormal.CreateFontIndirect(&lfFont); CRect rectForm; CRect rectBtn; GetClientRect(&rectForm); m_btnEndOfDay.GetWindowRect(&rectBtn); m_btnEndOfDay.SetWindowPos(NULL, rectForm.right - rectBtn.Width(), rectForm.bottom - rectBtn.Height(), 0, 0, SWP_NOSIZE | SWP_NOZORDER); m_btnCancel.GetWindowRect(&rectBtn); m_btnCancel.SetWindowPos(NULL, (rectForm.right - rectBtn.Width()) / 2, rectForm.bottom - rectBtn.Height(), 0, 0, SWP_NOSIZE | SWP_NOZORDER); // Hide End Of Day button m_btnEndOfDay.ShowWindow(SW_HIDE); m_rectCompass = CRect (0, 0, rectForm.right, 25); m_Compass.Create(NULL, NULL, WS_CHILD | WS_VISIBLE, m_rectCompass, this, 1); m_rectSpeed = CRect((rectForm.right / 2) + 25, m_rectCompass.bottom, rectForm.right, m_rectCompass.bottom + 32); m_rectDist = CRect((rectForm.right / 2) + 25, m_rectSpeed.bottom, rectForm.right, m_rectSpeed.bottom + 32); m_rectGPS = CRect((rectForm.right / 2) + 25, m_rectDist.bottom, rectForm.right + 57, m_rectDist.bottom + 32); // Load Icons ma_hIcons[ICON_GPS_GOOD] = AfxGetApp()->LoadIcon(IDI_GOODGPS); ma_hIcons[ICON_GPS_OFF] = AfxGetApp()->LoadIcon(IDI_BADGPS); ma_hIcons[ICON_GPS_BAD] = AfxGetApp()->LoadIcon(IDI_GPSON_BAD); ma_hIcons[ICON_GPS_MEDIUM] = AfxGetApp()->LoadIcon(IDI_GPSON_MEDIUM); m_hGpsStatus = ma_hIcons[ICON_GPS_OFF]; m_bmpLogo.LoadBitmap(IDB_LOGO); // Show Start screen PostMessage(WM_STARTGPS); return TRUE; // return TRUE unless you set the focus to a control } void CRTEngineTestDlg::OnTimer(UINT nIDEvent) { // Now lets check the current GPS Status and update things if they have changed RTGPSDATA rgdData; RTGpsGetData(&rgdData); // Did the speed change? if (fabs(rgdData.dSpeedMPH - m_dSpeed) > 0.01) { // Update it m_dSpeed = rgdData.dSpeedMPH; InvalidateRect(&m_rectSpeed); } HICON hIcon = m_hGpsStatus; switch (rgdData.gftFix) { case GPSFIX_3_SATELLITE_SOLUTION: case GPSFIX_3_PLUS_SATELLITE_SOLUTION: case GPSFIX_3D: hIcon = ma_hIcons[ICON_GPS_GOOD]; break; case GPSFIX_2_SATELLITE_SOLUTION: case GPSFIX_2D: hIcon = ma_hIcons[ICON_GPS_MEDIUM]; break; default: hIcon = ma_hIcons[ICON_GPS_BAD]; break; } if (!RTGpsActive()) hIcon = ma_hIcons[ICON_GPS_OFF]; // Did the time change? if (memcmp(&m_gutcTime, &rgdData.gutcTime, sizeof(m_gutcTime)) == 0) { // No, so lets see if we're past the no-time-change limit if (++m_dwNoTimeChangeCount > NO_TIME_CHANGE_LIMIT) { // We've lost communications with the GPS hIcon = ma_hIcons[ICON_GPS_OFF]; rgdData.gftFix = GPSFIX_UNAVAILABLE; } } else { // Copy the current time memcpy(&m_gutcTime, &rgdData.gutcTime, sizeof(m_gutcTime)); // Reset the bad count m_dwNoTimeChangeCount = 0; } // Did the fix type change? if (hIcon != m_hGpsStatus) { // Update it m_hGpsStatus = hIcon; m_dSpeed = 0; InvalidateRect(m_rectGPS); } // Did heading change? if (rgdData.dTrueHeading != m_dHeading) { // Update it m_Compass.SetHeading(rgdData.dTrueHeading); m_dHeading = rgdData.dTrueHeading; m_Compass.Invalidate(); } if (fabs(rgdData.dMiles - m_dMiles) > 0.01) { m_dMiles = rgdData.dMiles; InvalidateRect(&m_rectDist); } CDialog::OnTimer(nIDEvent); } LRESULT CRTEngineTestDlg::OnStartGPSMessage(WPARAM wParam, LPARAM lParam) { CRTStartDlg dlgStart(this); BOOL fStartPage = TRUE; while (fStartPage) { int iResult = dlgStart.DoModal(); switch (iResult) { case IDC_START: { RTSetDriverInformation(TEXT("Test Driver"), TEXT("Test Vehicle"), TEXT("Test Route")); // Reset the trip distance RTResetDistance(); // Force screen redraw UpdateWindow(); // get the latest settings LoadSettings(); // Hide End Of Day button m_btnEndOfDay.ShowWindow(SW_HIDE); // Start the GPS if (StartTheGPS()) { // Set the Bluetooth Mac Address if we have one if (!m_strMacAddress.IsEmpty()) RTSetBluetoothAddress(m_strMacAddress); // Open the log file RTERROR rteError = RTOpenLogFile(TEXT("\\RTEngineTest.log")); if (rteError == RTE_NONE) { // Are we using a logger? if (RTGetLogMode() == RTLOG_LOGGER) { // Yes, so let's see if there is any data stored DWORD dwRecords = 0; AfxGetApp()->DoWaitCursor(1); // Show some status as to what we are doing now SetStatus(TEXT("Checking logger status...")); // Setup status bar and cancel button m_btnCancel.ShowWindow(SW_SHOW); m_btnCancel.EnableWindow(TRUE); m_Progress.ShowWindow(SW_SHOW); m_Progress.SetRange(0, 100); m_Progress.SetPos(0); m_fCanceled = FALSE; // Let's see if there are any data records in the logger RTERROR rteError = RTGpsLoggerGetRecordCount(&dwRecords); // Do we have any logged data? if (dwRecords > 0) { SetStatus(TEXT("Getting previously logged data...")); // Yes, so get the previously stored logger data rteError = RTGpsLoggerGetDataRecords(); } // Only reset the logger settings if we didn't abortt the transfer if (rteError != RTE_LOGGER_DUMP_ABORTED) { SetStatus(TEXT("Ressetting logger...")); // Reset logger interval rteError = RTGpsLoggerSetInterval(m_iLoggerInterval); if (rteError != RTE_NONE) MessageBox(TEXT("Error setting logger interval.")); } // Clear the status and hide controls SetStatus(TEXT("")); m_btnCancel.ShowWindow(SW_HIDE); m_Progress.ShowWindow(SW_HIDE); AfxGetApp()->DoWaitCursor(-1); } // Show Endo Of Day button m_btnEndOfDay.ShowWindow(SW_SHOW); fStartPage = FALSE; } else { switch (rteError) { case RTE_INVALID_PARAMETER: MessageBox(TEXT("Invalid parameter passed to RTOpenLogFile()")); break; case RTE_LOG_FILE_OPEN: MessageBox(TEXT("Unable to open the log file.")); break; } } } } break; case IDC_UPLOAD: TransferToServer(TEXT("\\"), TEXT("murray.corp.linkspoint.com"), TEXT("RouteTrak"), NULL, NULL); break; case ID_APP_EXIT: PostMessage(WM_CLOSE); fStartPage = FALSE; break; default: // unknow result so stay on the Start screen fStartPage = FALSE; } } return 0; } void CRTEngineTestDlg::OnPaint() { CPaintDC dc(this); // device context for painting CString str; CFont *pOldFont = dc.SelectObject(&m_cfLarge); if (m_hGpsStatus == ma_hIcons[ICON_GPS_OFF]) str = TEXT("N/A"); else str.Format(TEXT("%.2lf"), m_dSpeed); dc.DrawText(str, m_rectSpeed,DT_VCENTER |DT_LEFT | DT_NOCLIP | DT_SINGLELINE ); str.Format(TEXT("%.2lf"), m_dMiles); dc.DrawText(str, m_rectDist,DT_VCENTER |DT_LEFT | DT_NOCLIP | DT_SINGLELINE ); dc.SelectObject(&m_cfNormal); CRect rectClient = CRect(5, m_rectSpeed.top, m_rectSpeed.left, m_rectSpeed.bottom); dc.DrawText(L"Speed (MPH):", rectClient,DT_VCENTER |DT_LEFT | DT_NOCLIP | DT_SINGLELINE ); rectClient = CRect(5, m_rectDist.top, m_rectDist.left, m_rectDist.bottom); dc.DrawText(L"Miles:", rectClient,DT_VCENTER |DT_LEFT | DT_NOCLIP | DT_SINGLELINE ); rectClient = CRect(5, m_rectGPS.top, m_rectGPS.left, m_rectGPS.bottom); dc.DrawText(L"GPS:", rectClient,DT_VCENTER |DT_LEFT | DT_NOCLIP | DT_SINGLELINE ); dc.DrawIcon(m_rectGPS.TopLeft(), m_hGpsStatus); // Draw the company logo CDC dcTmp; BITMAP bm; GetClientRect(&rectClient); dcTmp.CreateCompatibleDC(&dc); CBitmap * pbmpOld = dcTmp.SelectObject(&m_bmpLogo); m_bmpLogo.GetBitmap(&bm); dc.BitBlt((rectClient.Width() - bm.bmWidth) / 2, m_rectGPS.top + 50, bm.bmWidth, bm.bmHeight, &dcTmp, 0, 0, SRCCOPY); dcTmp.SelectObject(pbmpOld); dc.SelectObject(pOldFont); dcTmp.DeleteDC(); // Do not call CDialog::OnPaint() for painting messages } BOOL CRTEngineTestDlg::StartTheGPS() { int iPort; _stscanf(m_strPort, _T("COM%d:"), &iPort); RTGpsConfigure(iPort, m_lBaud, GPSPROTOCOL_NMEA, GPSRECEIVER_EMTAC); // Set the logger mode RTSetLogMode(m_fUseLogger ? RTLOG_LOGGER : RTLOG_LIVE); // Clear the status SetStatus(TEXT("Connecting to the GPS...")); // Now start the GPS RTERROR rteError = RTGpsStart(); if (rteError != RTE_NONE) { if (rteError == RTE_GPS_INVALID_PORT) MessageBox(TEXT("Invalid communications port.")); else MessageBox(TEXT("Error starting GPS.")); // Bring up the settings dialog to choose another device PostMessage(WM_COMMAND, IDC_SETTINGS, 0); } AfxGetApp()->DoWaitCursor(-1); // Clear the status SetStatus(TEXT("")); return rteError == RTE_NONE; } void CRTEngineTestDlg::LoadSettings() { m_strPort = AfxGetApp()->GetProfileString(TEXT("GPS"), TEXT("Port"), TEXT("COM1:")); m_lBaud = AfxGetApp()->GetProfileInt(TEXT("GPS"), TEXT("Baud"), 4800); m_fUseLogger = (BOOL) AfxGetApp()->GetProfileInt(TEXT("GPS"), TEXT("UseLogger"), 0); m_iLoggerInterval = AfxGetApp()->GetProfileInt(TEXT("GPS"), TEXT("Interval"), 0); } void CRTEngineTestDlg::SetStatus(LPCTSTR lpszStatus) { CWnd * pwndStatus = GetDlgItem(IDC_STATUS); if (pwndStatus) { pwndStatus->SetWindowText(lpszStatus); pwndStatus->Invalidate(); pwndStatus->UpdateWindow(); } } BOOL CRTEngineTestDlg::DestroyWindow() { KillTimer(1); RTTerminate(); return CDialog::DestroyWindow(); } void CRTEngineTestDlg::OnRTDataChanged(PRTGPSDATA pData) { TRACE2("Data Changed - Lat: %lf, Lon: %lf\r\n", pData->gpPosition.dLatitude, pData->gpPosition.dLongitude); } void CRTEngineTestDlg::OnRTDataSaved(DWORD dwSavedRecords) { TRACE1("Record %lu saved\r\n", dwSavedRecords); } void CRTEngineTestDlg::OnEndofday() { AfxGetApp()->DoWaitCursor(1); if (RTGetLogMode() == RTLOG_LOGGER) { DWORD dwRecords = 0; // Disable End of Day button m_btnEndOfDay.ShowWindow(SW_HIDE); // Show some status as to what we are doing now SetStatus(TEXT("Checking logger status...")); RTERROR rteError = RTGpsLoggerGetRecordCount(&dwRecords); if (dwRecords == 0) MessageBox(TEXT("No records have been logged.")); else { SetStatus(TEXT("Getting previously logged data...")); m_btnCancel.ShowWindow(SW_SHOW); m_btnCancel.EnableWindow(TRUE); m_Progress.ShowWindow(SW_SHOW); m_Progress.SetRange(0, 100); m_Progress.SetPos(0); m_fCanceled = FALSE; rteError = RTGpsLoggerGetDataRecords(); m_btnCancel.ShowWindow(SW_HIDE); m_Progress.ShowWindow(SW_HIDE); } SetStatus(TEXT("Resetting data logger...")); // Reset logger interval to 60 seconds rteError = RTGpsLoggerSetInterval(60); if (rteError != RTE_NONE) MessageBox(TEXT("Error setting logger interval.")); } SetStatus(TEXT("Stopping GPS...")); // Stop the GPS RTGpsStop(); SetStatus(TEXT("Closing log file...")); // Close the current log file RTCloseLogFile(); SetStatus(TEXT("")); AfxGetApp()->DoWaitCursor(-1); // Go back to start screen PostMessage(WM_STARTGPS); } BOOL CRTEngineTestDlg::OnRTLogDataRecord(GPSLOGGER_RECORD * pglrLogData) { // Just allow base class to handle any data filtering for now return CRTEngine::OnRTLogDataRecord(pglrLogData); } BOOL CRTEngineTestDlg::OnRTGetExtendedDataRecord(LPBYTE pbExtendedData, DWORD dwSize) { return TRUE; } BOOL CRTEngineTestDlg::OnRTLoggerDownloadStatus(RTLOGGERDOWNLOAD rldDownload, int iPercentComplete) { switch (rldDownload) { case RTLOGGERDOWNLOAD_START: // Show the progress bar and cancel button TRACE0("Starting Logger Download...\r\n"); break; case RTLOGGERDOWNLOAD_STATUS: // Update the latest status TRACE1("Logger Download %d%% complete...\r\n", iPercentComplete); m_Progress.SetPos(iPercentComplete); break; case RTLOGGERDOWNLOAD_COMPLETE: // We're done so hide the status and cancel windows TRACE0("Logger download complete.\r\n"); break; } return TRUE; } BOOL CRTEngineTestDlg::OnRTCancelLoggerDownload() { return m_fCanceled; } void CRTEngineTestDlg::OnCanceldl() { // Cancel the download m_btnCancel.EnableWindow(FALSE); m_fCanceled = TRUE; } BOOL CRTEngineTestDlg::TransferToServer(LPCTSTR lpszPath, LPCTSTR lpszURL, LPCTSTR lpszFolder, LPCTSTR lpszUser, LPCTSTR lpszPassword) { if (!lpszURL) return FALSE; WIN32_FIND_DATA fdFind; HANDLE hFind = INVALID_HANDLE_VALUE; BOOL fRet = TRUE; CString strFromFile; HINTERNET hInternet = InternetOpen(TEXT("RouteTrakFTP"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); if (hInternet == NULL) return FALSE; CString strFromDirectory = lpszPath; hFind = FindFirstFile(strFromDirectory + CString(TEXT("*.log")), &fdFind); if (hFind != INVALID_HANDLE_VALUE) { TRACE1("Connecting to %s...", lpszURL); // Get a connection to the server HINTERNET hConnect = InternetConnect(hInternet, lpszURL, INTERNET_DEFAULT_FTP_PORT, lpszUser, lpszPassword, INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE | INTERNET_FLAG_DONT_CACHE, 1); if (hConnect) { BOOL fResult = TRUE; char *pBuffer = new char [4096]; TRACE0("connected\r\n"); // Change directories if applicable if (lpszFolder) { TRACE1("Changing to folder %s...", lpszFolder); fResult = FtpSetCurrentDirectory(hConnect, lpszFolder); TRACE1("%s\r\n", fResult ? TEXT("succeeded") : TEXT("failed")); } while (fResult) { strFromFile.Format(_T("%s%s"), strFromDirectory, fdFind.cFileName); TRACE1("Opening file %s for transfer...", strFromFile); HANDLE hData = CreateFile(strFromFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hData != INVALID_HANDLE_VALUE) { CString strDestFilename; BOOL fUploaded = TRUE; TRACE0("succeeded\r\n"); CTime ctTime = CTime::GetCurrentTime(); CString strFilename = fdFind.cFileName; int iIndex = strFilename.Find('.', 0); if (iIndex != -1) strFilename = strFilename.Left(iIndex); strDestFilename.Format(_T("%s%02d%02d%02d%02d%02d%02d.log"), strFilename, ctTime.GetMonth(), ctTime.GetDay(), ctTime.GetYear(), ctTime.GetHour(), ctTime.GetMinute(), ctTime.GetSecond()); TRACE1("Creating file %s on server...", strDestFilename); HANDLE hFile = FtpOpenFile(hConnect, strDestFilename, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_NO_CACHE_WRITE, 1); if (hFile) { DWORD dwRead = 0; DWORD dwTotalBytes = 0; TRACE0("succeeded\r\n"); do { if (ReadFile(hData, pBuffer, 4096, &dwRead, NULL)) { DWORD dwWritten = 0; if (dwRead > 0) { if (InternetWriteFile(hFile, pBuffer, dwRead, &dwWritten)) dwTotalBytes += dwWritten; else fUploaded = FALSE; } } else fUploaded = FALSE; } while (dwRead == 4096); // Close the remote file InternetCloseHandle(hFile); TRACE1("Transferred %lu bytes to server\r\n", dwTotalBytes); } else { TRACE0("failed\r\n"); } // Close the local file CloseHandle(hData); // File has been uploaded so let's delete it if (fUploaded) DeleteFile(strFromFile); } else TRACE0("failed\r\n"); fResult = FindNextFile(hFind, &fdFind); } // Close the remote connection InternetCloseHandle(hConnect); // Free the buffer delete [] pBuffer; } else { TRACE0("failed\r\n"); fRet = FALSE; } } else fRet = FALSE; // Close the handle InternetCloseHandle(hInternet); return fRet; }