Я пытаюсь использовать интерфейс IFileSystemImage2 для создания ISO с несколькими загрузочными записями, используя Imapi2.
Для этого я должен быть в состоянии использовать put_BootImageOptionsArray
проходя в SAFEARRAY*
из VT_DISPATCH
тип, т.е. COM указатели типа IBootOptions
для каждой конфигурации параметров загрузки. В качестве короткой демонстрации у меня есть следующий код (я только один создал IBootOptions
в этом случае):
SAFEARRAYBOUND bounds[1];
bounds[0].cElements = 1;
bounds[1].lLbound = 0;
IBootOptions* BootOptionsArrayData = NULL;SAFEARRAY* Array = SafeArrayCreateEx(VT_DISPATCH,
1,
bounds,
(void*) &IID_IBootOptions);
hr = SafeArrayAccessData(Array,
reinterpret_cast<void**>(&BootOptionsArrayData));
BootOptionsArrayData = BootOptions; // BootOptions = IBootOptions*
hr = SafeArrayUnaccessData(Array);
hr = IsoImage->put_BootImageOptionsArray(Array);
Тем не менее, каждый раз, когда я звоню put_BootImageOptionsArray
я получил E_NOINTERFACE
вернулся.
IsoImage создается так, как вы ожидаете:
hr = CoCreateInstance(CLSID_MsftFileSystemImage,
NULL,
CLSCTX_ALL,
__uuidof(IFileSystemImage2),
(void**) &IsoImage);
С помощью IFileSystemImage2
любая унаследованная функциональность от IFileSystemImage
работает отлично. Точно так же я могу CoCreateInstance
IFileSystemImage
вместо этого, и этот интерфейс может использоваться просто отлично.
Я прикрепил к моему процессу в WinDbg и установил точку останова в CMsftFileSystemImage::put_BootOptionsArray
однако эта функция (базовая реализация) просто не вызывается.
Поэтому мой вопрос прост: реализация, кажется, там, но я, кажется, не могу это назвать. Есть ли у кого-нибудь опыт использования этой конкретной функциональности, и если да, то как вы заставили ее работать?
документация предусматривает SAFEARRAY должен быть массивом VARIANT, который содержит указатели интерфейса IDispatch, чтобы вы могли сделать что-то вроде этого (я использую умные указатели, что проще …):
CComPtr<IFileSystemImage2> image;
CComPtr<IBootOptions> options;
image.CoCreateInstance(CLSID_MsftFileSystemImage);
options.CoCreateInstance(CLSID_BootOptions);
// set various options here...
options->put_Manufacturer(CComBSTR(L"joe"));
// create a SAFEARRAY of VARIANT
CComSafeArray<VARIANT> a(1);
// create a VARIANT of type VT_UNKNONW (or VT_DISPATCH)
CComVariant v(options);
// put it in the array
a.SetAt(0, v);
HRESULT hr = pImage->put_BootImageOptionsArray(a.m_psa);
Других решений пока нет …