Geoff Chappell - Software Analyst
This function gets the item ID list (PIDL) that represents a given object in the shell namespace.
HRESULT SHGetIDListFromObject ( IUnknown *punk, PIDLIST_ABSOLUTE *ppidl);
The punk argument is any interface pointer to the object.
The ppidl argument is the address of a variable that is to receive the address of an item ID list that represents the object.
The function returns zero for success, else an error code.
If the punk argument is NULL, there is no object and the function fails (returning E_NOINTERFACE).
For the function to obtain a PIDL, the object must implement one of the following interfaces:
The function tries each interface in turn. The first that has the interface is the only interface from which the function seeks a PIDL. If the object has none of these interfaces, the function fails (returning E_NOINTERFACE).
If the object has an IPersistIDList interface, then the function succeeds or fails according to the GetIDList method.
If the object has an IPersistFolder2 interface, then the function is straightforwardly a call to the GetCurFolder method, except that if the method succeeds without actually producing a PIDL, then the function fails, returning the HRESULT from ERROR_FILE_NOT_FOUND.
If the object has an IDataObject interface, the the function is essentially a call to the GetData method for all data in the clipboard format CFSTR_SHELLIDLIST (with no target device, DVASPECT_CONTENT and TYMED_HGLOBAL). If the data so obtained (as a CIDA structure) does not have exactly one relative PIDL, the function fails (returning E_FAIL). Otherwise, the PIDL produced by the function is a combination of the folder and child items from the CIDA. If the function cannot combine these, it fails (returning E_OUTOFMEMORY).
The SHGetIDListFromObject function is exported by name from SHELL32.DLL in the version 6.00 from Windows Vista, and higher.
SHELL32 has this function as an internal procedure, named SHGetIDListFromUnk (according to the symbol files) at least as early as version 5.00. It just took Microsoft a while to provide it as a utility for wider use. The original implementation checks IPersistFolder2 only. Version 6.00 added IPersistIDList. Support for IDataObject is new for Windows Vista.
The function is documented by Microsoft, though inevitably without noting which interfaces are expected. Documentation of IPersistFolder2 does say that all shell namespace extensions need to implement that interface, but if that actually is a requirement and is adhered to by all Microsoft’s namespace extensions, then why does this function bother to consider other interfaces? Of course, the function may be intended for objects other than namespace extensions, but then why not document its scope? There may be something worth looking into about this.