Skip to content

Commit 6433103

Browse files
Adam Sitnikcarlossanlop
authored andcommitted
Microsoft.IO.Redist part (and a build fix)
CHILD: .NET CORE | ElevationOfPrivilege: Microsoft.IO.Redist part (and a build fix) It turned out that https://dev.azure.com/dnceng/internal/_git/dotnet-runtime/pullrequest/39614 was incomplete and caused a build break. The code was compiling fine for the default config (.NET 6), but not Full Framework, which includes Microsoft.IO.Redist which compiles the affected files. I could not use exact same fix for Framework as for 6.0 as the code was using umanaged function pointers and causing error CS8889, so I've applied the same fix I did for Full Framework.
1 parent 0a0dd0e commit 6433103

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetProcAddress.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ internal static partial class Interop
1010
{
1111
internal static partial class Kernel32
1212
{
13+
#if !MS_IO_REDIST // SafeLibraryHandle is inaccessible due to its protection level
1314
[DllImport(Libraries.Kernel32, CharSet = CharSet.Ansi, BestFitMapping = false)]
1415
public static extern IntPtr GetProcAddress(SafeLibraryHandle hModule, string lpProcName);
16+
#endif
1517

1618
[DllImport(Libraries.Kernel32, CharSet = CharSet.Ansi, BestFitMapping = false)]
1719
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.InteropServices;
5+
6+
internal static partial class Interop
7+
{
8+
internal static partial class Kernel32
9+
{
10+
[DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
11+
internal static extern uint GetTempPathW(int bufferLen, ref char buffer);
12+
13+
[DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
14+
internal static extern uint GetTempPath2W(int bufferLen, ref char buffer);
15+
}
16+
}

src/libraries/Microsoft.IO.Redist/src/Microsoft.IO.Redist.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<IsPackable>true</IsPackable>
4+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
5+
<ServicingVersion>1</ServicingVersion>
46
<PackageDescription>Downlevel support package for System.IO classes.</PackageDescription>
57
<DefineConstants>$(DefineConstants);MS_IO_REDIST</DefineConstants>
68
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -108,6 +110,10 @@
108110
Link="Interop\Windows\Interop.GetTempFileNameW.cs" />
109111
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GetTempPathW.cs"
110112
Link="Interop\Windows\Kernel32\Interop.GetTempPathW.cs" />
113+
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GetModuleHandle.cs"
114+
Link="Interop\Windows\Kernel32\Interop.GetModuleHandle.cs" />
115+
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GetProcAddress.cs"
116+
Link="Interop\Windows\Kernel32\Interop.GetProcAddress.cs" />
111117
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.MAX_PATH.cs"
112118
Link="Interop\Windows\Interop.MAX_PATH.cs" />
113119
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.REPARSE_DATA_BUFFER.cs"

src/libraries/System.Private.CoreLib/src/System/IO/Path.Windows.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ namespace System.IO
1717
{
1818
public static unsafe partial class Path
1919
{
20+
#if MS_IO_REDIST
21+
private static volatile int s_GetTempPathVersion;
22+
#else
2023
private static volatile delegate* unmanaged<int, char*, uint> s_GetTempPathWFunc;
24+
#endif
2125

2226
public static char[] GetInvalidFileNameChars() => new char[]
2327
{
@@ -155,6 +159,20 @@ public static string GetTempPath()
155159
return path;
156160
}
157161

162+
#if MS_IO_REDIST
163+
private static int GetGetTempPathVersion()
164+
{
165+
IntPtr kernel32 = Interop.Kernel32.GetModuleHandle(Interop.Libraries.Kernel32);
166+
if (kernel32 != IntPtr.Zero)
167+
{
168+
if (Interop.Kernel32.GetProcAddress(kernel32, "GetTempPath2W") != IntPtr.Zero)
169+
{
170+
return 2;
171+
}
172+
}
173+
return 1;
174+
}
175+
#else
158176
private static unsafe delegate* unmanaged<int, char*, uint> GetGetTempPathWFunc()
159177
{
160178
IntPtr kernel32 = Interop.Kernel32.LoadLibraryEx(Interop.Libraries.Kernel32, IntPtr.Zero, Interop.Kernel32.LOAD_LIBRARY_SEARCH_SYSTEM32);
@@ -166,6 +184,7 @@ public static string GetTempPath()
166184

167185
return (delegate* unmanaged<int, char*, uint>)func;
168186
}
187+
#endif
169188

170189
internal static void GetTempPath(ref ValueStringBuilder builder)
171190
{
@@ -183,6 +202,16 @@ internal static void GetTempPath(ref ValueStringBuilder builder)
183202

184203
static uint GetTempPathW(int bufferLen, ref char buffer)
185204
{
205+
#if MS_IO_REDIST
206+
int getTempPathVersion = s_GetTempPathVersion;
207+
if (getTempPathVersion == 0)
208+
{
209+
s_GetTempPathVersion = getTempPathVersion = GetGetTempPathVersion();
210+
}
211+
return getTempPathVersion == 2
212+
? Interop.Kernel32.GetTempPath2W(bufferLen, ref buffer)
213+
: Interop.Kernel32.GetTempPathW(bufferLen, ref buffer);
214+
#else
186215
delegate* unmanaged<int, char*, uint> func = s_GetTempPathWFunc;
187216
if (func == null)
188217
{
@@ -200,6 +229,7 @@ static uint GetTempPathW(int bufferLen, ref char buffer)
200229

201230
Marshal.SetLastPInvokeError(lastError);
202231
return retVal;
232+
#endif
203233
}
204234
}
205235

0 commit comments

Comments
 (0)