Skip to content

Commit

Permalink
Convert to OleDb assembly and last Cryptography DllImport to Generate…
Browse files Browse the repository at this point in the history
…dDllImport (#61184)

* Enable DllImport generator for all source projects.

* Convert OleDb to only use GeneratedDllImport.

* Update source generator to distinguish between "no marshalling info"
  which can cause a failure vs "missing support" which enables us to
  fallback to the marshalling forwarder.

* Remove unused DllImports.

* Reuse existing P/Invoke definitions.
  • Loading branch information
AaronRobinsonMSFT authored Nov 6, 2021
1 parent 215ff0b commit f080744
Show file tree
Hide file tree
Showing 27 changed files with 199 additions and 192 deletions.
14 changes: 11 additions & 3 deletions eng/generators.targets
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<EnabledGenerators Include="DllImportGenerator"
Condition="'$(EnableDllImportGenerator)' == ''
and '$(IsFrameworkSupportFacade)' != 'true'
and '$(IsNetCoreAppSrc)' == 'true'
and '$(IsSourceProject)' == 'true'
and '$(MSBuildProjectExtension)' == '.csproj'
and (
('@(Reference)' != ''
Expand All @@ -27,6 +27,12 @@
and @(Reference->AnyHaveMetadataValue('Identity', 'System.Memory')))
or ('@(ProjectReference)' != ''
and @(ProjectReference->AnyHaveMetadataValue('Identity', '$(CoreLibProject)'))))" />
<EnabledGenerators Include="DllImportGenerator"
Condition="'$(EnableDllImportGenerator)' == ''
and '$(IsFrameworkSupportFacade)' != 'true'
and '$(IsSourceProject)' == 'true'
and '$(MSBuildProjectExtension)' == '.csproj'
and '$(TargetFrameworkIdentifier)' == '.NETStandard'" />
</ItemGroup>

<!-- Use this complex ItemGroup-based filtering to add the ProjectReference to make sure dotnet/runtime stays compatible with NuGet Static Graph Restore. -->
Expand All @@ -35,8 +41,10 @@
and '$(IncludeDllImportGeneratorSources)' == 'true'">
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.InteropServices\gen\DllImportGenerator\DllImportGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<Compile Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\GeneratedDllImportAttribute.cs" />
<Compile Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\GeneratedMarshallingAttribute.cs" />
<Compile Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\ArrayMarshaller.cs" />

<!-- Only add the following files if we are on the latest TFM (that is, net7). -->
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'" Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\GeneratedMarshallingAttribute.cs" />
<Compile Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)'" Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\ArrayMarshaller.cs" />
</ItemGroup>

<Target Name="ConfigureGenerators"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,55 @@ internal static partial class Interop
internal static partial class Crypt32
{
#if DLLIMPORTGENERATOR_ENABLED
[GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
internal static unsafe partial bool CryptMsgGetParam(
SafeCryptMsgHandle hCryptMsg,
CryptMsgParamType dwParamType,
int dwIndex,
byte* pvData,
ref int pcbData);

[GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
internal static partial bool CryptMsgGetParam(SafeCryptMsgHandle hCryptMsg,
CryptMsgParamType dwParamType,
int dwIndex,
out int pvData,
ref int pcbData);
[GeneratedDllImport(Libraries.Crypt32, SetLastError = true)]
internal static partial bool CryptMsgGetParam(
#else
[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
[DllImport(Libraries.Crypt32, SetLastError = true)]
internal static extern bool CryptMsgGetParam(
#endif
SafeCryptMsgHandle hCryptMsg,
CryptMsgParamType dwParamType,
int dwIndex,
out int pvData,
[In, Out] ref int pcbData);
#endif
ref int pcbData);

[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CryptMsgGetParam(
#if DLLIMPORTGENERATOR_ENABLED
[GeneratedDllImport(Libraries.Crypt32, SetLastError = true)]
internal static unsafe partial bool CryptMsgGetParam(
#else
[DllImport(Libraries.Crypt32, SetLastError = true)]
internal static unsafe extern bool CryptMsgGetParam(
#endif
SafeCryptMsgHandle hCryptMsg,
CryptMsgParamType dwParamType,
int dwIndex,
out CryptMsgType pvData,
[In, Out] ref int pcbData);
byte* pvData,
ref int pcbData);

[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
#if DLLIMPORTGENERATOR_ENABLED
[GeneratedDllImport(Libraries.Crypt32, SetLastError = true)]
internal static partial bool CryptMsgGetParam(
#else
[DllImport(Libraries.Crypt32, SetLastError = true)]
internal static extern bool CryptMsgGetParam(
#endif
SafeCryptMsgHandle hCryptMsg,
CryptMsgParamType dwParamType,
int dwIndex,
[Out] byte[]? pvData,
[In, Out] ref int pcbData);
out CryptMsgType pvData,
ref int pcbData);

[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
#if DLLIMPORTGENERATOR_ENABLED
[GeneratedDllImport(Libraries.Crypt32, SetLastError = true)]
internal static partial bool CryptMsgGetParam(
#else
[DllImport(Libraries.Crypt32, SetLastError = true)]
internal static extern bool CryptMsgGetParam(
#endif
SafeCryptMsgHandle hCryptMsg,
CryptMsgParamType dwParamType,
int dwIndex,
IntPtr pvData,
[In, Out] ref int pcbData);
ref int pcbData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Kernel32
{
[GeneratedDllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode, PreserveSig = true)]
internal static partial int GetUserDefaultLCID();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ internal static partial class Kernel32
{
internal const uint LMEM_FIXED = 0x0000;
internal const uint LMEM_MOVEABLE = 0x0002;
internal const uint LMEM_ZEROINIT = 0x0040;

[DllImport(Libraries.Kernel32)]
internal static extern IntPtr LocalAlloc(uint uFlags, nuint uBytes);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Ole32
{
[GeneratedDllImport(Interop.Libraries.Ole32)]
internal static partial void PropVariantClear(IntPtr pObject);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class OleAut32
{
// only using this to clear existing error info with null
[GeneratedDllImport(Interop.Libraries.OleAut32)]
// TLS values are preserved between threads, need to check that we use this API to clear the error state only.
internal static partial void SetErrorInfo(int dwReserved, IntPtr pIErrorInfo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ internal static partial class Interop
{
internal static partial class OleAut32
{
[DllImport(Libraries.OleAut32, CharSet = CharSet.Unicode)]
internal static extern IntPtr SysAllocStringLen(IntPtr src, uint len);
[GeneratedDllImport(Libraries.OleAut32, CharSet = CharSet.Unicode)]
internal static partial IntPtr SysAllocStringLen(IntPtr src, uint len);

[GeneratedDllImport(Libraries.OleAut32, CharSet = CharSet.Unicode)]
internal static partial IntPtr SysAllocStringLen(string src, uint len);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<EnableDefaultItems>true</EnableDefaultItems>
<Nullable>annotations</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);NO_SUPPRESS_GC_TRANSITION</DefineConstants>
<!-- Use targeting pack references instead of granular ones in the project file. -->
<DisableImplicitAssemblyReferences>false</DisableImplicitAssemblyReferences>
Expand Down
14 changes: 7 additions & 7 deletions src/libraries/System.Data.OleDb/src/DbPropSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ public DBPropSet() : base(IntPtr.Zero, true)
internal DBPropSet(int propertysetCount) : this()
{
this.propertySetCount = propertysetCount;
IntPtr countOfBytes = (IntPtr)(propertysetCount * ODB.SizeOf_tagDBPROPSET);
nuint countOfBytes = (nuint)(propertysetCount * ODB.SizeOf_tagDBPROPSET);
RuntimeHelpers.PrepareConstrainedRegions();
try
{ }
finally
{
base.handle = SafeNativeMethods.CoTaskMemAlloc(countOfBytes);
base.handle = Interop.Ole32.CoTaskMemAlloc(countOfBytes);
if (ADP.PtrZero != base.handle)
{
SafeNativeMethods.ZeroMemory(base.handle, (int)countOfBytes);
Expand Down Expand Up @@ -145,12 +145,12 @@ protected override bool ReleaseHandle()
IntPtr vptr = ADP.IntPtrOffset(rgProperties, ODB.OffsetOf_tagDBPROP_Value);
for (int k = 0; k < cProperties; ++k, vptr = ADP.IntPtrOffset(vptr, ODB.SizeOf_tagDBPROP))
{
SafeNativeMethods.VariantClear(vptr);
Interop.OleAut32.VariantClear(vptr);
}
SafeNativeMethods.CoTaskMemFree(rgProperties);
Interop.Ole32.CoTaskMemFree(rgProperties);
}
}
SafeNativeMethods.CoTaskMemFree(ptr);
Interop.Ole32.CoTaskMemFree(ptr);
}
return true;
}
Expand Down Expand Up @@ -227,7 +227,7 @@ internal void SetPropertySet(int index, Guid propertySet, ItagDBPROP[] propertie
Debug.Assert(Guid.Empty != propertySet, "invalid propertySet");
Debug.Assert((null != properties) && (0 < properties.Length), "invalid properties");

IntPtr countOfBytes = (IntPtr)(properties.Length * ODB.SizeOf_tagDBPROP);
nuint countOfBytes = (nuint)(properties.Length * ODB.SizeOf_tagDBPROP);
tagDBPROPSET propset = new tagDBPROPSET(properties.Length, propertySet);

bool mustRelease = false;
Expand All @@ -244,7 +244,7 @@ internal void SetPropertySet(int index, Guid propertySet, ItagDBPROP[] propertie
finally
{
// must allocate and clear the memory without interruption
propset.rgProperties = SafeNativeMethods.CoTaskMemAlloc(countOfBytes);
propset.rgProperties = Interop.Ole32.CoTaskMemAlloc(countOfBytes);
if (ADP.PtrZero != propset.rgProperties)
{
// clearing is important so that we don't treat existing
Expand Down
64 changes: 1 addition & 63 deletions src/libraries/System.Data.OleDb/src/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace System.Data.Common
{
internal static class NativeMethods
internal static partial class NativeMethods
{
[Guid("0c733a1e-2a1c-11ce-ade5-00aa0044773d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComImport]
internal interface ISourcesRowset
Expand All @@ -32,67 +32,5 @@ void JoinTransaction(
[In] int isoFlags,
[In] IntPtr pOtherOptions);
}

[DllImport(Interop.Libraries.Kernel32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, IntPtr dwNumberOfBytesToMap);

[DllImport(Interop.Libraries.Kernel32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);

[DllImport(Interop.Libraries.Kernel32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern bool CloseHandle(IntPtr handle);

[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern bool AllocateAndInitializeSid(
IntPtr pIdentifierAuthority, // authority
byte nSubAuthorityCount, // count of subauthorities
int dwSubAuthority0, // subauthority 0
int dwSubAuthority1, // subauthority 1
int dwSubAuthority2, // subauthority 2
int dwSubAuthority3, // subauthority 3
int dwSubAuthority4, // subauthority 4
int dwSubAuthority5, // subauthority 5
int dwSubAuthority6, // subauthority 6
int dwSubAuthority7, // subauthority 7
ref IntPtr pSid); // SID

[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern int GetLengthSid(
IntPtr pSid); // SID to query

[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern bool InitializeAcl(
IntPtr pAcl, // ACL
int nAclLength, // size of ACL
int dwAclRevision); // revision level of ACL

[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern bool AddAccessDeniedAce(
IntPtr pAcl, // access control list
int dwAceRevision, // ACL revision level
int AccessMask, // access mask
IntPtr pSid); // security identifier

[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern bool AddAccessAllowedAce(
IntPtr pAcl, // access control list
int dwAceRevision, // ACL revision level
uint AccessMask, // access mask
IntPtr pSid); // security identifier

[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern bool InitializeSecurityDescriptor(
IntPtr pSecurityDescriptor, // SD
int dwRevision); // revision level
[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern bool SetSecurityDescriptorDacl(
IntPtr pSecurityDescriptor, // SD
bool bDaclPresent, // DACL presence
IntPtr pDacl, // DACL
bool bDaclDefaulted); // default DACL

[DllImport(Interop.Libraries.Advapi32, ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
internal static extern IntPtr FreeSid(
IntPtr pSid); // SID to free
}
}
4 changes: 2 additions & 2 deletions src/libraries/System.Data.OleDb/src/OleDbError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index)
if (OleDbHResult.DB_E_NOLOCALE == hr)
{
Marshal.ReleaseComObject(errorInfo);
lcid = SafeNativeMethods.GetUserDefaultLCID();
lcid = Interop.Kernel32.GetUserDefaultLCID();
errorInfo = errorRecords.GetErrorInfo(index, lcid);

if (null != errorInfo)
Expand All @@ -44,7 +44,7 @@ internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index)
if (OleDbHResult.DB_E_NOLOCALE == hr)
{
Marshal.ReleaseComObject(errorInfo);
lcid = SafeNativeMethods.GetUserDefaultLCID();
lcid = Interop.Kernel32.GetUserDefaultLCID();
errorInfo = errorRecords.GetErrorInfo(index, lcid);

if (null != errorInfo)
Expand Down
8 changes: 4 additions & 4 deletions src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,19 @@ protected override bool ReleaseHandle()
for (int k = 0; k < infoCount; ++k)
{
IntPtr valuePtr = ADP.IntPtrOffset(infoPtr, (k * ODB.SizeOf_tagDBPROPINFO) + ODB.OffsetOf_tagDBPROPINFO_Value);
SafeNativeMethods.VariantClear(valuePtr);
Interop.OleAut32.VariantClear(valuePtr);
}
SafeNativeMethods.CoTaskMemFree(infoPtr); // was allocated by provider
Interop.Ole32.CoTaskMemFree(infoPtr); // was allocated by provider
}
}
SafeNativeMethods.CoTaskMemFree(ptr);
Interop.Ole32.CoTaskMemFree(ptr);
}

ptr = this.descBuffer;
this.descBuffer = IntPtr.Zero;
if (IntPtr.Zero != ptr)
{
SafeNativeMethods.CoTaskMemFree(ptr);
Interop.Ole32.CoTaskMemFree(ptr);
}
return true;
}
Expand Down
Loading

0 comments on commit f080744

Please sign in to comment.