15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


CFtpFileFind bug?

Gregory Nisnevich -- NisnevG@Helisys.com
Tuesday, February 04, 1997

Environment: MSVC 4.2b, Win95, WinNT

I apologize for a lengthy post but it reflects results of my little
research which
I hope may be useful for MFC users.
It all started when I just wanted to get a file from an FTP server. So
here is the code
that works:

#include 
#include 

int main()
{
	CInternetSession session("My FTP Session");
	CFtpConnection* pConn = NULL;
	int nRet = 0;

	pConn = session.GetFtpConnection
		("ftp.somewhere.com"); // Put your server name here

	CString csFileName = 
		"Test1/accesdlg.h.stub"; // Put your file here
	//get the file
	if (!pConn->GetFile(csFileName, 
		"e:\\temp\\temp.txt", FALSE))
	{
		int nErr = GetLastError();
		cout << "Error in GetFile(): " << nErr << endl;
		nRet = -1;
	}
	delete pConn;
	session.Close();
	return nRet;
}
But if the file doesn't exist you are in trouble: GetFile() will just
wait, and I've never
been patient enough to figure out for how long. Besides MFC
documentation
recommends in the article "Steps in typical FTP client application" to
use 
CFtpFileFind::FindFile() and CFtpFileFind::FindNextFile() to make sure
that the file
you need exists. So here is another code which doesn't work:

#include 
#include 

int main()
{
	CInternetSession session("My FTP Session");
	CFtpConnection* pConn = NULL;
	int nRet = 0;

	pConn = session.GetFtpConnection
		("ftp.somewhere.com"); // Put your server name here

	//find the file
	CFtpFileFind ftpFind(pConn);
	CString csFileName = 
		"Test1/accesdlg.h.stub"; // Put your file here
    	CString str;

	if (ftpFind.FindFile(csFileName) == FALSE)
	{
		cout << "File not found" << endl;
		ftpFind.Close();
		nRet = -1;
	}
	else
	{
		BOOL bContinue = TRUE;

		while(bContinue)
		{
			bContinue = ftpFind.FindNextFile();
			str = ftpFind.GetFileName();
			cout << "File" << str << "found" << endl;
		}

		ftpFind.Close();

		//get the file
		if (!pConn->GetFile(csFileName, 
			"e:\\temp\\temp.txt", FALSE))
		{
			int nErr = GetLastError();
			cout << "Error in GetFile(): " << nErr << endl;
			nRet = -1;
		}
	}
	delete pConn;
	session.Close();
	return nRet;
}

Well, it doesn't break or return an error, but the file I get, temp.txt
is always 320 bytes
long (!) and contains somewhere inside it a name of the remote file I
was trying to get.
Now, if you remove FindNextFile() call the file is fine! (Note that if
you just need one file
this can be acceptable.) 
The mysteries, however, continue. Even after you remove FindNextFile()
call, 
you are still in trouble if you want to use instead of GetFile() a set
of CFtpConnection::OpenFile(), CInternetFile::Read(),
CInternetFile::Close(). In that
case, after you use

	CInternetFile *pFile;
	pFile = pFtpConnection->OpenFile(csFileName);
	int nSize = pFile->GetLength();

nSize wil be 320!
So I think there must be something wrong with CFtpFileFind class.
Any comments will be strongly appreciated.

Gregory.



William Boyer -- wboyer@emerald.oz.net
Wednesday, February 05, 1997

I have a small program that I just check for the existance of a file. A 
form of locking mechanism. If the file exists, I won't send the control 
file. Here's the beginning of the code where I do the CFtp

	CInternetSession iSession(NULL,
				1,
				INTERNET_OPEN_TYPE_DIRECT,
				NULL,
				NULL,
				INTERNET_FLAG_DONT_CACHE);
	CFtpConnection *pFtp;

	TRY {
		//	Open an FTP session with the DHCP server
		pFtp = iSession.GetFtpConnection(pszServer,
						m_DHCPUserid,
						m_DHCPPassword,
						INTERNET_DEFAULT_FTP_PORT,
						FALSE);
	}
	CATCH (CInternetException, e1) {
		char szBuffer[256];
		e1->GetErrorMessage(szBuffer, sizeof(szBuffer), NULL);
		// Display message here....
		iSession.Close();
		return;
	}
	END_CATCH

	CFtpFileFind ff(pFtp, 9);
	BOOL bff = ff.FindFile("LockFile.*", 
INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE);
	if (bff == 1) {   // File is there!
		pFtp->Close();
		iSession.Close();
		delete pFtp;
		return;
	}

Bill Boyer
mailto:wboyer@oz.net  mailto:boyer.w@ghc.org
"Invalid or missing reality.sys -- Universe halted."

----------
From: 	Gregory Nisnevich[SMTP:NisnevG@Helisys.com]
Sent: 	Tuesday, February 04, 1997 8:33 AM
To: 	'MFL Mailing List'
Subject: 	CFtpFileFind bug?

Environment: MSVC 4.2b, Win95, WinNT

I apologize for a lengthy post but it reflects results of my little
research which
I hope may be useful for MFC users.
It all started when I just wanted to get a file from an FTP server. So
here is the code
that works:

#include 
#include 

int main()
{
	CInternetSession session("My FTP Session");
	CFtpConnection* pConn = NULL;
	int nRet = 0;

	pConn = session.GetFtpConnection
		("ftp.somewhere.com"); // Put your server name here

	CString csFileName =
		"Test1/accesdlg.h.stub"; // Put your file here
	//get the file
	if (!pConn->GetFile(csFileName,
		"e:\\temp\\temp.txt", FALSE))
	{
		int nErr = GetLastError();
		cout << "Error in GetFile(): " << nErr << endl;
		nRet = -1;
	}
	delete pConn;
	session.Close();
	return nRet;
}
But if the file doesn't exist you are in trouble: GetFile() will just
wait, and I've never
been patient enough to figure out for how long. Besides MFC
documentation
recommends in the article "Steps in typical FTP client application" to
use
CFtpFileFind::FindFile() and CFtpFileFind::FindNextFile() to make sure
that the file
you need exists. So here is another code which doesn't work:

#include 
#include 

int main()
{
	CInternetSession session("My FTP Session");
	CFtpConnection* pConn = NULL;
	int nRet = 0;

	pConn = session.GetFtpConnection
		("ftp.somewhere.com"); // Put your server name here

	//find the file
	CFtpFileFind ftpFind(pConn);
	CString csFileName =
		"Test1/accesdlg.h.stub"; // Put your file here
    	CString str;

	if (ftpFind.FindFile(csFileName) == FALSE)
	{
		cout << "File not found" << endl;
		ftpFind.Close();
		nRet = -1;
	}
	else
	{
		BOOL bContinue = TRUE;

		while(bContinue)
		{
			bContinue = ftpFind.FindNextFile();
			str = ftpFind.GetFileName();
			cout << "File" << str << "found" << endl;
		}

		ftpFind.Close();

		//get the file
		if (!pConn->GetFile(csFileName,
			"e:\\temp\\temp.txt", FALSE))
		{
			int nErr = GetLastError();
			cout << "Error in GetFile(): " << nErr << endl;
			nRet = -1;
		}
	}
	delete pConn;
	session.Close();
	return nRet;
}

Well, it doesn't break or return an error, but the file I get, temp.txt
is always 320 bytes
long (!) and contains somewhere inside it a name of the remote file I
was trying to get.
Now, if you remove FindNextFile() call the file is fine! (Note that if
you just need one file
this can be acceptable.)
The mysteries, however, continue. Even after you remove FindNextFile()
call,
you are still in trouble if you want to use instead of GetFile() a set
of CFtpConnection::OpenFile(), CInternetFile::Read(),
CInternetFile::Close(). In that
case, after you use

	CInternetFile *pFile;
	pFile = pFtpConnection->OpenFile(csFileName);
	int nSize = pFile->GetLength();

nSize wil be 320!
So I think there must be something wrong with CFtpFileFind class.
Any comments will be strongly appreciated.

Gregory.



Mike Blaszczak -- mikeblas@nwlink.com
Thursday, February 06, 1997

At 08:33 2/4/97 -0800, Gregory Nisnevich wrote:
>Environment: MSVC 4.2b, Win95, WinNT

>But if the file doesn't exist you are in trouble: GetFile() will just
>wait,

That's interesting: I immediately get a 12003 failure. I'm not using
4.2b, though--but the code hasn't changed.  CFtpFileFind::FindFile()
changes in my version to fix a bug in calculating the root directory
of the search, but I can't see how that would cause the problems
you're experiencing.

>Well, it doesn't break or return an error,

You're not searching for a file with wildcards.  Why are you looping?
That doesn't make any sense to me.

>but the file I get, temp.txt
>is always 320 bytes long (!) and contains somewhere inside it a name
>of the remote file I was trying to get.

I can't reproduce that behaviour.  You're sticking with the default
dwFlags parameter value, though, which means that WININET is going to
figure that the file is binary.  Some servers get upset if you transfer
binary files with text FTP, or binary FTP for a text file.

What version of WININET.DLL do you have installed on your machine?
Are you working through a proxy server?

>Now, if you remove FindNextFile() call the file is fine! (Note that if
>you just need one file this can be acceptable.) 

What sort of server software are you using?  I can't reproduce this
using Microsoft IIS 2.0 here at home.

>you are still in trouble if you want to use instead of GetFile() a set
>of CFtpConnection::OpenFile(), CInternetFile::Read(),
>CInternetFile::Close(). In that case, after you use
>
>	CInternetFile *pFile;
>	pFile = pFtpConnection->OpenFile(csFileName);
>	int nSize = pFile->GetLength();
>
>nSize wil be 320!

GetLength() on a CInternetFile-derived object only works if the object is
in cache, and only works if the object in question is a CHttpFile.  This
is documented in the README.TXT file for VC++, I think (I don't have 4.2
at home anymore, so I can't check).  It's a limitation of WININET.DLL, not
of MFC.


.B ekiM
http://www.nwlink.com/~mikeblas/
These words are my own. I do not speak on behalf of Microsoft.
           This performance was not lip-synched.




Gregory Nisnevich -- NisnevG@Helisys.com
Friday, February 14, 1997

Mike Blaszczak wrote:
> 
> >but the file I get, temp.txt
> >is always 320 bytes long (!) and contains somewhere inside it a name
> >of the remote file I was trying to get.
> 
> I can't reproduce that behaviour.  You're sticking with the default
> dwFlags parameter value, though, which means that WININET is going to
> figure that the file is binary.  Some servers get upset if you transfer
> binary files with text FTP, or binary FTP for a text file.
> 
> What version of WININET.DLL do you have installed on your machine?
> Are you working through a proxy server?
> 
Version 4.70.1157

> >Now, if you remove FindNextFile() call the file is fine! (Note that if
> >you just need one file this can be acceptable.)
> 
> What sort of server software are you using?  I can't reproduce this
> using Microsoft IIS 2.0 here at home.
> 
I tried two: Windows NT 4.0 FTP server (under IIS 2.0, Version 4.0 Build
1381)
and SunOS Unix FTP server (version 5.142). And oddly enough, the call
        ftpFind.FindFile(csFileName);
always returns FALSE under NT if the file doesn't exist, and TRUE under
SunOS.
So in order to find out if file really exists in the latter case you
would have
to use a pair of
        ftpFind.FindNextFile();
        str = ftpFind.GetFileName();
and eventually ftpFind.GetFileName() would return something like
" not found", and then you know that the file doesn't exist. 
Now, if you try to call ftpFind.GetFileName() for the file that
is not there for NT FTP server, you'll get something like
": The system cannot find the file specified.",
so the return form ftpFind.GetFileName() is not uniform and 
actually reproduces the message after you try to "dir" nonexistent
file on either server. So in case you would really like to know if
some file exists and you are writing a client that is supposed to 
with any FTP server, you would have to compare the return from
ftpFind.GetFileName() with csFileName.

Gregory







Mike Blaszczak -- mikeblas@nwlink.com
Tuesday, February 18, 1997

At 08:05 2/14/97 -0800, Gregory Nisnevich wrote:

>I tried two: Windows NT 4.0 FTP server (under IIS 2.0, Version 4.0 Build
>1381) and SunOS Unix FTP server (version 5.142). And oddly enough,
> the call
>        ftpFind.FindFile(csFileName);
>always returns FALSE under NT if the file doesn't exist, and TRUE under
>SunOS.

So, it sounds like you've found a compatibility problem tbetween your
SunOS FTP server software and the code in WININET.  I'll tell the WININET
guys about it.


.B ekiM
http://www.nwlink.com/~mikeblas/
These words are my own. I do not speak on behalf of Microsoft.
           This performance was not lip-synched.





Become an MFC-L member | Вернуться в корень Архива |