From 55b6513e730126ce5512a83d2e00dea30971a523 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 15 Oct 2018 02:47:05 -0700 Subject: getpwuid(mingw): initialize the structure only once Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'compat') diff --git a/compat/mingw.c b/compat/mingw.c index 858ca14a57..32fa6e7c1f 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1770,16 +1770,27 @@ int mingw_getpagesize(void) struct passwd *getpwuid(int uid) { + static unsigned initialized; static char user_name[100]; - static struct passwd p; + static struct passwd *p; + DWORD len; - DWORD len = sizeof(user_name); - if (!GetUserName(user_name, &len)) + if (initialized) + return p; + + 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 = "unknown"; + p->pw_dir = NULL; + + initialized = 1; + return p; } static HANDLE timer_event; -- cgit v1.2.1 From 564be791f33a72d28497420dafbd3b272b9a1380 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 15 Oct 2018 02:47:06 -0700 Subject: getpwuid(mingw): provide a better default for the user name We do have the excellent GetUserInfoEx() function to obtain more detailed information of the current user (if the user is part of a Windows domain); Let's use it. Suggested by Lutz Roeder. To avoid the cost of loading Secur32.dll (even lazily, loading DLLs takes a non-neglibile amount of time), we use the established technique to load DLLs only when, and if, needed. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'compat') diff --git a/compat/mingw.c b/compat/mingw.c index 32fa6e7c1f..9055471293 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -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) @@ -1768,6 +1769,33 @@ 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; +} + struct passwd *getpwuid(int uid) { static unsigned initialized; @@ -1786,7 +1814,9 @@ struct passwd *getpwuid(int uid) p = xmalloc(sizeof(*p)); p->pw_name = user_name; - p->pw_gecos = "unknown"; + p->pw_gecos = get_extended_user_info(NameDisplay); + if (!p->pw_gecos) + p->pw_gecos = "unknown"; p->pw_dir = NULL; initialized = 1; -- cgit v1.2.1 From 501afcb8b021611758bf07d0e18fa8ff7fbbed73 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 15 Oct 2018 02:47:08 -0700 Subject: mingw: use domain information for default email When a user is registered in a Windows domain, it is really easy to obtain the email address. So let's do that. Suggested by Lutz Roeder. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 5 +++++ compat/mingw.h | 2 ++ 2 files changed, 7 insertions(+) (limited to 'compat') diff --git a/compat/mingw.c b/compat/mingw.c index 9055471293..45c8046c7c 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1796,6 +1796,11 @@ static char *get_extended_user_info(enum EXTENDED_NAME_FORMAT type) return NULL; } +char *mingw_query_user_email(void) +{ + return get_extended_user_info(NameUserPrincipal); +} + struct passwd *getpwuid(int uid) { static unsigned initialized; diff --git a/compat/mingw.h b/compat/mingw.h index 571019d0bd..f31dcff2be 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -424,6 +424,8 @@ static inline void convert_slashes(char *path) int mingw_offset_1st_component(const char *path); #define offset_1st_component mingw_offset_1st_component #define PATH_SEP ';' +extern char *mingw_query_user_email(void); +#define query_user_email mingw_query_user_email #if !defined(__MINGW64_VERSION_MAJOR) && (!defined(_MSC_VER) || _MSC_VER < 1800) #define PRIuMAX "I64u" #define PRId64 "I64d" -- cgit v1.2.1