aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2022-08-04 23:48:19 +0200
committerCorinna Vinschen <corinna@vinschen.de>2022-08-04 23:48:19 +0200
commit58e981a5a42cd46ff52591d0394deeea9d3f01f0 (patch)
treeea2c1d8ab02add17911f2b2fd5da8c2fc4500ae8
parent35c5017438dc83d19f85ab0c73ecdc242e9c7511 (diff)
downloadnewlib-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.cc6
-rw-r--r--winsup/cygwin/mount.cc27
-rw-r--r--winsup/cygwin/mount.h8
-rw-r--r--winsup/cygwin/wchar.h10
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__ */