diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2015-10-06 14:25:36 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2015-10-06 14:25:36 (GMT) |
commit | 40ba2e067496a7fab51129617bbcd0f5553f285f (patch) | |
tree | 413fc6b0166b78eebf5341d3e76025cad73600ea | |
parent | 1781dd91805d388923c459d467c95112a815d1bf (diff) | |
download | tcl-40ba2e067496a7fab51129617bbcd0f5553f285f.zip tcl-40ba2e067496a7fab51129617bbcd0f5553f285f.tar.gz tcl-40ba2e067496a7fab51129617bbcd0f5553f285f.tar.bz2 |
Fix [b42a851475]: file normalize ~user returns wrong directory on Windows
-rwxr-xr-x | win/tclWinFile.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/win/tclWinFile.c b/win/tclWinFile.c index fe30c55..73a2183 100755 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -17,6 +17,7 @@ #include <winioctl.h> #include <shlobj.h> #include <lmaccess.h> /* For TclpGetUserHome(). */ +#include <userenv.h> /* For TclpGetUserHome(). */ /* * The number of 100-ns intervals between the Windows system epoch (1601-01-01 @@ -177,6 +178,10 @@ typedef NET_API_STATUS NET_API_FUNCTION NETAPIBUFFERFREEPROC(LPVOID Buffer); typedef NET_API_STATUS NET_API_FUNCTION NETGETDCNAMEPROC( LPWSTR servername, LPWSTR domainname, LPBYTE *bufptr); +typedef BOOL WINAPI GETPROFILESDIRECTORYPROC( + LPWSTR lpProfilesDir, LPDWORD lpcchSize +); + /* * Declarations for local functions defined in this file: */ @@ -1418,15 +1423,18 @@ TclpGetUserHome( { char *result; HINSTANCE netapiInst; + HINSTANCE userenvInst; result = NULL; Tcl_DStringInit(bufferPtr); netapiInst = LoadLibraryA("netapi32.dll"); - if (netapiInst != NULL) { + userenvInst = LoadLibraryA("userenv.dll"); + if (netapiInst != NULL && userenvInst != NULL) { NETAPIBUFFERFREEPROC *netApiBufferFreeProc; NETGETDCNAMEPROC *netGetDCNameProc; NETUSERGETINFOPROC *netUserGetInfoProc; + GETPROFILESDIRECTORYPROC *getProfilesDirectoryProc; netApiBufferFreeProc = (NETAPIBUFFERFREEPROC *) GetProcAddress(netapiInst, "NetApiBufferFree"); @@ -1434,8 +1442,10 @@ TclpGetUserHome( GetProcAddress(netapiInst, "NetGetDCName"); netUserGetInfoProc = (NETUSERGETINFOPROC *) GetProcAddress(netapiInst, "NetUserGetInfo"); + getProfilesDirectoryProc = (GETPROFILESDIRECTORYPROC *) + GetProcAddress(userenvInst, "GetProfilesDirectoryW"); if ((netUserGetInfoProc != NULL) && (netGetDCNameProc != NULL) - && (netApiBufferFreeProc != NULL)) { + && (netApiBufferFreeProc != NULL) && (getProfilesDirectoryProc != NULL)) { USER_INFO_1 *uiPtr, **uiPtrPtr = &uiPtr; Tcl_DString ds; int nameLen, badDomain; @@ -1467,12 +1477,17 @@ TclpGetUserHome( } else { /* * User exists but has no home dir. Return - * "{Windows Drive}:/users/default". + * "{GetProfilesDirectory}/<user>". */ - - GetWindowsDirectoryW(buf, MAX_PATH); - Tcl_UniCharToUtfDString(buf, 2, bufferPtr); - Tcl_DStringAppend(bufferPtr, "/users/default", -1); + DWORD size = MAX_PATH; + int i; + getProfilesDirectoryProc(buf, &size); + for (i = 0; i < size; ++i){ + if (buf[i] == '\\') buf[i] = '/'; + } + Tcl_UniCharToUtfDString(buf, size-1, bufferPtr); + Tcl_DStringAppend(bufferPtr, "/", -1); + Tcl_DStringAppend(bufferPtr, name, -1); } result = Tcl_DStringValue(bufferPtr); (*netApiBufferFreeProc)((void *) uiPtr); @@ -1483,6 +1498,7 @@ TclpGetUserHome( (*netApiBufferFreeProc)((void *) wDomain); } } + FreeLibrary(userenvInst); FreeLibrary(netapiInst); } if (result == NULL) { |