FUSEって知ってますか?Unix、Linux用のソフトウェアで、オリジナルファイルシステムを簡単に作れる面白いソフトウェアです。
Filesystem in Userspace - Wikipedia
このFUSEのWindows版ともいえるのがDokanです。
Dokan - User mode file system library for windows with FUSE Wrapper
これを使えば、オリジナルデバイスをファイルシステム経由で制御したり、ネットサービスをファイルシステムとしてマウントしたりできます。Flickrをマウントした人もいるみたいですね。
WindowsでもFUSEの魅力を「Dokan」|オープンソース・ソフトウェア、ITニュースを毎日紹介するエンジニア、デザイナー向けブログ
そんな面白いDokanには、指定したフォルダをドライブとしてマウントするサンプルが付いています。Dokanの挙動を理解するにはサンプルをビルドしてみるのが一番なんですが、ビルドにちょっとコツが必要だったのでまとめておきます。
今回は、Visual C++ 2010 Expressでビルドしてみました。Visual C++ 2010 Expressのダウンロード/インストール方法はこちらを見てください。
Visual Studio 2010 Expressのダウンロード方法(Visual C++,Visual C#,Visual Basicなど)
Dokanインストール
こちらからDokanをダウンロードしてインストールします。
Dokan - User mode file system library for windows with FUSE Wrapper
今回はDokanライブラリ0.6.0を使用しました。
プロジェクト作成
Visual C++ 2010 Expressでプロジェクトを作成します。Win32 コンソールアプリケーション(空のプロジェクト)を生成してください。今回は、mirrorという名前でプロジェクトを作りました。
一応、手順を載せておきます。
プロジェクト設定
サンプルのソースコードは
C:\Program Files (x86)\Dokan\DokanLibrary\sample\mirror\mirror.c (64bit OSの場合)
C:\Program Files\Dokan\DokanLibrary\sample\mirror\mirror.c (32bit OSの場合)
です。このファイルを先ほど作成したプロジェクトに追加しましょう。
また、Dokanライブラリを使うには、
C:\Program Files (x86)\Dokan\DokanLibrary\dokan.lib (64bit OSの場合)
C:\Program Files\Dokan\DokanLibrary\dokan.lib (32bit OSの場合)
が必要になります。
このファイルも先ほど作成したプロジェクトに追加しましょう。 プロジェクトへの追加方法は簡単です。ファイルをソリューションエクスプローラ上のプロジェクト名(mirror)にD&Dするだけです。
プロジェクトにmirror.cとdokan.libが追加された状態がこちらです。
次にプロジェクトの設定を行います。ソリューションエクスプローラのmirrorを右クリックして、プロパティを選択します。
mirrorプロパティページが表示されるので、左上の[構成]をすべての構成に変更して、[C/C++]-[全般]-[追加のインクルードディレクトリ]に
C:\Program Files (x86)\Dokan\DokanLibrary (64bit OSの場合)
C:\Program Files\Dokan\DokanLibrary (32bit OSの場合)
を設定します。
[OK]を押してプロパティページを閉じます。
ビルド
では、ビルドです。。。エラーが出ますね。
c:\program files (x86)\dokan\dokanlibrary\sample\mirror\mirror.c(29): fatal error C1083: include ファイルを開けません。'fileinfo.h': No such file or directory
fileinfo.hは必要ないので、#include "fileinfo.h" の行をコメントアウトします。 再度ビルドします。。。まだエラーが出ますね。
c:\program files (x86)\dokan\dokanlibrary\sample\mirror\mirror.c(1100): error C2440: '=' : 'int (cdecl *)(LPCWSTR,DWORD,DWORD,DWORD,DWORD,PDOKAN_FILE_INFO)' から 'int (stdcall *)(LPCWSTR,DWORD,DWORD,DWORD,DWORD,PDOKAN_FILE_INFO)' に変換できません。
これは呼び出し規約が異なる為に起きるエラーです。エラーが起きている行を見てみると、
dokanOperations->CreateFile = MirrorCreateFile;
と書かれてますね。
このdokanOperations->CreateFileは呼び出し規約stdcallの関数を期待しています。一方、MirrorCreateFile()は呼び出し規約cdeclです。呼び出し規約が合わないためにエラーになっているんです。
コンパイラオプション/Gzを付ける事で正常にビルド出来る様になりますが、これだと今後使いづらいので、ソースを修正することにします。
MirrorCreateFile()の定義を
static int MirrorCreateFile(
から
static int DOKAN_CALLBACK
MirrorCreateFile(
に修正します。
dokan.h(追加のインクルードディレクトリで指定したフォルダにあります)を見ると、DOKAN_CALLBACKは
define DOKAN_CALLBACK __stdcall
と定義されていますね。これにより、MirrorCreateFile()が呼び出し規約__stdcallでビルドされます。
MirrorCreateFile()以外にも同様のエラーが出ているはずですので、エラーが出ている関数全てを同様に修正します。
最後に、main()の定義を
int __cdecl wmain(ULONG argc, PWCHAR argv)
から
int wmain(ULONG argc, PWCHAR argv)
に変更します。これでビルドすればmirror.exeが生成されます。
サンプル実行
mirror.exeに以下のオプションを付けて実行します。 /r c:\ /l z /t 1 /d /s
Visual C++ 2010 Expressでデバッグする際には、mirrorプロパティページの[デバッグ]-[コマンドライン引数]に設定します。
実行すると、エクスプローラにDOKAN(Z:)というドライブが現れています。中身を見ると、/rオプションで指定したフォルダの中身がそのまま見えます。だからmirrorなんですね。
これだけだと、substコマンドとなんら変わりませんが、これを応用すればFlickrをマウントしたり、RAMドライブを作ったり、オリジナルのデバイスをファイルシステム経由で制御したりなんてことが可能になります。
ぜひ試してみてください。