I found a blog posting with the most thorough, even elaborate, function I have ever seen to solve this problem. It handles anything, even horrible corner cases like V:foo.txt
where you used the subst
command to map V:
to Z:
but you already used subst
to map Z:
to some other drive; it loops until all subst
commands are unwound. URL:
http://pdh11.blogspot.com/2009/05/pathcanonicalize-versus-what-it-says-on.html
My project is pure C code, and that function is C++. I started to translate it, but then I figured out that I could get the normalized path that I wanted with one function call: GetLongPathName(). This won't handle the horrible corner cases, but it handled my immediate needs.
I discovered that GetLongPathName("foo.txt")
just returns foo.txt
, but just by prepending ./
to the filename I got the expansion to normalized form:
GetLongPathName("./foo.txt")
, if executed in directory C:\Users\steveha
, returns C:\Users\steveha\foo.txt
.
So, in pseudocode:
if the second char of the pathname is ':' or the first char is '/' or '\', just call GetLongPathName()
else, copy "./" to a temp buffer, then copy the filename to temp buffer + 2, to get a copy of the filename prepended with "./" and then call GetLongPathName().