1

問題:
あらゆる種類のメディアをフォーマットするプログラムを作成しようとしています。これまでのところ、ハードディスク パーティション、フラッシュ メモリ、SDRAM、RDX をフォーマットできました。
しかし、フォーマットする必要がある最後のタイプのメディア (DVD-RAM) があります。私のプログラムはこのメディアをフォーマットできません。の関数
を使用しています。この関数の使い方がまったくわかりませんでした。その名前と、. これの助けを借りて、このライブラリを使用する簡単なプログラムを見つけることができました。それでも、それを使用する方法に関する完全な情報は提供されません。 FormatExfmifs.dllfmifs.dll

私が試したこと:、そのパラメーター、および各パラメーターが取り得る正確な値
に関する完全なドキュメントを探しています。 Google と MSDN で検索してみました。これが私が見つけたものです。まず第一に、これは私が取り組んでいる機能ではありません。しかし、それを脇に置いても、関数の使用方法に関する十分な情報はありません (どのヘッダー/ライブラリを使用するかなど)。FormatEx

編集:使用する代替手段がある場合
は、使用する必要はありません。教えてください。FormatEx

編集 2:
さらなるテスト中に、最初のファイル システムが「FAT32」の場合、DVD-RAM をフォーマットできることに気付きました。ただし、「UDF」リビジョンのいずれかの場合、フォーマットは失敗します。
さらに、クイック フォーマットは即座に失敗し、通常のフォーマットは 90% 以上の進行後に失敗します。しかし、後でディスクの内容を確認すると、すべて同じです。あたかもフォーマットが試みさえしなかったかのように。

4

2 に答える 2

7

ソースを公開した Mark Russinovich (Sysinternals) によって書かれまし

http://pete.akeo.ie/2012/04/chkdskx-and-formatx-by-mark-russinovich.html

于 2012-11-06T14:14:56.733 に答える
1

あなたが持っている唯一の障害は、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;

}
于 2012-11-14T10:58:38.693 に答える