diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2022-08-04 23:48:19 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2022-08-04 23:48:19 +0200 |
commit | 58e981a5a42cd46ff52591d0394deeea9d3f01f0 (patch) | |
tree | ea2c1d8ab02add17911f2b2fd5da8c2fc4500ae8 | |
parent | 35c5017438dc83d19f85ab0c73ecdc242e9c7511 (diff) | |
download | newlib-58e981a5a42cd46ff52591d0394deeea9d3f01f0.zip newlib-58e981a5a42cd46ff52591d0394deeea9d3f01f0.tar.gz newlib-58e981a5a42cd46ff52591d0394deeea9d3f01f0.tar.bz2 |
Cygwin: use locale-aware conversion to UNICODE_STRING checking mount points
mount_info::get_mounts_here used RtlCreateUnicodeStringFromAsciiz
which translates bytes into wide chars verbatim.
Create a new function sys_mbstouni_alloc which can be used from
mount_info::get_mounts_here to convert multibyte mount point
strings to UNICODE_STRINGS in a locale-aware way.
For symmetry, create a function mount_info::free_mounts_here,
so the knwoledge how to free the UNICODE_STRING buffers is
encapsulated in the same class.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/mount.cc | 27 | ||||
-rw-r--r-- | winsup/cygwin/mount.h | 8 | ||||
-rw-r--r-- | winsup/cygwin/wchar.h | 10 |
4 files changed, 35 insertions, 16 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 22d8aba..62c18e5 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -40,7 +40,7 @@ class __DIR_mounts { int count; const char *parent_dir; - int parent_dir_len; + size_t parent_dir_len; UNICODE_STRING mounts[MAX_MOUNTS]; bool found[MAX_MOUNTS + 3]; UNICODE_STRING cygdrive; @@ -60,9 +60,7 @@ public: } ~__DIR_mounts () { - for (int i = 0; i < count; ++i) - RtlFreeUnicodeString (&mounts[i]); - RtlFreeUnicodeString (&cygdrive); + mount_table->free_mounts_here (mounts, count, &cygdrive); } /* For an entry within this dir, check if a mount point exists. */ bool check_mount (PUNICODE_STRING fname) diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 10574ba..76d1e9a 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -723,12 +723,12 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, return rc; } -int -mount_info::get_mounts_here (const char *parent_dir, int parent_dir_len, +size_t +mount_info::get_mounts_here (const char *parent_dir, size_t parent_dir_len, PUNICODE_STRING mount_points, PUNICODE_STRING cygd) { - int n_mounts = 0; + size_t n_mounts = 0; for (int i = 0; i < nmounts; i++) { @@ -739,20 +739,29 @@ mount_info::get_mounts_here (const char *parent_dir, int parent_dir_len, if (last_slash == mi->posix_path) { if (parent_dir_len == 1 && mi->posix_pathlen > 1) - RtlCreateUnicodeStringFromAsciiz (&mount_points[n_mounts++], - last_slash + 1); + sys_mbstouni_alloc (&mount_points[n_mounts++], HEAP_NOTHEAP, + last_slash + 1); } - else if (parent_dir_len == last_slash - mi->posix_path + else if (parent_dir_len == (size_t) (last_slash - mi->posix_path) && strncasematch (parent_dir, mi->posix_path, parent_dir_len)) - RtlCreateUnicodeStringFromAsciiz (&mount_points[n_mounts++], - last_slash + 1); + sys_mbstouni_alloc (&mount_points[n_mounts++], HEAP_NOTHEAP, + last_slash + 1); } - RtlCreateUnicodeStringFromAsciiz (cygd, cygdrive + 1); + sys_mbstouni_alloc (cygd, HEAP_NOTHEAP, cygdrive + 1); if (cygd->Length) cygd->Length -= 2; // Strip trailing slash return n_mounts; } +void +mount_info::free_mounts_here (PUNICODE_STRING mount_points, int n_mounts, + PUNICODE_STRING cygd) +{ + for (int i = 0; i < n_mounts; ++i) + free (mount_points[i].Buffer); + free (cygd->Buffer); +} + /* cygdrive_posix_path: Build POSIX path used as the mount point for cygdrives created when there is no other way to obtain a POSIX path from a Win32 one. diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index d3e1f18..5bb84b9 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -199,9 +199,11 @@ class mount_info int get_cygdrive_info (char *user, char *system, char* user_flags, char* system_flags); void cygdrive_posix_path (const char *src, char *dst, int flags); - int get_mounts_here (const char *parent_dir, int, - PUNICODE_STRING mount_points, - PUNICODE_STRING cygd); + size_t get_mounts_here (const char *parent_dir, size_t, + PUNICODE_STRING mount_points, + PUNICODE_STRING cygd); + void free_mounts_here (PUNICODE_STRING, int, PUNICODE_STRING); + private: void sort (); diff --git a/winsup/cygwin/wchar.h b/winsup/cygwin/wchar.h index 4291905..ff1d4f1 100644 --- a/winsup/cygwin/wchar.h +++ b/winsup/cygwin/wchar.h @@ -91,6 +91,16 @@ sys_mbstowcs (wchar_t * dst, size_t dlen, const char *src, size_t sys_mbstowcs_alloc (wchar_t **, int, const char *, size_t = (size_t) -1); +static inline size_t +sys_mbstouni_alloc (PUNICODE_STRING dst, int type, const char *src, + size_t nms = (size_t) -1) +{ + size_t len = sys_mbstowcs_alloc (&dst->Buffer, type, src, nms); + dst->MaximumLength = len * sizeof (WCHAR); + dst->Length = dst->MaximumLength - sizeof (WCHAR); + return dst->MaximumLength; +} + #endif /* __cplusplus */ #endif /* __INSIDE_CYGWIN__ */ |