From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2124) id CF3E93858C24; Fri, 5 Apr 2024 08:43:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CF3E93858C24 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1712306584; bh=Ab8A1rdj8EXbbaRdoeWXQvMycrku9J0cwxfiFdnjgJI=; h=From:To:Subject:Date:From; b=A2lsYFir7OGLASiYztFbUX2W56rD19AZ7PyX0MJJX9xcUkwITtxuL+FOdb2+YgLnw yEgy4EQTjtH3JzBfUum5jApoE6u+BMeSBaFTYgvcKTE1Qk+QTdocpqRKYmVh1sGDWk 93TaT1GYcVf+uR4pF/qeUxMsUnPckLA5O7aH1c+U= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Nick Clifton To: binutils-cvs@sourceware.org Subject: [binutils-gdb] Add support for Windows network paths to the UNC support in _bfd_real_open(). X-Act-Checkin: binutils-gdb X-Git-Author: Zhiqing Xiong X-Git-Refname: refs/heads/master X-Git-Oldrev: 54e2d897a6470167d1922f17e86ae16067408f16 X-Git-Newrev: eac88f3298491fdf2caa0d7dd97a3dde954b8b74 Message-Id: <20240405084304.CF3E93858C24@sourceware.org> Date: Fri, 5 Apr 2024 08:43:04 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Deac88f329849= 1fdf2caa0d7dd97a3dde954b8b74 commit eac88f3298491fdf2caa0d7dd97a3dde954b8b74 Author: Zhiqing Xiong Date: Fri Apr 5 09:41:40 2024 +0100 Add support for Windows network paths to the UNC support in _bfd_real_o= pen(). =20 PR 31527 Diff: --- bfd/bfdio.c | 108 ++++++++++++++++++++++++++++++++++++++++----------------= ---- 1 file changed, 72 insertions(+), 36 deletions(-) diff --git a/bfd/bfdio.c b/bfd/bfdio.c index 4ed0eeadc52..718cbe89023 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -29,6 +29,8 @@ #if defined (_WIN32) #include #include +/* FIXME: Do we need a configure time test for the presence of this header= s ? */ +#include /* Needed for PathIsNetworkPathA(). */ #endif =20 #ifndef S_IXUSR @@ -118,61 +120,95 @@ _bfd_real_fopen (const char *filename, const char *mo= des) =20 #elif defined (_WIN32) /* PR 25713: Handle extra long path names possibly containing '..' and '= .'. */ - wchar_t ** lpFilePart =3D {NULL}; - const wchar_t prefix[] =3D L"\\\\?\\"; - const size_t partPathLen =3D strlen (filename) + 1; + wchar_t ** lpFilePart =3D {NULL}; + const wchar_t prefixDOS[] =3D L"\\\\?\\"; + const wchar_t prefixUNC[] =3D L"\\\\?\\UNC\\"; + const size_t partPathLen =3D strlen (filename) + 1; + const wchar_t * prefix; + size_t sizeof_prefix; + + /* PR 31527: Paths that begin with two backslash characters + (\\) are interpreted as Universal Naming Convention (UNC) + paths. They use the "\\?\UNC\" prefix for network UNC paths + and the "\\?\" prefix for dos UNC paths. For more information + see: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-f= ile-path-limitation?tabs=3Dregistry + */ + bool is_network_path =3D PathIsNetworkPathA (filename); + + if (is_network_path) + { + prefix =3D prefixUNC; + sizeof_prefix =3D sizeof (prefixUNC); + } + else + { + prefix =3D prefixDOS; + sizeof_prefix =3D sizeof (prefixDOS); + } + #ifdef __MINGW32__ #if !HAVE_DECL____LC_CODEPAGE_FUNC -/* This prototype was added to locale.h in version 9.0 of MinGW-w64. */ - _CRTIMP unsigned int __cdecl ___lc_codepage_func (void); + /* This prototype was added to locale.h in version 9.0 of MinGW-w64. */ + _CRTIMP unsigned int __cdecl ___lc_codepage_func (void); #endif - const unsigned int cp =3D ___lc_codepage_func (); + const unsigned int cp =3D ___lc_codepage_func (); #else - const unsigned int cp =3D CP_UTF8; + const unsigned int cp =3D CP_UTF8; #endif =20 - /* Converting the partial path from ascii to unicode. - 1) Get the length: Calling with lpWideCharStr set to null returns th= e length. - 2) Convert the string: Calling with cbMultiByte set to -1 includes t= he terminating null. */ - size_t partPathWSize =3D MultiByteToWideChar (cp, 0, filename, = -1, NULL, 0); - wchar_t * partPath =3D calloc (partPathWSize, sizeof(wchar_t)); - size_t ix; + /* Converting the partial path from ascii to unicode. + 1) Get the length: Calling with lpWideCharStr set to null returns the= length. + 2) Convert the string: Calling with cbMultiByte set to -1 includes th= e terminating null. */ + size_t partPathWSize =3D MultiByteToWideChar (cp, 0, filename, -1, N= ULL, 0); + wchar_t * partPath =3D calloc (partPathWSize, sizeof(wchar_t)); + size_t ix; =20 - MultiByteToWideChar (cp, 0, filename, -1, partPath, partPathWSize); + MultiByteToWideChar (cp, 0, filename, -1, partPath, partPathWSize); =20 - /* Convert any UNIX style path separators into the DOS i.e. backslash s= eparator. */ - for (ix =3D 0; ix < partPathLen; ix++) - if (IS_UNIX_DIR_SEPARATOR(filename[ix])) - partPath[ix] =3D '\\'; + /* Convert any UNIX style path separators into the DOS i.e. backslash se= parator. */ + for (ix =3D 0; ix < partPathLen; ix++) + if (IS_UNIX_DIR_SEPARATOR(filename[ix])) + partPath[ix] =3D '\\'; =20 - /* Getting the full path from the provided partial path. - 1) Get the length. - 2) Resolve the path. */ - long fullPathWSize =3D GetFullPathNameW (partPath, 0, NULL, lpFil= ePart); - wchar_t * fullPath =3D calloc (fullPathWSize + sizeof(prefix) + 1, siz= eof(wchar_t)); + /* Getting the full path from the provided partial path. + 1) Get the length. + 2) Resolve the path. */ + long fullPathWSize =3D GetFullPathNameW (partPath, 0, NULL, lpFile= Part); + wchar_t * fullPath =3D calloc (fullPathWSize + sizeof_prefix + 1, sizeo= f(wchar_t)); =20 - wcscpy (fullPath, prefix); + wcscpy (fullPath, prefix); =20 - int prefixLen =3D sizeof(prefix) / sizeof(wchar_t); + int prefixLen =3D sizeof_prefix / sizeof(wchar_t); =20 - /* Do not add a prefix to the null device. */ - if (stricmp (filename, "nul") =3D=3D 0) + /* Do not add a prefix to the null device. */ + if (stricmp (filename, "nul") =3D=3D 0) prefixLen =3D 1; =20 - wchar_t * fullPathOffset =3D fullPath + prefixLen - 1; + wchar_t * fullPathOffset =3D fullPath + prefixLen - 1; + + GetFullPathNameW (partPath, fullPathWSize, fullPathOffset, lpFilePart); + + if (is_network_path) + { + /* Remove begining of the beginning two backslash characters (\\). = */ + wchar_t *_fullPath =3D calloc (fullPathWSize + sizeof_prefix + 1, si= zeof(wchar_t)); + + GetFullPathNameW (fullPath, fullPathWSize + sizeof_prefix + 1, _full= Path, lpFilePart); + free (fullPath); + fullPath =3D _fullPath; + } =20 - GetFullPathNameW (partPath, fullPathWSize, fullPathOffset, lpFilePart); - free (partPath); + free (partPath); =20 - /* It is non-standard for modes to exceed 16 characters. */ - wchar_t modesW[16]; + /* It is non-standard for modes to exceed 16 characters. */ + wchar_t modesW[16]; =20 - MultiByteToWideChar (cp, 0, modes, -1, modesW, sizeof(modesW)); + MultiByteToWideChar (cp, 0, modes, -1, modesW, sizeof(modesW)); =20 - FILE * file =3D _wfopen (fullPath, modesW); - free (fullPath); + FILE * file =3D _wfopen (fullPath, modesW); + free (fullPath); =20 - return close_on_exec (file); + return close_on_exec (file); =20 #elif defined (HAVE_FOPEN64) return close_on_exec (fopen64 (filename, modes));