Page 1 of 1

Bug in cGetFile()

Posted: Tue May 16, 2006 2:13 pm
by Enrico Maria Giordano
This is a sample (try to select text.txt):

Code: Select all

#include "Fivewin.ch"


FUNCTION MAIN()

    LOCAL cDir := REPLICATE( "X", 128 )

    LMKDIR( cDir )

    MEMOWRIT( cDir + "\" + "test.txt", "This is a test" )

    ? CGETFILE32( "All files (*.*)|*.*", "Select a file", , CURDRIVE() + ":\" + CURDIR() + "\" + cDir )

    RETURN NIL
The problem seems to be that the memory allocated for the selected path+filename is limited to 128 bytes while the maximum length allowed by the file system is 256.

EMG

Posted: Tue May 16, 2006 3:10 pm
by modicr
I confirm:
http://fivetechsoft.com/forums/viewtopi ... t=cgetfile

BTW, in your source you use cGetFile32.

Roman

Posted: Tue May 16, 2006 3:35 pm
by Enrico Maria Giordano
Ops, sorry. Anyway, same behaviour.

EMG

Posted: Tue May 16, 2006 4:04 pm
by modicr
Hello!
... while the maximum length allowed by the file system is 256.
"How can I use path names longer than 255 characters?"
http://www.windowsitpro.com/Article/Art ... 14607.html
A. Windows NT has a maximum path size defined as MAX_PATH which is 255 characters. It is possible to use more characters by calling the wide (W) version of CreateFile and prefixing "\\?\" to the path. The "\\?\" tells the function to turn off path parsing. This lets you use paths that are nearly 32,000 Unicode characters long. You must use fully-qualified paths with this technique. This also works with UNC names.

The "\\?\" is ignored as part of the path.

For example, "\\?\D:\documents\faq.txt" is seen as "D:\documents\faq.txt".

Programs expecting to find legal file lengths may fall over attempting to open a file with a long path. If, for example the buffer they are putting the path into expects a legal file length.
http://www.osronline.com/showThread.CFM?link=91868
The maximum length of a file/folder is a problem. Almost everything in
Windows uses a MAXIMUM_FILENAME_LENGTH of 256 and MAX_PATH of 260. But
there is also a MAXPATHLEN parameter which is 1024. Any single element of
the path is limited to 255 characters.

But the Unicode versions of several functions permit a maximum path length
of 32,767 characters, composed of components up to 255 characters in length.
To specify such a path, use the "\\?\" prefix. For example,
"\\?\D:\<path>". But many functions don't handle this.

So 260 *usually* works, but 32K is guaranteed to work. (Note that this is
characters, not bytes -- each Unicode character is 2 bytes.)
http://www.cygwin.com/ml/cygwin/2004-10/msg01330.html
CreateFileA on an nt-based system just converts all strings from MBCS to
Unicode via the current locale's code page, and then calls CreateFileW.
CreateFileA is always limited to MAX_PATH.

On Win98/WinME, it works differently. There is no routine called
NtCreateFile.

CreateFileW is a dummy routine that always returns an error, unless you
link with the Microsoft Layer for Unicode (Unicows.dll). Unicows.dll
translates all UNICODE argument strings to the current code page, and
calls CreateFileA.

So you can always link with CreateFileW, since it always exists, but it
may not be functional.

The special \\?\ prefix doesn't do what you want on Win9x systems, as you
always go through CreateFileA, so paths are always limited to MAX_PATH.
http://msdn.microsoft.com/library/defau ... a_file.asp

Roman

Re: Bug in cGetFile()

Posted: Wed May 17, 2006 12:28 pm
by Enrico Maria Giordano
EnricoMaria wrote:The problem seems to be that the memory allocated for the selected path+filename is limited to 128 bytes while the maximum length allowed by the file system is 256.
Replacing all 128 to 256 and all 127 to 255 in getfile.c solves the problem.

EMG

Posted: Thu May 18, 2006 10:01 am
by Antonio Linares
Enrico,

Thanks! :)

Posted: Fri May 19, 2006 11:01 am
by Vladimir Grigoriev
The maximum number of characters in a full path, including the drive letter, colon, leading backslash, file name, and terminating null character, is 260.

Posted: Fri May 19, 2006 11:05 am
by Enrico Maria Giordano
I confirm, you are right.

EMG