disable Win32 short file names
Igor Sysoev
10 years ago
9 | 9 | |
10 | 10 | #define NGX_UTF16_BUFLEN 256 |
11 | 11 | |
12 | static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len); | |
12 | static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len); | |
13 | 13 | |
14 | 14 | |
15 | 15 | /* FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory */ |
17 | 17 | ngx_fd_t |
18 | 18 | ngx_open_file(u_char *name, u_long mode, u_long create, u_long access) |
19 | 19 | { |
20 | u_short *u; | |
20 | size_t len; | |
21 | u_long n; | |
22 | u_short *u, *lu; | |
21 | 23 | ngx_fd_t fd; |
22 | 24 | ngx_err_t err; |
23 | 25 | u_short utf16[NGX_UTF16_BUFLEN]; |
24 | 26 | |
25 | u = ngx_utf8_to_utf16(utf16, name, NGX_UTF16_BUFLEN); | |
27 | len = NGX_UTF16_BUFLEN; | |
28 | u = ngx_utf8_to_utf16(utf16, name, &len); | |
26 | 29 | |
27 | 30 | if (u == NULL) { |
28 | 31 | return INVALID_HANDLE_VALUE; |
32 | } | |
33 | ||
34 | fd = INVALID_HANDLE_VALUE; | |
35 | lu = NULL; | |
36 | ||
37 | if (create == NGX_FILE_OPEN) { | |
38 | ||
39 | lu = malloc(len * 2); | |
40 | if (lu == NULL) { | |
41 | goto failed; | |
42 | } | |
43 | ||
44 | n = GetLongPathNameW(u, lu, len); | |
45 | ||
46 | if (n == 0) { | |
47 | goto failed; | |
48 | } | |
49 | ||
50 | if (n != len - 1 || ngx_memcmp(u, lu, n) != 0) { | |
51 | ngx_set_errno(NGX_ENOENT); | |
52 | goto failed; | |
53 | } | |
29 | 54 | } |
30 | 55 | |
31 | 56 | fd = CreateFileW(u, mode, |
32 | 57 | FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, |
33 | 58 | NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
34 | 59 | |
60 | failed: | |
61 | ||
62 | err = ngx_errno; | |
63 | ||
64 | if (lu) { | |
65 | ngx_free(lu); | |
66 | } | |
67 | ||
35 | 68 | if (u != utf16) { |
36 | err = ngx_errno; | |
37 | 69 | ngx_free(u); |
38 | ngx_set_errno(err); | |
39 | } | |
70 | } | |
71 | ||
72 | ngx_set_errno(err); | |
40 | 73 | |
41 | 74 | return fd; |
42 | 75 | } |
243 | 276 | ngx_int_t |
244 | 277 | ngx_file_info(u_char *file, ngx_file_info_t *sb) |
245 | 278 | { |
279 | size_t len; | |
246 | 280 | long rc; |
247 | 281 | u_short *u; |
248 | 282 | ngx_err_t err; |
249 | 283 | WIN32_FILE_ATTRIBUTE_DATA fa; |
250 | 284 | u_short utf16[NGX_UTF16_BUFLEN]; |
251 | 285 | |
252 | u = ngx_utf8_to_utf16(utf16, file, NGX_UTF16_BUFLEN); | |
286 | len = NGX_UTF16_BUFLEN; | |
287 | ||
288 | u = ngx_utf8_to_utf16(utf16, file, &len); | |
253 | 289 | |
254 | 290 | if (u == NULL) { |
255 | 291 | return NGX_FILE_ERROR; |
510 | 546 | |
511 | 547 | |
512 | 548 | static u_short * |
513 | ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len) | |
549 | ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len) | |
514 | 550 | { |
515 | 551 | u_char *p; |
516 | 552 | u_short *u, *last; |
518 | 554 | |
519 | 555 | p = utf8; |
520 | 556 | u = utf16; |
521 | last = utf16 + len; | |
557 | last = utf16 + *len; | |
522 | 558 | |
523 | 559 | while (u < last) { |
524 | 560 | |
525 | 561 | if (*p < 0x80) { |
526 | *u = (u_short) *p; | |
562 | *u++ = (u_short) *p; | |
527 | 563 | |
528 | 564 | if (*p == 0) { |
565 | *len = u - utf16; | |
529 | 566 | return utf16; |
530 | 567 | } |
531 | 568 | |
532 | u++; | |
533 | 569 | p++; |
534 | 570 | |
535 | 571 | continue; |
553 | 589 | return NULL; |
554 | 590 | } |
555 | 591 | |
556 | ngx_memcpy(u, utf16, len * 2); | |
592 | ngx_memcpy(u, utf16, *len * 2); | |
557 | 593 | |
558 | 594 | utf16 = u; |
559 | u += len; | |
595 | u += *len; | |
560 | 596 | |
561 | 597 | for ( ;; ) { |
562 | 598 | |
563 | 599 | if (*p < 0x80) { |
564 | *u = (u_short) *p; | |
600 | *u++ = (u_short) *p; | |
565 | 601 | |
566 | 602 | if (*p == 0) { |
603 | *len = u - utf16; | |
567 | 604 | return utf16; |
568 | 605 | } |
569 | 606 | |
570 | u++; | |
571 | 607 | p++; |
572 | 608 | |
573 | 609 | continue; |