Why does SHGetKnownFolderPath return E_FAIL for a known folder?

Raymond Chen

A customer reported having problems with the SH­Get­Known­Folder­Path function. I’ve left in the red herrings.

On Windows 7, I’m trying to retrieve the Internet folder with the following code:

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
{
 HRESULT hr = SHGetKnownFolderPath(FOLDERID_InternetFolder,
                              KF_FLAG_DONT_VERIFY, hToken, &pszPath);
 ...
}

The call always fails with E_FAIL. What am I doing wrong? I tried passing NULL as the token, but that didn’t help.

The reason the call fails has nothing to do with Windows 7 or the token. The call fails because FOLDERID_Internet­Folder is a virtual folder—there is no path in the first place!

The reason is that the folder you are requesting is a virtual folder (KF_CATEGORY_VIRTUAL). Virtual folders don’t exist in the file system, so they don’t have a path. SH­Get­Known­Folder­Item should work.

The customer appears to have misinterpreted this response in a way I wasn’t expecting (but which sadly I’ve seen before):

I added the KF_CATEGORY_VIRTUAL flag, but I still get the same error back.

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
{
 HRESULT hr = SHGetKnownFolderPath(FOLDERID_InternetFolder,
                              KF_FLAG_DONT_VERIFY | KF_CATEGORY_VIRTUAL,
                              hToken, &pszPath);
 ...
}

Um, no, that makes no sense at all. KF_CATEGORY_VIRTUAL is a KF_CATEGORY value, but the second parameter to SH­GetKnown­Folder­Path is a KNOWN_FOLDER_FLAG. You can’t just combine unrelated values like that. It’s like adding 3 grams to 12 meters.

And second, the KF_CATEGORY_VIRTUAL enumeration isn’t something that you pass in to “override” anything. The point is that FOLDERID_Internet­Folder is a virtual folder: It has no path, so if you try to ask for its path, you’ll just get an error back because the thing you’re looking for simply doesn’t exist.

I never did figure out what this customer was trying to do. Maybe they figured, since they can’t download the Internet, they could at least try to do a Find­First­File on it.