程序以格式化C 中的每个媒体

Program to format every media in c++

本文关键字:媒体 格式化 程序      更新时间:2023-10-16

问题:
我正在尝试编写一种格式化任何类型媒体的程序。到目前为止但是,我需要格式化的最后一种媒体(DVD-RAM)。我的程序无法格式化此媒体。
我正在使用fmifs.dll中的FormatEx函数。我绝对不知道如何使用此功能,除了它的名称,并且它位于fmifs.dll中。在此的帮助下,我设法找到了一个使用此库的简单程序。然而,它仍然没有提供有关如何使用它的完整信息。

我尝试了什么:
我正在寻找有关FormatEx的完整文档,其参数以及每个参数可以采用的值。
我尝试在Google和MSDN上搜索。这就是我发现的。首先,这不是我正在使用的功能。但是,即使将其放在一边,也没有足够的有关如何使用该功能的信息(例如要使用哪些标题/库)。

编辑:
如果有替代方案,请告诉我,我不必使用FormatEx

编辑2:
在进一步的测试中,我注意到如果DVD-RAM的初始文件系统为" FAT32",我可以格式化DVD-RAM。但是,如果是" UDF"修订格式失败。
此外,快速格式会立即失败,并且在90%以上的进展后,常规格式失败。但是,当我检查磁盘内容时,它都相同。好像格式甚至没有尝试。

它是由马克·罗西诺维奇(Mark Russinovich)(sysinternals)撰写的,他可以使用该来源,如果您为 fmifs russinovich 。。>

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

看来,您拥有的唯一绊脚石是格式化为UDF。fmfifs.dll中的formatex是一个垫片(或助手)实用程序,它是Microsoft可安装的文件系统基础结构(IFS)的一部分,将格式任务分配到较低级别的驱动程序。IF基本上允许Microsoft添加对新文件系统的支持。

在UDF的情况下,相应的库将udf.dll(该约定为其他文件系统保留,例如NTFS将由UNTFS.DLL,UFAT.DLL等处理)。Windows XP系统上是否存在此DLL?

使用deweds.eexe查看uudf.dll的导出,我看到了包括臭名昭著的formatex在内的各种功能的支持。formatex似乎是cdecl,并且(查看解雇)期望有16个字节(大概是4个参数)。虽然能够直接调用该函数很方便,但在任何地方都没有记录下来,这将是一个痛苦的问题来弄清楚这些论点。而且,我认为fmifs.dll如果可以的话会做正确的事情。

UDF支持几个修订版(请参阅OSTA规范) - 您的问题很可能是您的WinXP上的Uudf.dll版本在UDF版本上存在问题。

可以做的是将DeviceIocontrol函数与IOCTL_SCSCI_PASSHHTHROUGH_DIRECT CONTROR代码一起使用,该函数将使您直接与设备进行交谈。应该可能使用SCSI/MMC(多媒体命令)格式化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)2。接口的filesystoccoteate()函数以将其格式化为UDF。潜在的比设备iocontrol路线更简单。

由于我从未这样做,所以我决定将一个快速的例子放在一起。快速&肮脏和未经测试(在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;
}