Skip to content

Commit

Permalink
Update the TypeLib embedding and add comments on API use (#105416)
Browse files Browse the repository at this point in the history
There is an undocumented semantic of Win32 Resource APIs.
The missing semantic is that all resource type/name
strings are transparently converted to uppercase
when calling any of the Win32 Resource APIs.

We don't want to apply this undocumented semantic to the reader/writer API
so we document it instead. We are avoiding applying the behavior
since ReadyToRun scenarios are designed to be a byte for byte copy
of the resource, including name as it was written by other tooling.
  • Loading branch information
AaronRobinsonMSFT authored and directhex committed Jul 26, 2024
1 parent a16097d commit 4541933
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections;
using System.Diagnostics;

#if HOST_MODEL
namespace Microsoft.NET.HostModel.Win32Resources
Expand All @@ -26,6 +27,7 @@ private void AddResourceInternal(object name, object type, ushort language, byte
}
else
{
Debug.Assert(type is string);
if (!_resTypeHeadName.TryGetValue((string)type, out resType))
{
resType = new ResType();
Expand All @@ -45,6 +47,7 @@ private void AddResourceInternal(object name, object type, ushort language, byte
}
else
{
Debug.Assert(name is string);
if (!resType.NameHeadName.TryGetValue((string)name, out resName))
{
resName = new ResName();
Expand All @@ -57,28 +60,30 @@ private void AddResourceInternal(object name, object type, ushort language, byte

private byte[] FindResourceInternal(object name, object type, ushort language)
{
ResType resType = null;
ResType resType;

if (type is ushort)
{
_resTypeHeadID.TryGetValue((ushort)type, out resType);
}
if (type is string)
else
{
Debug.Assert(type is string);
_resTypeHeadName.TryGetValue((string)type, out resType);
}

if (resType == null)
return null;

ResName resName = null;
ResName resName;

if (name is ushort)
{
resType.NameHeadID.TryGetValue((ushort)name, out resName);
}
if (name is string)
else
{
Debug.Assert(name is string);
resType.NameHeadName.TryGetValue((string)name, out resName);
}

Expand Down
24 changes: 24 additions & 0 deletions src/coreclr/tools/Common/Compiler/Win32Resources/ResourceData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public ResourceData(Internal.TypeSystem.Ecma.EcmaModule ecmaModule, Func<object,
/// <summary>
/// Find a resource in the resource data
/// </summary>
/// <remarks>
/// The Win32 APIs typcially perform an uppercase transform on string arguments - during add and find.
/// If the resource will be read by Win32 APIs, it is recommended to make the resource name upper case.
/// </remarks>
public byte[] FindResource(string name, string type, ushort language)
{
return FindResourceInternal(name, type, language);
Expand All @@ -68,6 +72,10 @@ public byte[] FindResource(string name, string type, ushort language)
/// <summary>
/// Find a resource in the resource data
/// </summary>
/// <remarks>
/// The Win32 APIs typcially perform an uppercase transform on string arguments - during add and find.
/// If the resource will be read by Win32 APIs, it is recommended to make the resource name upper case.
/// </remarks>
public byte[] FindResource(ushort name, string type, ushort language)
{
return FindResourceInternal(name, type, language);
Expand All @@ -76,6 +84,10 @@ public byte[] FindResource(ushort name, string type, ushort language)
/// <summary>
/// Find a resource in the resource data
/// </summary>
/// <remarks>
/// The Win32 APIs typcially perform an uppercase transform on string arguments - during add and find.
/// If the resource will be read by Win32 APIs, it is recommended to make the resource name upper case.
/// </remarks>
public byte[] FindResource(string name, ushort type, ushort language)
{
return FindResourceInternal(name, type, language);
Expand All @@ -92,16 +104,28 @@ public byte[] FindResource(ushort name, ushort type, ushort language)
/// <summary>
/// Add or update resource
/// </summary>
/// <remarks>
/// The Win32 APIs typcially perform an uppercase transform on string arguments - during add and find.
/// If the resource will be read by Win32 APIs, it is recommended to make the resource name upper case.
/// </remarks>
public void AddResource(string name, string type, ushort language, byte[] data) => AddResourceInternal(name, type, language, data);

/// <summary>
/// Add or update resource
/// </summary>
/// <remarks>
/// The Win32 APIs typcially perform an uppercase transform on string arguments - during add and find.
/// If the resource will be read by Win32 APIs, it is recommended to make the resource name upper case.
/// </remarks>
public void AddResource(string name, ushort type, ushort language, byte[] data) => AddResourceInternal(name, type, language, data);

/// <summary>
/// Add or update resource
/// </summary>
/// <remarks>
/// The Win32 APIs typcially perform an uppercase transform on string arguments - during add and find.
/// If the resource will be read by Win32 APIs, it is recommended to make the resource name upper case.
/// </remarks>
public void AddResource(ushort name, string type, ushort language, byte[] data) => AddResourceInternal(name, type, language, data);

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static void Create(
if (tlbFileBytes.Length == 0)
throw new InvalidTypeLibraryException(typeLibrary.Value);

updater.AddResource(tlbFileBytes, "typelib", (IntPtr)typeLibrary.Key);
updater.AddResource(tlbFileBytes, "TYPELIB", (IntPtr)typeLibrary.Key);
}
catch (FileNotFoundException ex)
{
Expand Down

0 comments on commit 4541933

Please sign in to comment.