Beispiel #1
0
BOOL
WINAPI
CreateEnvironmentBlock(OUT LPVOID *lpEnvironment,
                       IN HANDLE hToken,
                       IN BOOL bInherit)
{
    NTSTATUS Status;
    LONG lError;
    PWSTR* Environment = (PWSTR*)lpEnvironment;
    DWORD Length;
    DWORD dwType;
    HKEY hKey;
    HKEY hKeyUser;
    LPWSTR lpUserName = NULL;
    LPWSTR lpDomainName = NULL;
    WCHAR Buffer[MAX_PATH];
    WCHAR szValue[1024];

    DPRINT("CreateEnvironmentBlock() called\n");

    if (lpEnvironment == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    Status = RtlCreateEnvironment((BOOLEAN)bInherit, Environment);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("RtlCreateEnvironment() failed (Status %lx)\n", Status);
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    /* Set 'SystemRoot' variable */
    Length = ARRAYSIZE(Buffer);
    if (GetEnvironmentVariableW(L"SystemRoot", Buffer, Length))
    {
        SetUserEnvironmentVariable(Environment,
                                   L"SystemRoot",
                                   Buffer,
                                   FALSE);
    }

    /* Set 'SystemDrive' variable */
    if (GetEnvironmentVariableW(L"SystemDrive", Buffer, Length))
    {
        SetUserEnvironmentVariable(Environment,
                                   L"SystemDrive",
                                   Buffer,
                                   FALSE);
    }

    /* Set variables from Session Manager */
    if (!SetSystemEnvironment(Environment))
    {
        RtlDestroyEnvironment(*Environment);
        return FALSE;
    }

    /* Set 'COMPUTERNAME' variable */
    Length = ARRAYSIZE(Buffer);
    if (GetComputerNameW(Buffer, &Length))
    {
        SetUserEnvironmentVariable(Environment,
                                   L"COMPUTERNAME",
                                   Buffer,
                                   FALSE);
    }

    /* Set 'ALLUSERSPROFILE' variable */
    Length = ARRAYSIZE(Buffer);
    if (GetAllUsersProfileDirectoryW(Buffer, &Length))
    {
        SetUserEnvironmentVariable(Environment,
                                   L"ALLUSERSPROFILE",
                                   Buffer,
                                   FALSE);
    }

    /* Set 'USERPROFILE' variable to the default users profile */
    Length = ARRAYSIZE(Buffer);
    if (GetDefaultUserProfileDirectoryW(Buffer, &Length))
    {
        SetUserEnvironmentVariable(Environment,
                                   L"USERPROFILE",
                                   Buffer,
                                   TRUE);
    }

    lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                           L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
                           0,
                           KEY_READ,
                           &hKey);
    if (lError == ERROR_SUCCESS)
    {
        Length = sizeof(szValue);
        lError = RegQueryValueExW(hKey,
                                  L"ProgramFilesDir",
                                  NULL,
                                  &dwType,
                                  (LPBYTE)szValue,
                                  &Length);
        if (lError == ERROR_SUCCESS)
        {
            SetUserEnvironmentVariable(Environment,
                                       L"ProgramFiles",
                                       szValue,
                                       FALSE);
        }

        Length = sizeof(szValue);
        lError = RegQueryValueExW(hKey,
                                  L"CommonFilesDir",
                                  NULL,
                                  &dwType,
                                  (LPBYTE)szValue,
                                  &Length);
        if (lError == ERROR_SUCCESS)
        {
            SetUserEnvironmentVariable(Environment,
                                       L"CommonProgramFiles",
                                       szValue,
                                       FALSE);
        }

        RegCloseKey(hKey);
    }

    /*
     * If no user token is specified, the system environment variables are set
     * and we stop here, otherwise continue setting the user-specific variables.
     */
    if (hToken == NULL)
        return TRUE;

    hKeyUser = GetCurrentUserKey(hToken);
    if (hKeyUser == NULL)
    {
        DPRINT1("GetCurrentUserKey() failed\n");
        RtlDestroyEnvironment(*Environment);
        return FALSE;
    }

    /* Set 'USERPROFILE' variable */
    Length = ARRAYSIZE(Buffer);
    if (GetUserProfileDirectoryW(hToken, Buffer, &Length))
    {
        DWORD MinLen = 2;

        SetUserEnvironmentVariable(Environment,
                                   L"USERPROFILE",
                                   Buffer,
                                   FALSE);

        // FIXME: Strangely enough the following two environment variables
        // are not set by userenv.dll in Windows... See r68284 / CORE-9875
        // FIXME2: This is done by msgina.dll !!

        /* At least <drive letter>:<path> */
        if (Length > MinLen)
        {
            /* Set 'HOMEDRIVE' variable */
            StringCchCopyNW(szValue, ARRAYSIZE(Buffer), Buffer, MinLen);
            SetUserEnvironmentVariable(Environment,
                                       L"HOMEDRIVE",
                                       szValue,
                                       FALSE);

            /* Set 'HOMEPATH' variable */
            StringCchCopyNW(szValue, ARRAYSIZE(Buffer), Buffer + MinLen, Length - MinLen);
            SetUserEnvironmentVariable(Environment,
                                       L"HOMEPATH",
                                       szValue,
                                       FALSE);
        }
    }
    else
    {
        DPRINT1("GetUserProfileDirectoryW failed with error %lu\n", GetLastError());
    }

    if (GetUserAndDomainName(hToken,
                             &lpUserName,
                             &lpDomainName))
    {
        /* Set 'USERNAME' variable */
        SetUserEnvironmentVariable(Environment,
                                   L"USERNAME",
                                   lpUserName,
                                   FALSE);

        /* Set 'USERDOMAIN' variable */
        SetUserEnvironmentVariable(Environment,
                                   L"USERDOMAIN",
                                   lpDomainName,
                                   FALSE);

        if (lpUserName != NULL)
            LocalFree(lpUserName);

        if (lpDomainName != NULL)
            LocalFree(lpDomainName);
    }

    /* Set user environment variables */
    SetUserEnvironment(Environment,
                       hKeyUser,
                       L"Environment");

    /* Set user volatile environment variables */
    SetUserEnvironment(Environment,
                       hKeyUser,
                       L"Volatile Environment");

    RegCloseKey(hKeyUser);

    return TRUE;
}
Beispiel #2
0
BOOL
NTAPI
BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
                         IN PANSI_STRING AnsiEnv,
                         IN PUNICODE_STRING UnicodeEnv)
{
    BOOL Result;
    ULONG RegionSize, EnvironmentSize = 0;
    PWCHAR p, Environment, NewEnvironment = NULL;
    NTSTATUS Status;

    /* Make sure we have both strings */
    if (!(AnsiEnv) || !(UnicodeEnv))
    {
        /* Fail */
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Check if an environment was passed in */
    if (!lpEnvironment)
    {
        /* Nope, create one */
        Status = RtlCreateEnvironment(TRUE, (PWCHAR*)&Environment);
        if (!NT_SUCCESS(Status)) goto Quickie;
    }
    else
    {
        /* Use the one we got */
        Environment = lpEnvironment;
    }

    /* Do we have something now ? */
    if (!Environment)
    {
        /* Still not, fail out */
        SetLastError(ERROR_BAD_ENVIRONMENT);
        goto Quickie;
    }

    /* Count how much space the whole environment takes */
    p = Environment;
    while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++;
    EnvironmentSize += sizeof(UNICODE_NULL);

    /* Allocate a new copy */
    RegionSize = (EnvironmentSize + MAX_PATH) * sizeof(WCHAR);
    if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(),
                                            (PVOID*)&NewEnvironment,
                                            0,
                                            &RegionSize,
                                            MEM_COMMIT,
                                            PAGE_READWRITE)))
    {
        /* We failed, bail out */
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        NewEnvironment = NULL;
        goto Quickie;
    }

    /* Begin parsing the new environment */
    p = NewEnvironment;

    /* FIXME: Code here */

    /* Terminate it */
    *p++ = UNICODE_NULL;

    /* Initialize the unicode string to hold it */
    EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR);
    RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, (USHORT)EnvironmentSize);
    UnicodeEnv->Length = (USHORT)EnvironmentSize;

    /* Create the ASCII version of it */
    Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE);
    if (!NT_SUCCESS(Status))
    {
        /* Set last error if conversion failure */
        BaseSetLastNTError(Status);
    }
    else
    {
        /* Everything went okay, so return success */
        Result = TRUE;
        NewEnvironment = NULL;
    }

Quickie:
    /* Cleanup path starts here, start by destroying the envrionment copy */
    if (!(lpEnvironment) && (Environment)) RtlDestroyEnvironment(Environment);

    /* See if we are here due to failure */
    if (NewEnvironment)
    {
        /* Initialize the paths to be empty */
        RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0);
        RtlInitEmptyAnsiString(AnsiEnv, NULL, 0);

        /* Free the environment copy */
        RegionSize = 0;
        Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                     (PVOID*)&NewEnvironment,
                                     &RegionSize,
                                     MEM_RELEASE);
        ASSERT(NT_SUCCESS(Status));
    }

    /* Return the result */
    return Result;
}
Beispiel #3
0
BOOL WINAPI CreateEnvironmentBlock( LPVOID* lpEnvironment,
                     HANDLE hToken, BOOL bInherit )
{
    static const WCHAR env_keyW[] = {'S','y','s','t','e','m','\\',
        'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
        'C','o','n','t','r','o','l','\\',
        'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
        'E','n','v','i','r','o','n','m','e','n','t',0};
    static const WCHAR profile_keyW[] = {'S','o','f','t','w','a','r','e','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'W','i','n','d','o','w','s',' ','N','T','\\',
        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
        'P','r','o','f','i','l','e','L','i','s','t',0};
    static const WCHAR envW[] = {'E','n','v','i','r','o','n','m','e','n','t',0};
    static const WCHAR volatile_envW[] = {'V','o','l','a','t','i','l','e',' ','E','n','v','i','r','o','n','m','e','n','t',0};
    static const WCHAR ProfilesDirectoryW[] = {'P','r','o','f','i','l','e','s','D','i','r','e','c','t','o','r','y',0};

    static const WCHAR SystemRootW[] = {'S','y','s','t','e','m','R','o','o','t',0};
    static const WCHAR SystemDriveW[] = {'S','y','s','t','e','m','D','r','i','v','e',0};
    static const WCHAR AllUsersProfileW[] = {'A','l','l','U','s','e','r','s','P','r','o','f','i','l','e',0};
    static const WCHAR ALLUSERSPROFILEW[] = {'A','L','L','U','S','E','R','S','P','R','O','F','I','L','E',0};
    static const WCHAR USERNAMEW[] = {'U','S','E','R','N','A','M','E',0};
    static const WCHAR USERPROFILEW[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
    static const WCHAR DefaultW[] = {'D','e','f','a','u','l','t',0};
    static const WCHAR COMPUTERNAMEW[] = {'C','O','M','P','U','T','E','R','N','A','M','E',0};

    WCHAR *env, buf[UNICODE_STRING_MAX_CHARS], profiles_dir[MAX_PATH];
    UNICODE_STRING us_name, us_val;
    DWORD len;
    HKEY hkey, hsubkey;

    TRACE("%p %p %d\n", lpEnvironment, hToken, bInherit );

    if (!lpEnvironment)
        return FALSE;

    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, env_keyW, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
        return FALSE;

    if (RtlCreateEnvironment(bInherit, &env) != STATUS_SUCCESS)
    {
        RegCloseKey(hkey);
        return FALSE;
    }

    if (!GetEnvironmentVariableW(SystemRootW, buf, UNICODE_STRING_MAX_CHARS))
    {
        if (!get_reg_value(env, hkey, SystemRootW, buf, UNICODE_STRING_MAX_CHARS))
        {
            buf[0] = 0;
            WARN("SystemRoot variable not set\n");
        }
    }
    RtlInitUnicodeString(&us_name, SystemRootW);
    RtlInitUnicodeString(&us_val, buf);
    RtlSetEnvironmentVariable(&env, &us_name, &us_val);

    if (!GetEnvironmentVariableW(SystemDriveW, buf, UNICODE_STRING_MAX_CHARS))
    {
        if (!get_reg_value(env, hkey, SystemRootW, buf, UNICODE_STRING_MAX_CHARS))
        {
            buf[0] = 0;
            WARN("SystemDrive variable not set\n");
        }
    }
    RtlInitUnicodeString(&us_name, SystemDriveW);
    RtlInitUnicodeString(&us_val, buf);
    RtlSetEnvironmentVariable(&env, &us_name, &us_val);

    set_registry_variables(&env, hkey, REG_SZ, !bInherit);
    set_registry_variables(&env, hkey, REG_EXPAND_SZ, !bInherit);

    if (RegOpenKeyExW(hkey, envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
    {
        set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
        set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
        RegCloseKey(hsubkey);
    }

    if (RegOpenKeyExW(hkey, volatile_envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
    {
        set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
        set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
        RegCloseKey(hsubkey);
    }
    RegCloseKey(hkey);

    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, profile_keyW, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
    {
        if (get_reg_value(env, hkey, ProfilesDirectoryW, profiles_dir, MAX_PATH-sizeof(WCHAR)))
        {
            len = strlenW(profiles_dir);
            if (profiles_dir[len-1] != '\\')
            {
                profiles_dir[len++] = '\\';
                profiles_dir[len] = '\0';
            }

            memcpy(buf, profiles_dir, len*sizeof(WCHAR));
            if (get_reg_value(env, hkey, AllUsersProfileW, buf+len, UNICODE_STRING_MAX_CHARS-len))
            {
                RtlInitUnicodeString(&us_name, ALLUSERSPROFILEW);
                RtlInitUnicodeString(&us_val, buf);
                RtlSetEnvironmentVariable(&env, &us_name, &us_val);
            }
        }
        else
        {
            profiles_dir[0] = 0;
        }

        RegCloseKey(hkey);
    }

    len = sizeof(buf)/sizeof(WCHAR);
    if (GetComputerNameW(buf, &len))
    {
        RtlInitUnicodeString(&us_name, COMPUTERNAMEW);
        RtlInitUnicodeString(&us_val, buf);
        RtlSetEnvironmentVariable(&env, &us_name, &us_val);
    }

    set_wow64_environment(&env);

    if (!hToken)
    {
        if (profiles_dir[0])
        {
            len = strlenW(profiles_dir);
            if (len*sizeof(WCHAR)+sizeof(DefaultW) < sizeof(buf))
            {
                memcpy(buf, profiles_dir, len*sizeof(WCHAR));
                memcpy(buf+len, DefaultW, sizeof(DefaultW));
                RtlInitUnicodeString(&us_name, USERPROFILEW);
                RtlInitUnicodeString(&us_val, buf);
                RtlSetEnvironmentVariable(&env, &us_name, &us_val);
            }
        }

        buf[0] = '.';
        memcpy(buf+1, DefaultW, sizeof(DefaultW));
    }
    else
    {
        TOKEN_USER *token_user = NULL;
        SID_NAME_USE use;
        WCHAR *sidW;
        DWORD size, tmp=0;

        if (GetTokenInformation(hToken, TokenUser, NULL, 0, &len) ||
                GetLastError()!=ERROR_INSUFFICIENT_BUFFER ||
                !(token_user = HeapAlloc(GetProcessHeap(), 0, len)) ||
                !GetTokenInformation(hToken, TokenUser, token_user, len, &len) ||
                !ConvertSidToStringSidW(token_user->User.Sid, &sidW))
        {
            HeapFree(GetProcessHeap(), 0, token_user);
            RtlDestroyEnvironment(env);
            return FALSE;
        }

        len = strlenW(profiles_dir);
        memcpy(buf, profiles_dir, len*sizeof(WCHAR));

        size = UNICODE_STRING_MAX_CHARS-len;
        if (LookupAccountSidW(NULL, token_user->User.Sid,
                    buf+len, &size, NULL, &tmp, &use))
        {
            RtlInitUnicodeString(&us_name, USERNAMEW);
            RtlInitUnicodeString(&us_val, buf+len);
            RtlSetEnvironmentVariable(&env, &us_name, &us_val);

            if (len)
            {
                RtlInitUnicodeString(&us_name, USERPROFILEW);
                RtlInitUnicodeString(&us_val, buf);
                RtlSetEnvironmentVariable(&env, &us_name, &us_val);
            }
        }

        HeapFree(GetProcessHeap(), 0, token_user);
        strcpyW(buf, sidW);
        LocalFree(sidW);
    }

    if (RegOpenKeyExW(HKEY_USERS, buf, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
    {
        if (RegOpenKeyExW(hkey, envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
        {
            set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
            set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
            RegCloseKey(hsubkey);
        }

        if (RegOpenKeyExW(hkey, volatile_envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
        {
            set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
            set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
            RegCloseKey(hsubkey);
        }
        RegCloseKey(hkey);
    }

    *lpEnvironment = env;
    return TRUE;
}