/*
 * Process environment management
 *
 * Copyright 1996, 1998 Alexandre Julliard
 */

#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/winestring.h"
#include "process.h"
#include "heap.h"
#include "selectors.h"
#include "winerror.h"

/* Format of an environment block:
 * ASCIIZ   string 1 (xx=yy format)
 * ...
 * ASCIIZ   string n
 * BYTE     0
 * WORD     1
 * ASCIIZ   program name (e.g. C:\WINDOWS\SYSTEM\KRNL386.EXE)
 *
 * Notes:
 * - contrary to Microsoft docs, the environment strings do not appear
 *   to be sorted on Win95 (although they are on NT); so we don't bother
 *   to sort them either.
 */

static const char ENV_program_name[] = "C:\\WINDOWS\\SYSTEM\\KRNL386.EXE";

/* Maximum length of a Win16 environment string (including NULL) */
#define MAX_WIN16_LEN  128

/* Extra bytes to reserve at the end of an environment */
#define EXTRA_ENV_SIZE (sizeof(BYTE) + sizeof(WORD) + sizeof(ENV_program_name))

/* Fill the extra bytes with the program name and stuff */
#define FILL_EXTRA_ENV(p) \
    *(p) = '\0'; \
    PUT_WORD( (p) + 1, 1 ); \
    strcpy( (p) + 3, ENV_program_name );


/***********************************************************************
 *           ENV_FindVariable
 *
 * Find a variable in the environment and return a pointer to the value.
 * Helper function for GetEnvironmentVariable and ExpandEnvironmentStrings.
 */
static LPCSTR ENV_FindVariable( LPCSTR env, LPCSTR name, INT len )
{
    while (*env)
    {
        if (!lstrncmpiA( name, env, len ) && (env[len] == '='))
            return env + len + 1;
        env += strlen(env) + 1;
    }
    return NULL;
}


/***********************************************************************
 *           ENV_BuildEnvironment
 *
 * Build the environment for the initial process
 */
BOOL ENV_BuildEnvironment(void)
{
    extern char **environ;
    LPSTR p, *e;
    int size;

    /* Compute the total size of the Unix environment */

    size = EXTRA_ENV_SIZE;
    for (e = environ; *e; e++) size += strlen(*e) + 1;

    /* Now allocate the environment */

    if (!(p = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
    PROCESS_Current()->env_db->environ = p;

    /* And fill it with the Unix environment */

    for (e = environ; *e; e++)
    {
        strcpy( p, *e );
        p += strlen(p) + 1;
    }

    /* Now add the program name */

    FILL_EXTRA_ENV( p );
    return TRUE;
}


/***********************************************************************
 *           ENV_InheritEnvironment
 *
 * Make a process inherit the environment from its parent or from an
 * explicit environment.
 */
BOOL ENV_InheritEnvironment( PDB *pdb, LPCSTR env )
{
    DWORD size;
    LPCSTR src;
    LPSTR dst;

    /* Compute the environment size */

    src = env;
    size = EXTRA_ENV_SIZE;
    while (*src)
    {
        int len = strlen(src) + 1;
        src += len;
        if ((len > MAX_WIN16_LEN) && (pdb->flags & PDB32_WIN16_PROC))
            len = MAX_WIN16_LEN;
        size += len;
    }

    /* Copy the environment */

    if (!(pdb->env_db->environ = HeapAlloc( GetProcessHeap(), 0, size )))
        return FALSE;
    pdb->env_db->env_sel = SELECTOR_AllocBlock( pdb->env_db->environ,
                                                0x10000, SEGMENT_DATA,
                                                FALSE, FALSE );
    src = env;
    dst = pdb->env_db->environ;
    while (*src)
    {
        if (pdb->flags & PDB32_WIN16_PROC)
            lstrcpynA( dst, src, MAX_WIN16_LEN );
        else
            strcpy( dst, src );
        src += strlen(src) + 1;
        dst += strlen(dst) + 1;
    }
    FILL_EXTRA_ENV( dst );
    return TRUE;
}


/***********************************************************************
 *           ENV_FreeEnvironment
 *
 * Free a process environment.
 */
void ENV_FreeEnvironment( PDB *pdb )
{
    if (!pdb->env_db) return;
    if (pdb->env_db->env_sel) SELECTOR_FreeBlock( pdb->env_db->env_sel, 1 );
    DeleteCriticalSection( &pdb->env_db->section );
    /* the storage will be deleted when the process heap is destroyed */
}


/***********************************************************************
 *           GetCommandLineA      (KERNEL32.289)
 */
LPCSTR WINAPI GetCommandLineA(void)
{
    return PROCESS_Current()->env_db->cmd_line;
}

/***********************************************************************
 *           GetCommandLineW      (KERNEL32.290)
 */
LPCWSTR WINAPI GetCommandLineW(void)
{
    PDB *pdb = PROCESS_Current();
    EnterCriticalSection( &pdb->env_db->section );
    if (!pdb->env_db->cmd_lineW)
        pdb->env_db->cmd_lineW = HEAP_strdupAtoW( GetProcessHeap(), 0,
                                                  pdb->env_db->cmd_line );
    LeaveCriticalSection( &pdb->env_db->section );
    return pdb->env_db->cmd_lineW;
}


/***********************************************************************
 *           GetEnvironmentStringsA   (KERNEL32.319) (KERNEL32.320)
 */
LPSTR WINAPI GetEnvironmentStringsA(void)
{
    PDB *pdb = PROCESS_Current();
    return pdb->env_db->environ;
}


/***********************************************************************
 *           GetEnvironmentStringsW   (KERNEL32.321)
 */
LPWSTR WINAPI GetEnvironmentStringsW(void)
{
    INT size;
    LPWSTR ret;
    PDB *pdb = PROCESS_Current();

    EnterCriticalSection( &pdb->env_db->section );
    size = HeapSize( GetProcessHeap(), 0, pdb->env_db->environ );
    if ((ret = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )) != NULL)
    {
        LPSTR pA = pdb->env_db->environ;
        LPWSTR pW = ret;
        while (size--) *pW++ = (WCHAR)(BYTE)*pA++;
    }
    LeaveCriticalSection( &pdb->env_db->section );
    return ret;
}


/***********************************************************************
 *           FreeEnvironmentStringsA   (KERNEL32.268)
 */
BOOL WINAPI FreeEnvironmentStringsA( LPSTR ptr )
{
    PDB *pdb = PROCESS_Current();
    if (ptr != pdb->env_db->environ)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    return TRUE;
}


/***********************************************************************
 *           FreeEnvironmentStringsW   (KERNEL32.269)
 */
BOOL WINAPI FreeEnvironmentStringsW( LPWSTR ptr )
{
    return HeapFree( GetProcessHeap(), 0, ptr );
}


/***********************************************************************
 *           GetEnvironmentVariableA   (KERNEL32.322)
 */
DWORD WINAPI GetEnvironmentVariableA( LPCSTR name, LPSTR value, DWORD size )
{
    LPCSTR p;
    INT ret = 0;
    PDB *pdb = PROCESS_Current();

    if (!name || !*name)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return 0;
    }
    EnterCriticalSection( &pdb->env_db->section );
    if ((p = ENV_FindVariable( pdb->env_db->environ, name, strlen(name) )))
    {
        ret = strlen(p);
        if (size <= ret)
        {
            /* If not enough room, include the terminating null
             * in the returned size and return an empty string */
            ret++;
            if (value) *value = '\0';
        }
        else if (value) strcpy( value, p );
    }
    LeaveCriticalSection( &pdb->env_db->section );
    return ret;  /* FIXME: SetLastError */
}


/***********************************************************************
 *           GetEnvironmentVariableW   (KERNEL32.323)
 */
DWORD WINAPI GetEnvironmentVariableW( LPCWSTR nameW, LPWSTR valW, DWORD size)
{
    LPSTR name = HEAP_strdupWtoA( GetProcessHeap(), 0, nameW );
    LPSTR val  = valW ? HeapAlloc( GetProcessHeap(), 0, size ) : NULL;
    DWORD res  = GetEnvironmentVariableA( name, val, size );
    HeapFree( GetProcessHeap(), 0, name );
    if (val)
    {
        lstrcpynAtoW( valW, val, size );
        HeapFree( GetProcessHeap(), 0, val );
    }
    return res;
}


/***********************************************************************
 *           SetEnvironmentVariableA   (KERNEL32.641)
 */
BOOL WINAPI SetEnvironmentVariableA( LPCSTR name, LPCSTR value )
{
    INT old_size, len, res;
    LPSTR p, env, new_env;
    BOOL ret = FALSE;
    PDB *pdb = PROCESS_Current();

    EnterCriticalSection( &pdb->env_db->section );
    env = p = pdb->env_db->environ;

    /* Find a place to insert the string */

    res = -1;
    len = strlen(name);
    while (*p)
    {
        if (!lstrncmpiA( name, p, len ) && (p[len] == '=')) break;
        p += strlen(p) + 1;
    }
    if (!value && !*p) goto done;  /* Value to remove doesn't exist */

    /* Realloc the buffer */

    len = value ? strlen(name) + strlen(value) + 2 : 0;
    if (*p) len -= strlen(p) + 1;  /* The name already exists */
    old_size = HeapSize( GetProcessHeap(), 0, env );
    if (len < 0)
    {
        LPSTR next = p + strlen(p) + 1;  /* We know there is a next one */
        memmove( next + len, next, old_size - (next - env) );
    }
    if (!(new_env = HeapReAlloc( GetProcessHeap(), 0, env, old_size + len )))
        goto done;
    if (pdb->env_db->env_sel)
        SELECTOR_MoveBlock( pdb->env_db->env_sel, new_env );
    p = new_env + (p - env);
    if (len > 0) memmove( p + len, p, old_size - (p - new_env) );

    /* Set the new string */

    if (value)
    {
        strcpy( p, name );
        strcat( p, "=" );
        strcat( p, value );
    }
    pdb->env_db->environ = new_env;
    ret = TRUE;

done:
    LeaveCriticalSection( &pdb->env_db->section );
    return ret;
}


/***********************************************************************
 *           SetEnvironmentVariableW   (KERNEL32.642)
 */
BOOL WINAPI SetEnvironmentVariableW( LPCWSTR name, LPCWSTR value )
{
    LPSTR nameA  = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
    LPSTR valueA = HEAP_strdupWtoA( GetProcessHeap(), 0, value );
    BOOL ret = SetEnvironmentVariableA( nameA, valueA );
    HeapFree( GetProcessHeap(), 0, nameA );
    HeapFree( GetProcessHeap(), 0, valueA );
    return ret;
}


/***********************************************************************
 *           ExpandEnvironmentStringsA   (KERNEL32.216)
 *
 * Note: overlapping buffers are not supported; this is how it should be.
 */
DWORD WINAPI ExpandEnvironmentStringsA( LPCSTR src, LPSTR dst, DWORD count )
{
    DWORD len, total_size = 1;  /* 1 for terminating '\0' */
    LPCSTR p, var;
    PDB *pdb = PROCESS_Current();

    if (!count) dst = NULL;
    EnterCriticalSection( &pdb->env_db->section );

    while (*src)
    {
        if (*src != '%')
        {
            if ((p = strchr( src, '%' ))) len = p - src;
            else len = strlen(src);
            var = src;
            src += len;
        }
        else  /* we are at the start of a variable */
        {
            if ((p = strchr( src + 1, '%' )))
            {
                len = p - src - 1;  /* Length of the variable name */
                if ((var = ENV_FindVariable( pdb->env_db->environ,
                                             src + 1, len )))
                {
                    src += len + 2;  /* Skip the variable name */
                    len = strlen(var);
                }
                else
                {
                    var = src;  /* Copy original name instead */
                    len += 2;
                    src += len;
                }
            }
            else  /* unfinished variable name, ignore it */
            {
                var = src;
                len = strlen(src);  /* Copy whole string */
                src += len;
            }
        }
        total_size += len;
        if (dst)
        {
            if (count < len) len = count;
            memcpy( dst, var, len );
            dst += len;
            count -= len;
        }
    }
    LeaveCriticalSection( &pdb->env_db->section );

    /* Null-terminate the string */
    if (dst)
    {
        if (!count) dst--;
        *dst = '\0';
    }
    return total_size;
}


/***********************************************************************
 *           ExpandEnvironmentStringsW   (KERNEL32.217)
 */
DWORD WINAPI ExpandEnvironmentStringsW( LPCWSTR src, LPWSTR dst, DWORD len )
{
    LPSTR srcA = HEAP_strdupWtoA( GetProcessHeap(), 0, src );
    LPSTR dstA = dst ? HeapAlloc( GetProcessHeap(), 0, len ) : NULL;
    DWORD ret  = ExpandEnvironmentStringsA( srcA, dstA, len );
    if (dstA)
    {
        lstrcpyAtoW( dst, dstA );
        HeapFree( GetProcessHeap(), 0, dstA );
    }
    HeapFree( GetProcessHeap(), 0, srcA );
    return ret;
}

