Moved the 16-bit environment support to dlls/kernel.

This commit is contained in:
Alexandre Julliard 2003-09-18 04:28:22 +00:00
parent 2ac34461ad
commit 0f01858228
3 changed files with 47 additions and 80 deletions

View File

@ -166,9 +166,6 @@ static BOOL process_attach(void)
LoadLibrary16( "system.drv" );
}
/* Create 16-bit task */
TASK_CreateMainTask();
/* Create the shared heap for broken win95 native dlls */
HeapCreate( HEAP_SHARED, 0, 0 );
@ -195,7 +192,9 @@ static BOOL process_attach(void)
if (main_create_flags & CREATE_NEW_PROCESS_GROUP)
SetConsoleCtrlHandler(NULL, TRUE);
/* Create 16-bit task */
thread_attach();
TASK_CreateMainTask();
return TRUE;
}

View File

@ -1554,3 +1554,47 @@ DWORD WINAPI GetAppCompatFlags16( HTASK16 hTask )
if (GlobalSize16(hTask) < sizeof(TDB)) return 0;
return pTask->compat_flags;
}
/***********************************************************************
* GetDOSEnvironment (KERNEL.131)
*
* Note: the environment is allocated once, it doesn't track changes
* made using the Win32 API. This shouldn't matter.
*
* Format of a 16-bit 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)
*/
SEGPTR WINAPI GetDOSEnvironment16(void)
{
static const char ENV_program_name[] = "C:\\WINDOWS\\SYSTEM\\KRNL386.EXE";
static HGLOBAL16 handle; /* handle to the 16 bit environment */
if (!handle)
{
DWORD size;
LPSTR p, env;
p = env = GetEnvironmentStringsA();
while (*p) p += strlen(p) + 1;
p++; /* skip last null */
size = (p - env) + sizeof(WORD) + sizeof(ENV_program_name);
handle = GlobalAlloc16( GMEM_FIXED, size );
if (handle)
{
WORD one = 1;
LPSTR env16 = GlobalLock16( handle );
memcpy( env16, env, p - env );
memcpy( env16 + (p - env), &one, sizeof(one));
memcpy( env16 + (p - env) + sizeof(WORD), ENV_program_name, sizeof(ENV_program_name));
GlobalUnlock16( handle );
}
FreeEnvironmentStringsA( env );
}
return K32WOWGlobalLock16( handle );
}

View File

@ -31,87 +31,23 @@
#include "winbase.h"
#include "winerror.h"
#include "thread.h"
#include "wine/winbase16.h"
#include "wine/server.h"
#include "wine/library.h"
#include "heap.h"
#include "winternl.h"
#include "selectors.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(environ);
/* TODO:
* - 16 bit environment ??? (see generate_env_block16 for the details)
*/
/* 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:
/* 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.
* - on Win2K (and likely most of NT versions) the last part (WORD 1 and
* program name no longer appear in the environment block (from the 32
* bit interface)
*/
static const char ENV_program_name[] = "C:\\WINDOWS\\SYSTEM\\KRNL386.EXE";
static STARTUPINFOW startup_infoW;
static STARTUPINFOA startup_infoA;
/* Maximum length of a Win16 environment string (including NULL) */
#define MAX_WIN16_LEN 128
static WORD env_sel; /* selector to the 16 bit environment */
/******************************************************************
* generate_env_block16
*
* This internal function generates a suitable environment for the 16 bit
* subsystem and returns the value as a segmented pointer.
*
* FIXME: current implementation will allocate a private copy of the
* environment strings, but will not follow the modifications (if any)
* from the unicode env block stored in the PEB
* => how should this be updated from the ntdll modifications ?
* should we use the peb->EnvironmentUpdateCount field to
* know when environment has changed ???
* we currently regenerate this block each time an environment
* variable is modified from a Win32 API call, but we'll miss all
* direct access to the NTDLL APIs
*/
static SEGPTR generate_env_block16(void)
{
static LPSTR env16;
DWORD size, new_size;
WORD one = 1;
if (env16) FreeEnvironmentStringsA( env16 );
env16 = GetEnvironmentStringsA();
size = HeapSize(GetProcessHeap(), 0, env16);
new_size = size + sizeof(WORD) + sizeof(ENV_program_name);
if (!(env16 = HeapReAlloc( GetProcessHeap(), 0, env16, new_size ))) return 0;
memcpy(env16 + size, &one, sizeof(one));
memcpy(env16 + size + sizeof(WORD), ENV_program_name, sizeof(ENV_program_name));
if (env_sel)
env_sel = SELECTOR_ReallocBlock( env_sel, env16, new_size );
else
env_sel = SELECTOR_AllocBlock( env16, 0x10000, WINE_LDT_FLAGS_DATA );
return MAKESEGPTR( env_sel, 0 );
}
/***********************************************************************
* GetCommandLineA (KERNEL32.@)
@ -361,9 +297,6 @@ BOOL WINAPI SetEnvironmentVariableW( LPCWSTR name, LPCWSTR value )
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/* FIXME: see comments in generate_env_block16 */
if (env_sel) generate_env_block16();
return TRUE;
}
@ -429,15 +362,6 @@ DWORD WINAPI ExpandEnvironmentStringsW( LPCWSTR src, LPWSTR dst, DWORD len )
}
/***********************************************************************
* GetDOSEnvironment (KERNEL.131)
*/
SEGPTR WINAPI GetDOSEnvironment16(void)
{
return generate_env_block16();
}
/***********************************************************************
* GetStdHandle (KERNEL32.@)
*/