forked from maraf/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwinfix.cpp
More file actions
142 lines (116 loc) · 4.49 KB
/
winfix.cpp
File metadata and controls
142 lines (116 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//*****************************************************************************
// WinWrap.cpp
//
//*****************************************************************************
#include "stdafx.h" // Precompiled header key.
#include "winwrap.h" // Header for macros and functions.
#include "utilcode.h"
#include "holder.h"
// The only purpose of this function is to make a local copy of lpCommandLine.
// Because windows implementation of CreateProcessW can actually change lpCommandLine,
// but we'd like to keep it const.
BOOL
WszCreateProcess(
LPCWSTR lpApplicationName,
LPCWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
BOOL fResult;
DWORD err;
{
size_t commandLineLength = u16_strlen(lpCommandLine) + 1;
NewArrayHolder<WCHAR> nonConstCommandLine(new (nothrow) WCHAR[commandLineLength]);
if (nonConstCommandLine == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
memcpy(nonConstCommandLine, lpCommandLine, commandLineLength * sizeof(WCHAR));
fResult = CreateProcessW(lpApplicationName,
nonConstCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
(LPWSTR)lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
// At the end of the current scope, the last error code will be overwritten by the destructor of
// NewArrayHolder. So we save the error code here, and restore it after the end of the current scope.
err = GetLastError();
}
SetLastError(err);
return fResult;
}
#ifndef HOST_UNIX
#include "psapi.h"
#include "winnls.h"
//********** Globals. *********************************************************
static volatile ULONG g_dwMaxDBCSCharByteSize = 0;
// Detect Unicode support of the operating system, and initialize globals
DWORD GetMaxDBCSCharByteSize()
{
STATIC_CONTRACT_NOTHROW;
STATIC_CONTRACT_FORBID_FAULT;
STATIC_CONTRACT_CANNOT_TAKE_LOCK;
if (g_dwMaxDBCSCharByteSize == 0)
{
DWORD dwMaxDBCSCharByteSize;
CPINFO cpInfo;
if (GetCPInfo(CP_ACP, &cpInfo))
dwMaxDBCSCharByteSize = cpInfo.MaxCharSize;
else
dwMaxDBCSCharByteSize = 2;
g_dwMaxDBCSCharByteSize = dwMaxDBCSCharByteSize;
}
return g_dwMaxDBCSCharByteSize;
}
typedef HRESULT(WINAPI *pfnSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription);
extern pfnSetThreadDescription g_pfnSetThreadDescription;
// Dummy method if windows version does not support it
HRESULT SetThreadDescriptionDummy(HANDLE hThread, PCWSTR lpThreadDescription)
{
return NOERROR;
}
HRESULT WINAPI InitializeSetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription)
{
HMODULE hKernel32 = WszLoadLibrary(W("kernel32.dll"));
pfnSetThreadDescription pLocal = NULL;
if (hKernel32 != NULL)
{
// store to thread local variable to prevent data race
pLocal = (pfnSetThreadDescription)GetProcAddress(hKernel32, "SetThreadDescription");
}
if (pLocal == NULL) // method is only available with Windows 10 Creators Update or later
{
g_pfnSetThreadDescription = SetThreadDescriptionDummy;
}
else
{
g_pfnSetThreadDescription = pLocal;
}
return g_pfnSetThreadDescription(hThread, lpThreadDescription);
}
pfnSetThreadDescription g_pfnSetThreadDescription = &InitializeSetThreadDescription;
// Set unmanaged thread name which will show up in ETW and Debuggers which know how to read this data.
HRESULT SetThreadName(HANDLE hThread, PCWSTR lpThreadDescription)
{
return g_pfnSetThreadDescription(hThread, lpThreadDescription);
}
#else //!HOST_UNIX
HRESULT SetThreadName(HANDLE hThread, PCWSTR lpThreadDescription)
{
return SetThreadDescription(hThread, lpThreadDescription);
}
#endif //!HOST_UNIX