// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include "comhost.h"
+#include <cstring>
#include <trace.h>
#include <utils.h>
#include <error_codes.h>
{
HRESULT string_to_clsid(_In_ const pal::string_t &str, _Out_ CLSID &clsid)
{
- // If the first character of the GUID is not '{' then COM will
- // attempt to look up the string in the CLSID table.
- if (str[0] == _X('{'))
+ pal::char_t guid_buf[] = _X("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}");
+ const pal::char_t *guid_maybe = str.data();
+
+ // If the first character of the GUID is not '{' COM will
+ // interpret the string as a ProgID. The COM host doesn't
+ // support ProgIDs so coerce strings into GUID format.
+ // The buffer size is minus 2 to account for null and first '{'.
+ if (str[0] != _X('{')
+ && str.size() < ((sizeof(guid_buf) / sizeof(pal::char_t)) - 2))
{
- if (SUCCEEDED(::CLSIDFromString(str.data(), &clsid)))
- return S_OK;
+ // Increment the output buffer 1 to skip over the '{'.
+ std::memcpy(guid_buf + 1, str.data(), str.size() * sizeof(pal::char_t));
+ guid_maybe = guid_buf;
}
- return __HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
+ if (FAILED(::CLSIDFromString(guid_maybe, &clsid)))
+ return __HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
+
+ return S_OK;
}
clsid_map parse_stream(_Inout_ pal::istream_t &json_map_raw)
if (FAILED(hr))
{
assert(false && "Invalid CLSID");
+ trace::error(_X("Invalid CLSID format in .clsidmap"));
continue;
}
}
return mapping;
-}
\ No newline at end of file
+}
namespace
{
- const WCHAR EntryKeyFmt[] = L"SOFTWARE\\Classes\\CLSID\\%s";
+ const WCHAR EntryKeyFmt[] = _X("SOFTWARE\\Classes\\CLSID\\%s");
struct OleStr : public std::unique_ptr<std::remove_pointer<LPOLESTR>::type, decltype(&::CoTaskMemFree)>
{
RegKey regKey{ regKeyRaw };
+ // Set the default value for all COM host servers
+ const WCHAR defServerName[] = _X("CoreCLR COMHost Server");
+ res = ::RegSetValueExW(
+ regKey.get(),
+ nullptr,
+ 0,
+ REG_SZ,
+ reinterpret_cast<const BYTE*>(defServerName),
+ static_cast<DWORD>(sizeof(defServerName) * sizeof(defServerName[0])));
+ if (res != ERROR_SUCCESS)
+ return __HRESULT_FROM_WIN32(res);
+
WCHAR regKeyServerPath[ARRAYSIZE(regKeyClsidPath) * 2];
::swprintf_s(regKeyServerPath, L"%s\\InProcServer32", regKeyClsidPath);
COM_API HRESULT STDMETHODCALLTYPE DllRegisterServer(void)
{
+ // Step 0: Initialize logging
+ trace::setup();
+
// Step 1: Get CLSID mapping
clsid_map map;
RETURN_HRESULT_IF_EXCEPT(map = comhost::get_clsid_map());
+ trace::info(_X("Registering %d CLSIDs"), (int)map.size());
+
// Step 2: Register each CLSID
HRESULT hr;
for (clsid_map::const_reference p : map)
COM_API HRESULT STDMETHODCALLTYPE DllUnregisterServer(void)
{
+ // Step 0: Initialize logging
+ trace::setup();
+
// Step 1: Get CLSID mapping
clsid_map map;
RETURN_HRESULT_IF_EXCEPT(map = comhost::get_clsid_map());