Skip to content

Commit 025271a

Browse files
hoyosjscarlossanlop
authored andcommitted
Use GetTempPath2 on Windows if available
## Description Since Windows 10 Build 20348, there is a new API to get the temporary files path called [`GetTempPath2`](https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-gettemppath2w). This API returns a directory inaccessible to non-SYSTEM processes if the calling process runs as SYSTEM, and [it is recommended to call this function instead of `GetTempPath`](https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-gettemppathw#remarks). This PR tries to find `GetTempPath2A` / `GetTempPath2W` and uses that, otherwise it falls back to `GetTempPathA` / `GetTempPathW`. *Note:* this PR removes an unused function called `WszGetTempPath` that which referenced GetTempPathW ## Customer Impact - [ ] Customer reported - [X] Found internally This was found by code inspection. ## Regression - [ ] Yes - [X] No ## Testing PR validation ## Risk Low
1 parent eae2d42 commit 025271a

File tree

7 files changed

+72
-50
lines changed

7 files changed

+72
-50
lines changed

src/coreclr/debug/createdump/createdump.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ extern MINIDUMP_TYPE GetMiniDumpType(DumpType dumpType);
151151

152152
#ifdef HOST_WINDOWS
153153
extern std::string GetLastErrorString();
154+
extern DWORD GetTempPathWrapper(IN DWORD nBufferLength, OUT LPSTR lpBuffer);
155+
#else
156+
#define GetTempPathWrapper GetTempPathA
154157
#endif
155158
extern void printf_status(const char* format, ...);
156159
extern void printf_error(const char* format, ...);

src/coreclr/debug/createdump/createdumpmain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ int createdump_main(const int argc, const char* argv[])
205205
ArrayHolder<char> tmpPath = new char[MAX_LONGPATH];
206206
if (options.DumpPathTemplate == nullptr)
207207
{
208-
if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0)
208+
if (GetTempPathWrapper(MAX_LONGPATH, tmpPath) == 0)
209209
{
210210
printf_error("GetTempPath failed\n");
211211
return -1;

src/coreclr/debug/createdump/createdumpwindows.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,38 @@ GetLastErrorString()
135135
return result;
136136
}
137137

138+
139+
typedef DWORD(WINAPI *pfnGetTempPathA)(DWORD nBufferLength, LPSTR lpBuffer);
140+
141+
static volatile pfnGetTempPathA
142+
g_pfnGetTempPathA = nullptr;
143+
144+
145+
DWORD
146+
GetTempPathWrapper(
147+
IN DWORD nBufferLength,
148+
OUT LPSTR lpBuffer)
149+
{
150+
if (g_pfnGetTempPathA == nullptr)
151+
{
152+
HMODULE hKernel32 = LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
153+
154+
pfnGetTempPathA pLocalGetTempPathA = NULL;
155+
if (hKernel32 != NULL)
156+
{
157+
// store to thread local variable to prevent data race
158+
pLocalGetTempPathA = (pfnGetTempPathA)::GetProcAddress(hKernel32, "GetTempPath2A");
159+
}
160+
161+
if (pLocalGetTempPathA == NULL) // method is only available with Windows 10 Creators Update or later
162+
{
163+
g_pfnGetTempPathA = &GetTempPathA;
164+
}
165+
else
166+
{
167+
g_pfnGetTempPathA = pLocalGetTempPathA;
168+
}
169+
}
170+
171+
return g_pfnGetTempPathA(nBufferLength, lpBuffer);
172+
}

src/coreclr/inc/longfilepathwrappers.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ SearchPathWrapper(
5959
_Out_opt_ LPWSTR * lpFilePart
6060
);
6161

62-
DWORD WINAPI GetTempPathWrapper(
63-
SString& lpBuffer
64-
);
65-
6662
DWORD
6763
GetModuleFileNameWrapper(
6864
_In_opt_ HMODULE hModule,

src/coreclr/inc/winwrap.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,6 @@
204204
//Can not use extended syntax
205205
#define WszGetFullPathName GetFullPathNameW
206206

207-
//Long Files will not work on these till redstone
208-
#define WszGetTempPath GetTempPathWrapper
209-
210207
//APIS which have a buffer as an out parameter
211208
#define WszGetEnvironmentVariable GetEnvironmentVariableWrapper
212209
#define WszSearchPath SearchPathWrapper

src/coreclr/utilcode/longfilepathwrappers.cpp

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -184,47 +184,6 @@ GetModuleFileNameWrapper(
184184
return ret;
185185
}
186186

187-
DWORD WINAPI GetTempPathWrapper(
188-
SString& lpBuffer
189-
)
190-
{
191-
CONTRACTL
192-
{
193-
NOTHROW;
194-
}
195-
CONTRACTL_END;
196-
197-
HRESULT hr = S_OK;
198-
DWORD ret = 0;
199-
DWORD lastError = 0;
200-
201-
EX_TRY
202-
{
203-
//Change the behaviour in Redstone to retry
204-
COUNT_T size = MAX_LONGPATH;
205-
206-
ret = GetTempPathW(
207-
size,
208-
lpBuffer.OpenUnicodeBuffer(size - 1)
209-
);
210-
211-
lastError = GetLastError();
212-
lpBuffer.CloseBuffer(ret);
213-
}
214-
EX_CATCH_HRESULT(hr);
215-
216-
if (hr != S_OK)
217-
{
218-
SetLastError(hr);
219-
}
220-
else if (ret == 0)
221-
{
222-
SetLastError(lastError);
223-
}
224-
225-
return ret;
226-
}
227-
228187
DWORD WINAPI GetEnvironmentVariableWrapper(
229188
_In_opt_ LPCTSTR lpName,
230189
_Out_opt_ SString& lpBuffer

src/native/corehost/hostmisc/pal.windows.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,38 @@
1010
#include <ShlObj.h>
1111
#include <ctime>
1212

13+
namespace
14+
{
15+
typedef DWORD(WINAPI *get_temp_path_func_ptr)(DWORD buffer_len, LPWSTR buffer);
16+
static volatile get_temp_path_func_ptr s_get_temp_path_func = nullptr;
17+
18+
DWORD get_temp_path(DWORD buffer_len, LPWSTR buffer)
19+
{
20+
if (s_get_temp_path_func == nullptr)
21+
{
22+
HMODULE kernel32 = ::LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
23+
24+
get_temp_path_func_ptr get_temp_path_func_local = NULL;
25+
if (kernel32 != NULL)
26+
{
27+
// store to thread local variable to prevent data race
28+
get_temp_path_func_local = (get_temp_path_func_ptr)::GetProcAddress(kernel32, "GetTempPath2W");
29+
}
30+
31+
if (get_temp_path_func_local == NULL) // method is only available with Windows 10 Creators Update or later
32+
{
33+
s_get_temp_path_func = &GetTempPathW;
34+
}
35+
else
36+
{
37+
s_get_temp_path_func = get_temp_path_func_local;
38+
}
39+
}
40+
41+
return s_get_temp_path_func(buffer_len, buffer);
42+
}
43+
}
44+
1345
bool GetModuleFileNameWrapper(HMODULE hModule, pal::string_t* recv)
1446
{
1547
pal::string_t path;
@@ -639,7 +671,7 @@ bool get_extraction_base_parent_directory(pal::string_t& directory)
639671
const size_t max_len = MAX_PATH + 1;
640672
pal::char_t temp_path[max_len];
641673

642-
size_t len = GetTempPathW(max_len, temp_path);
674+
size_t len = get_temp_path(max_len, temp_path);
643675
if (len == 0)
644676
{
645677
return false;

0 commit comments

Comments
 (0)