Home » Blog
date 7.Feb.2016

■ Windows XP can also browse into 7zip/RAR etc archives with a little TLC

There is a shell extension that allows windows explorer, xplorer² and such shell friendly file managers to browse into 7Z archives as folders. It works pretty well at what it does, offering rich preview and search capabilities inside compressed files, only it (used to) require windows vista or later. Windows XP need not apply.

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.

Perchance, I was checking some search features in windows XP when it occured to me to see if the said NSE would work, or rather how would it fail. As expected the original version didn't want to hear about XP. By another lucky accident, that XP virtual machine had windows search installed, and I was amazed to realize that the problem was just 4 missing imports (see the dependency walker report)
  1. SHCreateDataObject, fundamental for extracting files out of the archive
  2. SHCreateDefaultContextMenu, for shell context menu creation
  3. AssocCreateForClasses, used for context menus mainly
  4. SHCreateDefaultExtractIcon, for icon extraction
dependency walker reveals missing shell imports

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!?

Convincing XP to browse into compressed archive folders

If you are not a programmer, just skip this section and proceed to the download link.
The problem of missing DLL imports ("Cannot find entry point...") is easily fixed by dynamic loading as opposed to compile-time linkage. So instead of calling SHCreateDataObject directly, use GetProcAddress to obtain a function pointer and call through it. If the API doesn't exist in an older version of the shell DLL, at least the NSE dll itself won't fail to load. If the function isn't there you can "fail gracefully". That's 3 out of 4 missing functions sorted!

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.

Download the XP-compatible compressed archive shell extension

This NSE will let you browse in 7Z, RAR, ARJ, GZ, GZIP, LZH, LHA, LZMA, TAR, ZIPX, JAR archives and ISO, IMG, DMG images on windows XP or later. You get nice functionality that you won't see in your standalone archive program like rich preview straight from within the archive (no extraction required), and you can also search inside these archives.
Click to download 7z NSE (1.5MB, build 1.400)

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 »

Share |

©2002-2016 ZABKAT LTD, all rights reserved | Privacy policy | Sitemap