Created
January 31, 2021 06:47
-
-
Save uemuraj/f322c2bd88994dfa1405f0cbdf11177c to your computer and use it in GitHub Desktop.
ISO イメージを作成するには...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "pch.h" | |
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <comdef.h> | |
#include <imapi2fs.h> | |
#include <Shlwapi.h> | |
#pragma comment(lib, "Shlwapi.lib") | |
template<typename T> | |
using com_ptr_t = _com_ptr_t<_com_IIID<T, &__uuidof(T)>>; | |
/* | |
* グローバルな Set-Up と Tear-Down で COM を使用可能にしておきます | |
* http://opencv.jp/googletestdocs/advancedguide.html#adv-global-setup-teardown | |
*/ | |
class CoInitializedEnvironment : public testing::Environment | |
{ | |
public: | |
void SetUp() override | |
{ | |
ASSERT_HRESULT_SUCCEEDED(::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)); | |
} | |
void TearDown() override | |
{ | |
::CoUninitialize(); | |
} | |
}; | |
int main(int argc, char * argv[]) | |
{ | |
testing::InitGoogleTest(&argc, argv); | |
AddGlobalTestEnvironment(new CoInitializedEnvironment()); | |
return RUN_ALL_TESTS(); | |
} | |
class EventConnection | |
{ | |
IConnectionPointPtr cp; | |
DWORD cookie = 0; | |
public: | |
EventConnection(IConnectionPointContainerPtr cpc, REFIID riid); | |
~EventConnection(); | |
void Advise(IUnknown * sink); | |
}; | |
class FileSystemImageEvents : public DFileSystemImageEvents, public DFileSystemImageImportEvents | |
{ | |
LONG m_count = 0; | |
public: | |
// IDispatch を介して継承されました | |
STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObject) override; | |
STDMETHODIMP_(ULONG) AddRef(void) override; | |
STDMETHODIMP_(ULONG) Release(void) override; | |
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo) override; | |
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) override; | |
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) override; | |
STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) override; | |
// DFileSystemImageEvents を介して継承されました | |
STDMETHODIMP Update(IDispatch * object, BSTR currentFile, LONG copiedSectors, LONG totalSectors) override; | |
// DFileSystemImageImportEvents を介して継承されました | |
STDMETHODIMP UpdateImport(IDispatch * object, FsiFileSystems fileSystem, BSTR currentItem, LONG importedDirectoryItems, LONG totalDirectoryItems, LONG importedFileItems, LONG totalFileItems) override; | |
}; | |
struct MsftFileSystemImageTest : public testing::Test | |
{ | |
com_ptr_t<IFileSystemImage3> m_fileSystemImage; | |
const wchar_t * m_OutputFileName = VS_TARGETDIR "MsftFileSystemImageTest.iso"; | |
void SetUp() override | |
{ | |
m_fileSystemImage.CreateInstance(__uuidof(MsftFileSystemImage)); | |
EXPECT_TRUE(::DeleteFile(m_OutputFileName) || ::GetLastError() == ERROR_FILE_NOT_FOUND); | |
} | |
}; | |
TEST_F(MsftFileSystemImageTest, CreateImage) | |
{ | |
EventConnection connection0(m_fileSystemImage, __uuidof(DFileSystemImageEvents)); | |
EventConnection connection1(m_fileSystemImage, __uuidof(DFileSystemImageImportEvents)); | |
connection0.Advise(com_ptr_t<DFileSystemImageEvents>(new FileSystemImageEvents)); | |
connection1.Advise(com_ptr_t<DFileSystemImageImportEvents>(new FileSystemImageEvents)); | |
auto name = testing::UnitTest::GetInstance()->current_test_info()->test_case_name(); | |
ASSERT_HRESULT_SUCCEEDED(m_fileSystemImage->ChooseImageDefaultsForMediaType(IMAPI_MEDIA_TYPE_DISK)); | |
EXPECT_HRESULT_SUCCEEDED(m_fileSystemImage->put_FileSystemsToCreate(static_cast<FsiFileSystems>(FsiFileSystemJoliet | FsiFileSystemISO9660))); | |
EXPECT_HRESULT_SUCCEEDED(m_fileSystemImage->put_VolumeName(_bstr_t(name))); | |
{ | |
com_ptr_t<IFsiDirectoryItem> item; | |
m_fileSystemImage->get_Root(&item); | |
EXPECT_HRESULT_SUCCEEDED(item->AddTree(_bstr_t(VS_PROJECTDIR), VARIANT_FALSE)); // ものによるが数十秒かかる | |
} | |
com_ptr_t<IFileSystemImageResult> result; | |
EXPECT_HRESULT_SUCCEEDED(m_fileSystemImage->CreateResultImage(&result)); | |
IStreamPtr in; | |
ASSERT_HRESULT_SUCCEEDED(result->get_ImageStream(&in)); | |
IStreamPtr out; | |
ASSERT_HRESULT_SUCCEEDED(::SHCreateStreamOnFile(m_OutputFileName, STGM_CREATE | STGM_WRITE, &out)); | |
LONG a{}, b{}; | |
result->get_TotalBlocks(&a); | |
result->get_BlockSize(&b); | |
ULARGE_INTEGER cb{}; | |
cb.QuadPart = UInt32x32To64(a, b); | |
EXPECT_HRESULT_SUCCEEDED(in->CopyTo(out, cb, nullptr, nullptr)); | |
EXPECT_HRESULT_SUCCEEDED(out->Commit(STGC_DEFAULT)); | |
} | |
EventConnection::EventConnection(IConnectionPointContainerPtr cpc, REFIID riid) | |
{ | |
EXPECT_HRESULT_SUCCEEDED(cpc->FindConnectionPoint(riid, &cp)); | |
} | |
EventConnection::~EventConnection() | |
{ | |
if (cp) | |
{ | |
cp->Unadvise(cookie); | |
} | |
} | |
void EventConnection::Advise(IUnknown * sink) | |
{ | |
if (cp) | |
{ | |
EXPECT_HRESULT_SUCCEEDED(cp->Advise(sink, &cookie)); | |
} | |
} | |
HRESULT FileSystemImageEvents::QueryInterface(REFIID riid, void ** ppvObject) | |
{ | |
if (riid == __uuidof(DFileSystemImageEvents) || riid == IID_IUnknown || riid == IID_IDispatch) | |
{ | |
AddRef(); | |
*ppvObject = (DFileSystemImageEvents *) this; | |
return S_OK; | |
} | |
if (riid == __uuidof(DFileSystemImageImportEvents)) | |
{ | |
AddRef(); | |
*ppvObject = (DFileSystemImageImportEvents *) this; | |
return S_OK; | |
} | |
*ppvObject = nullptr; | |
return E_NOINTERFACE; | |
} | |
ULONG FileSystemImageEvents::AddRef(void) | |
{ | |
return ::InterlockedIncrement(&m_count); | |
} | |
ULONG FileSystemImageEvents::Release(void) | |
{ | |
LONG count = ::InterlockedDecrement(&m_count); | |
if (count == 0) | |
{ | |
delete this; | |
} | |
return count; | |
} | |
HRESULT FileSystemImageEvents::GetTypeInfoCount(UINT * pctinfo) | |
{ | |
return E_NOTIMPL; | |
} | |
HRESULT FileSystemImageEvents::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) | |
{ | |
return E_NOTIMPL; | |
} | |
HRESULT FileSystemImageEvents::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) | |
{ | |
return E_NOTIMPL; | |
} | |
HRESULT FileSystemImageEvents::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) | |
{ | |
switch (dispIdMember) | |
{ | |
case DISPID_DFILESYSTEMIMAGEEVENTS_UPDATE: | |
if (pDispParams->cArgs >= 4) | |
{ | |
auto & object = pDispParams->rgvarg[3]; | |
auto & currentFile = pDispParams->rgvarg[2]; | |
auto & copiedSectors = pDispParams->rgvarg[1]; | |
auto & totalSectors = pDispParams->rgvarg[0]; | |
if (currentFile.vt == VT_BSTR) | |
{ | |
::OutputDebugString(currentFile.bstrVal); | |
::OutputDebugString(L"\r\n"); | |
} | |
return S_OK; | |
} | |
break; | |
case DISPID_DFILESYSTEMIMAGEIMPORTEVENTS_UPDATEIMPORT: | |
if (pDispParams->cArgs >= 7) | |
{ | |
auto & object = pDispParams->rgvarg[6]; | |
auto & fileSystem = pDispParams->rgvarg[5]; | |
auto & currentFile = pDispParams->rgvarg[4]; | |
auto & importedDirectoryItems = pDispParams->rgvarg[3]; | |
auto & totalDirectoryItems = pDispParams->rgvarg[2]; | |
auto & importedFileItems = pDispParams->rgvarg[1]; | |
auto & totalFileItems = pDispParams->rgvarg[0]; | |
if (currentFile.vt == VT_BSTR) | |
{ | |
::OutputDebugString(currentFile.bstrVal); | |
::OutputDebugString(L"\r\n"); | |
} | |
return S_OK; | |
} | |
break; | |
} | |
return S_FALSE; | |
} | |
HRESULT FileSystemImageEvents::Update(IDispatch * object, BSTR currentFile, LONG copiedSectors, LONG totalSectors) | |
{ | |
return S_FALSE; // 常に DISPID による呼び出しが使われるため、ここには来ない | |
} | |
HRESULT FileSystemImageEvents::UpdateImport(IDispatch * object, FsiFileSystems fileSystem, BSTR currentItem, LONG importedDirectoryItems, LONG totalDirectoryItems, LONG importedFileItems, LONG totalFileItems) | |
{ | |
return S_FALSE; // 常に DISPID による呼び出しが使われるため、ここには来ない | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment