在C++中对每个媒体进行格式化的程序

在C++中对每个媒体进行格式化的程序,c++,windows-xp,format,drive,C++,Windows Xp,Format,Drive,问题: 我正试图编写一个程序来格式化任何类型的媒体。 到目前为止,我已经成功地格式化了硬盘分区、闪存、SDRAM和RDX。 但我需要格式化最后一种媒体DVD-RAM。我的程序无法格式化此媒体。 我正在使用fmifs.dll中的FormatEx函数。我完全不知道如何使用这个函数,除了它的名称和它驻留在fmifs.dll中。在我的帮助下,我设法找到了一个使用这个图书馆的图书馆。但它仍然没有给出关于如何使用它的完整信息 我所尝试的: 我正在寻找有关FormatEx及其参数的完整文档,以及每个参数可以接

问题: 我正试图编写一个程序来格式化任何类型的媒体。 到目前为止,我已经成功地格式化了硬盘分区、闪存、SDRAM和RDX。 但我需要格式化最后一种媒体DVD-RAM。我的程序无法格式化此媒体。 我正在使用fmifs.dll中的FormatEx函数。我完全不知道如何使用这个函数,除了它的名称和它驻留在fmifs.dll中。在我的帮助下,我设法找到了一个使用这个图书馆的图书馆。但它仍然没有给出关于如何使用它的完整信息

我所尝试的: 我正在寻找有关FormatEx及其参数的完整文档,以及每个参数可以接受的值。 我试着在谷歌和MSDN上搜索。这就是我发现的。首先,这不是我正在使用的函数。但是,即使把它放在一边,也没有足够的信息说明如何使用函数,比如使用哪些头/库

编辑: 我不必使用FormatEx,如果有其他选择,请告诉我

编辑2: 在进一步的测试中,我注意到如果DVD-RAM的初始文件系统是FAT32,我可以格式化它。但如果是任何UDF修订版,格式化都会失败。
此外,快速格式化会立即失败,常规格式化会在90%以上的进度后失败。但当我检查磁盘内容后,一切都一样。似乎格式根本就没有尝试过。

它是由马克·罗斯诺维奇(Mark Russinovich Sysinovich)编写的,他提供了源代码,如果你在谷歌上搜索fmifs Russinovich,会有很多副本


它是由马克·鲁西诺维奇(MarkRussinovich)写的,他提供了源代码,如果你用谷歌搜索fmifs鲁西诺维奇,会有很多副本


看起来,唯一的障碍是将格式设置为UDF。fmfifs.dll中的FormatEx是一个垫片或辅助工具实用程序,它将格式化任务分派给较低级别的驱动程序,作为Microsoft可安装文件系统基础结构的一部分。IFS基本上允许Microsoft添加对新文件系统的支持

在UDF的情况下,对应的库将是UUDF.DLL,此约定适用于其他文件系统,例如NTFS将由UNTFS.DLL、UFAT.DLL等处理。您的Windows XP系统上是否存在此dll

通过使用depends.exe查看UUDF.dll的导出,我看到了对各种函数的支持,包括臭名昭著的FormatEx。FormatEx似乎是cdecl,查看DISAssembly需要16字节的参数,可能是4个参数。虽然能够直接调用函数是很方便的,但它并没有在任何地方记录下来,弄清楚参数也是一件痛苦的事情。此外,如果可以的话,我认为fmifs.dll会做正确的事情

UDF支持多个版本-您的问题可能是WinXP上的UUDF.dll版本与DVD-RAM格式化时使用的UDF版本存在问题

你可以做的是使用带有控制代码的函数,这将使你能够直接与设备对话。使用SCSI/MMC多媒体命令格式化DVD-RAM应该是可能的-请查阅说明。MMC命令是在T10工作草案中指定的——它们很难掌握,但我相信注册后可以作为来宾下载副本

如果easy-fmifs.dll方法对您不起作用,您将不得不采用艰难的方法,或者找到第三方dll来帮助您

更新:

从MSDN上看,XP Service Pack 2支持IMAPI2映像主控API。使用fmifs.dll的另一种方法是使用IDicFormat2Erase接口的EraseMedia函数擦除光盘,然后使用IFileSystemImage接口的文件系统创建函数格式化为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;

}

看起来,唯一的障碍是将格式设置为UDF。fmfifs.dll中的FormatEx是一个垫片或辅助工具实用程序,它将格式化任务分派给较低级别的驱动程序,作为Microsoft可安装文件系统基础结构的一部分。IFS基本上允许Microsoft添加对新文件系统的支持

在UDF的情况下,对应的库将是UUDF.DLL,此约定适用于其他文件系统,例如NTFS将由UNTFS.DLL、UFAT.DLL等处理。您的Windows XP系统上是否存在此dll

通过使用depends.exe查看UUDF.dll的导出,我看到了对各种函数的支持,包括臭名昭著的FormatEx。FormatEx似乎是cdecl,查看DISAssembly需要16字节的参数,可能是4个参数。虽然能够直接调用函数是很方便的,但它并没有在任何地方记录下来,弄清楚参数也是一件痛苦的事情。此外,我假设fmifs.dll 如果可能的话,我会做正确的事情

UDF支持多个版本-您的问题可能是WinXP上的UUDF.dll版本与DVD-RAM格式化时使用的UDF版本存在问题

你可以做的是使用带有控制代码的函数,这将使你能够直接与设备对话。使用SCSI/MMC多媒体命令格式化DVD-RAM应该是可能的-请查阅说明。MMC命令是在T10工作草案中指定的——它们很难掌握,但我相信注册后可以作为来宾下载副本

如果easy-fmifs.dll方法对您不起作用,您将不得不采用艰难的方法,或者找到第三方dll来帮助您

更新:

从MSDN上看,XP Service Pack 2支持IMAPI2映像主控API。使用fmifs.dll的另一种方法是使用IDicFormat2Erase接口的EraseMedia函数擦除光盘,然后使用IFileSystemImage接口的文件系统创建函数格式化为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;

}

谷歌fmifs russinovich;Alex K.的评论和回答指向MarkRussinovich的FormatEx源代码副本。代码几乎记录了fmifs.dll FormatEx函数。函数本身从未被记录。您是否尝试将UDF或FAT32作为格式化参数传递给FormatEx以格式化DVD-RAM?@Anthill,我正在传递FAT32。通过测试不同的东西,我注意到当DVD-RAM已经格式化为FAT32时,我可以格式化它,但当它的初始格式为UDF时,我不能。我想这是FormatEx的一个限制。当试图格式化为UDF时,您的quickformat参数是什么?你传递的信息是假的吗;Alex K.的评论和回答指向MarkRussinovich的FormatEx源代码副本。代码几乎记录了fmifs.dll FormatEx函数。函数本身从未被记录。您是否尝试将UDF或FAT32作为格式化参数传递给FormatEx以格式化DVD-RAM?@Anthill,我正在传递FAT32。通过测试不同的东西,我注意到当DVD-RAM已经格式化为FAT32时,我可以格式化它,但当它的初始格式为UDF时,我不能。我想这是FormatEx的一个限制。当试图格式化为UDF时,您的quickformat参数是什么?你传错了吗?谢谢你的回复。我已经安装了DVD-RAM驱动程序,在windows中使用格式选项可以轻松快速地完成工作。但我无法使用windows搜索找到uudf.dll。要么它正在使用其他dll,要么它隐藏在某个地方。感谢您提供的示例代码。我一有机会就去看看。谢谢你的回复。我已经安装了DVD-RAM驱动程序,在windows中使用格式选项可以轻松快速地完成工作。但我无法使用windows搜索找到uudf.dll。要么它正在使用其他dll,要么它隐藏在某个地方。感谢您提供的示例代码。我一有机会就去看看。