IMAPI2:添加文件和文件夹失败

Posted

技术标签:

【中文标题】IMAPI2:添加文件和文件夹失败【英文标题】:IMAPI2: adding files and folders fails 【发布时间】:2014-03-24 21:30:54 【问题描述】:

我正在尝试通过 IMAPI2 创建光盘映像。代码非常简单:

#include <windows.h>
#include <iostream>
#include <fstream>
#include <shlwapi.h>
#include <cstdio>

#include <imapi.h>
#include <imapi2.h>
#include <imapi2fs.h>
#include <imapierror.h>
#include <imapi2error.h>
#include <imapi2fserror.h>

using namespace std;

int main() 
CoInitialize(NULL);

HRESULT res = 0;
IFileSystemImage* image = NULL;
IFileSystemImageResult* result = NULL;
IFsiDirectoryItem* root = NULL;
IStream* file = NULL;
IStream* r_i = NULL;

res = CoCreateInstance(CLSID_MsftFileSystemImage, NULL, CLSCTX_ALL, __uuidof(IFileSystemImage), (void**) &image);
printf("1 %08X\n", res);
res = image -> put_FileSystemsToCreate((FsiFileSystems)(FsiFileSystemJoliet | FsiFileSystemISO9660));
printf("2 %08X\n", res);
res = image -> put_VolumeName(L"Pictures");
printf("3 %08X\n", res);
res = image -> ChooseImageDefaultsForMediaType(IMAPI_MEDIA_TYPE_CDRW);
printf("4 %08X\n", res);

res = image -> get_Root(&root);
printf("5 %08X\n", res);
res = root -> AddTree(L"C:\\pictures", VARIANT_TRUE);
printf("6 %08X\n", res);
res = SHCreateStreamOnFileEx(L"C:\\main.cpp", STGM_READ | STGM_SHARE_DENY_NONE | STGM_DELETEONRELEASE, FILE_ATTRIBUTE_NORMAL, false, NULL, &file);
printf("7 %08X\n", res);
res = root -> AddFile(L"main.cpp", file);
printf("8 %08X\n", res);

res = image -> CreateResultImage(&result);
printf("9 %08X\n", res);
res = result -> get_ImageStream(&r_i);
printf("0 %08X\n", res);

STATSTG stg;
r_i -> Stat(&stg, 1);
char* data = new char[stg.cbSize.QuadPart];
ULONG junk;
r_i -> Read(data, stg.cbSize.QuadPart, &junk);

FILE* f = fopen("image.iso", "wb");
fwrite(data, stg.cbSize.QuadPart, 1, f);
fclose(f);

delete data;
r_i -> Release();
file -> Release();
root -> Release();
result -> Release();
image -> Release();

CoUninitialize();
printf("Completed.\n");
scanf("%d", &junk);

命令 6 和 8 失败,出现 0xC0AAB101(无效参数)。这发生在 Win XP SP3 和 Win 7 Pro SP1 x32 上。其余的工作正常,我得到一个空图像。 我错过了什么? (P.S. 上面的代码灵感来自一个开源应用程序。它开箱即用,但当我在我的机器上重建它时有时会开始失败。)

【问题讨论】:

【参考方案1】:

->AddTree(和大多数 COM 对象方法)需要一个 BSTR 字符串,您可以创建它并且需要释放它以防止内存泄漏。 您可以使用诸如...之类的东西。

// allocate a bstr string
BSTR bstrPictures = SysAllocString(L"C:\\Pictures");

// use it
res = root -> AddTree(bstrPictures, VARIANT_TRUE);
printf("6 %08X\n", res);

// free the bstr string
SysFreeString(bstrPictures);

虽然 BSTR 可以用来代替“宽字符字符串”,但反过来并不总是正确的。 BSTR 在实际字符数据之前有额外的数据,因此需要操作它们的函数。

尽量不要养成这样使用它们的坏习惯......

res = root -> AddTree(SysAllocString(L"C:\\Pictures"), VARIANT_TRUE);

因为你会有内存泄漏。

玩得开心。

【讨论】:

以上是关于IMAPI2:添加文件和文件夹失败的主要内容,如果未能解决你的问题,请参考以下文章

IMAPI2 如何刻录已经创建的iso

.NET 中的 IMAPI2 MsftFileSystemImage 在创建 ISO 时未释放文件

将流作为文件添加到 ISO

查找 imapi2 com 对象的 uuid/标头或让 __uuidof 在 mingw 上工作

在磁盘中创建一个文件夹并使用 IMAPI 2 刻录到它

如何使用 IMAPI2 检索和设置刻录速度?