探索文件系统扩展的奥秘

在Windows操作系统中,资源管理器(Explorer)是一个强大的工具,它允许用户浏览和管理文件系统。但知道吗?它还可以通过注册特定的URL前缀来扩展其功能,从而支持自定义的文件系统。例如,Microsoft就利用这一特性实现了FTP文件夹的集成。

要实现这一点,需要在注册表中添加自己的URL前缀。具体来说,需要复制并修改位于HKEY_CLASSES_ROOT\ftp中的条目。但这里有一个奇怪的现象:不会在资源管理器中看到一个名为"ftp文件夹"的根项目,所有的FTP文件夹都直接以"Internet Explorer"项目作为根。

这种设计意味着"Internet Explorer"项目必须能够理解所有底层命名空间的pidls(项目标识符列表)。为了解决这个问题,Internet Explorer采用了一种特殊的机制,即IDelegateFolder接口。

通过IDelegateFolder接口,命名空间扩展将获得一个IMalloc接口。这个接口的Alloc函数会分配一个指向命名空间扩展的Internet Explorer pidl,并预留空间以插入自己的pidl。

下面是IDelegateFolder接口的IID定义:

DEFINE_GUID(IID_IDelegateFolder, 0xADD8BA80L, 0x002B, 0x11D0, 0x8F, 0x0F, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62);

下面是IDelegateFolder接口的定义:

DECLARE_INTERFACE_(IDelegateFolder, IUnknown) { // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE; STDMETHOD_(ULONG,AddRef)(THIS) PURE; STDMETHOD_(ULONG,Release)(THIS) PURE; // IDelegateFolder methods STDMETHOD(SetItemAlloc)(THIS_ IMalloc *pMalloc) PURE; };

当命名空间扩展被实例化后,Internet Explorer会查询IDelegateFolder接口,并调用SetItemAlloc方法,传递一个IMalloc接口。必须存储这个接口。

从这一刻起,每当需要创建一个pidl时,必须遵循以下步骤:

  1. 调用这个IMallocAlloc函数。
  2. 将自己的完整pidl(包括大小)插入到返回缓冲区的偏移量4处。
  3. 将这个缓冲区作为自己的pidl返回。

返回的缓冲区将已经是一个pidl,以2字节的大小开始,然后是一个2字节的签名(0x61 0x03)。所有传递到命名空间扩展的pidls也将有这种格式。这意味着将在偏移量4处找到自己的pidl。

pidls仍然使用标准的shell分配器进行释放。如果命名空间扩展有子文件夹,那么这些子文件夹将遵循正常的系统规则。列表中的第一个id将是特殊的Internet Explorer pidl,所有随后的都是自己的标准pidls。

这不是Microsoft选择的一个干净解决方案。如果Internet Explorer根节点能够执行嵌入pidl的插入和提取,那么就可以消除对这个接口的需求,这将会更加简单。

通过这种方式,可以扩展Windows资源管理器的功能,实现自定义的文件系统。这不仅增加了资源管理器的灵活性,也为开发者提供了更多的创新空间。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485