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>
This commit is contained in:
Corinna Vinschen 2022-08-04 23:48:19 +02:00
parent 35c5017438
commit 58e981a5a4
4 changed files with 35 additions and 16 deletions

View File

@ -40,7 +40,7 @@ class __DIR_mounts
{ {
int count; int count;
const char *parent_dir; const char *parent_dir;
int parent_dir_len; size_t parent_dir_len;
UNICODE_STRING mounts[MAX_MOUNTS]; UNICODE_STRING mounts[MAX_MOUNTS];
bool found[MAX_MOUNTS + 3]; bool found[MAX_MOUNTS + 3];
UNICODE_STRING cygdrive; UNICODE_STRING cygdrive;
@ -60,9 +60,7 @@ public:
} }
~__DIR_mounts () ~__DIR_mounts ()
{ {
for (int i = 0; i < count; ++i) mount_table->free_mounts_here (mounts, count, &cygdrive);
RtlFreeUnicodeString (&mounts[i]);
RtlFreeUnicodeString (&cygdrive);
} }
/* For an entry within this dir, check if a mount point exists. */ /* For an entry within this dir, check if a mount point exists. */
bool check_mount (PUNICODE_STRING fname) bool check_mount (PUNICODE_STRING fname)

View File

@ -723,12 +723,12 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
return rc; return rc;
} }
int size_t
mount_info::get_mounts_here (const char *parent_dir, int parent_dir_len, mount_info::get_mounts_here (const char *parent_dir, size_t parent_dir_len,
PUNICODE_STRING mount_points, PUNICODE_STRING mount_points,
PUNICODE_STRING cygd) PUNICODE_STRING cygd)
{ {
int n_mounts = 0; size_t n_mounts = 0;
for (int i = 0; i < nmounts; i++) 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 (last_slash == mi->posix_path)
{ {
if (parent_dir_len == 1 && mi->posix_pathlen > 1) if (parent_dir_len == 1 && mi->posix_pathlen > 1)
RtlCreateUnicodeStringFromAsciiz (&mount_points[n_mounts++], sys_mbstouni_alloc (&mount_points[n_mounts++], HEAP_NOTHEAP,
last_slash + 1); 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)) && strncasematch (parent_dir, mi->posix_path, parent_dir_len))
RtlCreateUnicodeStringFromAsciiz (&mount_points[n_mounts++], sys_mbstouni_alloc (&mount_points[n_mounts++], HEAP_NOTHEAP,
last_slash + 1); last_slash + 1);
} }
RtlCreateUnicodeStringFromAsciiz (cygd, cygdrive + 1); sys_mbstouni_alloc (cygd, HEAP_NOTHEAP, cygdrive + 1);
if (cygd->Length) if (cygd->Length)
cygd->Length -= 2; // Strip trailing slash cygd->Length -= 2; // Strip trailing slash
return n_mounts; 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 /* cygdrive_posix_path: Build POSIX path used as the
mount point for cygdrives created when there is no other way to mount point for cygdrives created when there is no other way to
obtain a POSIX path from a Win32 one. obtain a POSIX path from a Win32 one.

View File

@ -199,9 +199,11 @@ class mount_info
int get_cygdrive_info (char *user, char *system, char* user_flags, int get_cygdrive_info (char *user, char *system, char* user_flags,
char* system_flags); char* system_flags);
void cygdrive_posix_path (const char *src, char *dst, int flags); void cygdrive_posix_path (const char *src, char *dst, int flags);
int get_mounts_here (const char *parent_dir, int, size_t get_mounts_here (const char *parent_dir, size_t,
PUNICODE_STRING mount_points, PUNICODE_STRING mount_points,
PUNICODE_STRING cygd); PUNICODE_STRING cygd);
void free_mounts_here (PUNICODE_STRING, int, PUNICODE_STRING);
private: private:
void sort (); void sort ();

View File

@ -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); 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 /* __cplusplus */
#endif /* __INSIDE_CYGWIN__ */ #endif /* __INSIDE_CYGWIN__ */