Introduction

The Galaxy FilesSystem Toolkit (GFT) allows developers to create user-level file-system extensions that are viewable through Windows Explorer. While the toolkit itself is constructed using C++ COM/ATL code, extension developers can program in higher-level strongly-typed, garbage-collected languages such as C# and Java. Thus, the Toolkit eases the development of user-level file-systems on the Windows platform. The GFT has been used with a Java file-system extension to create a Windows Explorer interface to NFS version 2 fileservers. Other examples of possible extensions include:

Windows Explorer interface to Google’s Gmail, similar in functionality to Gmail drive. Gmail folders would be modeled as file-system folders, and mail messages would map to files. Alternatively, blocks within a file could be mapped to individual messages to allow for larger file storage.

A Windows Explorer interface to a SQL database. Tables could be modeled as folders, and rows could be modeled as files within folders.

A Windows Explorer interface to the PlanetLab. Folders would contain sites of machines, and files would contain attributes of individual machines, e.g., load averages.

A /proc-like interface using Windows Explorer. Files within the "/proc" folder would map to processes, and file contents would show process attributes.

1.1 What is it?

The Toolkit is a Windows Shell NameSpace Extension (NSE) which communicates to your custom code (the extension) via a proxy and stub pair. For a view of this, see Figure 1. The Toolkit manages a part of the Shell namespace, e.g., the Windows path "C:\Custom", and converts all Windows Explorer operations on this namespace into the appropriate method invocations on your file-system extension. For example, when a file is dragged-n-dropped onto the folder "C:\Custom", the Toolkit will first invoke CreateFile and then a series of Write calls on your extension.

The rest of this document describes the steps necessary to install the Toolkit and to create a simple extension. Section 2 covers the steps needed to install the Toolkit, while the bulk of the document, Section 3, will guide you through the creation of a sample extension in C#. Known issues and limitations are listed in Section 4, and Acknowledgements are given in Section 5.

2 Installation

To begin, download either the Toolkit source code or the binary installer package from the website. C# programmers will install from the source, since the source zip file contains the necessary interfaces and sample code. Java developers will typically install the GFT using the binary installer, since this procedure does not require Visual Studio.

2.1 Installing from the source

The GFT can be installed from a Visual Studio solution file and the source code, using the following steps:

Download: Download the latest GalaxySource.zip file from the CodeProject website.

Extract: Extract the source, and open the Galaxy.sln Visual Studio solution file.

Build and Start: Navigate to the Build menu in Visual Studio, and select Build Solution. Then, navigate to the Debug menu in Visual Studio, and select Start. This will cause the C# Mirror FileSystem to start (you should see a blank Command Prompt window). Now, go to Section 2.3.

2.2 Installing from the binary

Installing from the binary involves the following steps:

Download: Download the latest GalaxyBinary.zip binary installer from the website. This is a Zip file that can be extracted to a temporary location.

Run the setup.exe program. Open the setup.exe or GalaxyToolkit.msi install files. This will install the C++ namespace extension (NSE) and a C# mirroring file-system.

Start the Mirror FileSystem. Navigate to Start, Programs, Galaxy, and click on the "Start C# Mirror FileSystem" link. This step will not work on an older version of Windows, such as Win98, or any OS which does not have the .NET redistributable installed. Get the .NET 1.1 redistributable from the Microsoft website.

2.3 Exploring the FileSystem

At this point, you should have the Galaxy namespace extension (NSE) installed, and a sample C# Mirroring FileSystem extension running.

To explore this Mirror FileSystem, start a Windows Explorer process (Windows Key + E) and navigate to "My Computer". You should notice a new system folder called "Galaxy". Browsing to this folder should reveal two files: COPYING.txt and Subfolder. You can open the text file (the GNU GPL) and also open the Subfolder folder, as well as open the JPG file contained in the Subfolder folder. (These files are mirrors of the files contained in the folder, Test, which was distributed with the source or installed along with the binary, depending on your method of installation.)

You can try copying files to and from the Galaxy file-system, with the caveat that multiple selections are not yet supported. (In other words, you can copy entire folders, but you cannot highlight and copy two or more files at the same time.) Other caveats are listed in Section 4.

3 Tutorial

To create your own C# file-system extension, you will need to perform two steps:

implement a single abstract class, CSharpFileSystem.FileSystem and,

change line 50 of the file Driver.cs to specify your extension class name.

In this tutorial, we will create a dummy read-only file-system extension called "RandomFileSystem", which will display random text files which are each filled with random text.

First, startup Visual Studio (or your personal IDE) and open the CSharpFileSystem solution file. Now, create a new class in the CSharpFileSystem namespace, which inherits from CSharpFileSystem.FileSystem. We will call this new class "RandomFileSystem". Give the default constructor a single integer argument which specifies how many files to display per folder.

Now, we need to implement the nine methods of the FileSystem abstract class. In each of the following sections, we will implement a method and discuss the implementation details. In the methods where we do not provide an implementation, we still return a success code of true; Galaxy’s error handling is not yet robust, and thus a false return value is likely to cause a failed assertion.

3.1 Command

This command is used for extensibility, and it allows the namespace extension to pass an arbitrary command string to your file-system. Currently, the only command that is passed is "trace", which gets passed when the user selects "Trace" from the context menu (by right clicking). We can safely ignore this, and so we give a dummy implementation:

3.2 CopyFile

This method is used for a fast-path copy so that the Galaxy namespace extension can pass filenames (instead of file contents) when it wants to copy a file to your file system. Since this is an optimization, we will ignore this method and provide the following debugging implementation (Note: You must fully-qualify the FileInfo class since Galaxy defines a FileInfo class as well):

3.5 Delete

3.6 ListFiles

Here, we need to create a random set of files and return them. We will make use of the myNumFiles field to help us choose how many files to return. We choose each odd numbered file to be a text file, while each even-numbered file returned is a folder (i.e., a directory). Each text file is given a random FileSize from 0 to 1023 bytes. This size will be displayed in Windows Explorer, and also used by Galaxy: whenever the file is opened or copied, only the first FileSize bytes will be read.

Folders are given a size of 0, and whenever a folder is opened in Windows Explorer, this ListFiles method will be called on that path name. (Note: While we fill in all of the fields, only the FileName, FileSize, and FolderFlag are currently used by Galaxy.)

3.7 Read

The Read method is called whenever a file in Galaxy is copied to Windows, or when a Galaxy file is opened. Since we are implementing a simple read-only random file system, we will return a random string of bytes for the read call (taking care to return only the specified number of bytes). Note that we do not keep the file size consistent across calls, and simply create a new file size in this call. Also, we make sure not to return more bytes than Windows Explorer is asking for (count), and we only return data when the offset into the file is equal to 0 (i.e., normally, the first read call).

3.8 Stat

The Stat method is called by Galaxy to get file information whenever files are copied from Galaxy to Windows. We will parse the path name to determine if we are being asked for a file with a name containing the string ".txt". If it does, then we know that the path refers to a file. Otherwise, the path refers to a folder. (Since we control all file names, we can be sure that folders do not contain the string ".txt")

Note that we do not take special care to preserve consistent file sizes: the file size returned from this method is random, and is probably different from the file size returned from the ListFiles method.

Note that we are passing the second command line argument to the RandomFileSystem constructor as an integer. So, let’s now change this command line parameter to a proper value. Select the CSharpFileSystem project, then select Properties. Change the command line params under "Configuration Properties, Debugging, Start Options, Command Line Arguments" from "8052 ../../Test" to "8052 10". This should allow up to 10 files per folder in our new random file-system. Apply the change, and click "OK". Now, build the code and start our new random file-system by hitting "F5".

Navigate to the Galaxy file system using Windows Explorer, and verify that the random file system works. You may get what seems like strange behavior (zero files, the number of files keep changing, the content of each file changes) but this is how the RandomFileSystem works! You can copy files from the RandomFileSystem, but take care when copying folders: you have a very good chance of exceeding the maximum path length of 260 characters since the depth of any folder is a random variable with unbounded expectation.

3.11 Next steps

As a next step, you can read through the MirrorFileSystem file system contained in FileSystems.MirrorFileSystem.cs in the source code bundle. This is a more complete file system example which mirrors a specified folder of the local Windows file system. Be sure to change the command line arguments of the CSharpFileSystem project back to their original form.

Since, for the MirrorFileSystem, the second command line argument specifies which folder to mirror, you are free to change this to any folder that you choose. For example, you can change the command line arguments to "8052 C:\Windows" if you would like. (The first argument, 8052, specifies which port the File Server will listen to and must match the port used by the Galaxy namespace extension.)

4 Known issues

While basic file operations are implemented (e.g., cut-and-paste, drag-n-drop), there are some limitations in the NSE which should be fixed in future releases. These limitations for Galaxy v1.0 are listed below:

Explorer will hang if your file system is accessed before your extension starts up. This is fixable, but as long as you take care to start your file system extension before you navigate to it, you should be okay. If you run into this problem, simply kill the explorer.exe process and restart it using the Task Manager.

Icons for files are limited. Icons are restricted to either the folder icon or the icon for text files. This will be fixed in a future release.

Renaming of files is not currently supported. This is a priority for me to fix right now, and should change with the next release of the code.

Multiple selections are not allowed when copying from/to the Galaxy namespace. This is a restriction that should be relaxed in future releases.

Deletion of files occurs with out confirmation. When you delete a file in the Windows file system, typically a Yes/No dialog box is used to confirm the delete. This is not implemented (yet) in Galaxy.

Properties of files/folders in Galaxy is not yet supported.

The attributes of a file/folder is limited to filename and file size. Future releases will support the display of the file’s last modified and creation times, among other attributes.

The current maximum file and path length is 260 characters. If Unicode paths are used, then it is possible to extend this to 65,000 characters.

5 Acknowledgments

The task of learning COM and the NSE interfaces was made easier by the contribution of several whom we would like to acknowledge here. First, the articles published by Pascal Hurni, Nemanja Trifunovic, Henk Devos, and Michael Dunn on the CodeProject.com website were invaluable in bringing us up to speed on namespace extensions and COM programming in the Windows environment.

The GPL’d code from Pascal Hurni on the CodeProject website and the GPL’d Amiga Disk File namespace extension by Bjarke Viksoe formed the basis for our GFT toolkit. Finally, all of the users who frequent the newsgroup microsoft.public.platformsdk.shell and, in particular, Jim Barry were helpful in finding subtle bugs in our implementation.

Comments and Discussions

Quick Question: I compiled your provided code in Win7(32 bit)and when I try to open copying.txt in notepad (through open dialog) it gives an error: Path does not exist, check the path and try again. When I browse to the Galaxy folder through explorer and double click on same file it opens fine in notepad.

In debug, I can see from open dialog it is "not" calling BindToObject() with IID_IStream, so looks like it is failing before that. Any idea what might be the problem.

this namespace extension is working well but...
After closing the windows explorer a interface to the Galaxy IShellFolder is not released.
DllCanUnloadNow has been called but the dll can't be unloaded because 1 interface is open. It happens always after calling IShellFolder::EnumObjects();
Is this a known problem?

I am new to namespace extention. I just tried to run it in Windows Vista and got a lot of problems like copying (from extension to windows) is not working, browsing with multiple levels of folders is not working etc.

I am just wondering is it possible to make it work in Windows Vista. If yes, could you please give an idea as to how much change is required.

Microsoft recommends against programming shell extensions in managed languages. See here[^] for details. I don't know if this applies in this instance because I don't know the details of the toolkit: but if the managed code is loaded in-process it does apply and could destabilise the system.

Hi
I am using namespace extension to map
folders on a network drive . Our drive works fine with Opendialogs but old style drive comboboxes doesn't show our drive as a local drive . Is there any way to do this using namspace extensions. For information Galaxy is not listed in drive comboboxes too.Do I have to use windows device driver?

i installed it on my xp machine. i have .net framework 1.1 which was its pre-req. i got Galaxy icon on my computer explorer but when i click it to open... nothing happens.. what could be wrong please guide me. thanks