Skip to content

Use GetTempPath2 on Windows if available #104642

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

Merged
merged 1 commit into from
Jul 10, 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
3 changes: 3 additions & 0 deletions src/coreclr/debug/createdump/createdump.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ extern MINIDUMP_TYPE GetMiniDumpType(DumpType dumpType);

#ifdef HOST_WINDOWS
extern std::string GetLastErrorString();
extern DWORD GetTempPathWrapper(IN DWORD nBufferLength, OUT LPSTR lpBuffer);
#else
#define GetTempPathWrapper GetTempPathA
#endif
extern void printf_status(const char* format, ...);
extern void printf_error(const char* format, ...);
2 changes: 1 addition & 1 deletion src/coreclr/debug/createdump/createdumpmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ int createdump_main(const int argc, const char* argv[])
ArrayHolder<char> tmpPath = new char[MAX_LONGPATH];
if (options.DumpPathTemplate == nullptr)
{
if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0)
if (GetTempPathWrapper(MAX_LONGPATH, tmpPath) == 0)
{
printf_error("GetTempPath failed\n");
return -1;
Expand Down
35 changes: 35 additions & 0 deletions src/coreclr/debug/createdump/createdumpwindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,38 @@ GetLastErrorString()
return result;
}


typedef DWORD(WINAPI *pfnGetTempPathA)(DWORD nBufferLength, LPSTR lpBuffer);

static volatile pfnGetTempPathA
g_pfnGetTempPathA = nullptr;


DWORD
GetTempPathWrapper(
IN DWORD nBufferLength,
OUT LPSTR lpBuffer)
{
if (g_pfnGetTempPathA == nullptr)
{
HMODULE hKernel32 = LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);

pfnGetTempPathA pLocalGetTempPathA = NULL;
if (hKernel32 != NULL)
{
// store to thread local variable to prevent data race
pLocalGetTempPathA = (pfnGetTempPathA)::GetProcAddress(hKernel32, "GetTempPath2A");
}

if (pLocalGetTempPathA == NULL) // method is only available with Windows 10 Creators Update or later
{
g_pfnGetTempPathA = &GetTempPathA;
}
else
{
g_pfnGetTempPathA = pLocalGetTempPathA;
}
}

return g_pfnGetTempPathA(nBufferLength, lpBuffer);
}
4 changes: 0 additions & 4 deletions src/coreclr/inc/longfilepathwrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ SearchPathWrapper(
_Out_opt_ LPWSTR * lpFilePart
);

DWORD WINAPI GetTempPathWrapper(
SString& lpBuffer
);

DWORD
GetModuleFileNameWrapper(
_In_opt_ HMODULE hModule,
Expand Down
41 changes: 0 additions & 41 deletions src/coreclr/utilcode/longfilepathwrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,47 +184,6 @@ GetModuleFileNameWrapper(
return ret;
}

DWORD WINAPI GetTempPathWrapper(
SString& lpBuffer
)
{
CONTRACTL
{
NOTHROW;
}
CONTRACTL_END;

HRESULT hr = S_OK;
DWORD ret = 0;
DWORD lastError = 0;

EX_TRY
{
//Change the behaviour in Redstone to retry
COUNT_T size = MAX_LONGPATH;

ret = GetTempPathW(
size,
lpBuffer.OpenUnicodeBuffer(size - 1)
);

lastError = GetLastError();
lpBuffer.CloseBuffer(ret);
}
EX_CATCH_HRESULT(hr);

if (hr != S_OK)
{
SetLastError(hr);
}
else if (ret == 0)
{
SetLastError(lastError);
}

return ret;
}

DWORD WINAPI GetEnvironmentVariableWrapper(
_In_opt_ LPCTSTR lpName,
_Out_opt_ SString& lpBuffer
Expand Down
34 changes: 33 additions & 1 deletion src/native/corehost/hostmisc/pal.windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,38 @@ void pal::out_vprint_line(const pal::char_t* format, va_list vl) {
print_line_to_handle(&buffer[0], ::GetStdHandle(STD_OUTPUT_HANDLE), stdout);
}

namespace
{
typedef DWORD(WINAPI *get_temp_path_func_ptr)(DWORD buffer_len, LPWSTR buffer);
static volatile get_temp_path_func_ptr s_get_temp_path_func = nullptr;

DWORD get_temp_path(DWORD buffer_len, LPWSTR buffer)
{
if (s_get_temp_path_func == nullptr)
{
HMODULE kernel32 = ::LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);

get_temp_path_func_ptr get_temp_path_func_local = NULL;
if (kernel32 != NULL)
{
// store to thread local variable to prevent data race
get_temp_path_func_local = (get_temp_path_func_ptr)::GetProcAddress(kernel32, "GetTempPath2W");
}

if (get_temp_path_func_local == NULL) // method is only available with Windows 10 Creators Update or later
{
s_get_temp_path_func = &GetTempPathW;
}
else
{
s_get_temp_path_func = get_temp_path_func_local;
}
}

return s_get_temp_path_func(buffer_len, buffer);
}
}

bool GetModuleFileNameWrapper(HMODULE hModule, pal::string_t* recv)
{
pal::string_t path;
Expand Down Expand Up @@ -695,7 +727,7 @@ bool get_extraction_base_parent_directory(pal::string_t& directory)
const size_t max_len = MAX_PATH + 1;
pal::char_t temp_path[max_len];

size_t len = GetTempPathW(max_len, temp_path);
size_t len = get_temp_path(max_len, temp_path);
if (len == 0)
{
return false;
Expand Down
Loading