Russian Qt Forum

Компиляторы и платформы => Windows => Тема начата: koldun90 от Август 10, 2016, 22:05



Название: вопросы по imapi2
Отправлено: koldun90 от Август 10, 2016, 22:05
Здравствуйте решил написать программу для записи дисков для windows
в качестве api использую imapi2
проект делаю в qt

существует небольшая проблема у меня
а именно в методе
put_ClientName класса IDiscFormat2Data

Код
C++ (Qt)
HRESULT put_ClientName(
 [in] BSTR value
);
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364884(v=vs.85).aspx

как я понял из описания данного метода перед записью нужно в числе всего прочего
передать имя своей программы(exeшник моей программы burning.exe)
так вот когда я

вот кусок кода
Код
C++ (Qt)
BSTR imya=BSTR(_T("burning"));
HRESULT res=discformatdata2->put_ClientName(imya)
if (!SUCCEEDED(res))
{
     printf("0x%08x\n",res);
}

код ошибки
Код:
0xC0aa0408
не могу понять в чем дело
судя по коду ошибки и ее описанию The client name is not valid
неправильное имя клиента
хотя у меня процесс burning
пробовал burning.exe заместо burning все равно тоже самое



Название: Re: вопросы по imapi2
Отправлено: gil9red от Август 11, 2016, 00:07
Могу только предложить посмотреть как сделано у других:
раз (https://github.com/Cantek/CodeSamplesFromDifferentProjects/blob/12c1afb55bc53e85c09078a9fe9d164dc046233d/Desktop/C%2B%2B/CD%20Burner%20Sample%20Important%20Parts/DiscFormatData.cpp)
два (https://github.com/lgtkgtv/WindowsSDK7-Samples/blob/e8fe83b043727e71f5179da11fc6228475e7973c/winbase/imapi/imapi2sample/RawWriter.cpp)
три (https://github.com/lgtkgtv/WindowsSDK7-Samples/blob/e8fe83b043727e71f5179da11fc6228475e7973c/winbase/imapi/imapi2sample/erase.cpp)

Заметил также что, у них способ получения имени отличается от вашего:
Код
C++ (Qt)
BSTR appName = ::SysAllocString(L"Imapi2Sample");
hr = eraser->put_ClientName(appName);


Название: Re: вопросы по imapi2
Отправлено: koldun90 от Август 13, 2016, 10:53
спасибо аз информацию
будут вопросы отпишу еще....


Название: Re: вопросы по imapi2
Отправлено: gil9red от Август 13, 2016, 13:25
спасибо аз информацию
будут вопросы отпишу еще....

Помогло?


Название: Re: вопросы по imapi2
Отправлено: koldun90 от Август 13, 2016, 20:10
да помогло
но вот еще такой вопрос допустим я пишу свою прогу для записи
а как нибудь можно эмулировать запись на чистую болванку cd или dvd
просто чтоб добавить виртуальный привод можно поставить alcohol или daemon
а вот как сделать эмуляцию записи на чистые диски cd-r/rw dwb+-r/rw вот вопрос....?

ps привода нету да и если бы был не очень хочется диски портить при отладке


Название: Re: вопросы по imapi2
Отправлено: kambala от Август 13, 2016, 22:36
rw диски не испортишь


Название: Re: вопросы по imapi2
Отправлено: koldun90 от Август 13, 2016, 23:14
а эмулировать нельзя ?просто резак только на работе....


Название: Re: вопросы по imapi2
Отправлено: Bepec от Август 14, 2016, 10:53
Можно, но вам ВСЕ РАВНО придётся тестировать это на реальном железе.
Т.е. вы себе двойную работу задаёте.

PS если уж проектов по эмуляции USB до сих пор, по пальцам пересчитать, то шансов на готовое решение по имитации записи CD/DVD очень мало.


Название: Re: вопросы по imapi2
Отправлено: koldun90 от Август 15, 2016, 22:48
вообщем начал потихоньку разбираться написал функцию записи папки а диск
вот что получилось....
Код
C++ (Qt)
HRESULT MainWindow::writedataoncd()
{
   IDiscFormat2Data *discformatdata=NULL;
   IDiscRecorder2 *discrecorder=NULL;
   IDiscMaster2 *master=NULL;
   IFileSystemImage * image = NULL;
   IFileSystemImageResult * fsiresult = NULL;
   FsiFileSystems fileSystem;
   IFsiDirectoryItem *root;
   IStream *stream;
   BSTR dir = ::SysAllocString(L"C:\\test");
   //инициализируем идискформатдата 2
   HRESULT m_hResult=CoCreateInstance(__uuidof(MsftDiscFormat2Data),NULL,CLSCTX_ALL,
                              __uuidof(IDiscFormat2Data),(void**)&discformatdata);
   if (!SUCCEEDED(m_hResult))
   {
       msg.setText(QString::fromLocal8Bit("Дискформатдата не проинициализирована"));
       msg.exec();
   }
   //инициализируем идискрекордер
   m_hResult = CoCreateInstance(__uuidof(MsftDiscRecorder2), NULL, CLSCTX_INPROC_SERVER,
   __uuidof(IDiscRecorder2), (void**)&discrecorder);
   if (!SUCCEEDED(m_hResult))
   {
       msg.setText(QString::fromLocal8Bit("ошибка инициализации"));
       msg.exec();
   }
   BSTR info=NULL;
   m_hResult = CoCreateInstance(__uuidof(MsftDiscMaster2), NULL, CLSCTX_INPROC_SERVER,
   __uuidof(IDiscMaster2), (void**)&master);
   HRESULT res=master->get_Item(0,&info);  //получили полное имя привода в системе
   if (FAILED(res))  //если  не получили дискмастер
   {
       msg.setText(QString::fromLocal8Bit("Не инициализирован идискмастер"));
       msg.exec();
   }
   //получаем имя
   res=master->get_Item(0,&info);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //инициализируем идискрекордер (привод 0-первый привод в системе
   res=discrecorder->InitializeDiscRecorder(info);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   BSTR appname=::SysAllocString(L"burning");
   res=discrecorder->AcquireExclusiveAccess(false,appname);
   if (!SUCCEEDED(res))
   {
       msg.setText("не получили экслюзивный доступ к устройству");
       msg.exec();
   }
   res=discformatdata->put_Recorder(discrecorder);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //BSTR appname=::SysAllocString(L"burning");
   res=discformatdata->put_ClientName(appname);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
 
   SAFEARRAY *value=NULL;
   res=discformatdata->get_SupportedMediaTypes(&value);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //не закрываем диск для последующей записи
   res=discformatdata->put_ForceMediaToBeClosed(VARIANT_FALSE);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //discformatdata->
   res = CoCreateInstance(CLSID_MsftFileSystemImage,
       NULL, CLSCTX_ALL, __uuidof(IFileSystemImage), (void**)&image);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
 
   res=discformatdata->put_ForceOverwrite(true);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //УСТАНАВЛИВАЕМ ФАЙЛОВУЮ СИСТЕМУ ОБРАЗА
   fileSystem=FsiFileSystemUDF;
   res=image->put_FileSystemsToCreate(fileSystem);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
       return res;
   }
   BSTR mt=BSTR(L"metka");
   res=image->put_VolumeName(mt);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   res=image->get_Root(&root);
 
   if (SUCCEEDED(res))
   {
       root->AddTree(dir,false);
   }
   res=image->CreateResultImage(&fsiresult);
   if (SUCCEEDED(res))
   {
       res=fsiresult->get_ImageStream(&stream);
       if (SUCCEEDED(res))
       {
           msg.setText("образ готов для записи");
           msg.exec();
       }
   }
   if (SUCCEEDED(res))
   {
 
       res=discformatdata->Write(stream);
   }
   if (stream)
   {
       stream->Release();
       stream=NULL;
   }
   if (SUCCEEDED(res))
   {
       printf("disc uspeshnp zapisan\n");
       IMAPI_MEDIA_WRITE_PROTECT_STATE value =
            (IMAPI_MEDIA_WRITE_PROTECT_STATE)0;
 
       res = discformatdata->get_WriteProtectStatus(&value);
   }
   if (!SUCCEEDED(res))
   {
       printf("oshibka zapisi na disk=0x%08x\n\n",res);
   }
   discrecorder->EjectMedia();
   if (SUCCEEDED(res))
   {
       res = discformatdata->put_Recorder(NULL);
   }
   if (image)
   {
       image->Release();
       image = NULL;
   }
   if (fsiresult)
   {
       fsiresult->Release();
       fsiresult=NULL;
   }
   if (discformatdata)
   {
       discformatdata->Release();
       discformatdata=NULL;
   }
   if (discrecorder)
   {
       discrecorder->Release();
       discrecorder=NULL;
   }
   return res;
 
}
 
но соответсвенно есть небольшая проблемка функция записывает содержимое папки на диск
но почему то метод write
Код
C++ (Qt)
res=discformatdata->Write(stream);
 
возвращает
ошибку
Код
C++ (Qt)
0x80004005
судя по описанию ошибки
https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa364892(v=vs.85).aspx

это Unspecified failure.
вся загвоздка в том что данные реально на диск записались корректно(пишу тестовый файл doc)
что может быть?
os windows 7


Название: Re: вопросы по imapi2
Отправлено: koldun90 от Август 24, 2016, 22:04
сумел вроде бы реализовать методы записи папок и файлов
но вопрос остался мне нужно реализовать прогресс бар записи диска
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366443(v=vs.85).aspx
Только мне не совсем понятен момент как мне подключить свой idiscformatdata к обработчику событий
я так понял  WScript.ConnectObject  dataWriter, "dwBurnEvent_"
но как мне это сделать на с++


Название: Re: вопросы по imapi2
Отправлено: mxmedia от Август 11, 2022, 10:13
вообщем начал потихоньку разбираться написал функцию записи папки а диск
вот что получилось....
Код
C++ (Qt)
HRESULT MainWindow::writedataoncd()
{
   IDiscFormat2Data *discformatdata=NULL;
   IDiscRecorder2 *discrecorder=NULL;
   IDiscMaster2 *master=NULL;
   IFileSystemImage * image = NULL;
   IFileSystemImageResult * fsiresult = NULL;
   FsiFileSystems fileSystem;
   IFsiDirectoryItem *root;
   IStream *stream;
   BSTR dir = ::SysAllocString(L"C:\\test");
   //инициализируем идискформатдата 2
   HRESULT m_hResult=CoCreateInstance(__uuidof(MsftDiscFormat2Data),NULL,CLSCTX_ALL,
                              __uuidof(IDiscFormat2Data),(void**)&discformatdata);
   if (!SUCCEEDED(m_hResult))
   {
       msg.setText(QString::fromLocal8Bit("Дискформатдата не проинициализирована"));
       msg.exec();
   }
   //инициализируем идискрекордер
   m_hResult = CoCreateInstance(__uuidof(MsftDiscRecorder2), NULL, CLSCTX_INPROC_SERVER,
   __uuidof(IDiscRecorder2), (void**)&discrecorder);
   if (!SUCCEEDED(m_hResult))
   {
       msg.setText(QString::fromLocal8Bit("ошибка инициализации"));
       msg.exec();
   }
   BSTR info=NULL;
   m_hResult = CoCreateInstance(__uuidof(MsftDiscMaster2), NULL, CLSCTX_INPROC_SERVER,
   __uuidof(IDiscMaster2), (void**)&master);
   HRESULT res=master->get_Item(0,&info);  //получили полное имя привода в системе
   if (FAILED(res))  //если  не получили дискмастер
   {
       msg.setText(QString::fromLocal8Bit("Не инициализирован идискмастер"));
       msg.exec();
   }
   //получаем имя
   res=master->get_Item(0,&info);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //инициализируем идискрекордер (привод 0-первый привод в системе
   res=discrecorder->InitializeDiscRecorder(info);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   BSTR appname=::SysAllocString(L"burning");
   res=discrecorder->AcquireExclusiveAccess(false,appname);
   if (!SUCCEEDED(res))
   {
       msg.setText("не получили экслюзивный доступ к устройству");
       msg.exec();
   }
   res=discformatdata->put_Recorder(discrecorder);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //BSTR appname=::SysAllocString(L"burning");
   res=discformatdata->put_ClientName(appname);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
 
   SAFEARRAY *value=NULL;
   res=discformatdata->get_SupportedMediaTypes(&value);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //не закрываем диск для последующей записи
   res=discformatdata->put_ForceMediaToBeClosed(VARIANT_FALSE);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //discformatdata->
   res = CoCreateInstance(CLSID_MsftFileSystemImage,
       NULL, CLSCTX_ALL, __uuidof(IFileSystemImage), (void**)&image);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
 
   res=discformatdata->put_ForceOverwrite(true);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   //УСТАНАВЛИВАЕМ ФАЙЛОВУЮ СИСТЕМУ ОБРАЗА
   fileSystem=FsiFileSystemUDF;
   res=image->put_FileSystemsToCreate(fileSystem);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
       return res;
   }
   BSTR mt=BSTR(L"metka");
   res=image->put_VolumeName(mt);
   if (!SUCCEEDED(res))
   {
       msg.setText("ошибка");
       msg.exec();
   }
   res=image->get_Root(&root);
 
   if (SUCCEEDED(res))
   {
       root->AddTree(dir,false);
   }
   res=image->CreateResultImage(&fsiresult);
   if (SUCCEEDED(res))
   {
       res=fsiresult->get_ImageStream(&stream);
       if (SUCCEEDED(res))
       {
           msg.setText("образ готов для записи");
           msg.exec();
       }
   }
   if (SUCCEEDED(res))
   {
 
       res=discformatdata->Write(stream);
   }
   if (stream)
   {
       stream->Release();
       stream=NULL;
   }
   if (SUCCEEDED(res))
   {
       printf("disc uspeshnp zapisan\n");
       IMAPI_MEDIA_WRITE_PROTECT_STATE value =
            (IMAPI_MEDIA_WRITE_PROTECT_STATE)0;
 
       res = discformatdata->get_WriteProtectStatus(&value);
   }
   if (!SUCCEEDED(res))
   {
       printf("oshibka zapisi na disk=0x%08x\n\n",res);
   }
   discrecorder->EjectMedia();
   if (SUCCEEDED(res))
   {
       res = discformatdata->put_Recorder(NULL);
   }
   if (image)
   {
       image->Release();
       image = NULL;
   }
   if (fsiresult)
   {
       fsiresult->Release();
       fsiresult=NULL;
   }
   if (discformatdata)
   {
       discformatdata->Release();
       discformatdata=NULL;
   }
   if (discrecorder)
   {
       discrecorder->Release();
       discrecorder=NULL;
   }
   return res;
 
}
 
но соответсвенно есть небольшая проблемка функция записывает содержимое папки на диск
но почему то метод write
Код
C++ (Qt)
res=discformatdata->Write(stream);
 
возвращает
ошибку
Код
C++ (Qt)
0x80004005
судя по описанию ошибки
https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa364892(v=vs.85).aspx

это Unspecified failure.
вся загвоздка в том что данные реально на диск записались корректно(пишу тестовый файл doc)
что может быть?
os windows 7

Не подскажете в чем проблема была?
Столкнулся с подобной - образ создается, но не пишется - на вызове
Код
C++ (Qt)
IDiscFormat2Data->write
получаю ошибку
Код
C++ (Qt)
0x80004005

Пытаюсь писать на диски RW, на R не пробовал.