COMHost logging and registration bugs (dotnet/core-setup#5496)
authorAaron Robinson <arobins@microsoft.com>
Sat, 16 Mar 2019 22:41:24 +0000 (15:41 -0700)
committerGitHub <noreply@github.com>
Sat, 16 Mar 2019 22:41:24 +0000 (15:41 -0700)
Initialize logging during registration
Set default name for COM server entry
Handle cases where GUIDs supplied in .clsidmap are not in full GUID format

Commit migrated from https://github.com/dotnet/core-setup/commit/606cf1f607d23f0ae5557c580e55f4f99d6d4ece

src/installer/corehost/cli/comhost/clsidmap.cpp
src/installer/corehost/cli/comhost/exports.cpp

index 1f5d4aa..085b5b6 100644 (file)
@@ -2,6 +2,7 @@
 // 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>
@@ -16,15 +17,25 @@ namespace
 {
     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)
@@ -55,6 +66,7 @@ namespace
             if (FAILED(hr))
             {
                 assert(false && "Invalid CLSID");
+                trace::error(_X("Invalid CLSID format in .clsidmap"));
                 continue;
             }
 
@@ -150,4 +162,4 @@ clsid_map comhost::get_clsid_map()
     }
 
     return mapping;
-}
\ No newline at end of file
+}
index 1428e6c..4476458 100644 (file)
@@ -122,7 +122,7 @@ COM_API HRESULT STDMETHODCALLTYPE DllCanUnloadNow(void)
 
 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)>
     {
@@ -210,6 +210,18 @@ namespace
 
         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);
 
@@ -273,10 +285,15 @@ namespace
 
 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)
@@ -287,6 +304,9 @@ COM_API HRESULT STDMETHODCALLTYPE DllRegisterServer(void)
 
 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());