Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump metadata versions: SDK: 60.0.34, WDK: 0.11.4 #1148

Merged
merged 6 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
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
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