Merge branch 'js/mingw-load-sys-dll'
authorJunio C Hamano <gitster@pobox.com>
Tue, 30 Oct 2018 06:43:48 +0000 (15:43 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 30 Oct 2018 06:43:48 +0000 (15:43 +0900)
The way DLLs are loaded on the Windows port has been improved.

* js/mingw-load-sys-dll:
  mingw: load system libraries the recommended way

1  2 
compat/mingw.c

diff --combined compat/mingw.c
@@@ -5,7 -5,6 +5,7 @@@
  #include "../strbuf.h"
  #include "../run-command.h"
  #include "../cache.h"
 +#include "win32/lazyload.h"
  
  #define HCAST(type, handle) ((type)(intptr_t)handle)
  
@@@ -203,31 -202,6 +203,31 @@@ static int ask_yes_no_if_possible(cons
        }
  }
  
 +/* Normalizes NT paths as returned by some low-level APIs. */
 +static wchar_t *normalize_ntpath(wchar_t *wbuf)
 +{
 +      int i;
 +      /* fix absolute path prefixes */
 +      if (wbuf[0] == '\\') {
 +              /* strip NT namespace prefixes */
 +              if (!wcsncmp(wbuf, L"\\??\\", 4) ||
 +                  !wcsncmp(wbuf, L"\\\\?\\", 4))
 +                      wbuf += 4;
 +              else if (!wcsnicmp(wbuf, L"\\DosDevices\\", 12))
 +                      wbuf += 12;
 +              /* replace remaining '...UNC\' with '\\' */
 +              if (!wcsnicmp(wbuf, L"UNC\\", 4)) {
 +                      wbuf += 2;
 +                      *wbuf = '\\';
 +              }
 +      }
 +      /* convert backslashes to slashes */
 +      for (i = 0; wbuf[i]; i++)
 +              if (wbuf[i] == '\\')
 +                      wbuf[i] = '/';
 +      return wbuf;
 +}
 +
  int mingw_unlink(const char *pathname)
  {
        int ret, tries = 0;
@@@ -943,29 -917,8 +943,29 @@@ struct tm *localtime_r(const time_t *ti
  
  char *mingw_getcwd(char *pointer, int len)
  {
 -      wchar_t wpointer[MAX_PATH];
 -      if (!_wgetcwd(wpointer, ARRAY_SIZE(wpointer)))
 +      wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
 +      DWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);
 +
 +      if (!ret || ret >= ARRAY_SIZE(cwd)) {
 +              errno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());
 +              return NULL;
 +      }
 +      ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
 +      if (!ret && GetLastError() == ERROR_ACCESS_DENIED) {
 +              HANDLE hnd = CreateFileW(cwd, 0,
 +                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 +                      OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 +              if (hnd == INVALID_HANDLE_VALUE)
 +                      return NULL;
 +              ret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);
 +              CloseHandle(hnd);
 +              if (!ret || ret >= ARRAY_SIZE(wpointer))
 +                      return NULL;
 +              if (xwcstoutf(pointer, normalize_ntpath(wpointer), len) < 0)
 +                      return NULL;
 +              return pointer;
 +      }
 +      if (!ret || ret >= ARRAY_SIZE(wpointer))
                return NULL;
        if (xwcstoutf(pointer, wpointer, len) < 0)
                return NULL;
@@@ -1624,7 -1577,8 +1624,8 @@@ static void ensure_socket_initializatio
                        WSAGetLastError());
  
        for (name = libraries; *name; name++) {
-               ipv6_dll = LoadLibrary(*name);
+               ipv6_dll = LoadLibraryExA(*name, NULL,
+                                         LOAD_LIBRARY_SEARCH_SYSTEM32);
                if (!ipv6_dll)
                        continue;
  
@@@ -1845,63 -1799,18 +1846,63 @@@ int mingw_getpagesize(void
        return si.dwAllocationGranularity;
  }
  
 +/* See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx */
 +enum EXTENDED_NAME_FORMAT {
 +      NameDisplay = 3,
 +      NameUserPrincipal = 8
 +};
 +
 +static char *get_extended_user_info(enum EXTENDED_NAME_FORMAT type)
 +{
 +      DECLARE_PROC_ADDR(secur32.dll, BOOL, GetUserNameExW,
 +              enum EXTENDED_NAME_FORMAT, LPCWSTR, PULONG);
 +      static wchar_t wbuffer[1024];
 +      DWORD len;
 +
 +      if (!INIT_PROC_ADDR(GetUserNameExW))
 +              return NULL;
 +
 +      len = ARRAY_SIZE(wbuffer);
 +      if (GetUserNameExW(type, wbuffer, &len)) {
 +              char *converted = xmalloc((len *= 3));
 +              if (xwcstoutf(converted, wbuffer, len) >= 0)
 +                      return converted;
 +              free(converted);
 +      }
 +
 +      return NULL;
 +}
 +
 +char *mingw_query_user_email(void)
 +{
 +      return get_extended_user_info(NameUserPrincipal);
 +}
 +
  struct passwd *getpwuid(int uid)
  {
 +      static unsigned initialized;
        static char user_name[100];
 -      static struct passwd p;
 +      static struct passwd *p;
 +      DWORD len;
 +
 +      if (initialized)
 +              return p;
  
 -      DWORD len = sizeof(user_name);
 -      if (!GetUserName(user_name, &len))
 +      len = sizeof(user_name);
 +      if (!GetUserName(user_name, &len)) {
 +              initialized = 1;
                return NULL;
 -      p.pw_name = user_name;
 -      p.pw_gecos = "unknown";
 -      p.pw_dir = NULL;
 -      return &p;
 +      }
 +
 +      p = xmalloc(sizeof(*p));
 +      p->pw_name = user_name;
 +      p->pw_gecos = get_extended_user_info(NameDisplay);
 +      if (!p->pw_gecos)
 +              p->pw_gecos = "unknown";
 +      p->pw_dir = NULL;
 +
 +      initialized = 1;
 +      return p;
  }
  
  static HANDLE timer_event;