Page 1 of 1

Bugs in Windows API functions

Posted: Sun Sep 26, 2010 2:56 pm
by Little John
Hi all,

I think it's useful to collect all bugs in Windows API functions that we know of here in one thread, and to discuss the best ways to work around them.

Please post neither "Microsoft is evil" polemics, nor "Microsoft is infallible like the Pope" propaganda. Bugs are just a consequence of the nature of human factors in the programming task, and any software of a sufficient extent does contain bugs. So it's not the aim here to blame Microsoft, and there's also no need to defend Microsoft against "bad guys", who dare to say that there are bugs in the Windows API. I really hope that here will be an objective discussion, which is of practical help for all of us.
(As I recently experienced, unfortunately it is necessary to write such an appeal here.)

Don't forget to post the precise Windows version on which you encountered the bug. Of course, it is appreciated when other people will report whether or not a particular bug does exist on other Windows versions as well.

Regards, Little John

Re: Bugs in Windows API functions

Posted: Sun Sep 26, 2010 2:58 pm
by Little John
Here is the first bug which I encountered.

WinAPI function: PathRelativePathTo (for reference see MSDN here).
Purpose of the function: Creates a relative path from one file or folder to another.
Bug encountered on: Windows XP Professional SP3 x86

Code which demonstrates the bug (tested with PB 4.51):

Code: Select all

EnableExplicit

Define BaseDir$, AbsPath$
Define RelPath${#MAX_PATH}, FullName${#MAX_PATH}

BaseDir$ = "C:\Dokumente und Einstellungen\John\Desktop\"  ; an existing directory
AbsPath$ = BaseDir$ + "pc.txt"                             ; an existing file

Debug PathRelativePathTo_(@RelPath$, @BaseDir$, #FILE_ATTRIBUTE_DIRECTORY, @AbsPath$, #FILE_ATTRIBUTE_NORMAL)
Debug RelPath$   ; => "\pc.txt"   ERROR

SetCurrentDirectory(BaseDir$)
Debug GetFullPathName_(@RelPath$, #MAX_PATH, @FullName$, #Null)
Debug FullName$  ; => "C:\pc.txt"
Explanation: When AbsPath$ denotes a file that is in the directory BaseDir$, then PathRelativePathTo erraneously returns the name of the file with a leading backslash. The leading backslash denotes the root directory of the current drive. Consequently, when "\pc.txt" is passed to GetFullPathName, it correctly returns "C:\pc.txt".
However, looking at the original absolute file name, we see that "pc.txt" is not in the root directory of drive C:, but in "C:\Dokumente und Einstellungen\John\Desktop\". So PathRelativePathTo should return "pc.txt" instead of "\pc.txt".

This is confirmed by the following code:

Code: Select all

EnableExplicit

Define BaseDir$
Define RelPath${#MAX_PATH}, FullName${#MAX_PATH}

BaseDir$ = "C:\Dokumente und Einstellungen\John\Desktop\"  ; an existing directory
RelPath$ = "pc.txt"    ; *correct* relative name

SetCurrentDirectory(BaseDir$)
Debug GetFullPathName_(@RelPath$, #MAX_PATH, @FullName$, #Null)
Debug FullName$        ; => "C:\Dokumente und Einstellungen\John\Desktop\pc.txt"
So when the correct relative name is passed to GetFullPathName, then it returns the original absolute path name as expected.

Workaround: In order to create a relative path, use this function written in PureBasic (which is even cross-platform).

Regards, Little John