diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 22d8aba83..62c18e5e4 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 10574ba58..76d1e9a6d 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 d3e1f1843..5bb84b976 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 42919054a..ff1d4f1fa 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__ */