Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/jcl/win32/syshelp.c
6000 views
1
/*******************************************************************************
2
* Copyright (c) 1998, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
/* Undefine the winsockapi because winsock2 defines it. Removes warnings. */
23
#if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
24
#undef _WINSOCKAPI_
25
#endif
26
#include <winsock2.h>
27
#include <windows.h>
28
#include <winbase.h>
29
#include <stdlib.h>
30
#include <LMCONS.H>
31
#include <direct.h>
32
#include "jcl.h"
33
#include "jclprots.h"
34
#include "jclglob.h"
35
#include "util_api.h"
36
37
38
#include "portsock.h"
39
40
#include <WinSDKVer.h>
41
42
#if defined(_WIN32_WINNT_WINBLUE) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE)
43
#include <VersionHelpers.h>
44
#endif
45
46
/* JCL_J2SE */
47
#define JCL_J2SE
48
49
50
char* getPlatformFileEncoding(JNIEnv *env, char *codepage, int size, int encodingType);
51
I_32 convertToUTF8(J9PortLibrary* portLibrary, const wchar_t* unicodeString, char* utf8Buffer, UDATA size);
52
char * getTmpDir(JNIEnv *env, char **tempdir);
53
jobject getPlatformPropertyList(JNIEnv *env, const char *strings[], int propIndex);
54
void mapLibraryToPlatformName(const char *inPath, char *outPath);
55
56
57
jobject getPlatformPropertyList(JNIEnv *env, const char *strings[], int propIndex) {
58
PORT_ACCESS_FROM_ENV(env);
59
#if !defined(_WIN32_WINNT_WINBLUE) || (_WIN32_WINNT_MAXVER < _WIN32_WINNT_WINBLUE)
60
OSVERSIONINFO versionInfo;
61
#endif /* !defined(_WIN32_WINNT_WINBLUE) || (_WIN32_WINNT_MAXVER < _WIN32_WINNT_WINBLUE) */
62
I_32 envSize;
63
char *envSpace = NULL, *tempdir = NULL;
64
jobject result;
65
char userhome[EsMaxPath];
66
wchar_t unicodeTemp[EsMaxPath];
67
int i;
68
char userdir[EsMaxPath];
69
wchar_t unicodeHome[EsMaxPath];
70
HANDLE process, token;
71
UDATA handle;
72
BOOL (WINAPI *func)(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize);
73
#if !defined(JCL_J2SE)
74
UINT codePage;
75
char codePageBuf[32];
76
CPINFO cpInfo;
77
#endif
78
79
/* Hard coded file/path separators and other values */
80
81
strings[propIndex++] = "file.separator";
82
strings[propIndex++] = "\\";
83
84
strings[propIndex++] = "line.separator";
85
strings[propIndex++] = "\r\n";
86
87
/* Get the Temp Dir name */
88
strings[propIndex++] = "java.io.tmpdir";
89
strings[propIndex++] = getTmpDir(env, &tempdir);
90
91
strings[propIndex++] = "user.home";
92
i = propIndex;
93
envSize = (I_32)j9sysinfo_get_env("USERPROFILE", NULL, 0);
94
if (-1 != envSize) {
95
envSpace = jclmem_allocate_memory(env, envSize); /* trailing null taken into account */
96
if (NULL == envSpace) {
97
strings[propIndex++] = "\\";
98
} else {
99
j9sysinfo_get_env("USERPROFILE", envSpace, envSize);
100
strings[propIndex++] = envSpace;
101
}
102
}
103
#if defined(_WIN32_WINNT_WINBLUE) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE)
104
/* dwPlatformId, VER_PLATFORM_WIN32_NT = https://msdn.microsoft.com/en-us/library/windows/desktop/ms724834(v=vs.85).aspx */
105
if ((i == propIndex) && IsWindowsVersionOrGreater( 5, 0, 0))
106
#else /* defined(_WIN32_WINNT_WINBLUE) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE) */
107
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
108
if ((i == propIndex) && GetVersionEx(&versionInfo) && (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT))
109
#endif /* defined(_WIN32_WINNT_WINBLUE) && (_WIN32_WINNT_MAXVER >= _WIN32_WINNT_WINBLUE) */
110
{
111
process = GetCurrentProcess();
112
if (OpenProcessToken(process, TOKEN_QUERY, &token)) {
113
envSize = 0;
114
if (j9util_open_system_library("userenv", &handle, TRUE) == 0) {
115
if (i == propIndex) {
116
if (j9sl_lookup_name(handle, "GetUserProfileDirectoryW", (UDATA *)&func, "ZPLP") == 0) {
117
envSize = EsMaxPath;
118
if (func(token, unicodeHome, &envSize)) {
119
/* When the SystemDrive environment variable isn't set, such as when j9 is exec'ed
120
* running JCK tests, we get %SystemDrive%/Documents and Settings/...
121
*/
122
if (!wcsncmp(unicodeHome, L"%SystemDrive%", 13)) {
123
/* Borrow userdir variable, which is used for real below */
124
if (GetSystemDirectoryW(unicodeTemp, EsMaxPath) > 1) {
125
unicodeHome[0] = unicodeTemp[0];
126
unicodeHome[1] = unicodeTemp[1];
127
wcsncpy(&unicodeHome[2], &unicodeHome[13], envSize - 13);
128
}
129
}
130
convertToUTF8(PORTLIB, unicodeHome, userhome, EsMaxPath);
131
strings[propIndex++] = userhome;
132
}
133
}
134
}
135
}
136
}
137
}
138
139
if (i == propIndex) {
140
/* Fallback to Windows Directory */
141
envSize = (I_32)j9sysinfo_get_env("WINDIR", NULL, 0);
142
if (-1 == envSize) {
143
strings[propIndex++] = "\\";
144
} else {
145
envSpace = jclmem_allocate_memory(env,envSize); /* trailing null taken into account */
146
if(!envSpace) {
147
strings[propIndex++] = "\\";
148
} else {
149
j9sysinfo_get_env("WINDIR", envSpace, envSize);
150
strings[propIndex++] = envSpace;
151
}
152
}
153
}
154
155
/* Get the directory where the executable was started */
156
strings[propIndex++] = "user.dir";
157
if (GetCurrentDirectoryW(EsMaxPath, unicodeTemp) == 0) {
158
strings[propIndex++] = "\\";
159
} else {
160
convertToUTF8(PORTLIB, unicodeTemp, userdir, EsMaxPath);
161
strings[propIndex++] = userdir;
162
}
163
164
if (JAVA_SPEC_VERSION < 12) {
165
/* Get the timezone */
166
strings[propIndex++] = "user.timezone";
167
strings[propIndex++] = "";
168
}
169
170
/* Jazz 52075 JCL_J2SE is always true */
171
172
result = createSystemPropertyList(env, strings, propIndex);
173
if (tempdir) jclmem_free_memory(env,tempdir);
174
if (envSpace) jclmem_free_memory(env,envSpace);
175
return result;
176
}
177
178
179
char* getPlatformFileEncoding(JNIEnv *env, char *codepage, int size, int encodingType) {
180
PORT_ACCESS_FROM_ENV(env);
181
LCID threadLocale;
182
CPINFO cpInfo;
183
int cp;
184
#ifdef UNICODE
185
int i;
186
#endif
187
int length;
188
189
/* Called with codepage == NULL to initialize the locale */
190
if (!codepage) return NULL;
191
192
if (encodingType == 2) {
193
/* file.encoding */
194
threadLocale = GetUserDefaultLCID();
195
} else {
196
threadLocale = GetSystemDefaultLCID();
197
}
198
length = GetLocaleInfo(threadLocale, LOCALE_IDEFAULTANSICODEPAGE, (LPTSTR)&codepage[2], size - 2);
199
200
#ifdef UNICODE
201
// convert double byte to single byte
202
for (i=0; i < length; i++) {
203
codepage[i+2] = (char)((short *)&codepage[2])[i];
204
}
205
codepage[length+2]='\0';
206
#endif
207
208
/*[PR CMVC 84620] file.encoding is incorrect for foreign locales */
209
if (length == 2 && codepage[2] == '0') {
210
/* no ANSI code page, return UTF8 if its supported, otherwise fall through to return ISO8859_1 */
211
if (IsValidCodePage(65001)) {
212
return "UTF8";
213
}
214
}
215
216
if (length == 0 || (cp = atoi(&codepage[2])) == 0)
217
return "ISO8859_1";
218
219
/*[PR 94901] Get info about the current code page, not the system code page (CP_ACP) */
220
if (GetCPInfo(cp, &cpInfo) && cpInfo.MaxCharSize > 1) {
221
if (cp == 936) {
222
J9JavaVM* vm = ((J9VMThread *)env)->javaVM;
223
if (J2SE_VERSION(vm) < J2SE_V11) {
224
if (IsValidCodePage(54936)) {
225
return "GB18030";
226
}
227
}
228
return "GBK";
229
} else if (cp == 54936) return "GB18030";
230
codepage[0] = 'M';
231
codepage[1] = 'S';
232
} else {
233
codepage[0] = 'C';
234
#if defined(JCL_J2SE)
235
codepage[1] = 'p';
236
#else
237
codepage[1] = 'P';
238
#endif
239
}
240
241
return codepage;
242
}
243
244
245
/**
246
* Turns a platform independent DLL name into a platform specific one
247
*/
248
void mapLibraryToPlatformName(const char *inPath, char *outPath) {
249
strcpy(outPath,inPath);
250
strcat(outPath, ".dll");
251
}
252
253
254
/**
255
* Try to find the 'correct' windows temp directory.
256
*/
257
char * getTmpDir(JNIEnv *env, char **tempdir) {
258
PORT_ACCESS_FROM_ENV(env);
259
260
DWORD rc;
261
wchar_t unicodeBuffer[EsMaxPath];
262
char *buffer = NULL;
263
char *retVal = ".";
264
265
rc = GetTempPathW(EsMaxPath, unicodeBuffer);
266
267
/* If the function succeeds, the return value is the number of characters stored into
268
the buffer, not including the terminating null character. If the buffer is not large enough,
269
the return value will exceed the length parameter (i.e. the required size)
270
*/
271
272
if((rc != 0) && (rc < EsMaxPath)) {
273
/* convert */
274
rc = WideCharToMultiByte(OS_ENCODING_CODE_PAGE, OS_ENCODING_WC_FLAGS, unicodeBuffer, -1, NULL, 0, NULL, NULL);
275
if(rc != 0) {
276
buffer = jclmem_allocate_memory(env, rc);
277
if(NULL != buffer) {
278
rc = WideCharToMultiByte(OS_ENCODING_CODE_PAGE, OS_ENCODING_WC_FLAGS, unicodeBuffer, -1, buffer, rc, NULL, NULL);
279
if(rc == 0) {
280
jclmem_free_memory(env, buffer);
281
buffer = NULL;
282
} else {
283
retVal = buffer;
284
}
285
}
286
}
287
}
288
*tempdir = buffer;
289
return retVal;
290
}
291
292
/**
293
* @internal
294
* Converts the Unicode string to UTF8 encoded data in the provided buffer.
295
*
296
* @param[in] portLibrary The port library
297
* @param[in] unicodeString The unicode buffer to convert
298
* @param[in] utf8Buffer The buffer to store the UTF8 encoded bytes into
299
* @param[in] size The size of utf8Buffer
300
*
301
* @return 0 on success, -1 on failure.
302
*/
303
I_32
304
convertToUTF8(J9PortLibrary* portLibrary, const wchar_t* unicodeString, char* utf8Buffer, UDATA size)
305
{
306
PORT_ACCESS_FROM_PORT(portLibrary);
307
if(0 == WideCharToMultiByte(OS_ENCODING_CODE_PAGE, OS_ENCODING_WC_FLAGS, unicodeString, -1, utf8Buffer, (int)size, NULL, NULL)) {
308
j9error_set_last_error(GetLastError(), J9PORT_ERROR_OPFAILED); /* continue */
309
return -1;
310
}
311
return 0;
312
}
313
314