summaryrefslogtreecommitdiffhomepage
path: root/src/os/win32
diff options
context:
space:
mode:
Diffstat (limited to 'src/os/win32')
-rw-r--r--src/os/win32/ngx_errno.h1
-rw-r--r--src/os/win32/ngx_files.c111
-rw-r--r--src/os/win32/ngx_files.h12
3 files changed, 115 insertions, 9 deletions
diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h
index 58cbbf402..75ae73f5d 100644
--- a/src/os/win32/ngx_errno.h
+++ b/src/os/win32/ngx_errno.h
@@ -48,6 +48,7 @@ typedef DWORD ngx_err_t;
#define NGX_EHOSTDOWN WSAEHOSTDOWN
#define NGX_EHOSTUNREACH WSAEHOSTUNREACH
#define NGX_ENOMOREFILES ERROR_NO_MORE_FILES
+#define NGX_EILSEQ ERROR_NO_UNICODE_TRANSLATION
#define NGX_EALREADY WSAEALREADY
#define NGX_EINVAL WSAEINVAL
diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c
index afe31b9a0..f20b47973 100644
--- a/src/os/win32/ngx_files.c
+++ b/src/os/win32/ngx_files.c
@@ -8,6 +8,38 @@
#include <ngx_core.h>
+#define NGX_UTF16_BUFLEN 256
+
+static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len);
+
+
+/* FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory */
+
+ngx_fd_t
+ngx_open_file(u_char *name, u_long mode, u_long create, u_long access)
+{
+ u_short *u;
+ ngx_fd_t fd;
+ u_short utf16[NGX_UTF16_BUFLEN];
+
+ u = ngx_utf8_to_utf16(utf16, name, NGX_UTF16_BUFLEN);
+
+ if (u == NULL) {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ fd = CreateFileW(u, mode,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+ if (u != utf16) {
+ ngx_free(u);
+ }
+
+ return fd;
+}
+
+
ssize_t
ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
{
@@ -529,3 +561,82 @@ ngx_fs_bsize(u_char *name)
return sc * bs;
}
+
+
+static u_short *
+ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len)
+{
+ u_char *p;
+ u_short *u, *last;
+ uint32_t n;
+
+ p = utf8;
+ u = utf16;
+ last = utf16 + len;
+
+ while (u < last) {
+
+ if (*p < 0x80) {
+ *u = (u_short) *p;
+
+ if (*p == 0) {
+ return utf16;
+ }
+
+ u++;
+ p++;
+
+ continue;
+ }
+
+ n = ngx_utf8_decode(&p, 4);
+
+ if (n > 0xffff) {
+ free(utf16);
+ ngx_set_errno(NGX_EILSEQ);
+ return NULL;
+ }
+
+ *u++ = (u_short) n;
+ }
+
+ /* the given buffer is not enough, allocate a new one */
+
+ u = malloc(((p - utf8) + ngx_strlen(p) + 1) * sizeof(u_short));
+ if (u == NULL) {
+ return NULL;
+ }
+
+ ngx_memcpy(u, utf16, len * 2);
+
+ utf16 = u;
+ u += len;
+
+ for ( ;; ) {
+
+ if (*p < 0x80) {
+ *u = (u_short) *p;
+
+ if (*p == 0) {
+ return utf16;
+ }
+
+ u++;
+ p++;
+
+ continue;
+ }
+
+ n = ngx_utf8_decode(&p, 4);
+
+ if (n > 0xffff) {
+ free(utf16);
+ ngx_set_errno(NGX_EILSEQ);
+ return NULL;
+ }
+
+ *u++ = (u_short) n;
+ }
+
+ /* unreachable */
+}
diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h
index 47a76611b..5efd0fe1a 100644
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -57,22 +57,16 @@ typedef struct {
#define NGX_FILE_ERROR 0
-/*
- * FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory
- */
-
-#define ngx_open_file(name, mode, create, access) \
- CreateFile((const char *) name, mode, \
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, \
- NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL)
+ngx_fd_t ngx_open_file(u_char *name, u_long mode, u_long create, u_long access);
#define ngx_open_file_n "CreateFile()"
#define NGX_FILE_RDONLY GENERIC_READ
#define NGX_FILE_WRONLY GENERIC_WRITE
#define NGX_FILE_RDWR GENERIC_READ|GENERIC_WRITE
+#define NGX_FILE_APPEND FILE_APPEND_DATA|SYNCHRONIZE
+
#define NGX_FILE_CREATE_OR_OPEN OPEN_ALWAYS
#define NGX_FILE_OPEN OPEN_EXISTING
-#define NGX_FILE_APPEND 0
#define NGX_FILE_DEFAULT_ACCESS 0
#define NGX_FILE_OWNER_ACCESS 0