Как я могу использовать IFileSystemImage2 put_BootImageOptionsArray из IMAPI2 (получение E_NOINTERFACE)?

Я пытаюсь использовать интерфейс 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 однако эта функция (базовая реализация) просто не вызывается.

Поэтому мой вопрос прост: реализация, кажется, там, но я, кажется, не могу это назвать. Есть ли у кого-нибудь опыт использования этой конкретной функциональности, и если да, то как вы заставили ее работать?

1 ответ

Решение

В документации указано, что 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);
Другие вопросы по тегам