--- environ.cc.orig 2002-06-06 21:02:20.000000000 -0400 +++ environ.cc 2002-06-08 13:50:20.000000000 -0400 @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include #include "pinfo.h" #include "perprocess.h" #include "security.h" @@ -867,3 +870,136 @@ return __cygwin_environ; } + +/* The default Windows environment variables */ +static NO_COPY struct _WinDefEnv { + const char * name; + const size_t namelen; +} WinDefEnv[] = { + { "HOMEDRIVE=", sizeof("HOMEDRIVE=") - 1}, + { "HOMEPATH=", sizeof("HOMEPATH=") - 1}, + { "HOMESHARE=", sizeof("HOMESHARE=") - 1}, /* Clear only */ + { "LOGONSERVER=", sizeof("LOGONSERVER=") - 1}, + { "USERDOMAIN=", sizeof("USERDOMAIN=") - 1}, + { "USERNAME=", sizeof("USERNAME=") - 1}, + { "USERPROFILE=", sizeof("USERPROFILE=") - 1} +}; +/* Must be in same order as above */ +enum {HD, HP, HS, LS, UD, UN, UP }; + +/* True if name matches one of the names above */ +BOOL +inWinDefEnv(const char * name) +{ + struct _WinDefEnv * ptr = NULL; + if (name[0] == 'H') + { + if (name[4] == 'D') ptr = &WinDefEnv[HD]; + else if (name[4] == 'P') ptr = &WinDefEnv[HP]; + else if (name[4] == 'S') ptr = &WinDefEnv[HS]; + } + else if (name[0] == 'L') ptr = &WinDefEnv[LS]; + else if (name[0] == 'U') + { + if (name[4] == 'D') ptr = &WinDefEnv[UD]; + if (name[4] == 'N') ptr = &WinDefEnv[UN]; + if (name[4] == 'P') ptr = &WinDefEnv[UP]; + } + if (ptr) + return !strncmp(name, ptr->name, ptr->namelen); + else return FALSE; +} + +static BOOL +writeWinDefEnv(char *** pwhere, int offset, char * value) +{ + if (value[0]) + { + **pwhere = (char *) cmalloc (HEAP_1_STR, strlen(value) + + WinDefEnv[offset].namelen + 1); + if (!**pwhere) return FALSE; + strcpy(**pwhere, WinDefEnv[offset].name); + strcpy(**pwhere + WinDefEnv[offset].namelen, value); + (*pwhere)++; + } + return TRUE; +} + +/* Build default Windows environment variables */ +char ** +buildWinDefEnv(char ** ptr, PSID pusersid) +{ + char username[UNLEN + 1] = {0}; + DWORD ulen = sizeof (username); + char userdomain[DNLEN + 1] = {0}; + DWORD dlen = sizeof (userdomain); + char userprofile[MAX_PATH +1] = {0}; + char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3] = {0}; /* With leading \\ */ + WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; /* With leading \\ */ + char homepath[MAX_PATH + 1] = {0, 0}; /* Used for drive + path */ + LPUSER_INFO_3 ui = NULL; + + if (!pusersid) + goto out; + /* Warning: the info is incorrect + if the pusersid is impersonated. */ + SID_NAME_USE use; + if (!LookupAccountSid (NULL, pusersid, username, &ulen, + userdomain, &dlen, &use)) + { + __seterrno (); + goto out; + } + if (!writeWinDefEnv(&ptr, UD, userdomain) || + !writeWinDefEnv(&ptr, UN, username)) + goto out; + if (!strcasematch (username, "SYSTEM")) + { + if (get_logon_server (userdomain, logsrv, wlogsrv)) + { + if (!writeWinDefEnv(&ptr, LS, logsrv)) + goto out; + + WCHAR wuser[UNLEN + 1]; + NET_API_STATUS ret; + sys_mbstowcs (wuser, username, sizeof (wuser) / sizeof (*wuser)); + if ((ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui))) + debug_printf("NetUserGetInfo: %d", ret); + else + { + sys_wcstombs (homepath, ui->usri3_home_dir, sizeof (homepath)); + debug_printf("homepath(1) %s\n", homepath); + if (homepath[1] != ':') + { + sys_wcstombs (homepath, ui->usri3_home_dir_drive, sizeof (homepath)); + debug_printf("homepath(2) %s", homepath); + homepath[2] = '\\'; homepath[3] = 0; + } +// sys_wcstombs (userprofile, ui->usri3_profile, sizeof (userprofile)); +// debug_printf("userprofile(1) %s\n", userprofile); + NetApiBufferFree (ui); + } + } + if (get_registry_hive_path (pusersid, userprofile)) + { + debug_printf("userprofile(2) %s\n", userprofile); + if (!writeWinDefEnv(&ptr, UP, userprofile)) + goto out; + } + } + if (homepath[1] != ':') + { + GetSystemDirectoryA (homepath, sizeof (homepath)); + homepath[3] = 0; + } + if (homepath[1] == ':') + { + if (!writeWinDefEnv(&ptr, HP, &homepath[2]) || + (homepath[2] = 0) || + !writeWinDefEnv(&ptr, HD, homepath)) + goto out; + } + out: + *ptr = NULL; + return ptr; +}