Skip to content

Commit

Permalink
Merge pull request #1148 from microsoft/bumpMetadata
Browse files Browse the repository at this point in the history
Bump metadata versions: SDK: 60.0.34, WDK: 0.11.4
  • Loading branch information
AArnott authored May 9, 2024
2 parents 9b7a024 + 9c9861c commit 67da07f
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 18 deletions.
4 changes: 2 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<MetadataVersion>56.0.13-preview</MetadataVersion>
<WDKMetadataVersion>0.9.9-experimental</WDKMetadataVersion>
<MetadataVersion>60.0.34-preview</MetadataVersion>
<WDKMetadataVersion>0.11.4-experimental</WDKMetadataVersion>
<!-- <DiaMetadataVersion>0.2.185-preview-g7e1e6a442c</DiaMetadataVersion> -->
<ApiDocsVersion>0.1.42-alpha</ApiDocsVersion>
<CodeAnalysisVersion>4.8.0</CodeAnalysisVersion>
Expand Down
34 changes: 21 additions & 13 deletions src/Microsoft.Windows.CsWin32/Generator.Constant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ ReadOnlyMemory<char> TrimCurlyBraces(ReadOnlyMemory<char> arg)
return argExpressions;
}

private ObjectCreationExpressionSyntax? CreateConstantViaCtor(List<ReadOnlyMemory<char>> args, TypeSyntax targetType, TypeDefinition targetTypeDef)
private ObjectCreationExpressionSyntax? CreateConstantViaCtor(List<ReadOnlyMemory<char>> args, TypeSyntax targetType, TypeDefinition targetTypeDef, out bool unsafeRequired)
{
unsafeRequired = false;
foreach (MethodDefinitionHandle methodDefHandle in targetTypeDef.GetMethods())
{
MethodDefinition methodDef = this.Reader.GetMethodDefinition(methodDefHandle);
Expand All @@ -218,7 +219,8 @@ ReadOnlyMemory<char> TrimCurlyBraces(ReadOnlyMemory<char> arg)
for (int i = 0; i < args.Count; i++)
{
TypeHandleInfo parameterTypeInfo = ctorSignature.ParameterTypes[i];
argExpressions[i] = Argument(this.CreateConstant(args[i], parameterTypeInfo));
argExpressions[i] = Argument(this.CreateConstant(args[i], parameterTypeInfo, out bool thisRequiresUnsafe));
unsafeRequired |= thisRequiresUnsafe;
i++;
}

Expand All @@ -229,8 +231,9 @@ ReadOnlyMemory<char> TrimCurlyBraces(ReadOnlyMemory<char> arg)
return null;
}

private ObjectCreationExpressionSyntax? CreateConstantByField(List<ReadOnlyMemory<char>> args, TypeSyntax targetType, TypeDefinition targetTypeDef)
private ObjectCreationExpressionSyntax? CreateConstantByField(List<ReadOnlyMemory<char>> args, TypeSyntax targetType, TypeDefinition targetTypeDef, out bool unsafeRequired)
{
unsafeRequired = false;
if (targetTypeDef.GetFields().Count != args.Count)
{
return null;
Expand All @@ -246,7 +249,8 @@ ReadOnlyMemory<char> TrimCurlyBraces(ReadOnlyMemory<char> arg)
fieldAssignmentExpressions[i] = AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
IdentifierName(fieldName),
this.CreateConstant(args[i], fieldTypeInfo));
this.CreateConstant(args[i], fieldTypeInfo, out bool thisRequiresUnsafe));
unsafeRequired |= thisRequiresUnsafe;
i++;
}

Expand All @@ -255,18 +259,20 @@ ReadOnlyMemory<char> TrimCurlyBraces(ReadOnlyMemory<char> arg)
.WithInitializer(InitializerExpression(SyntaxKind.ObjectInitializerExpression, SeparatedList<ExpressionSyntax>()).AddExpressions(fieldAssignmentExpressions));
}

private ExpressionSyntax CreateConstant(ReadOnlyMemory<char> argsAsString, TypeHandleInfo targetType)
private ExpressionSyntax CreateConstant(ReadOnlyMemory<char> argsAsString, TypeHandleInfo targetType, out bool unsafeRequired)
{
unsafeRequired = targetType is PointerTypeHandleInfo;
return targetType switch
{
ArrayTypeHandleInfo { ElementType: PrimitiveTypeHandleInfo { PrimitiveTypeCode: PrimitiveTypeCode.Byte } } pointerType => this.CreateByteArrayConstant(argsAsString),
PrimitiveTypeHandleInfo primitiveType => ToExpressionSyntax(primitiveType.PrimitiveTypeCode, argsAsString),
HandleTypeHandleInfo handleType => this.CreateConstant(argsAsString, targetType.ToTypeSyntax(this.fieldTypeSettings, GeneratingElement.Constant, null).Type, (TypeReferenceHandle)handleType.Handle),
HandleTypeHandleInfo handleType => this.CreateConstant(argsAsString, targetType.ToTypeSyntax(this.fieldTypeSettings, GeneratingElement.Constant, null).Type, (TypeReferenceHandle)handleType.Handle, out unsafeRequired),
PointerTypeHandleInfo pointerType => CastExpression(pointerType.ToTypeSyntax(this.fieldTypeSettings, GeneratingElement.Constant, null).Type, ParenthesizedExpression(ToExpressionSyntax(PrimitiveTypeCode.UInt64, argsAsString))),
_ => throw new GenerationFailedException($"Unsupported constant type: {targetType}"),
};
}

private ExpressionSyntax CreateConstant(ReadOnlyMemory<char> argsAsString, TypeSyntax targetType, TypeReferenceHandle targetTypeRefHandle)
private ExpressionSyntax CreateConstant(ReadOnlyMemory<char> argsAsString, TypeSyntax targetType, TypeReferenceHandle targetTypeRefHandle, out bool unsafeRequired)
{
if (!this.TryGetTypeDefHandle(targetTypeRefHandle, out TypeDefinitionHandle targetTypeDefHandle))
{
Expand All @@ -275,6 +281,7 @@ private ExpressionSyntax CreateConstant(ReadOnlyMemory<char> argsAsString, TypeS
if (this.Reader.StringComparer.Equals(typeRef.Name, "Guid"))
{
List<ReadOnlyMemory<char>> guidArgs = SplitConstantArguments(argsAsString);
unsafeRequired = false;
return this.CreateGuidConstant(guidArgs);
}

Expand All @@ -287,8 +294,8 @@ private ExpressionSyntax CreateConstant(ReadOnlyMemory<char> argsAsString, TypeS
List<ReadOnlyMemory<char>> args = SplitConstantArguments(argsAsString);

ObjectCreationExpressionSyntax? result =
this.CreateConstantViaCtor(args, targetType, typeDef) ??
this.CreateConstantByField(args, targetType, typeDef);
this.CreateConstantViaCtor(args, targetType, typeDef, out unsafeRequired) ??
this.CreateConstantByField(args, targetType, typeDef, out unsafeRequired);

return result ?? throw new GenerationFailedException($"Unable to construct constant value given {args.Count} fields or constructor arguments.");
}
Expand Down Expand Up @@ -328,14 +335,15 @@ private ExpressionSyntax CreateGuidConstant(List<ReadOnlyMemory<char>> guidArgs)
return ObjectCreationExpression(GuidTypeSyntax).AddArgumentListArguments(ctorArgs.Select(t => Argument(LiteralExpression(SyntaxKind.NumericLiteralExpression, t))).ToArray());
}

private ExpressionSyntax CreateConstant(CustomAttribute constantAttribute, TypeHandleInfo targetType)
private ExpressionSyntax CreateConstant(CustomAttribute constantAttribute, TypeHandleInfo targetType, out bool unsafeRequired)
{
TypeReferenceHandle targetTypeRefHandle = (TypeReferenceHandle)((HandleTypeHandleInfo)targetType).Handle;
CustomAttributeValue<TypeSyntax> args = constantAttribute.DecodeValue(CustomAttributeTypeProvider.Instance);
return this.CreateConstant(
((string)args.FixedArguments[0].Value!).AsMemory(),
targetType.ToTypeSyntax(this.fieldTypeSettings, GeneratingElement.Constant, null).Type,
targetTypeRefHandle);
targetTypeRefHandle,
out unsafeRequired);
}

private FieldDeclarationSyntax DeclareConstant(FieldDefinition fieldDef)
Expand All @@ -346,12 +354,12 @@ private FieldDeclarationSyntax DeclareConstant(FieldDefinition fieldDef)
TypeHandleInfo fieldTypeInfo = fieldDef.DecodeSignature(SignatureHandleProvider.Instance, null) with { IsConstantField = true };
CustomAttributeHandleCollection customAttributes = fieldDef.GetCustomAttributes();
TypeSyntaxAndMarshaling fieldType = fieldTypeInfo.ToTypeSyntax(this.fieldTypeSettings, GeneratingElement.Constant, customAttributes);
bool requiresUnsafe = false;
ExpressionSyntax value =
fieldDef.GetDefaultValue() is { IsNil: false } constantHandle ? ToExpressionSyntax(this.Reader, constantHandle) :
this.FindInteropDecorativeAttribute(customAttributes, nameof(GuidAttribute)) is CustomAttribute guidAttribute ? GuidValue(guidAttribute) :
this.FindInteropDecorativeAttribute(customAttributes, "ConstantAttribute") is CustomAttribute constantAttribute ? this.CreateConstant(constantAttribute, fieldTypeInfo) :
this.FindInteropDecorativeAttribute(customAttributes, "ConstantAttribute") is CustomAttribute constantAttribute ? this.CreateConstant(constantAttribute, fieldTypeInfo, out requiresUnsafe) :
throw new NotSupportedException("Unsupported constant: " + name);
bool requiresUnsafe = false;
if (fieldType.Type is not PredefinedTypeSyntax && value is not ObjectCreationExpressionSyntax)
{
if (fieldTypeInfo is HandleTypeHandleInfo handleFieldTypeInfo && this.IsHandle(handleFieldTypeInfo.Handle, out _))
Expand Down
27 changes: 27 additions & 0 deletions src/Microsoft.Windows.CsWin32/Generator.Handle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public partial class Generator
IdentifierName(renamedReleaseMethod ?? releaseMethod)),
ArgumentList().AddArguments(releaseHandleArgument));
BlockSyntax? releaseBlock = null;
bool releaseMethodIsUnsafe = false;
if (!(releaseMethodReturnType.Type is PredefinedTypeSyntax { Keyword: { RawKind: (int)SyntaxKind.BoolKeyword } } ||
releaseMethodReturnType.Type is QualifiedNameSyntax { Right: { Identifier: { ValueText: "BOOL" } } }))
{
Expand Down Expand Up @@ -197,6 +198,15 @@ public partial class Generator
ExpressionSyntax noerror = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ParseName("global::Windows.Win32.Foundation.WIN32_ERROR"), IdentifierName("NO_ERROR"));
releaseInvocation = BinaryExpression(SyntaxKind.EqualsExpression, releaseInvocation, noerror);
break;
case "CONFIGRET":
noerror = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ParseName("global::Windows.Win32.Devices.DeviceAndDriverInstallation.CONFIGRET"), IdentifierName("CR_SUCCESS"));
releaseInvocation = BinaryExpression(SyntaxKind.EqualsExpression, releaseInvocation, noerror);
break;
case "LRESULT" when releaseMethod == "ICClose":
this.TryGenerateConstantOrThrow("ICERR_OK");
noerror = CastExpression(ParseName("global::Windows.Win32.Foundation.LRESULT"), MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("PInvoke"), IdentifierName("ICERR_OK")));
releaseInvocation = BinaryExpression(SyntaxKind.EqualsExpression, releaseInvocation, noerror);
break;
case "HGLOBAL":
case "HLOCAL":
releaseInvocation = BinaryExpression(SyntaxKind.EqualsExpression, releaseInvocation, DefaultExpression(releaseMethodReturnType.Type));
Expand All @@ -205,12 +215,29 @@ public partial class Generator
throw new NotSupportedException($"Return type {identifierName.Identifier.ValueText} on release method {releaseMethod} not supported.");
}

break;
case PointerTypeSyntax { ElementType: PredefinedTypeSyntax elementType }:
releaseMethodIsUnsafe = true;
switch (elementType.Keyword.Kind())
{
case SyntaxKind.VoidKeyword when releaseMethod == "FreeSid":
releaseInvocation = BinaryExpression(SyntaxKind.EqualsExpression, releaseInvocation, LiteralExpression(SyntaxKind.NullLiteralExpression));
break;
default:
throw new NotSupportedException($"Return type {elementType}* on release method {releaseMethod} not supported.");
}

break;
}
}

MethodDeclarationSyntax releaseHandleDeclaration = MethodDeclaration(PredefinedType(TokenWithSpace(SyntaxKind.BoolKeyword)), Identifier("ReleaseHandle"))
.AddModifiers(TokenWithSpace(SyntaxKind.ProtectedKeyword), TokenWithSpace(SyntaxKind.OverrideKeyword));
if (releaseMethodIsUnsafe)
{
releaseHandleDeclaration = releaseHandleDeclaration.AddModifiers(TokenWithSpace(SyntaxKind.UnsafeKeyword));
}

releaseHandleDeclaration = releaseBlock is null
? releaseHandleDeclaration
.WithExpressionBody(ArrowExpressionClause(releaseInvocation))
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.Windows.CsWin32/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ internal void RequestInteropType(TypeReferenceHandle typeRefHandle, Context cont
{
AssemblyReference assemblyRef = this.Reader.GetAssemblyReference((AssemblyReferenceHandle)typeRef.ResolutionScope);
string scope = this.Reader.GetString(assemblyRef.Name);
throw new GenerationFailedException($"Input metadata file \"{scope}\" has not been provided.");
throw new GenerationFailedException($"Input metadata file \"{scope}\" has not been provided, or is referenced at a version that is lacking the type \"{metadataName}\".");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.Windows.CsWin32/PointerTypeHandleInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal record PointerTypeHandleInfo(TypeHandleInfo ElementType) : TypeHandleIn
{
public override string ToString() => this.ToTypeSyntaxForDisplay().ToString();

internal override TypeSyntaxAndMarshaling ToTypeSyntax(TypeSyntaxSettings inputs, Generator.GeneratingElement forElement, CustomAttributeHandleCollection? customAttributes, ParameterAttributes parameterAttributes)
internal override TypeSyntaxAndMarshaling ToTypeSyntax(TypeSyntaxSettings inputs, Generator.GeneratingElement forElement, CustomAttributeHandleCollection? customAttributes, ParameterAttributes parameterAttributes = default)
{
Generator.NativeArrayInfo? nativeArrayInfo = customAttributes.HasValue ? inputs.Generator?.FindNativeArrayInfoAttribute(customAttributes.Value) : null;

Expand Down
1 change: 1 addition & 0 deletions test/Microsoft.Windows.CsWin32.Tests/ConstantsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public ConstantsTests(ITestOutputHelper logger)
[InlineData("X509_CERT")] // A constant defined as PCSTR
[InlineData("RT_CURSOR")] // PCWSTR constant
[InlineData("HBMMENU_POPUP_RESTORE")] // A HBITMAP handle as a constant
[InlineData("CONDITION_VARIABLE_INIT")] // A 0 constant typed void*

public void InterestingConstants(string name)
{
Expand Down
9 changes: 9 additions & 0 deletions test/Microsoft.Windows.CsWin32.Tests/HandleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,13 @@ public void ReleaseMethodGeneratedWithHandleStruct()
this.GenerateApi("HANDLE");
Assert.True(this.IsMethodGenerated("CloseHandle"));
}

[Theory]
[InlineData("ICOpen")]
[InlineData("CM_Register_Notification")]
[InlineData("AllocateAndInitializeSid")]
public void ReleaseMethodGeneratedWithUncommonReturnType(string api)
{
this.GenerateApi(api);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ internal static class MyReferenceAssemblies
{
#pragma warning disable SA1202 // Elements should be ordered by access - because field initializer depend on each other
private static readonly ImmutableArray<PackageIdentity> AdditionalLegacyPackages = ImmutableArray.Create(
new PackageIdentity("Microsoft.Windows.SDK.Contracts", "10.0.22621.2"));
new PackageIdentity("Microsoft.Windows.SDK.Contracts", "10.0.22621.2428"));

private static readonly ImmutableArray<PackageIdentity> AdditionalModernPackages = AdditionalLegacyPackages.AddRange(ImmutableArray.Create(
new PackageIdentity("System.Runtime.CompilerServices.Unsafe", "6.0.0"),
Expand Down

0 comments on commit 67da07f

Please sign in to comment.