IMAPIでCD-R/DVD-Rを焼く話

データの作成後に、CD-R/DVD-Rへのライティングまでまとめて行いという話があったので、IMAPIしてみた(・ω・)
まあ、この辺を参考にして。
http://www.codeproject.com/KB/miscctrl/imapi2.aspx


っということで、詳細は上のソースを見るとして、IMAPI(v2)のCOMインタフェース周りのメモ。

初期化

まずはCD/DVDデバイスの一覧を取得するために、MsftDiscMaster2を作ってIDiscMaster2を取得。
次いでIDiscMaster2.IsSupportedEnvironmentにより環境を確認。
IDiscMaster2からレコーダーIDの一覧を取得して、MsftDiscRecorder2を作ってIDiscRecorder2.InitializeDiscRecorder()により初期化を行う。

レコーダがサポートするメディア種別の取得

MsftDiscFormat2Dataを作ってIDiscFormat2Data.IsRecorderSupported()にIDiscRecorder2を指定してサポートを判定。
IDiscFormat2Data.SupportedMediaTypesでIMAPI_MEDIA_PHYSICAL_TYPEの一覧を取得して、レコーダがサポートするメディアを判定。
CD-RならIMAPI_MEDIA_TYPE_CDR、DVD-RならIMAPI_MEDIA_TYPE_DVDDASHRとか。

挿入されているメディア種別の取得

MsftDiscFormat2Dataを作ってIDiscFormat2Data.IsCurrentMediaSupported()にIDiscRecorder2を指定してサポートを判定。
IDiscFormat2Data.RecorderにIDiscRecorder2を設定して、IDiscFormat2Data.CurrentPhysicalMediaTypeにより挿入されているメディア種別を取得する。

空き容量の取得

IDiscFormat2Data.CurrentPhysicalMediaTypeを取得するところまでは、挿入されているメディア種別の取得に同じ。
次いでMsftFileSystemImageを作ってIFileSystemImage3.ChooseImageDefaultsForMediaType()にメディア種別を設定。


マルチセッションの場合の処理は、IFileSystemImage3.MediaHeuristicallyBlankでマルチセッションかどうかを判定。
IFileSystemImage3.MultisessionInterfacesにIDiscFormat2Data.MultisessionInterfacesを設定して、IFileSystemImage3.ImportFileSystem()でインポートを行う。


っで、IFileSystemImage3.FreeMediaBlocksにより空きセクタ数の取得が可能、セクタサイズをかけて空き容量を計算。

ライティング処理

まずはIDiscRecorder2.AcquireExclusiveAccess()で排他。
MsftDiscFormat2Dataを作ってIDiscFormat2Data.RecorderにIDiscRecorder2を設定。
そのほか、IDiscFormat2Data.ClientNameの設定や、IDiscFormat2Data.ForceMediaToBeClosedでクローズするかどうかの設定とかを行う。
あと、MsftDiscFormat2DataをIBurnVerificationにキャストして、IBurnVerification.BurnVerificationLevelで検証レベルの設定なんかも行う。


ライティングするデータの作成手順は次の通り。
まずはMsftFileSystemImageを作ってIFileSystemImage3.ChooseImageDefaults()にIDiscRecorder2を指定。
IFileSystemImage3.FileSystemsToCreateにはFsiFileSystems.FsiFileSystemJoliet | FsiFileSystems.FsiFileSystemISO9660とかを指定して、IFileSystemImage3.VolumeNameにボリュームラベルの名称を設定。
挿入されたメディアがマルチセッションなら既存Discのファイルシステムをインポート。
っで、IFileSystemImage3.RootのIFsiDirectoryItemに対してAddFile()で書き込むファイルのIStreamを追加していき、最後にライティングするイメージのIStreamをIFileSystemImage3.CreateResultImage()、IFileSystemImageResult.ImageStreamから取得。


これでライティングするデータが出来たので、IDiscFormat2Data.Write()に作成したIStreamを喰わせて焼き焼き(・∀・)


最後にIDiscRecorder2.ReleaseExclusiveAccess()でAcquireExclusiveAccess()したものを解放。


あと、書き込み中にキャンセルを行う場合はIDiscFormat2Data.CancelWrite()。
進捗状況を表示するためのコールバックを指定する場合は、ComVisibleをtrueにしておくことを忘れないように(´д`)


っということで、ライティング処理ができましたヽ(´ー`)ノ