Skip to content
Open
Changes from all 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
33 changes: 27 additions & 6 deletions ClrHost/CoreClrHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <atlbase.h>
#include <atlcomcli.h>
#include <MSCorEE.h>
#include <windows.h>

#define WINDOWS TRUE;

Expand Down Expand Up @@ -120,10 +121,26 @@ void module_handle_function() noexcept
{
}

static std::string ReplaceAll(std::string str, const std::string & from, const std::string & to) {
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Move past the replacement
}
return str;
}

std::string GetHostDirectory(HMODULE hModule)
{
char path[MAX_PATH];
GetModuleFileNameA(hModule, path, MAX_PATH);
Comment on lines +135 to +136
Copy link
Preview

Copilot AI Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a fixed-size buffer with GetModuleFileNameA without checking the return value could lead to truncated paths on systems with very long path names. Consider checking the return value and using GetModuleFileNameA's return value to verify the path wasn't truncated.

Suggested change
char path[MAX_PATH];
GetModuleFileNameA(hModule, path, MAX_PATH);
DWORD length = GetModuleFileNameA(hModule, path, MAX_PATH);
// If the function fails or truncates, return empty string
if (length == 0 || length == MAX_PATH) {
return "";
}

Copilot uses AI. Check for mistakes.

std::string dir(path);
size_t pos = dir.rfind(FS_SEPARATOR);
return (std::string::npos == pos) ? "" : dir.substr(0, pos);
}

BOOL CoreClrLoad(char* runtimePath, char* errorMessage, DWORD* size)
{

// The GET_MODULE_HANDLE_EX_FLAG_PIN flag seems to prevent VFP from unloading and clearing memory.
HMODULE hm = NULL;
void* address = module_handle_function;
Expand Down Expand Up @@ -162,6 +179,8 @@ BOOL CoreClrLoad(char* runtimePath, char* errorMessage, DWORD* size)
coreclr_initialize_ptr initializeCoreClr = (coreclr_initialize_ptr)GetProcAddress(coreClr, "coreclr_initialize");

std::string tpaList;
std::string desktopPath = ReplaceAll(runtimePath, "Microsoft.NETCore.App", "Microsoft.WindowsDesktop.App");
BuildTpaList(desktopPath.c_str(), ".dll", tpaList); // Desktop must come first so that its assemblies take precedence over .NET Core assemblies when the same assembly is present in different forms in both runtimes (e.g. WindowsBase.dll).
Copy link
Preview

Copilot AI Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the desktop path without verifying it exists could cause BuildTpaList to process an invalid directory. Consider checking if the desktop path exists before calling BuildTpaList to avoid potential issues when only .NET Core is installed.

Suggested change
BuildTpaList(desktopPath.c_str(), ".dll", tpaList); // Desktop must come first so that its assemblies take precedence over .NET Core assemblies when the same assembly is present in different forms in both runtimes (e.g. WindowsBase.dll).
DWORD desktopPathAttr = GetFileAttributesA(desktopPath.c_str());
if (desktopPathAttr != INVALID_FILE_ATTRIBUTES && (desktopPathAttr & FILE_ATTRIBUTE_DIRECTORY)) {
BuildTpaList(desktopPath.c_str(), ".dll", tpaList); // Desktop must come first so that its assemblies take precedence over .NET Core assemblies when the same assembly is present in different forms in both runtimes (e.g. WindowsBase.dll).
}

Copilot uses AI. Check for mistakes.

BuildTpaList(runtimePath, ".dll", tpaList);

// <Snippet3>
Expand All @@ -176,14 +195,16 @@ BOOL CoreClrLoad(char* runtimePath, char* errorMessage, DWORD* size)

char curDir[MAX_PATH];
GetCurrentDirectory(MAX_PATH, (LPSTR)curDir);
std::string hostDir = GetHostDirectory(hm);

std::string appPaths(curDir);

appPaths.append(PATH_DELIMITER);
appPaths.append((const char *)curDir);
appPaths.append(FS_SEPARATOR);
appPaths.append("bin");

appPaths.append((const char *)curDir).append(FS_SEPARATOR).append("bin");
Copy link
Preview

Copilot AI Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The method chaining on a single line makes the code harder to read and debug. Consider breaking this into separate append calls or using a more readable string building approach.

Suggested change
appPaths.append((const char *)curDir).append(FS_SEPARATOR).append("bin");
appPaths.append((const char *)curDir);
appPaths.append(FS_SEPARATOR);
appPaths.append("bin");

Copilot uses AI. Check for mistakes.

if (hostDir != curDir)
{
appPaths.append(PATH_DELIMITER);
appPaths.append(hostDir.c_str());
}

const char* propertyValues[] = {
tpaList.c_str(),
Expand Down