Everyone abandons XP nowadays. Microsoft has ended its support a couple of years ago, and it is almost 15 years old. But it is a good OS that served us faithfully for so many years — and there are people still using it. I get sentimental with old trysty OSs ("a dog is for life not just for christmas" kind of thing :) but spending a month or two for windows XP 7z-folder support was out of the question. The source code I used to write SevenZipShell extension uses fancy API that requires later SHELL32.DLL versions. Targetting older windows requires a completely different approach.
All these shell functions appear within IShellFolder::GetUIObjectOf implementation, but except for the first one, all the rest could be ignored without serious loss of functionality. This was no 2 month project, more likely a 2-hour effort!?
A quick compile demonstrated that indeed dynamic-loading the missing API turned the dead duck of an NSE into a much more useful browsing component. It would register with REGSVR32 and allow xplorer² to browse into 7z/RAR files. But without a data object, you can't extract, so there was still work to be done.
SHCreateDataObject was introduced with Vista. It provides a default IDataObject implementation that can take all the dozens of formats (CFSTR_SHELLIDLIST et al) required for shell data transfer. In normal folders you just need to add the filesystem paths in a CF_HDROP, but inside a virtual folder there are no paths; one needs to supply the "file" contents in a stream described by CFSTR_FILECONTENTS. SHCreateDataObject doesn't know how to get this IStream, so it accepts an inner IDataObject to do the heavy lifting. I had that one already availabe from the original NSE implementation.
Windows XP has this (sort of) undocumented equivalent called CIDLData_CreateFromIDArray, that accepts the same arguments as SHCreateDataObject except for the all important inner data object. According to expert opinion (hello Jim :) it cannot be used to handle virtual folders directly because it can deal with just one stream at a time. After this revellation I was about to throw the towel in, but then I had an idea: what if I turned my inner dataobject into a master outer object, and used the limping shell item as a backup for miscellaneous shell formats?
I have used the idea of COM subclassing many times already. Essentially one wraps a COM object and redirects all unhandled interface calls to the "base" object, in this case the one created by CIDLData_CreateFromIDArray. I only had to intercept GetData to supply the file contents, and redirect all other requests to the shell object. What a great idea, turn the inner object inside out like that... only why didn't bleeping work? It would only allow creating shortcuts (links) with drag-drop, but no proper content extraction. WTF? After about an hour of head scratching it dawned on me that the shell object's EnumFormatEtc didn't know about the extra formats (always obvious in hindsight :). That was then easily sorted out overriding EnumFormatEtc to supply a wholesome IEnumFORMATETC (gratis SHCreateStdEnumFmtEtc) that mentioned CFSTR_FILEDESCRIPTOR and CFSTR_FILECONTENTS support — and order was restored.
Originally I didn't plan to offer a context menu in XP 7zip-folders. Useful but not essential: you can see file details from columns and use the main menu or <Ctrl+C> to copy out. But apparently opening items from virtual folders relies on IContextMenu (the default verb is used), so I had a go replacing SHCreateDefaultContextMenu with CDefFolderMenu_Create2. I won't go into details because it proved a waste of time. Now there is a context menu but the most basic "open" command does nothing. This is windows XP after all and registy shell verbs expect filesystem paths, not streams. Not the end of the world really, and as the time allowance on the project was seriously inflated (reached 2 days instead of the 2 hours planned), I conceded defeat.
If you don't have WDS installed on XP you need to get it from here 32 bit or 64 bit
For vista and later you get full functionality. For windows XP (SP2 or SP3) there are a few limitations:
If you don't have WDS installed the NSE won't work for XP. That's bad news for resource consumption conscious XP users. However you only need to install it and leave it disabled. It needn't be running, you can stop the Windows Search service and leave it dormant. On the plus side, if you own xplorer² ultimate edition, installing WDS will give you great search performance.
Post a comment on this topic »