by Michael S. Kaplan, published on 2008/06/29 03:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2008/06/29/8666513.aspx
Sometimes the question you ask will have different answers depending on who you ask.
Like previously when I described (in the blogs entitled IsCharSomethingOrOther? and Is Kana 'alphabetic' ? Depends on who you ask....), where the answer would vary depending on whether one was asking the NLS API vs. the wrapper functions around NLS contained in Win32.
One could (convincingly) try to argue the differences between these two interfaces, but in the it usually boils down to different intents translating into a different understanding of the question, and thus coming up with slightly different answers.
Another such problem came up the other day, when a developer asked:
I am using PathIsRelative API is my code to ascertain where a path is relative or not. Now if I am giving input as “\Programfiles” or “\” as input the api does not take it as RelativePath. My understanding is that API will consider both of these paths as relative since in command window these inputs take me to root folder or folder relatives to root.
Let me know if I am wrong and also alternative way to find “\ProgramFiles” or “\” being relative or not.
One developer pointed out the problem in understanding, from the point of view of the function:
"\Program files" and "\" are absolute paths. Relative path is different if starts from different current folder. Relative to root is already an absolute path.
While another developer pointed out the overarching problem of the viewpoint:
I am confused about the meaning of "relative" here.
"\" and "\Program Files" are relative—to the current working directory. If cwd is "D:\foo" then "\" means "D:\", but if cwd is "E:\foo", then "\" means "E:\".
So… why is "relative to root … already an absolute path"? Is this simply how "relative" is defined in the world of the win32 API?
And that second developed answered this one in a way that not everyone will probably be able to parse completely, but which certainly failed to see the conflict that comes from the other point of view....
You are correct. But \Program files has the same meaning when cwd is "d:\foo1" or "d:\foo2". Relative path starts from cwd. \Program files always starts from root (although the root is relative to cwd), so it’s absolute. Maybe you can just take this as routine.
Another developer volunteered a response to this question that feel a lot like that USER32 response:
...a way to determine if paths with a leading "\" are to be considered relative ("\Program Files" was just an example).
In our code we have the same issue and just special case it ourselves:
BOOL PathIsRelativeBlah(LPCWSTR wszPath) {
ASSERT(wszPath != NULL);
BOOL bIsRelative = ::PathIsRelativeW(wszPath);
if (bIsRelative)
return TRUE;
if (wszPath[0] == L'\\' && wszPath[1] != L'\\')
return TRUE;
return FALSE;
}
Why would one care?
Well, if the current drive is unknown then in some cases the SHLWAPI PathIsRelative answer is dead wrong awful since one cannot make security decisions based on being sure the path is unambiguous with the response that PathIsRelative provides. So in some cases the function is acceptable, in others it is incomplete.
Now when wants to determine whether one is a relative or not in real life, it is much more complicate, and the many tests include:
What tests make sense depend a lot on the context -- is the goal to find out just if it is a relive? Or is it a check for parental identification?
What one is prepared to accept as the answer will have a lot to do with which question one is really asking, and for what purpose....
Now if one does want to call those "driveless" paths relative then wrapping the SHLWAPI PathIsRelative function with one's own additional logic the same ways USER32.DLL's Is* functions wrap the NLS GetStringTypeW function so they can provide their tweaks.
So that people who want a slightly different bit of logic applied to "is this relative" have the chance to see that done.
And I'll close this with a true story of a conversation that dates back several years with a friend of mine who was about to marry a single mother and the question of whether to adopt her kids came up:
Doug: So you had to go through this too?
Me: almost.
Doug: Why almost?
Me: One of the kids wanted me to adopt, the other two felt like it would be a betrayal, and it was mostly moot since the dad would never have gone for it and he h just started getting garnished for support so ironically in having the court acknowledge he was a deadbeat dad he actually had a say whereas he didn't before.
Doug: And then entirely irrelevant after you didn't actually get married.
Me: Also true. You have to read the fine print.
Doug: Windows is easier. One call to SetParent and your problems are solved.
Me: Actually, there are many times that the SetParent call is actually the start of even bigger problems....
Doug: So Windows isn't really easier, it just looks that way.
Me: Pretty much. The fine print gets you every time.
This blog brought to you by P (U+0050, aka LATIN CAPITAL LETTER P)