I am trying to use the IFileSystemImage2 interface to create an ISO with multiple boot records using Imapi2.
To do this, I should be able to use put_BootImageOptionsArray
passing in SAFEARRAY*
of VT_DISPATCH
type, i.e. COM pointers of type IBootOptions
for each boot options configuration. As a short demo, I have the following code (I only created one IBootOptions
in this case):
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);
However, every time I call put_BootImageOptionsArray
I get E_NOINTERFACE
returned.
IsoImage is being created as you'd expect:
hr = CoCreateInstance(CLSID_MsftFileSystemImage,
NULL,
CLSCTX_ALL,
__uuidof(IFileSystemImage2),
(void**) &IsoImage);
Using IFileSystemImage2
any inherited functionality from IFileSystemImage
works fine. Likewise, I can CoCreateInstance
a IFileSystemImage
instead, and this interface can be used just fine.
I have attached to my process in WinDbg and set a breakpoint in CMsftFileSystemImage::put_BootOptionsArray
, however, this function (the underlying implementation) simply isn't being called.
My question, therefore is simple: the implementation appears to be there, but I don't seem to be able to call it. Does anyone have any experience of using this particular bit of functionality and if so how did you get it to work?
The documentation stipulates the SAFEARRAY must be an array of VARIANT that contain IDispatch interface pointers, so you could do something like this (I'm using smart pointers which is easier...):
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);