For adding this flexibility, the known file APIs has been rename and designed with COM Interfaces.
New Shell APIs and COM Interfaces are introduced to replace the old Shell APIs
| New Function | Replaces | COM Equivalent |
| SHGetKnownFolderPath | SHGetFolderPath | IKnownFolder::GetPath |
| SHGetKnownFolderIDList | SHGetFolderLocation | IKnownFolder::GetIDList |
| SHSetKnownFolderPath | SHSetFolderPath | IKnownFolder::SetPath |
Old APIs were using CSIDL for representing the known location identifier. This has been replaced by KNOWFOLDERID. However Windows Vista and 7 still supports CSIDL and associated APIs for compatibility reasons. The new applications has to use the new APIs or COM Interface. When using both COM/New Shell API, you’ve to ensure that CoTaskMemFree function is called to release the output resources. Otherwise memory leak may occur. Also don’t call any other memory release function like free or delete operator. It may cause undefined behavior
How to Enumerate All Known Folders?
void EnumerateAllKnownFolders(CStringArray& strArray)
{
CStringArray strPathRet;
IKnownFolderManager* pkfm = NULL;
HRESULT hr = CoCreateInstance(CLSID_KnownFolderManager, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pkfm));
if( SUCCEEDED(hr))
{
KNOWNFOLDERID* rfid;
UINT uCount = 0;
if( FAILED( pkfm->GetFolderIds( &rfid, &uCount )))
return;
for (UINT uIdx = 0; uIdx < uCount; ++uIdx )
{
IKnownFolder* pFolder;
pkfm->GetFolder( rfid[uIdx], &pFolder );
LPWSTR szPath;
pFolder->GetPath(0, &szPath );
strArray.Add( szPath );
CoTaskMemFree( szPath );
pFolder->Release();
}
CoTaskMemFree( rfid );
pkfm->Release();
}
}
How to get the path of a specific known folder using new COM Interface?
CString GetKnownFolderIDCOM( KNOWNFOLDERID rfid )
{
CString strPathRet;
LPWSTR szPath;
IKnownFolderManager* pkfm = NULL;
HRESULT hr = CoCreateInstance(CLSID_KnownFolderManager, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pkfm));
if( SUCCEEDED(hr))
{
IKnownFolder* pFolder;
pkfm->GetFolder( rfid, &pFolder );
pFolder->GetPath(0, &szPath );
strPathRet = szPath;
CoTaskMemFree( szPath );
pFolder->Release();
}
pkfm->Release();
return strPathRet;
}
How to get path of a specific known folder Shell API?
CString GetKnownPathShell( KNOWNFOLDERID rfid )
{
CString strPath;
LPWSTR szPath;
SHGetKnownFolderPath( rfid, 0, 0, &szPath );
strPath = szPath;
CoTaskMemFree( szPath );
return strPath;
}