关闭

使用IMAPI V2 制作Boot image(启动盘)

1880人阅读 评论(1) 收藏 举报

  好久没有更新了,最近在研究用IMAPI 来刻录启动光盘。MSDN的例子都是VB script的例子,以下是我简单写的C++例子。

 附上MSDN 对于IMAPI的链接:http://msdn.microsoft.com/en-us/library/windows/desktop/aa366450(v=vs.85).aspx


// BurnTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <imapi2.h>
#include <imapi2error.h>
#include <imapi2fs.h>
#include <imapi2fserror.h>
#include <Shlwapi.h>

#define BOOT_FILE_NAME_LEGACY _T("F:\\BootFile\\boot\\etfsboot.com") //CSM boot
#define BOOT_FILE_NAME_UEFI   _T("F:\\BootFile\\efi\\microsoft\\boot\\efisys_noprompt.bin") //UEFI boot

IFsiDirectoryItem *g_hRootDir = NULL;


int _tmain(int argc, _TCHAR* argv[])
{
	::CoInitializeEx(NULL, COINIT_MULTITHREADED); 

	HRESULT hr;
	IDiscMaster2* DiscMaster;
	IDiscRecorder2* DiscRecorder;
	IDiscFormat2Data* DataWriter;
	IDiscFormat2Data* DataWriterB;
	long totalDevices = 0;

	//create Master
	hr = CoCreateInstance(_uuidof(MsftDiscMaster2),NULL,CLSCTX_INPROC_SERVER,_uuidof(IDiscMaster2),(void**)&DiscMaster);
	if (hr != S_OK)
	{
		 std::cout<<"Create Disc Master fail... \n";  
	}else{

		std::cout<<"Create Disc Master success... \n";
	}

	//Create recorder
	hr = CoCreateInstance(__uuidof(MsftDiscRecorder2), NULL, CLSCTX_INPROC_SERVER,
		__uuidof(IDiscRecorder2), (void**)&DiscRecorder); 
	if (hr != S_OK)
	{
		std::cout<<"Create Disc Recorder fail... \n";  
	}else{

		std::cout<<"Create Disc Recorder success... \n";
	}
	
	//Get total devices and device uniqueID
	hr = DiscMaster->get_Count(&totalDevices);

	//for (long iDeviceIndex=0;iDeviceIndex<totalDevices;iDeviceIndex++)
	//{
		BSTR bstrUniqueID = NULL;
		hr = DiscMaster->get_Item(2,&bstrUniqueID);  //这里我直接指定了第三个光驱,实际中可以用循环遍历。
		hr = DiscRecorder->InitializeDiscRecorder(bstrUniqueID);

		BSTR bstrProductID = NULL;

		hr = DiscRecorder->get_ProductId(&bstrProductID);
		std::wcout<<bstrProductID<<"\n";
	//}

	hr = CoCreateInstance(__uuidof(MsftDiscFormat2Data), NULL, CLSCTX_INPROC_SERVER,
		__uuidof(IDiscFormat2Data), (void**)&DataWriter);

	hr = DataWriter->put_Recorder(DiscRecorder);
	hr = DataWriter->put_ClientName(_T("BurnTestClientName"));
	
	BSTR bstrClientName;
	hr = DataWriter->get_ClientName(&bstrClientName);
	std::wcout<<"ClientName: "<<bstrClientName<<"\n";

	//Get support Media Type
	//SAFEARRAY* pSupportMediaType;
	//hr = DataWriter->get_SupportedMediaTypes(&pSupportMediaType);

	//int i = (int)pSupportMediaType->pvData;

	//Adding Boot Image code
	IBootOptions* BootOption;
	hr = CoCreateInstance(__uuidof(BootOptions), NULL, CLSCTX_INPROC_SERVER,
		__uuidof(IBootOptions), (void**)&BootOption); 

	hr = BootOption->put_Manufacturer(_T("xxxx"));
	hr = BootOption->put_PlatformId(PlatformX86);
	hr = BootOption->put_Emulation(EmulationNone);

	IStream* pBootStream = NULL;

	hr = SHCreateStreamOnFile(BOOT_FILE_NAME_LEGACY,STGM_READ|STGM_SHARE_DENY_WRITE,&pBootStream);
	hr = BootOption->AssignBootImage(pBootStream);

	hr = SHCreateStreamOnFile(BOOT_FILE_NAME_UEFI,STGM_READ|STGM_SHARE_DENY_WRITE,&pBootStream);
	hr = BootOption->AssignBootImage(pBootStream);

	VARIANT_BOOL bIsBlank = VARIANT_TRUE;
	hr = DataWriter->get_MediaHeuristicallyBlank(&bIsBlank);
	if (bIsBlank)
	{
		std::cout<<"The disc is blank \n";  
	}else{

		std::cout<<"The disc is not blank \n";
	}


	IFileSystemImage2* FSI;
	hr = CoCreateInstance(_uuidof(MsftFileSystemImage),NULL,CLSCTX_INPROC_SERVER,
		__uuidof(IFileSystemImage2),(void**)&FSI);

	hr = FSI->ChooseImageDefaults(DiscRecorder);
	hr = FSI->ChooseImageDefaultsForMediaType(IMAPI_MEDIA_TYPE_DVDROM);
	//hr = FSI->put_FileSystemsToCreate(FsiFileSystemISO9660);
	hr = FSI->put_BootImageOptions(BootOption);
	

	hr = FSI->get_Root(&g_hRootDir);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\boot")),VARIANT_TRUE);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\efi")),VARIANT_TRUE);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\Support")),VARIANT_TRUE);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\sources")),VARIANT_TRUE);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\autorun.inf")),VARIANT_TRUE);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\bootmgr")),VARIANT_TRUE);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\bootmgr.efi")),VARIANT_TRUE);
	hr = g_hRootDir->AddTree(::SysAllocString(_T("F:\\BootFile\\setup.exe")),VARIANT_TRUE);

	IFileSystemImageResult* pFileSystemImageResult;
	hr = FSI->CreateResultImage(&pFileSystemImageResult);

	IStream *ImageResultStream;
	hr = pFileSystemImageResult->get_ImageStream(&ImageResultStream);
	if (hr == S_OK)
	{
		std::cout<<"Get Image Stream success \n";
	}else{
		std::cout<<"Get Image Stream fail \n";
	}

	hr = CoCreateInstance(__uuidof(MsftDiscFormat2Data), NULL, CLSCTX_INPROC_SERVER,
		__uuidof(IDiscFormat2Data), (void**)&DataWriterB);

	hr = DataWriterB->put_Recorder(DiscRecorder);
	hr = DataWriterB->put_ClientName(_T("BurnTestClientNameB"));

	hr = DataWriterB->Write(ImageResultStream);
	if (hr == S_OK)
	{
		std::cout<<"Add Boot success \n";
	}else{
		std::cout<<"Add Boot Fail \n";
	}
	

	system( "PAUSE ");
	
	return 0;
}

这里只是简单的例子,只是一个暂时的调查结果。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:53462次
    • 积分:803
    • 等级:
    • 排名:千里之外
    • 原创:29篇
    • 转载:0篇
    • 译文:0篇
    • 评论:7条
    最新评论