diff options
Diffstat (limited to 'win')
-rw-r--r-- | win/tclWinFile.c | 48 | ||||
-rw-r--r-- | win/tclWinInit.c | 34 | ||||
-rw-r--r-- | win/tclWinInt.h | 2 |
3 files changed, 63 insertions, 21 deletions
diff --git a/win/tclWinFile.c b/win/tclWinFile.c index a70717e..0595e6c 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -1438,34 +1438,62 @@ TclpGetUserHome( * name of user's home directory. */ { char *result = NULL; - USER_INFO_1 *uiPtr, **uiPtrPtr = &uiPtr; + USER_INFO_1 *uiPtr; Tcl_DString ds; int nameLen = -1; - int badDomain = 0; - char *domain; + int rc = 0; + const char *domain; WCHAR *wName, *wHomeDir, *wDomain; WCHAR buf[MAX_PATH]; Tcl_DStringInit(bufferPtr); + wDomain = NULL; - domain = strchr(name, '@'); - if (domain != NULL) { + domain = Tcl_UtfFindFirst(name, '@'); + if (domain == NULL) { + const char *ptr; + + /* no domain - firstly check it's the current user */ + if ( (ptr = TclpGetUserName(&ds)) != NULL + && strcasecmp(name, ptr) == 0 + ) { + /* try safest and fastest way to get current user home */ + ptr = TclGetEnv("HOME", &ds); + if (ptr != NULL) { + Tcl_JoinPath(1, &ptr, bufferPtr); + rc = 1; + result = Tcl_DStringValue(bufferPtr); + } + } + Tcl_DStringFree(&ds); + } else { Tcl_DStringInit(&ds); wName = Tcl_UtfToUniCharDString(domain + 1, -1, &ds); - badDomain = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain); + rc = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain); Tcl_DStringFree(&ds); nameLen = domain - name; } - if (badDomain == 0) { + if (rc == 0) { Tcl_DStringInit(&ds); wName = Tcl_UtfToUniCharDString(name, nameLen, &ds); - if (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) uiPtrPtr) == 0) { + while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) { + /* + * user does not exists - if domain was not specified, + * try again using current domain. + */ + rc = 1; + if (domain != NULL) break; + /* get current domain */ + rc = NetGetDCName(NULL, NULL, (LPBYTE *) &wDomain); + if (rc != 0) break; + domain = INT2PTR(-1); /* repeat once */ + } + if (rc == 0) { DWORD i, size = MAX_PATH; wHomeDir = uiPtr->usri1_home_dir; if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) { size = lstrlenW(wHomeDir); - Tcl_UniCharToUtfDString(wHomeDir, size, - bufferPtr); + Tcl_UniCharToUtfDString(wHomeDir, size, bufferPtr); } else { /* * User exists but has no home dir. Return diff --git a/win/tclWinInit.c b/win/tclWinInit.c index 91f149b..b77a580 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -503,6 +503,27 @@ Tcl_GetEncodingNameFromEnvironment( return Tcl_DStringValue(bufPtr); } +const char * +TclpGetUserName( + Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with + * the name of user. */ +{ + Tcl_DStringInit(bufferPtr); + + if (TclGetEnv("USERNAME", bufferPtr) == NULL) { + TCHAR szUserName[UNLEN+1]; + DWORD cchUserNameLen = UNLEN; + + if (!GetUserName(szUserName, &cchUserNameLen)) { + return NULL; + } + cchUserNameLen--; + cchUserNameLen *= sizeof(TCHAR); + Tcl_WinTCharToUtf(szUserName, cchUserNameLen, bufferPtr); + } + return Tcl_DStringValue(bufferPtr); +} + /* *--------------------------------------------------------------------------- * @@ -533,8 +554,6 @@ TclpSetVariables( static OSVERSIONINFOW osInfo; static int osInfoInitialized = 0; Tcl_DString ds; - TCHAR szUserName[UNLEN+1]; - DWORD cchUserNameLen = UNLEN; Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL, TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY); @@ -609,15 +628,8 @@ TclpSetVariables( * Note: cchUserNameLen is number of characters including nul terminator. */ - Tcl_DStringInit(&ds); - if (TclGetEnv("USERNAME", &ds) == NULL) { - if (GetUserName(szUserName, &cchUserNameLen) != 0) { - int cbUserNameLen = cchUserNameLen - 1; - cbUserNameLen *= sizeof(TCHAR); - Tcl_WinTCharToUtf(szUserName, cbUserNameLen, &ds); - } - } - Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds), + ptr = TclpGetUserName(&ds); + Tcl_SetVar2(interp, "tcl_platform", "user", ptr ? ptr : "", TCL_GLOBAL_ONLY); Tcl_DStringFree(&ds); diff --git a/win/tclWinInt.h b/win/tclWinInt.h index a1ccb36..63835bf 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -64,6 +64,8 @@ MODULE_SCOPE int TclWinSymLinkDelete(const TCHAR *LinkOriginal, int linkOnly); MODULE_SCOPE int TclWinFileOwned(Tcl_Obj *); +MODULE_SCOPE const char*TclpGetUserName(Tcl_DString *bufferPtr); + /* Needed by tclWinFile.c and tclWinFCmd.c */ #ifndef FILE_ATTRIBUTE_REPARSE_POINT #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 |