アプリケーションにディスクフォーマットを組み込む方法

戻る

Windows95が発表された当時は,フォーマットを行うことのできるAPIは一切公開 されていませんでした.しかし,意外とフォーマットを自分のアプリケーションで 行うという要求が以外とあるようで、その後正式に公開されたAPIがあります. また,マイクロソフトは非公開にしているようですが,フォーマットやチェック ディスクを実行するためのAPIが,WindowsNT4.0に存在することが判明しましたので, それについても紹介したいと思います.

2-1 Windows95/98/NT4.0で行えるフォーマット処理

フォーマットを行う手段として,以前はFORMATコマンド呼び出すか,エクスプローラ のメニューから「フォーマット(M)」を選ぶしかありませんでした.
SHFormatDrive は,エクスプローラのメニューから表示されるフォーマットダイアログ ボックスを表示する,Windows95/98/NT4.0 で共通利用できるAPIです.
実際に求められるのは,アプリケーション内部にフォーマット処理を持っているように 見せることができるようなAPIですが,ほとんどの場合このAPIでも足りることが多い のではないかと思われます.


表2-1:Windows9x/NT4.0で共通に利用できるAPI SHFormatDrive
DWORD WINAPI SHFormatDrive(HWND hWnd, UINT uDrive, UINT uFmtId, UINT uOptions)
フォーマットダイアログボックスを表示する

引数
HWND hWnd ... 呼び出し元のウィンドウハンドル
UINT uDrive ... ドライブ番号(A: == 0)
UINT uFmtId ... SHFMT_ID_DEFAULTを指定する
UINT uOptions ... オプションフラグ
 SHFMT_OPT_FULL ... 通常フォーマットを行う
 SHFMT_OPT_SYSONLY ... システムディスクを作成
 0 ... クイックフォーマットを規定値にする

戻り値
 物理フォーマットID 正常終了
 0xFFFFFFFFL フォーマット時にエラーが発生した
 0xFFFFFFFEL フォーマットはキャンセルされた
 0xFFFFFFFDL このドライブはフォーマットできない

コラム●フォーマット時のシステムエラーメッセージを止めるには

フォーマットを行うドライブにディスクが挿入されていなかった場合など,システム がエラーメッセージを表示させ,再試行を行うかキャンセルするかを選択できる ようにします.もし,このAPIを呼び出したときにディスクがセットされていないとき には,システムがエラーメッセージを表示させます. このようなシステムが表示するエラーメッセージボックスを表示させないようにする には,Win32 API SetErrorMode を利用します.


表2-A:SetErrorMode
UINT SetErrorMode(UINT uErrorMode)
一連のエラーに対するオペレーティング システムの処理方法を制御する

引数
UINT uErrorMode
以下の値を指定する
SEM_FAILCRITICALERRORS
クリティカルエラーハンドラメッセージボックスを
表示するようなエラーが起きたときでも,
オペレーティングシステムは
メッセージボックスを表示しない
SEM_NOALIGNMENTFAULTEXCEPT
x86プロセッサには影響しない
SEM_NOGPFAULTERRORBOX
一般保護違反エラーが起きたとき,
オペレーティング システムは一般保護違反
メッセージボックスを表示しない
SEM_NOOPENFILEERRORBOX
オペレーティングシステムが
ファイルを見つけられなかったとき
メッセージボックスを表示しない

戻り値
 以前の状態を返す

例2-A:SetErrorModeの利用例
   UINT uMode;

   uMode = SetErrorMode(0);
   SetErrorMode(uMode & !SEM_FAILCRITICALERRORS);
   dwResult = SHFormatDrive(hMainWnd, 0, SHFMT_ID_DEFAULT, 0);
   SetErrorMode(uMode);

ディスクアクセスエラーを起こしてもエラーダイアログボックスが表示されないようにする


2-2 ダイアログボックスを表示させないようにするには

SHFormatDrive ではダイアログボックスを表示させずに処理を行うことができません. そのような処理を行う必要がある場合は,他の方法で行う必要があります.
FORMAT.COM を呼び出すのも1つの方法ですが,それ以外に何かないかを考えて 見ましょう.まずは,FORMAT.COM を覗いてみます.

2-3 WindowsNTフォーマットコマンドの正体

WindowsNTのフォーマットやチェックディスク機能はWindows95/98と異なり, 完全に32ビットアプリケーションとして作成されています.
フォーマットコマンドのファイル名は,FORMAT.COM になっています. Windows95/98 の FORMAT.COMは,MS-DOSアプリケーションですが,WindowsNTでは PEフォーマットの32ビット実行ファイルです.
ファイル拡張子を.COMにしているのは,いままでこのコマンドを呼び出す以外に, フォーマットを自分のアプリケーションで行う方法を提供していなかったからでは ないかと思われます.このため,フォーマットコマンドを呼び出す,MS-DOS, Win16 アプリケーション, 95/98対応の32ビットアプリケーションをWindowsNTでも 正常に動作させるには,フォーマットコマンドの拡張子を.COMにしなければ ならなかったと推測できます.フォーマットコマンド以外にも,いくつかのコマンド の拡張子が COM になっています.

例2-1:FORMAT.COMの正体(DUMPBIN.EXE /ALL FORMAT.COM の出力結果)

Dump of file format.com PE signature found ← 32ビットのPEヘッダを持っている File Type: EXECUTABLE IMAGE ← 実行形式のイメージであることを示している FILE HEADER VALUES 14C machine (i386) 5 number of sections 32E1815C time date stamp Sun Jan 19 11:05:16 1997 0 file pointer to symbol table 2E3 number of symbols E0 size of optional header 302 characteristics Executable 32 bit word machine Debug information stripped : : :


例2-2:WindowsNT4.0 ServicePack3 のシステムディレクトリに存在するCOMファイル

96/10/29 12:00a 23,520 chcp.com 96/10/29 12:00a 64,578 command.com 97/05/12 12:00a 33,408 DISKCOMP.COM 97/05/12 12:00a 29,792 DISKCOPY.COM 97/05/12 12:00a 61,120 FORMAT.COM 96/10/29 12:00a 35,296 graftabl.com 96/10/29 12:00a 21,086 graphics.com 96/10/29 12:00a 17,003 kb16.com 96/10/29 12:00a 26,752 keyb.com 96/10/29 12:00a 1,540 loadfix.com 96/10/29 12:00a 44,032 mode.com 96/10/29 12:00a 41,296 more.com 96/10/29 12:00a 29,648 tree.com 96/10/29 12:00a 21,376 win.com * command.com は,仮想DOSマシンのコマンドプロンプト ですので,16ビット(DOS)アプリケーションです. 他にもDOSアプリケーションがあるかもしれません.


例2-3:FORMAT.COMのモジュール依存関係(DUMPBIN /DEPENDENTS FORMAT.COMの出力結果)

Image has the following dependencies: ulib.dll ifsutil.dll ntdll.dll KERNEL32.dll



2-4 WindowsNTでフォーマットをサポートするDLL

フォーマットコマンドは,32ビットアプリケーションであるということは, DUMPBIN.EXE で利用しているDLLを参照できることになります.
そこで,
DUMPBIN /DEPENDENTS FORMAT.COM
を実行してみるといくつかの見慣れないDLLが利用されていることが分かります.
さらに,
DUMPBIN /IMPORTS FORMAT.COM
で利用しているDLLの関数を見てみると,ULIB.DLL, IFSUTIL.DLL はフォーマットの 処理に関係したAPIを持っていることが分かります.
SHFormatDrive は SHELL32.DLL にあるAPIですが,このAPIがULIB.DLLやIFSUTIL.DLL を利用しているのならどこかに形跡があるのではないかと思い,手当たり次第に DUMPBIN.EXE を実行してみると,FMIFS.DLL に突き当たりました.
しかし,SHELL32.DLLがFMIFS.DLL を直接呼んで処理を行っている訳ではないようです. そこで,MSDNなどで,FMIFS.DLL や Format APIについて調べてみましたが, 何も得られず,何も分からないまま調査を止めていました.
しかし,最近になって FMIFS.DLL の情報を公開しているWebサイトを見つけました. このサイトには,FMIFS.DLL が持つAPIのうち,FormatEx, Chkdsk の利用例が あります.それ以外にもFMIFS.DLL がエクスポートしているAPIがいくつかありますが, この原稿を執筆している時点では,これらのAPIは正式に公開されていませんので, 利用するときは,OSがバージョンアップされたときに利用できなくなる可能性がある ことに注意してください.なお,このWebサイトにはサンプルソースも公開して ありました.(* URLは参考文献を参照)

<FMIFS.DLLがエクスポートしているAPI>
1 0 000020E7 Chkdsk 2 1 000022B2 ChkdskEx 3 2 00001F30 DiskCopy 4 3 00001BA0 EnableVolumeCompression 5 4 000026CC Extend 6 5 00001582 Format 7 6 000018A0 FormatEx 8 7 00002018 InitializeFmIfs 9 8 00001C01 QuerySupportedMedia 10 9 00001D48 SetLabel

2-5 プログラムについて

SHFormatDrive を呼び出してフォーマットを行います.
コマンドを実行すると,フォーマットダイアログボックスを表示します. このダイアログボックスを閉じると,SHFormatDrive から制御が戻り,終了コードを メッセージボックスで表示します.

>SHFORMAT [/full | /sys] A: ... A:ドライブをフォーマットする
/full ... SHFMT_OPT_FULLを設定する /sys ... SHFMT_OPT_SYSONLYを設定する

●ソースファイル

SHFORMAT.EXE
 SHFMTDRV.H(SHFromatDrive を利用するためのヘッダーファイル)
 SHFORMAT.C(ソースファイル)
 SHFORMAT.RC(リソースファイル)
 SHFORMAT.ICO(アイコンファイル)
 MAKEFILE(メイクファイル)