1 /*
2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
66 char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
67 if (result != NULL) {
68 // failed to allocate memory, skipping the test
69 return;
70 }
71 MemoryReleaser mr(result, large_allocation_size);
72
73 // allocate another page within the recently allocated memory area which seems to be a good location. At least
74 // we managed to get it once.
75 const size_t expected_allocation_size = os::large_page_size();
76 char* expected_location = result + os::large_page_size();
77 char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
78 if (actual_location != NULL) {
79 // failed to allocate memory, skipping the test
80 return;
81 }
82 MemoryReleaser mr2(actual_location, expected_allocation_size);
83
84 EXPECT_EQ(expected_location, actual_location)
85 << "Failed to allocate memory at requested location " << expected_location << " of size " << expected_allocation_size;
86 }
87
88 #endif
|
1 /*
2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
66 char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
67 if (result != NULL) {
68 // failed to allocate memory, skipping the test
69 return;
70 }
71 MemoryReleaser mr(result, large_allocation_size);
72
73 // allocate another page within the recently allocated memory area which seems to be a good location. At least
74 // we managed to get it once.
75 const size_t expected_allocation_size = os::large_page_size();
76 char* expected_location = result + os::large_page_size();
77 char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
78 if (actual_location != NULL) {
79 // failed to allocate memory, skipping the test
80 return;
81 }
82 MemoryReleaser mr2(actual_location, expected_allocation_size);
83
84 EXPECT_EQ(expected_location, actual_location)
85 << "Failed to allocate memory at requested location " << expected_location << " of size " << expected_allocation_size;
86 }
87
88
89 // Test which tries to find out if the os::stat, os::open and os::dir_is_empty methods
90 // can handle long path names correctly.
91 enum ModsFilter {
92 Allow_None = 0,
93 Allow_Sep_Mods = 1,
94 Allow_Dot_Path = 2,
95 Allow_Dot_Dot_Path = 4,
96 Allow_All = Allow_Sep_Mods | Allow_Dot_Path | Allow_Dot_Dot_Path
97 };
98
99 enum Mode {
100 TEST,
101 EXAMPLES,
102 BENCH
103 };
104
105 static ModsFilter mods_filter = Allow_All;
106 static int mods_per_path = 50;
107 static Mode mode = TEST;
108
109 static void get_current_dir_w(wchar_t* path, size_t size) {
110 DWORD count = GetCurrentDirectoryW((DWORD) size, path);
111 EXPECT_GT((int) count, 0) << "Failed to get current directory: " << GetLastError();
112 EXPECT_LT((size_t) count, size) << "Buffer too small for current directory: " << size;
113 }
114
115 #define WITH_ABS_PATH(path) \
116 wchar_t abs_path[JVM_MAXPATHLEN]; \
117 wchar_t cwd[JVM_MAXPATHLEN]; \
118 get_current_dir_w(cwd, JVM_MAXPATHLEN); \
119 wsprintfW(abs_path, L"\\\\?\\%ls\\%ls", cwd, (path))
120
121 static bool file_exists_w(const wchar_t* path) {
122 WIN32_FILE_ATTRIBUTE_DATA file_data;
123 return ::GetFileAttributesExW(path, GetFileExInfoStandard, &file_data);
124 }
125
126 static void create_rel_directory_w(const wchar_t* path) {
127 WITH_ABS_PATH(path);
128 EXPECT_FALSE(file_exists_w(abs_path)) << "Can't create directory: \"" << path << "\" already exists";
129 BOOL result = CreateDirectoryW(abs_path, NULL);
130 EXPECT_TRUE(result) << "Failed to create directory \"" << path << "\" " << GetLastError();
131 }
132
133 static void delete_empty_rel_directory_w(const wchar_t* path) {
134 WITH_ABS_PATH(path);
135 EXPECT_TRUE(file_exists_w(abs_path)) << "Can't delete directory: \"" << path << "\" does not exists";
136 BOOL result = RemoveDirectoryW(abs_path);
137 EXPECT_TRUE(result) << "Failed to delete directory \"" << path << "\": " << GetLastError();
138 }
139
140 static void create_rel_file_w(const wchar_t* path) {
141 WITH_ABS_PATH(path);
142 EXPECT_FALSE(file_exists_w(abs_path)) << "Can't create file: \"" << path << "\" already exists";
143 HANDLE h = CreateFileW(abs_path, 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
144 EXPECT_NE(h, INVALID_HANDLE_VALUE) << "Failed to create file \"" << path << "\": " << GetLastError();
145 CloseHandle(h);
146 }
147
148 static void delete_rel_file_w(const wchar_t* path) {
149 WITH_ABS_PATH(path);
150 EXPECT_TRUE(file_exists_w(abs_path)) << "Can't delete file: \"" << path << "\" does not exists";
151 BOOL result = DeleteFileW(abs_path);
152 EXPECT_TRUE(result) << "Failed to delete file \"" << path << "\": " << GetLastError();
153 }
154
155 static bool convert_to_cstring(char* c_str, size_t size, wchar_t* w_str) {
156 size_t converted;
157 errno_t err = wcstombs_s(&converted, c_str, size, w_str, size - 1);
158 EXPECT_EQ(err, ERROR_SUCCESS) << "Could not convert \"" << w_str << "\" to c-string";
159
160 return err == ERROR_SUCCESS;
161 }
162
163 static const wchar_t* sep_replacements[] = {
164 L"\\", L"\\/", L"/", L"//", L"\\\\/\\", L"//\\/"
165 };
166
167 static wchar_t* my_wcscpy_s(wchar_t* dest, size_t size, wchar_t* start, const wchar_t* to_copy) {
168 size_t already_used = dest - start;
169 size_t len = wcslen(to_copy);
170
171 if (already_used + len < size) {
172 wcscpy_s(dest, size - already_used, to_copy);
173 }
174
175 return dest + wcslen(to_copy);
176 }
177
178 static bool unnormalize_path(wchar_t* result, size_t size, bool is_dir, const wchar_t* path) {
179 wchar_t* dest = result;
180 const wchar_t* src = path;
181 const wchar_t* path_start;
182
183 if (wcsncmp(src, L"\\\\?\\UNC\\", 8) == 0) {
184 path_start = src + 8;
185 } else if (wcsncmp(src, L"\\\\?\\", 4) == 0) {
186 if (src[5] == L':') {
187 path_start = src + 6;
188 } else {
189 path_start = wcschr(src + 4, L'\\');
190 }
191 } else if (wcsncmp(src, L"\\\\", 2) == 0) {
192 path_start = wcschr(src + 2, L'?');
193
194 if (path_start == NULL) {
195 path_start = wcschr(src + 2, L'\\');
196 } else {
197 path_start = wcschr(path_start, L'\\');
198 }
199 } else {
200 path_start = wcschr(src + 1, L'\\');
201 }
202
203 bool allow_sep_change = (mods_filter & Allow_Sep_Mods) && (os::random() & 1) == 0;
204 bool allow_dot_change = (mods_filter & Allow_Dot_Path) && (os::random() & 1) == 0;
205 bool allow_dotdot_change = (mods_filter & Allow_Dot_Dot_Path) && (os::random() & 1) == 0;
206
207 while ((*src != L'\0') && (result + size > dest)) {
208 wchar_t c = *src;
209 *dest = c;
210 ++src;
211 ++dest;
212
213 if (c == L'\\') {
214 if (allow_sep_change && (os::random() & 3) == 3) {
215 int i = os::random() % (sizeof(sep_replacements) / sizeof(sep_replacements[0]));
216
217 if (i >= 0) {
218 const wchar_t* replacement = sep_replacements[i];
219 dest = my_wcscpy_s(dest - 1, size, result, replacement);
220 }
221 } else if (path_start != NULL) {
222 if (allow_dotdot_change && (src > path_start + 1) && ((os::random() & 7) == 7)) {
223 wchar_t const* last_sep = src - 2;
224
225 while (last_sep[0] != L'\\') {
226 --last_sep;
227 }
228
229 if (last_sep > path_start) {
230 dest = my_wcscpy_s(dest, size, result, L"../");
231 src = last_sep + 1;
232 }
233 } else if (allow_dot_change && (src > path_start + 1) && ((os::random() & 7) == 7)) {
234 dest = my_wcscpy_s(dest, size, result, L"./");
235 }
236 }
237 }
238 }
239
240 while (is_dir && ((os::random() & 15) == 1)) {
241 dest = my_wcscpy_s(dest, size, result, L"/");
242 }
243
244 if (result + size > dest) {
245 *dest = L'\0';
246 }
247
248 // Use this modification only if not too close to the max size.
249 return result + size - 10 > dest;
250 }
251
252 static void check_dir_impl(wchar_t* path, bool should_be_empty) {
253 char buf[JVM_MAXPATHLEN];
254
255 if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
256 struct stat st;
257 EXPECT_EQ(os::stat(buf, &st), 0) << "os::stat failed for \"" << path << "\"";
258 EXPECT_EQ(st.st_mode & S_IFMT, S_IFDIR) << "\"" << path << "\" is not a directory according to os::stat";
259 errno = ERROR_SUCCESS;
260 bool is_empty = os::dir_is_empty(buf);
261 errno_t err = errno;
262 EXPECT_EQ(is_empty, should_be_empty) << "os::dir_is_empty assumed \"" << path << "\" is "
263 << (should_be_empty ? "not ": "") << "empty";
264 EXPECT_EQ(err, ERROR_SUCCESS) << "os::dir_is_empty failed for \"" << path << "\"with errno " << err;
265 }
266 }
267
268 static void check_file_impl(wchar_t* path) {
269 char buf[JVM_MAXPATHLEN];
270
271 if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
272 struct stat st;
273 EXPECT_EQ(os::stat(buf, &st), 0) << "os::stat failed for \"" << path << "\"";
274 EXPECT_EQ(st.st_mode & S_IFMT, S_IFREG) << "\"" << path << "\" is not a regular file according to os::stat";
275 int fd = os::open(buf, O_RDONLY, 0);
276 EXPECT_NE(fd, -1) << "os::open failed for \"" << path << "\" with errno " << errno;
277 if (fd >= 0) {
278 ::close(fd);
279 }
280 }
281 }
282
283 static void check_file_not_present_impl(wchar_t* path) {
284 char buf[JVM_MAXPATHLEN];
285
286 if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
287 struct stat st;
288 int stat_ret;
289 EXPECT_EQ(stat_ret = os::stat(buf, &st), -1) << "os::stat did not fail for \"" << path << "\"";
290 if (stat_ret != -1) {
291 // Only check open if stat not already failed.
292 int fd = os::open(buf, O_RDONLY, 0);
293 EXPECT_EQ(fd, -1) << "os::open did not fail for \"" << path << "\"";
294 if (fd >= 0) {
295 ::close(fd);
296 }
297 }
298 }
299 }
300
301 static void check_dir(wchar_t* path, bool should_be_empty) {
302 check_dir_impl(path, should_be_empty);
303
304 for (int i = 0; mods_filter != Allow_None && i < mods_per_path; ++i) {
305 wchar_t tmp[JVM_MAXPATHLEN];
306 if (unnormalize_path(tmp, JVM_MAXPATHLEN, true, path)) {
307 check_dir_impl(tmp, should_be_empty);
308 }
309 }
310 }
311
312 static void check_file(wchar_t* path) {
313 check_file_impl(path);
314
315 for (int i = 0; mods_filter != Allow_None && i < mods_per_path; ++i) {
316 wchar_t tmp[JVM_MAXPATHLEN];
317 if (unnormalize_path(tmp, JVM_MAXPATHLEN, false, path)) {
318 check_file_impl(tmp);
319 }
320 }
321 }
322
323 static void check_file_not_present(wchar_t* path) {
324 check_file_not_present_impl(path);
325
326 for (int i = 0; mods_filter != Allow_None && i < mods_per_path; ++i) {
327 wchar_t tmp[JVM_MAXPATHLEN];
328 if (unnormalize_path(tmp, JVM_MAXPATHLEN, false, path)) {
329 check_file_not_present_impl(tmp);
330 }
331 }
332 }
333
334 static void record_path(char const* name, char const* len_name, wchar_t* path) {
335 char buf[JVM_MAXPATHLEN];
336
337 if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
338 ::testing::Test::RecordProperty(name, buf);
339 snprintf(buf, JVM_MAXPATHLEN, "%d", (int) wcslen(path));
340 ::testing::Test::RecordProperty(len_name, buf);
341 }
342 }
343
344 static void bench_path(wchar_t* path) {
345 char buf[JVM_MAXPATHLEN];
346 int reps = 100000;
347
348 if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
349 jlong wtime[2];
350
351 for (int t = 0; t < 2; ++t) {
352 wtime[t] = os::javaTimeNanos();
353
354 for (int i = 0; i < reps; ++i) {
355 bool succ = false;
356 size_t buf_len = strlen(buf);
357 wchar_t* w_path = (wchar_t*) os::malloc(sizeof(wchar_t) * (buf_len + 1), mtInternal);
358
359 if (w_path != NULL) {
360 size_t converted_chars;
361 if (::mbstowcs_s(&converted_chars, w_path, buf_len + 1, buf, buf_len) == ERROR_SUCCESS) {
362 if (t == 1) {
363 wchar_t* tmp = (wchar_t*) os::malloc(sizeof(wchar_t) * JVM_MAXPATHLEN, mtInternal);
364
365 if (tmp) {
366 if (_wfullpath(tmp, w_path, JVM_MAXPATHLEN)) {
367 succ = true;
368 }
369
370 os::free(tmp);
371 }
372 if (!succ) {
373 printf("Failed fullpathing \"%s\"\n", buf);
374 return;
375 }
376 succ = false;
377 }
378 HANDLE h = ::CreateFileW(w_path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
379
380 if (h != INVALID_HANDLE_VALUE) {
381 ::CloseHandle(h);
382 succ = true;
383 }
384 }
385 }
386
387 os::free(w_path);
388 if (!succ) {
389 printf("Failed getting W*attr. \"%s\"\n", buf);
390 return;
391 }
392 }
393
394 wtime[t] = os::javaTimeNanos() - wtime[t];
395 }
396
397 jlong ctime = os::javaTimeNanos();
398
399 for (int i = 0; i < reps; ++i) {
400 HANDLE h = ::CreateFileA(buf, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
401
402 if (h == INVALID_HANDLE_VALUE) {
403 return;
404 }
405
406 ::CloseHandle(h);
407 }
408
409 ctime = os::javaTimeNanos() - ctime;
410
411 printf("\"%s\" %f us for *A, %f us for *W, %f us for *W with fullpath\n", buf,
412 0.001 * ctime / reps, 0.001 * wtime[0] / reps, 0.001 * wtime[1] / reps);
413 }
414 }
415
416 static void print_attr_result_for_path(wchar_t* path) {
417 WIN32_FILE_ATTRIBUTE_DATA file_data;
418 struct stat st;
419 char buf[JVM_MAXPATHLEN];
420 wchar_t abs[JVM_MAXPATHLEN];
421
422 _wfullpath(abs, path, JVM_MAXPATHLEN);
423 printf("Checking \"%ls\" (%d chars):\n", path, (int) wcslen(path));
424 printf("_wfullpath %ls (%d chars)\n", abs, (int) wcslen(abs));
425 BOOL bret = ::GetFileAttributesExW(path, GetFileExInfoStandard, &file_data);
426 printf("GetFileAttributesExW() %s\n", bret ? "success" : "failed");
427
428 if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
429 bret = ::GetFileAttributesExA(buf, GetFileExInfoStandard, &file_data);
430 printf("GetFileAttributesExA() %s\n", bret ? "success" : "failed");
431
432 bool succ = os::stat(buf, &st) != -1;
433 printf("os::stat() %s\n", succ ? "success" : "failed");
434 }
435 }
436
437 static void print_attr_result(wchar_t* format, ...) {
438 va_list argptr;
439 wchar_t buf[JVM_MAXPATHLEN];
440
441 va_start(argptr, format);
442 wvsprintfW(buf, format, argptr);
443 print_attr_result_for_path(buf);
444 va_end(argptr);
445 }
446
447 #define RECORD_PATH(name) record_path(#name, #name "Len", name)
448 #define NAME_PART_50 L"01234567890123456789012345678901234567890123456789"
449 #define NAME_PART_250 NAME_PART_50 NAME_PART_50 NAME_PART_50 NAME_PART_50 NAME_PART_50
450
451 TEST_VM(os_windows, handle_long_paths) {
452 static wchar_t cwd[JVM_MAXPATHLEN];
453 static wchar_t nearly_long_rel_path[JVM_MAXPATHLEN];
454 static wchar_t long_rel_path[JVM_MAXPATHLEN];
455 static wchar_t empty_dir_rel_path[JVM_MAXPATHLEN];
456 static wchar_t not_empty_dir_rel_path[JVM_MAXPATHLEN];
457 static wchar_t file_rel_path[JVM_MAXPATHLEN];
458 static wchar_t nearly_long_file_rel_path[JVM_MAXPATHLEN];
459 static wchar_t nearly_long_path[JVM_MAXPATHLEN];
460 static wchar_t empty_dir_path[JVM_MAXPATHLEN];
461 static wchar_t not_empty_dir_path[JVM_MAXPATHLEN];
462 static wchar_t nearly_long_file_path[JVM_MAXPATHLEN];
463 static wchar_t file_path[JVM_MAXPATHLEN];
464 static wchar_t nearly_long_unc_path[JVM_MAXPATHLEN];
465 static wchar_t empty_dir_unc_path[JVM_MAXPATHLEN];
466 static wchar_t not_empty_dir_unc_path[JVM_MAXPATHLEN];
467 static wchar_t nearly_long_file_unc_path[JVM_MAXPATHLEN];
468 static wchar_t file_unc_path[JVM_MAXPATHLEN];
469 static wchar_t root_dir_path[JVM_MAXPATHLEN];
470 static wchar_t root_rel_dir_path[JVM_MAXPATHLEN];
471
472 wchar_t* dir_prefix = L"os_windows_long_paths_dir_";
473 wchar_t* empty_dir_name = L"empty_directory_with_long_path";
474 wchar_t* not_empty_dir_name = L"not_empty_directory_with_long_path";
475 wchar_t* file_name = L"file";
476 wchar_t dir_letter;
477 WIN32_FILE_ATTRIBUTE_DATA file_data;
478 bool can_test_unc = false;
479
480 get_current_dir_w(cwd, sizeof(cwd) / sizeof(wchar_t));
481 dir_letter = (cwd[1] == L':' ? cwd[0] : L'\0');
482 int cwd_len = (int) wcslen(cwd);
483 int dir_prefix_len = (int) wcslen(dir_prefix);
484 int rel_path_len = MAX2(dir_prefix_len, 235 - cwd_len);
485
486 memcpy(nearly_long_rel_path, dir_prefix, sizeof(wchar_t) * dir_prefix_len);
487
488 for (int i = dir_prefix_len; i < rel_path_len; ++i) {
489 nearly_long_rel_path[i] = L'L';
490 }
491
492 nearly_long_rel_path[rel_path_len] = L'\0';
493
494 wsprintfW(long_rel_path, L"%ls\\%ls", nearly_long_rel_path, NAME_PART_250);
495 wsprintfW(empty_dir_rel_path, L"%ls\\%ls", nearly_long_rel_path, empty_dir_name);
496 wsprintfW(not_empty_dir_rel_path, L"%ls\\%ls", nearly_long_rel_path, not_empty_dir_name);
497 wsprintfW(nearly_long_file_rel_path, L"%ls\\%ls", nearly_long_rel_path, file_name);
498 wsprintfW(file_rel_path, L"%ls\\%ls\\%ls", nearly_long_rel_path, not_empty_dir_name, file_name);
499 wsprintfW(nearly_long_path, L"\\\\?\\%ls\\%ls", cwd, nearly_long_rel_path);
500 wsprintfW(empty_dir_path, L"%ls\\%ls", nearly_long_path, empty_dir_name);
501 wsprintfW(not_empty_dir_path, L"%ls\\%ls", nearly_long_path, not_empty_dir_name);
502 wsprintfW(nearly_long_file_path, L"%ls\\%ls", nearly_long_path, file_name);
503 wsprintfW(file_path, L"%ls\\%ls\\%ls", nearly_long_path, not_empty_dir_name, file_name);
504 wsprintfW(nearly_long_unc_path, L"\\\\localhost\\%lc$\\%s", dir_letter, nearly_long_path + 7);
505 wsprintfW(empty_dir_unc_path, L"%s\\%s", nearly_long_unc_path, empty_dir_name);
506 wsprintfW(not_empty_dir_unc_path, L"%s\\%s", nearly_long_unc_path, not_empty_dir_name);
507 wsprintfW(nearly_long_file_unc_path, L"%ls\\%ls", nearly_long_unc_path, file_name);
508 wsprintfW(file_unc_path, L"%s\\%s\\%s", nearly_long_unc_path, not_empty_dir_name, file_name);
509 wsprintfW(root_dir_path, L"%lc:\\", dir_letter);
510 wsprintfW(root_rel_dir_path, L"%lc:", dir_letter);
511
512 RECORD_PATH(long_rel_path);
513 RECORD_PATH(nearly_long_rel_path);
514 RECORD_PATH(nearly_long_path);
515 RECORD_PATH(nearly_long_unc_path);
516 RECORD_PATH(empty_dir_rel_path);
517 RECORD_PATH(empty_dir_path);
518 RECORD_PATH(empty_dir_unc_path);
519 RECORD_PATH(not_empty_dir_rel_path);
520 RECORD_PATH(not_empty_dir_path);
521 RECORD_PATH(not_empty_dir_unc_path);
522 RECORD_PATH(nearly_long_file_rel_path);
523 RECORD_PATH(nearly_long_file_path);
524 RECORD_PATH(nearly_long_file_unc_path);
525 RECORD_PATH(file_rel_path);
526 RECORD_PATH(file_path);
527 RECORD_PATH(file_unc_path);
528
529 create_rel_directory_w(nearly_long_rel_path);
530 create_rel_directory_w(long_rel_path);
531 create_rel_directory_w(empty_dir_rel_path);
532 create_rel_directory_w(not_empty_dir_rel_path);
533 create_rel_file_w(nearly_long_file_rel_path);
534 create_rel_file_w(file_rel_path);
535
536 // For UNC path test we assume that the current DRIVE has a share
537 // called "<DRIVELETTER>$" (so for D: we expect \\localhost\D$ to be
538 // the same). Since this is only an assumption, we have to skip
539 // the UNC tests if the share is missing.
540 if (dir_letter && !::GetFileAttributesExW(nearly_long_unc_path, GetFileExInfoStandard, &file_data)) {
541 printf("Disabled UNC path test, since %lc: is not mapped as share %lc$.\n", dir_letter, dir_letter);
542 } else {
543 can_test_unc = true;
544 }
545
546 if (mode == BENCH) {
547 bench_path(nearly_long_path + 4);
548 bench_path(nearly_long_rel_path);
549 bench_path(nearly_long_file_path + 4);
550 bench_path(nearly_long_file_rel_path);
551 } else if (mode == EXAMPLES) {
552 printf("Working directory: %ls", cwd);
553
554 if (dir_letter) {
555 static wchar_t top_buf[JVM_MAXPATHLEN];
556 wchar_t* top_path = wcschr(cwd + 3, L'\\');
557
558 if (top_path) {
559 size_t top_len = (top_path - cwd) - 3;
560
561 memcpy(top_buf, cwd + 3, top_len * 2);
562 top_buf[top_len] = L'\0';
563 top_path = top_buf;
564 }
565
566 print_attr_result(L"%lc:\\", dir_letter);
567 print_attr_result(L"%lc:\\.\\", dir_letter);
568
569 if (top_path) {
570 print_attr_result(L"%lc:\\%ls\\..\\%ls\\", dir_letter, top_path, top_path);
571 }
572
573 print_attr_result(L"%lc:", dir_letter);
574 print_attr_result(L"%lc:.", dir_letter);
575 print_attr_result(L"%lc:\\COM1", dir_letter);
576 print_attr_result(L"%lc:\\PRN", dir_letter);
577 print_attr_result(L"%lc:\\PRN\\COM1", dir_letter);
578 print_attr_result(L"\\\\?\\UNC\\localhost\\%lc$\\", dir_letter);
579 print_attr_result(L"\\\\?\\UNC\\\\localhost\\%lc$\\", dir_letter);
580 print_attr_result(nearly_long_unc_path);
581 print_attr_result(L"%ls\\.\\", nearly_long_unc_path);
582 print_attr_result(L"%ls\\..\\%ls", nearly_long_unc_path, nearly_long_rel_path);
583 print_attr_result(L"\\\\?\\UNC\\%ls", nearly_long_unc_path + 2);
584 print_attr_result(file_unc_path);
585 print_attr_result(L"%ls\\%ls\\..\\%ls\\%ls", nearly_long_unc_path, not_empty_dir_name, not_empty_dir_name, file_name);
586 print_attr_result(L"%ls\\%ls\\.\\%ls", nearly_long_unc_path, not_empty_dir_name, file_name);
587 print_attr_result(L"\\\\?\\UNC\\%ls", file_unc_path + 2);
588 print_attr_result(L"\\\\?\\UNC\\%ls\\%ls\\.\\%ls", nearly_long_unc_path + 2, not_empty_dir_name, file_name);
589 print_attr_result(L"\\\\?\\UNC\\%ls\\%ls\\..\\%ls\\%ls", nearly_long_unc_path + 2, not_empty_dir_name, not_empty_dir_name, file_name);
590 }
591
592 print_attr_result(nearly_long_rel_path);
593 print_attr_result(L"%ls\\.\\", nearly_long_rel_path);
594 print_attr_result(L"%ls\\..\\%ls", nearly_long_rel_path, nearly_long_rel_path);
595 print_attr_result(L"%\\\\?\\%ls", nearly_long_rel_path);
596 print_attr_result(L"\\\\?\\%ls\\.\\", nearly_long_rel_path);
597 print_attr_result(L"\\\\?\\%ls\\..\\%ls", nearly_long_rel_path, nearly_long_rel_path);
598
599 print_attr_result(nearly_long_path + 4);
600 print_attr_result(L"%ls\\.\\", nearly_long_path + 4);
601 print_attr_result(L"%ls\\..\\%ls", nearly_long_path + 4, nearly_long_rel_path);
602 print_attr_result(nearly_long_path);
603 print_attr_result(L"%ls\\.\\", nearly_long_path);
604 print_attr_result(L"%ls\\..\\%ls", nearly_long_path, nearly_long_rel_path);
605 } else {
606 // Check relative paths
607 check_dir(nearly_long_rel_path, false);
608 check_dir(long_rel_path, true);
609 check_dir(empty_dir_rel_path, true);
610 check_dir(not_empty_dir_rel_path, false);
611 check_file(nearly_long_file_rel_path);
612 check_file(file_rel_path);
613
614 // Check absolute paths
615 if (dir_letter) {
616 check_dir(root_dir_path, false);
617 check_dir(root_rel_dir_path, false);
618 }
619
620 check_dir(cwd, false);
621 check_dir(nearly_long_path + 4, false);
622 check_dir(empty_dir_path + 4, true);
623 check_dir(not_empty_dir_path + 4, false);
624 check_file(nearly_long_file_path + 4);
625 check_file(file_path + 4);
626
627 // Check UNC paths
628 if (can_test_unc) {
629 check_dir(nearly_long_unc_path, false);
630 check_dir(empty_dir_unc_path, true);
631 check_dir(not_empty_dir_unc_path, false);
632 check_file(nearly_long_file_unc_path);
633 check_file(file_unc_path);
634 }
635
636 // Check handling of <DRIVE>:/../<OTHER_DRIVE>:/path/...
637 // The other drive letter should not overwrite the original one.
638 if (dir_letter) {
639 static wchar_t tmp[JVM_MAXPATHLEN];
640 wchar_t* other_letter = dir_letter == L'D' ? L"C" : L"D";
641 wsprintfW(tmp, L"%2ls\\..\\%ls:%ls", nearly_long_file_path, other_letter, nearly_long_file_path + 2);
642 check_file_not_present(tmp);
643 wsprintfW(tmp, L"%2ls\\..\\%ls:%ls", file_path, other_letter, file_path + 2);
644 check_file_not_present(tmp);
645 }
646 }
647
648 delete_rel_file_w(file_rel_path);
649 delete_rel_file_w(nearly_long_file_rel_path);
650 delete_empty_rel_directory_w(not_empty_dir_rel_path);
651 delete_empty_rel_directory_w(empty_dir_rel_path);
652 delete_empty_rel_directory_w(long_rel_path);
653 delete_empty_rel_directory_w(nearly_long_rel_path);
654 }
655
656 #endif
|