Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/winrt/activation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ target_include_directories(winrtact PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_
set_target_properties(winrtact PROPERTIES OUTPUT_NAME "winrtact")
set_target_properties(winrtact PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(winrtact PUBLIC ${WINRT_INCLUDE_PATH} ${DETOURS_LIBRARY_PATH} ${XLANG_LIBRARY_PATH} ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR})
target_link_libraries(winrtact windowsapp detours)
target_link_libraries(winrtact windowsapp detours comsuppw shlwapi)

add_dependencies(winrtact detours)
79 changes: 60 additions & 19 deletions src/winrt/activation/catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
#include <roapi.h>
#include <winstring.h>
#include <rometadataresolution.h>
#include <combaseapi.h>
#include <wrl.h>
#include <xmllite.h>
#include <Shlwapi.h>
#include <comutil.h>
#include <iostream>
#include <fstream>
#include <unordered_map>
Expand All @@ -14,6 +19,7 @@
#include <catalog.h>

using namespace std;
using namespace Microsoft::WRL;

// TODO: Components won't respect COM lifetime. workaround to get them in the COM list?

Expand All @@ -27,7 +33,7 @@ extern "C"
struct component
{
wstring module_path;
wstring metadata_path;
wstring xmlns;
HMODULE handle = nullptr;
activation_factory_type get_activation_factory;
ABI::Windows::Foundation::ThreadingType threading_model;
Expand Down Expand Up @@ -70,26 +76,61 @@ static unordered_map < wstring, shared_ptr<component> > g_types;

HRESULT WinRTLoadComponent(PCWSTR manifest_path)
{
ComPtr<IStream> fileStream;
ComPtr<IXmlReader> xmlReader;
XmlNodeType nodeType;
const WCHAR* localName = L"";
auto this_component = make_shared<component>();
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

// first line is the name of the DLL that contains the types
ifstream manifest_file(manifest_path, ios_base::in);
std::string u8_module_name;
getline(manifest_file, u8_module_name);
this_component->module_path = converter.from_bytes(u8_module_name);

// second line is the name of the winmd that contains the types (in case of CLR, can be the same as dll)
string u8_metadata_path;
getline(manifest_file, u8_metadata_path);
this_component->metadata_path = converter.from_bytes(u8_metadata_path);

// each line after is an activatable class. No apartment-specific registration. Implicitly "both".
string u8_class_name;
while (getline(manifest_file, u8_class_name))

RETURN_IF_FAILED(SHCreateStreamOnFileEx(manifest_path, STGM_READ, FILE_ATTRIBUTE_NORMAL, false, nullptr, &fileStream));
RETURN_IF_FAILED(CreateXmlReader(__uuidof(IXmlReader), (void**)&xmlReader, nullptr));
RETURN_IF_FAILED(xmlReader->SetInput(fileStream.Get()));
const WCHAR* fileName;
while (S_OK == xmlReader->Read(&nodeType))
{
std::wstring wide_class_name = converter.from_bytes(u8_class_name);
g_types[wide_class_name] = this_component;
if (nodeType == XmlNodeType_Element)
{
RETURN_IF_FAILED((xmlReader->GetLocalName(&localName, nullptr)));
if (_wcsicmp(localName, L"file") == 0)
{
RETURN_IF_FAILED(xmlReader->MoveToAttributeByName(L"name", nullptr));
RETURN_IF_FAILED(xmlReader->GetValue(&fileName, nullptr));
this_component->module_path = fileName;
}
else if (_wcsicmp(localName, L"activatableClass") == 0)
{
const WCHAR* threadingModel;
RETURN_IF_FAILED(xmlReader->MoveToAttributeByName(L"threadingModel", nullptr));
RETURN_IF_FAILED(xmlReader->GetValue(&threadingModel, nullptr));

if (wcsicmp(L"sta", threadingModel) == 0)
{
this_component->threading_model = ABI::Windows::Foundation::ThreadingType::ThreadingType_STA;
}
else if (wcsicmp(L"mta", threadingModel) == 0)
{
this_component->threading_model = ABI::Windows::Foundation::ThreadingType::ThreadingType_MTA;
}
else if(wcsicmp(L"both", threadingModel) == 0)
{
this_component->threading_model = ABI::Windows::Foundation::ThreadingType::ThreadingType_BOTH;
}
else
{
return HRESULT_FROM_WIN32(ERROR_SXS_MANIFEST_PARSE_ERROR);
}

const WCHAR* xmlns;
RETURN_IF_FAILED(xmlReader->MoveToAttributeByName(L"xmlns", nullptr));
RETURN_IF_FAILED(xmlReader->GetValue(&xmlns, nullptr));
this_component->xmlns = xmlns;

const WCHAR* activatableClass;
RETURN_IF_FAILED(xmlReader->MoveToAttributeByName(L"clsid", nullptr));
RETURN_IF_FAILED(xmlReader->GetValue(&activatableClass, nullptr));
g_types[activatableClass] = this_component;
}
}
}

return S_OK;
Expand Down
14 changes: 12 additions & 2 deletions src/winrt/example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,25 @@ set_target_properties(activation_demo PROPERTIES OUTPUT_NAME "activation_demo")
target_include_directories(activation_demo PUBLIC ${WINRT_INCLUDE_PATH} ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR})
target_link_libraries(activation_demo windowsapp winrtact)

add_dependencies(activation_demo winrtact)
add_dependencies(activation_demo winrtact test_comp)

add_custom_command(TARGET activation_demo POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_BINARY_DIR}/../activation/winrtact.dll
${CMAKE_CURRENT_BINARY_DIR}
)

add_custom_command(TARGET activation_demo POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_BINARY_DIR}/../test/test_comp/test_comp.dll
${CMAKE_CURRENT_BINARY_DIR}/test_comp.dll
)

file(GLOB test_files
"test_files/*"
)
file(COPY ${test_files} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(TARGET activation_demo POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${test_files}
${CMAKE_CURRENT_BINARY_DIR}
)
3 changes: 0 additions & 3 deletions src/winrt/example/TestFiles/manifesttest1.txt

This file was deleted.

18 changes: 2 additions & 16 deletions src/winrt/example/demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,13 @@ using namespace Microsoft::WRL::Wrappers;

int main(int argc, char *argv[])
{
ExtRoLoadCatalog(L"demo.txt");
ExtRoLoadCatalog(L"demo2.txt");

HRESULT hr = S_OK;
CoInitialize(nullptr);
{
ComPtr<IInspectable> instance;
hr = RoActivateInstance(HStringReference(L"test_component.Class").Get(), &instance);
if (FAILED(hr)) { printf("Failed activate: %x\n", hr); return false; }

HString result;
instance->GetRuntimeClassName(result.GetAddressOf());
if (FAILED(hr)) { printf("Failed to load name: %x\n", hr); return false; }

unsigned int length = 0;
wprintf(L"%s\n", result.GetRawBuffer(&length));
}

ExtRoLoadCatalog(LR"(demo.manifest)");
{
ComPtr<IInspectable> instance;
hr = RoActivateInstance(HStringReference(L"MyComponent.SampleClass").Get(), &instance);
hr = RoActivateInstance(HStringReference(L"RegFreeWinRtTest.TestComp").Get(), &instance);
if (FAILED(hr)) { printf("Failed activate: %x\n", hr); return false; }

HString result;
Expand Down
Binary file removed src/winrt/example/test_files/MyComponent.winmd
Binary file not shown.
9 changes: 9 additions & 0 deletions src/winrt/example/test_files/demo.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="test_comp.dll">
<activatableClass
clsid="RegFreeWinRtTest.TestComp"
threadingModel="Both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
</assembly>
3 changes: 0 additions & 3 deletions src/winrt/example/test_files/demo.txt

This file was deleted.

3 changes: 0 additions & 3 deletions src/winrt/example/test_files/demo2.txt

This file was deleted.

Binary file removed src/winrt/example/test_files/test_component.dll
Binary file not shown.
6 changes: 5 additions & 1 deletion src/winrt/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ add_custom_command(TARGET regfree_winrt_test POST_BUILD
file(GLOB test_files
"test_files/*"
)
file(COPY ${test_files} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(TARGET regfree_winrt_test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${test_files}
${CMAKE_CURRENT_BINARY_DIR}
)

add_subdirectory(test_comp)
12 changes: 4 additions & 8 deletions src/winrt/test/test_apartment_activation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ using namespace Microsoft::WRL::Wrappers;

TEST_CASE("Test STA activation")
{
// TODO: Replace manifest with correct format that marks class as both STA and MTA
ExtRoLoadCatalog(L"manifesttest1.txt");
ExtRoLoadCatalog(L"manifestTestBoth.manifest");
HRESULT hr = S_OK;
CoInitialize(nullptr);
{
Expand All @@ -40,8 +39,7 @@ TEST_CASE("Test STA activation")

TEST_CASE("Test MTA activation")
{
// TODO: Replace manifest with correct format that marks class as both STA and MTA
ExtRoLoadCatalog(L"manifesttest1.txt");
ExtRoLoadCatalog(L"manifestTestBoth.manifest");
HRESULT hr = S_OK;
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
{
Expand All @@ -64,8 +62,7 @@ TEST_CASE("Test MTA activation")

TEST_CASE("Test cross apartment MTA activation")
{
// TODO: Replace manifest with correct format that marks class as only MTA
ExtRoLoadCatalog(L"manifesttest1.txt");
ExtRoLoadCatalog(L"manifestTestMTA.manifest");
HRESULT hr = S_OK;
CoInitialize(nullptr);
{
Expand All @@ -88,8 +85,7 @@ TEST_CASE("Test cross apartment MTA activation")

TEST_CASE("Test block STA to MTA activation")
{
// TODO: Replace manifest with correct format that marks class as only STA
ExtRoLoadCatalog(L"manifesttest1.txt");
ExtRoLoadCatalog(L"manifestTestSTA.manifest");
HRESULT hr = S_OK;
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
{
Expand Down
9 changes: 9 additions & 0 deletions src/winrt/test/test_files/manifestTestBoth.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="test_comp.dll">
<activatableClass
clsid="RegFreeWinRtTest.TestComp"
threadingModel="Both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
</assembly>
9 changes: 9 additions & 0 deletions src/winrt/test/test_files/manifestTestMTA.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="test_comp.dll">
<activatableClass
clsid="RegFreeWinRtTest.TestComp"
threadingModel="mta"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
</assembly>
9 changes: 9 additions & 0 deletions src/winrt/test/test_files/manifestTestSTA.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="test_comp.dll">
<activatableClass
clsid="RegFreeWinRtTest.TestComp"
threadingModel="sta"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
</assembly>