How can I detect that a shell item refers to a virtual folder, or to a file system inside a file?

Shell items have a bunch of attributes. For example, SFGAO_FOLDER means that the item is a folder, and it will show up in the navigation pane as a folder. Since it's a folder, you can bind to it and enumerate children. But what if you need more information about what kind of folder it is?

The other attributes SFGAO_FILE­SYSTEM, SFGAO_FILE­SYS­ANCESTOR, and SFGAO_STREAM can help you distinguish the various scenarios.

The SFGAO_FILE­SYSTEM attribute means that the item exists in the file system, and the parsing name for a SFGAO_FILE­SYSTEM object can be used to access the corresponding entity in the file system.

The SFGAO_FILE­SYS­ANCESTOR attribute means that the item or one of its children might have the SFGAO_FILE­SYSTEM attribute. This attribute is used by the File Open and File Save dialogs, for example, to decide whether to filter out the item. If it's possible to reach the file system via the item, then the File Open and File Save dialogs will include the item. You may not be able to save directly to the item (such as My Computer), but it will let you navigate through it on the way to something you can save to.

The SFGAO_STREAM attribute means that the item can produce bytes of data. If combined with the SFGAO_FILE­SYSTEM attribute, it means that the underlying storage for the item is a file. Even though the underlying storage is a file system file, it may be exposed in the shell namespace as a folder. For example, ZIP files are file system files, but they show up in the shell namespace as a folder, so that you can open them up and drag files into or out of them.

Let's summarize this in a chart.

Virtual file with no data Dial-up networking connectoid
SFGAO_STREAM Virtual file with data File on an FTP site
SFGAO_FOLDER   Virtual folder Control Panel
SFGAO_FOLDER | SFGAO_STREAM Virtual folder with data ?
SFGAO_FILE­SYSTEM   File system file with no data Symbolic link
SFGAO_FILE­SYSTEM | SFGAO_STREAM File system file with data Traditional file system file
SFGAO_FILE­SYSTEM | SFGAO_FOLDER   File system directory Traditional file system directory
SFGAO_FILE­SYSTEM | SFGAO_FOLDER | SFGAO_STREAM Virtual directory inside a file system file ZIP file

I couldn't think of an example of a virtual folder with data.

Comments (13)
  1. Mason Wheeler says:

    What does SFGAO stand for anyway?

    1. laonianren says:

      These values are returned from IShellFolder::GetAttributesOf.

    2. ...doug says:

      Probably Shell Folder Get Attributes Of, derived from the IShellFolder::GetAttributesOf method.

  2. IanBoyd says:

    I tested a ZIP file sitting on a phone connected using Media Transfer Protocol (MTP). It has `SFGAO_Stream`, but not `SFGAO_FileSystem` nor `SFGAO_Folder`. Looks like MTP shell handler doesn’t expose ZIPs as virtual folders with data.

    1. Makes sense. The Zip Folder implementation requires a file system file, and MTP can’t give it one.

    2. skSdnW says:

      I don’t think filesystem means any type of filesystem nor any type of hardware connection even if the filesystem is FAT etc. I believe it means; if the filesystem bit is set then the shell (IShellFolder implementation) is able to convert the PIDL to a path. Basically classic drive letters and UNC paths and most code probably assumes that the functions in kernel32 are able to parse said path.

      1. After all, there’s a file system on web servers and FTP servers, but they aren’t in the local file system either.

    3. Erik F says:

      Looking at the MTP spec ( from, it doesn’t appear that ZIP files have a object format so they are presented as “Unknown object” to the host. This limits what the MTP handler can do with it I would think.

  3. deskrule says:

    > I couldn’t think of an example of a virtual folder with data.

    a subfolder within a zipfolder

    1. Brian says:

      Wouldn’t that still have SFGAO_FILESYSTEM ?

      1. No, because there is no file name for “the foo subdirectory in”. It would be a virtual folder with data if the virtual folder implementation dynamically generated a new zip file for the subfolder. I don’t think anybody does this though.

  4. Joshua Schaeffer says:

    IShellFolder is strictly STA right? Does that mean any IStream produced by BindToStorage() is stuck on that thread? Is there a way to set up the bind context to know for sure?

Comments are closed.

Skip to main content