Проблема:
Я пытаюсь написать программу, которая форматирует любой тип медиа.
Пока что мне удалось отформатировать разделы жесткого диска, флэш-память, SDRAM, RDX.
Но есть последний тип носителя (DVD-RAM), который мне нужно отформатировать. Моя программа не может отформатировать этот носитель.
Я использую FormatEx
функция в fmifs.dll
, Я понятия не имел, как использовать эту функцию, за исключением ее имени и того, что она находится в fmifs.dll
, с помощью этот Мне удалось найти простая программа который использует эту библиотеку. Тем не менее, он не дает полной информации о том, как его использовать.
Что я пробовал:
Я ищу полную документацию о FormatEx
его параметры и какие значения может принимать каждый параметр.
Я пытался искать в Google и MSDN. это это то, что я нашел. Прежде всего, это не та функция, с которой я работаю. Но даже если оставить это в стороне, недостаточно информации о том, как использовать функцию (например, какие заголовки / библиотеки использовать).
РЕДАКТИРОВАТЬ:
Я не должен использовать FormatEx
если есть альтернатива, пожалуйста, сообщите.
РЕДАКТИРОВАТЬ 2:
Во время дальнейшего тестирования я заметил, что могу отформатировать DVD-RAM, если его исходная файловая система — «FAT32». Но если это какая-либо из «UDF» ревизий, то форматирование завершится неудачно.
Кроме того, быстрое форматирование завершается неудачно сразу же, а обычное форматирование не выполняется после 90% прогресса. Но когда я проверяю содержимое диска после этого все равно. Как будто формат даже не пытался.
Он был написан Марком Руссиновичем (Sysinternals), который сделал источник доступным, есть много копий, которые можно стучать, если вы Google для фмифы руссинович.
http://pete.akeo.ie/2012/04/chkdskx-and-formatx-by-mark-russinovich.html
Кажется, что единственным камнем преткновения является форматирование в UDF. FormatEx в fmfifs.dll — это утилита shim (или помощник), которая отправляет задачу форматирования на драйвер более низкого уровня как часть устанавливаемой инфраструктуры файловой системы Microsoft (IFS). IFS в основном позволяет Microsoft добавлять поддержку новых файловых систем.
В случае UDF соответствующая библиотека будет UUDF.DLL (это соглашение выполняется для других файловых систем, например, NTFS будет обрабатываться UNTFS.DLL, UFAT.DLL и т. Д.). Это dll присутствует в вашей системе Windows XP?
Глядя на экспорт UUDF.dll с использованием зависящего от.exe файла, я вижу поддержку различных функций, в том числе печально известного FormatEx. FormatEx выглядит как cdecl и (глядя на разборку) ожидает 16 байтов аргументов (вероятно, 4 аргумента). Хотя было бы удобно иметь возможность вызывать функцию напрямую, это нигде не задокументировано, и было бы сложно выяснить аргументы. Более того, я предполагаю, что fmifs.dll будет делать правильные вещи, если сможет.
UDF поддерживает несколько ревизий (см. спецификацию OSTA) — ваша проблема может заключаться в том, что ваша версия UUDF.dll на WinXP имеет проблемы с версией UDF, в которой отформатирован ваш DVD-RAM.
Что ты мог сделать вместо этого будет использовать DeviceIOControl функция с IOCTL_SCSCI_PASSHTHROUGH_DIRECT управляющий код, который позволит вам напрямую общаться с устройством. Форматирование DVD-RAM с использованием SCSI / MMC (Multi-Media-Commands) должно быть возможным — посмотрите описание Команда FORMAT_UNIT. Команды MMC указаны в http://www.t10.org/drafts.htm#MMC_Family Т10 рабочие черновики — их трудно достать, но я считаю, что после регистрации можно скачать копии в качестве гостя.
Если простой (fmifs.dll) способ не работает у вас, вам придется сделать это трудным путем или найти стороннюю dll, которая поможет вам.
Обновить:
Что касается MSDN, IMAPI2 (Image Mastering API) поддерживается из XP Service Pack 2. Альтернативой использованию fmifs.dll может быть использование функции EraseMedia () интерфейса IDicFormat2Erase для стирания диска, а затем использование FileSystemsToCreate интерфейса IFileSystemImage. ) функция для форматирования в UDF. Потенциально проще, чем маршрут DeviceIOControl.
Так как я никогда не делал этого, я решил собрать быстрый пример. Это быстро & грязный и непроверенный (создал файловую систему UDF rev 2.50 на DVD-RW и все), но это отправная точка (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;
}