I used the WinInet Ftp Function on both desktop and CE .NET (AGX), and I found the "InternetReadFile" function can hang under CE .NET (AGX) OS image. Since it's the Windows API function hangs, I don't have a way to recover it.
The only FTP server that I can make it work is the IIS 3.0. All FTP server works fine with FTP WinInet functions under desktop.
Not sure why?
regards,
William
Here is the source code that I'm using:
#include "Wininet.h"
#define LOCALROOTDIR TEXT("\\FlashFX Disk\\Content")
BOOL FtpRecursiveGetFile (HINTERNET hFtp, TCHAR *localDir)
{
TCHAR currentDirecotry[255];
DWORD dwLen=255;
if ( FtpGetCurrentDirectory (hFtp, currentDirecotry,&dwLen) == FALSE)
{
// current directory failed
return FALSE;
}
// we store current directory
TCHAR thePendingSubFolders[10][128];
int i=0, pendingSubFolderCnt=0;
for(i=0; i<10; i++)
{
memset (thePendingSubFolders[i],0,sizeof(thePendingSubFolders[i]));
}
WIN32_FIND_DATA swFD;
TCHAR myFileName[512];
HINTERNET hFile = FtpFindFirstFile (hFtp, TEXT("*"), &swFD, 0, 0);
BOOL success = FALSE;
// local file and directory
HANDLE myFileHandle;
WIN32_FIND_DATA myFileData;
TCHAR localDirectory[512];
memset (localDirectory,0,sizeof(localDirectory));
wcscpy (localDirectory, localDir);
if (hFile != 0)
{
if (swFD.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
RETAILMSG(1,(TEXT("Get Directory: %s\r\n"), swFD.cFileName));
wcscpy (thePendingSubFolders[pendingSubFolderCnt++], swFD.cFileName);
}
else
{
wsprintf (myFileName,TEXT("%s\\%s"),localDirectory,swFD.cFileName);
HINTERNET hOpenFile = FtpOpenFile (hFtp, swFD.cFileName, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 0);
if (hOpenFile != NULL)
{
TCHAR myFileBuf[2048];
DWORD actualRead, actualWrite;
HANDLE myOpenFile = CreateFile (myFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (myOpenFile != INVALID_HANDLE_VALUE)
{
for(;;)
{
if (InternetReadFile (hOpenFile, myFileBuf, 2000, &actualRead) == TRUE)
{
/*!!!!!!!!
InternetReadFile can hangs without returning when download multiple files around 20KB each
*/
if (actualRead > 0)
{
RETAILMSG(1,(TEXT("Write File: %s Bytes %d\r\n"), myFileName, actualRead));
WriteFile (myOpenFile, myFileBuf, actualRead, &actualWrite, NULL);
}
else
{
RETAILMSG(1,(TEXT("No More Read: %s\r\n"), myFileName));
break;
}
}
else
{
RETAILMSG(1,(TEXT("File Read Error: %s\r\n"), myFileName));
break;
}
}
// close it
CloseHandle (myOpenFile);
}
// finally close it
InternetCloseHandle (hOpenFile);
}
}
for(;;)
{
// walk through
if (InternetFindNextFile (hFile, &swFD) == FALSE)
{
DWORD dwErr = GetLastError ();
if (dwErr == ERROR_NO_MORE_FILES)
{
// test only
RETAILMSG (1,(TEXT("No More File: %d\r\n"), dwErr));
break;
}
else
{
// test only
RETAILMSG (1,(TEXT("Unknown Error: %d\r\n"), dwErr));
}
}
else
{
if (swFD.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
RETAILMSG(1,(TEXT("Get Directory: %s\r\n"), swFD.cFileName));
wcscpy (thePendingSubFolders[pendingSubFolderCnt++], swFD.cFileName);
}
else
{
// file is still valid
wsprintf (myFileName,TEXT("%s\\%s"),localDirectory,swFD.cFileName);
HINTERNET hOpenFile = FtpOpenFile (hFtp, swFD.cFileName, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 0);
if (hOpenFile != NULL)
{
TCHAR myFileBuf[2048];
DWORD actualRead, actualWrite;
HANDLE myOpenFile = CreateFile (myFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (myOpenFile != INVALID_HANDLE_VALUE)
{
for(;;)
{
RETAILMSG(1,(TEXT("Starting Read: %s\r\n"), swFD.cFileName));
if (InternetReadFile (hOpenFile, myFileBuf, 2000, &actualRead) == TRUE)
{
if (actualRead > 0)
{
RETAILMSG(1,(TEXT("Write File: %s Bytes %d\r\n"), myFileName, actualRead));
WriteFile (myOpenFile, myFileBuf, actualRead, &actualWrite, NULL);
}
else
{
RETAILMSG(1,(TEXT("No More Read: %s\r\n"), myFileName));
break;
}
}
else
{
RETAILMSG(1,(TEXT("File Read Error: %s\r\n"), myFileName));
break;
}
Sleep (100); /////Sleep (500);
}
// close it
CloseHandle (myOpenFile);
}
// finally close it
InternetCloseHandle (hOpenFile);
}
Sleep (1000);
}
}
}
// close this connection
InternetCloseHandle (hFile);
}
// check the pending subfolders
for (i=0; i {
if (thePendingSubFolders[i][0] != 0)
{
// a pending subfolder
if (FtpSetCurrentDirectory (hFtp, thePendingSubFolders[i]) == TRUE)
{
// set the local dirrectory too
TCHAR myNewLocalDir[512];
wsprintf (myNewLocalDir,TEXT("%s\\%s"),localDirectory,thePendingSubFolders[i]);
myFileHandle = FindFirstFile (myNewLocalDir, &myFileData);
if (myFileHandle != INVALID_HANDLE_VALUE)
{
FindClose (myFileHandle);
}
else
{
// create this directory
if ( CreateDirectory (myNewLocalDir, NULL) == FALSE)
{
}
}
FtpRecursiveGetFile (hFtp, myNewLocalDir);
if (FtpSetCurrentDirectory (hFtp, currentDirecotry) == FALSE)
{
// can't recover
return FALSE;
}
}
}
else
{
break;
}
}
return TRUE;
}
bool DMDownloadFiles (TCHAR *remDir, TCHAR *localDir, TCHAR *remHost, TCHAR *user, TCHAR *password)
{
// open the FTP session
HINTERNET hInet = InternetOpen (TEXT("DMAPP"), INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0);
if (hInet != 0)
{
BOOL success=FALSE;
HINTERNET hFtp = InternetConnect (hInet, remHost,
INTERNET_DEFAULT_FTP_PORT, user, password, INTERNET_SERVICE_FTP, 0, 0);
if (hFtp != 0)
{
// set current directory based on the given information
FtpSetCurrentDirectory (hFtp, remDir);
// check local directory
HANDLE myFileHandle;
WIN32_FIND_DATA myFileData;
myFileHandle = FindFirstFile (localDir, &myFileData);
if (myFileHandle != INVALID_HANDLE_VALUE)
{
FindClose (myFileHandle);
}
else
{
// create this directory
if ( CreateDirectory (localDir, NULL) == FALSE)
{
}
}
success = FtpRecursiveGetFile (hFtp, localDir);
InternetCloseHandle (hFtp);
}
InternetCloseHandle (hInet);
return (success==TRUE);
}
return false;
}
void FtpTest()
{
RETAILMSG (1,(TEXT("FTP Starts...\r\n")));
if ( DMDownloadFiles (TEXT("Content"), LOCALROOTDIR, TEXT("192.168.10.10"),
TEXT("anonymous"), TEXT("anonymous")) == true)
{
// ftp success
RETAILMSG(1,(TEXT("FTP Successful!\r\n")));
}
else
{
RETAILMSG(1,(TEXT("FTP Failed!\r\n")));
}
}