あなたが持っている唯一の障害は、UDF へのフォーマットのようです。fmfifs.dll の FormatEx は、Microsoft のインストール可能なファイル システム インフラストラクチャ ( IFS ) の一部として、書式設定タスクを下位レベルのドライバーにディスパッチする shim (またはヘルパー) ユーティリティです。基本的に、IFS により、Microsoft は新しいファイル システムのサポートを追加できます。
UDF の場合、対応するライブラリは UUDF.DLL になります (この規則は他のファイルシステムにも当てはまります。たとえば、NTFS は UNTFS.DLL や UFAT.DLL などによって処理されます)。この dll は Windows XP システムに存在しますか?
depends.exe を使用した UUDF.dll のエクスポートを見ると、悪名高い FormatEx を含むさまざまな機能がサポートされていることがわかります。FormatEx は cdecl のようで、(逆アセンブルを見ると) 16 バイトの引数 (おそらく 4 つの引数) が必要です。関数を直接呼び出すことができれば便利ですが、どこにも文書化されておらず、引数を理解するのは面倒です。さらに、可能であれば fmifs.dll が正しいことをすると思います。
UDF はいくつかのリビジョンをサポートしています ( OSTA 仕様を参照) - 問題は、WinXP 上の UUDF.dll のバージョンに、DVD-RAM がフォーマットされている UDF のバージョンに問題がある可能性があります。
代わりにできることは、デバイスと直接通信できるようにするIOCTL_SCSCI_PASSHTTHROUGH_DIRECT制御コードでDeviceIOControl関数を使用することです。SCSI/MMC (Multi-Media-Commands) を使用して DVD-RAM をフォーマットできるはずです。FORMAT_UNIT コマンドの説明を参照してください。MMC コマンドはhttp://www.t10.org/drafts.htm#MMC_Family T10 ワーキング ドラフトで指定されています。入手するのは面倒ですが、登録後にゲストとしてコピーをダウンロードできると思います。
簡単な (fmifs.dll) 方法がうまくいかない場合は、難しい方法で行うか、サードパーティの dll を見つけて支援する必要があります。
アップデート:
MSDN を見ると、XP Service Pack 2 から IMAPI2 (Image Mastering API) がサポートされています。fmifs.dll を使用する代わりに、IDicFormat2Erase インターフェイスの EraseMedia() 関数を使用してディスクを消去してから、IFileSystemImage インターフェイスの FileSystemsToCreate( ) UDF にフォーマットする関数。DeviceIOControl ルートより単純な可能性があります。
私はこれをやったことがないので、簡単な例をまとめることにしました。それは速くて汚れていて、テストされていません (DVD-RW で UDF rev 2.50 ファイルシステムを作成しただけです) が、出発点です (Visual Studio 2012):
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <Windows.h>
#include <imapi2.h>
#include <imapi2fs.h>
#include <imapi2error.h>
#include <imapi2fserror.h>
#include <comdef.h>
void ShowComError(HRESULT hr)
{
LPWSTR lpMsgBuf;
DWORD ret;
std::cout << "Failed - HRESULT = 0x" << std::hex << hr << std::endl;
ret = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle(TEXT("imapi2.dll")),
hr,
0,
(LPWSTR) &lpMsgBuf,
0, NULL );
if(ret)
{
std::wcout << L"HRESULT: " << lpMsgBuf << std::endl;
LocalFree(lpMsgBuf);
}
}
int main()
{
IDiscMaster2* ppMaster = NULL;
IDiscRecorder2* ppRecorder = NULL;
IDiscFormat2Erase* ppFormat2 = NULL;
IDiscFormat2Data* ppFormat2Data = NULL;
IFileSystemImage* ppFileImage = NULL;
IStream* fs = NULL;
IFileSystemImageResult* res = NULL;
HRESULT hr = CoInitialize(NULL);
BSTR clientName = SysAllocStringLen(L"TestBurner", lstrlen(L"TestBurner"));
SAFEARRAY* multi = NULL; // multi-sessions
hr = CoCreateInstance(__uuidof(MsftDiscMaster2),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IDiscMaster2),
(void **) &ppMaster);
if (FAILED(hr))
{
ShowComError(hr);
//nothing-wrong-with-a-goto-when-its-heart's-in-the-right-place ;)
goto Clean_Up;
}
hr = CoCreateInstance(__uuidof(MsftDiscRecorder2),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IDiscRecorder2),
(void **) &ppRecorder);
if (FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = CoCreateInstance(__uuidof(MsftDiscFormat2Erase),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IDiscFormat2Erase),
(void**) &ppFormat2);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = CoCreateInstance(__uuidof(MsftDiscFormat2Data),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IDiscFormat2Data),
(void**) &ppFormat2Data);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = CoCreateInstance(__uuidof(MsftFileSystemImage),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IFileSystemImage),
(void**) &ppFileImage);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
// got here - get the optical drives
LONG countDevices;
hr = ppMaster->get_Count(&countDevices);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
VARIANT_BOOL supported;
hr = ppMaster->get_IsSupportedEnvironment(&supported);
// check if it's supported - if yes we use it to format
// and then break out...
if(SUCCEEDED(hr) && supported == VARIANT_TRUE)
{
BSTR deviceName;
for(LONG i = 0; i < countDevices; i++)
{
hr = ppMaster->get_Item(i, &deviceName);
if(SUCCEEDED(hr))
{
std::wcout << L"Using: " << deviceName << std::endl;
hr = ppRecorder->InitializeDiscRecorder(deviceName);
if(FAILED(hr)) goto Clean_Up;
hr = ppRecorder->AcquireExclusiveAccess(VARIANT_TRUE, clientName);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = ppFormat2->put_Recorder(ppRecorder);
if(FAILED(hr)) goto Clean_Up;
// need to set client_name before erasing
hr = ppFormat2->put_ClientName(clientName);
if(FAILED(hr)) ShowComError(hr);
//SysFreeString(clientName);
BSTR owner = NULL;
hr = ppRecorder->get_ExclusiveAccessOwner(&owner);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
if(owner)
{
std::wcout << owner << std::endl;
SysFreeString(owner);
}
// erase the disc
hr = ppFormat2->put_FullErase(VARIANT_TRUE);
if(FAILED(hr)) goto Clean_Up;
hr = ppFormat2->EraseMedia();
if(FAILED(hr))
{
ShowComError(hr); // Need to pull eventual errors out of imapi2error omitted...
//goto Clean_Up;
}
hr = ppFormat2Data->put_Recorder(ppRecorder);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = ppFormat2Data->put_ClientName(clientName);
if(FAILED(hr)) ShowComError(hr);
hr = ppFormat2->IsCurrentMediaSupported(ppRecorder, &supported);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
VARIANT_BOOL blank;
hr = ppFormat2Data->get_MediaHeuristicallyBlank(&blank);
if(blank == VARIANT_FALSE)
{
hr = ppFormat2Data->get_MultisessionInterfaces(&multi);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
}
/*hr = ppFileImage->ChooseImageDefaults(ppRecorder);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}*/
FsiFileSystems imported = FsiFileSystemNone;
if(multi)
{
hr = ppFileImage->put_MultisessionInterfaces(multi);
if(FAILED(hr))
{
ShowComError(hr);
}
hr = ppFileImage->ImportFileSystem(&imported);
}
if(imported == FsiFileSystemNone || imported == FsiFileSystemUnknown)
{
imported = FsiFileSystemUDF;
// ask for UDF revision 2.50
hr = ppFileImage->put_UDFRevision(0x250);
if(FAILED(hr))
{
ShowComError(hr);
}
}
hr = ppFileImage->put_FileSystemsToCreate(imported);
if(FAILED(hr))
{
ShowComError(hr);
}
hr = ppFileImage->CreateResultImage(&res);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = res->get_ImageStream(&fs);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = ppFormat2Data->put_ForceOverwrite(VARIANT_TRUE);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = ppFormat2Data->Write(fs);
if(FAILED(hr))
{
ShowComError(hr);
goto Clean_Up;
}
hr = ppRecorder->EjectMedia();
break;
}
}
}
// clean up
Clean_Up:
if(res) res->Release();
if(fs) fs->Release();
if(multi) SafeArrayDestroy(multi);
if(clientName) SysFreeString(clientName);
if(ppFileImage) ppFileImage->Release();
if(ppFormat2Data) ppFormat2Data->Release();
if(ppFormat2) ppFormat2->Release();
if(ppRecorder) ppRecorder->Release();
if(ppMaster) ppMaster->Release();
CoUninitialize();
/**/
std::cout << "Press any key to continue..." << std::endl;
std::cin.get();
return 0;
}