Exec a separate wine binary for every win32 process so that they run
in separate address spaces.
Run 16-bit tasks as Win32 threads, not processes.
diff --git a/dlls/shell32/shell.c b/dlls/shell32/shell.c
index d327542..875d4a9 100644
--- a/dlls/shell32/shell.c
+++ b/dlls/shell32/shell.c
@@ -392,13 +392,11 @@
strcpy(cmd,lpFile);
strcat(cmd,lpParameters ? lpParameters : "");
- SYSLEVEL_ReleaseWin16Lock();
- retval = WinExec( cmd, iShowCmd );
- SYSLEVEL_RestoreWin16Lock();
+ retval = WinExec16( cmd, iShowCmd );
/* Unable to execute lpFile directly
Check if we can match an application to lpFile */
- if(retval < 31)
+ if(retval < 32)
{
cmd[0] = '\0';
retval = SHELL_FindExecutable( lpFile, lpOperation, cmd );
@@ -410,9 +408,7 @@
strcat(cmd," ");
strcat(cmd,lpParameters);
}
- SYSLEVEL_ReleaseWin16Lock();
- retval = WinExec( cmd, iShowCmd );
- SYSLEVEL_RestoreWin16Lock();
+ retval = WinExec16( cmd, iShowCmd );
}
else if(PathIsURLA((LPSTR)lpFile)) /* File not found, check for URL */
{
@@ -477,9 +473,7 @@
}
}
- SYSLEVEL_ReleaseWin16Lock();
- retval = WinExec( cmd, iShowCmd );
- SYSLEVEL_RestoreWin16Lock();
+ retval = WinExec16( cmd, iShowCmd );
}
}
/* Check if file specified is in the form www.??????.*** */
diff --git a/include/main.h b/include/main.h
index 9341f36..b724c07 100644
--- a/include/main.h
+++ b/include/main.h
@@ -7,8 +7,8 @@
#include "windef.h"
-extern BOOL MAIN_MainInit( int argc, char *argv[], BOOL win32 );
-extern BOOL MAIN_WineInit( int argc, char *argv[] );
+extern BOOL MAIN_MainInit( char *argv[] );
+extern void MAIN_WineInit(void);
extern int MAIN_GetLanguageID(char*lang, char*country, char*charset, char*dialect);
extern void MAIN_ParseDebugOptions(const char *options);
extern void MAIN_ParseLanguageOption( const char *arg );
diff --git a/include/module.h b/include/module.h
index 34bf2fe..5844b02 100644
--- a/include/module.h
+++ b/include/module.h
@@ -183,6 +183,7 @@
extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags );
extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
+extern BOOL MODULE_GetBinaryType( HANDLE hfile, LPCSTR filename, LPDWORD lpBinaryType );
extern HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );
extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name );
extern SEGPTR WINAPI HasGPHandler16( SEGPTR address );
@@ -201,12 +202,6 @@
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop );
extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
extern HANDLE NE_OpenFile( NE_MODULE *pModule );
-extern BOOL NE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
- BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
- LPPROCESS_INFORMATION info );
-extern BOOL NE_InitProcess( NE_MODULE *pModule );
-
/* loader/ne/resource.c */
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
diff --git a/include/options.h b/include/options.h
index 7ba4f99..b202de4 100644
--- a/include/options.h
+++ b/include/options.h
@@ -70,7 +70,7 @@
extern const char *argv0;
extern void OPTIONS_Usage(void) WINE_NORETURN;
-extern void OPTIONS_ParseOptions( int argc, char *argv[] );
+extern void OPTIONS_ParseOptions( char *argv[] );
/* Profile functions */
diff --git a/include/pe_image.h b/include/pe_image.h
index 809c289..4aaac26 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -41,11 +41,6 @@
extern HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename );
extern struct _wine_modref *PE_CreateModule( HMODULE hModule, LPCSTR filename,
DWORD flags, BOOL builtin );
-extern BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
- BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
- LPPROCESS_INFORMATION info );
-
extern void PE_InitTls(void);
extern BOOL PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved);
diff --git a/include/process.h b/include/process.h
index 48a7c9b..f7bf458 100644
--- a/include/process.h
+++ b/include/process.h
@@ -88,9 +88,7 @@
DWORD unknown8; /* c0 Unknown (NT) */
LCID locale; /* c4 Locale to be queried by GetThreadLocale (NT) */
/* The following are Wine-specific fields */
- void *server_pid; /* Server id for this process */
HANDLE *dos_handles; /* Handles mapping DOS -> Win32 */
- struct _PDB *next; /* List reference - list of PDB's */
WORD winver; /* Windows version figured out by VERSION_GetVersion */
struct _SERVICETABLE *service_table; /* Service table for service thread */
HANDLE idle_event; /* event to signal, when the process is idle */
@@ -149,22 +147,17 @@
/* memory/environ.c */
extern BOOL ENV_BuildEnvironment(void);
-extern BOOL ENV_InheritEnvironment( PDB *pdb, LPCSTR env );
-extern void ENV_FreeEnvironment( PDB *pdb );
/* scheduler/process.c */
-extern BOOL PROCESS_Init( BOOL win32 );
+extern BOOL PROCESS_Init(void);
+extern void PROCESS_InitWine( int argc, char *argv[] ) WINE_NORETURN;
+extern void PROCESS_InitWinelib( int argc, char *argv[] ) WINE_NORETURN;
extern PDB *PROCESS_IdToPDB( DWORD id );
extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule );
-extern PDB *PROCESS_Create( struct _NE_MODULE *pModule, HFILE hFile,
- LPCSTR cmd_line, LPCSTR env,
+extern BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags,
STARTUPINFOA *startup, PROCESS_INFORMATION *info );
-extern BOOL PROCESS_CreateUnixProcess( LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
- BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
- LPPROCESS_INFORMATION info );
static inline PDB * WINE_UNUSED PROCESS_Current(void)
{
diff --git a/include/task.h b/include/task.h
index d3e6a12..eeb6939 100644
--- a/include/task.h
+++ b/include/task.h
@@ -144,7 +144,8 @@
extern THHOOK *pThhook;
-extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow );
+extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow,
+ struct _TEB *teb, LPCSTR cmdline, BYTE len );
extern void TASK_KillTask( HTASK16 hTask );
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
extern void TASK_Reschedule(void);
diff --git a/include/thread.h b/include/thread.h
index 9939f32..e58b95d 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -120,7 +120,7 @@
/* scheduler/thread.c */
extern void THREAD_Init(void);
-extern TEB *THREAD_Create( struct _PDB *pdb, int fd, DWORD stack_size, BOOL alloc_stack16 );
+extern TEB *THREAD_Create( int fd, DWORD stack_size, BOOL alloc_stack16 );
extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 );
extern BOOL THREAD_IsWin16( TEB *thdb );
extern TEB *THREAD_IdToTEB( DWORD id );
diff --git a/loader/dos/module.c b/loader/dos/module.c
index a2522c3..8acf083 100644
--- a/loader/dos/module.c
+++ b/loader/dos/module.c
@@ -452,6 +452,7 @@
return TRUE;
}
+#if 0
BOOL MZ_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, LPCSTR env,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
@@ -508,6 +509,7 @@
}
return TRUE;
}
+#endif
void MZ_KillModule( LPDOSTASK lpDosTask )
{
diff --git a/loader/main.c b/loader/main.c
index a036a08..1652e5e 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -60,19 +60,17 @@
/***********************************************************************
* Main initialisation routine
*/
-BOOL MAIN_MainInit( int argc, char *argv[], BOOL win32 )
+BOOL MAIN_MainInit( char *argv[] )
{
/* store the program name */
argv0 = argv[0];
/* Create the initial process */
- if (!PROCESS_Init( win32 )) return 0;
-
- /* Initialize syslevel handling */
- SYSLEVEL_Init();
+ if (!PROCESS_Init()) return FALSE;
/* Parse command line arguments */
- MAIN_WineInit( argc, argv );
+ OPTIONS_ParseOptions( argv );
+ MAIN_WineInit();
/* Load the configuration file */
if (!PROFILE_LoadWineIni()) return FALSE;
diff --git a/loader/module.c b/loader/module.c
index 65a9624..0b324ba 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -39,35 +39,6 @@
DEFAULT_DEBUG_CHANNEL(module);
DECLARE_DEBUG_CHANNEL(win32);
-/*************************************************************************
- * MODULE_WalkModref
- * Walk MODREFs for input process ID
- */
-void MODULE_WalkModref( DWORD id )
-{
- int i;
- WINE_MODREF *zwm, *prev = NULL;
- PDB *pdb = PROCESS_IdToPDB( id );
-
- if (!pdb) {
- MESSAGE("Invalid process id (pid)\n");
- return;
- }
-
- MESSAGE("Modref list for process pdb=%p\n", pdb);
- MESSAGE("Modref next prev handle deps flags name\n");
- for ( zwm = pdb->modref_list; zwm; zwm = zwm->next) {
- MESSAGE("%p %p %p %04x %5d %04x %s\n", zwm, zwm->next, zwm->prev,
- zwm->module, zwm->nDeps, zwm->flags, zwm->modname);
- for ( i = 0; i < zwm->nDeps; i++ ) {
- if ( zwm->deps[i] )
- MESSAGE(" %d %p %s\n", i, zwm->deps[i], zwm->deps[i]->modname);
- }
- if (prev != zwm->prev)
- MESSAGE(" --> modref corrupt, previous pointer wrong!!\n");
- prev = zwm;
- }
-}
/*************************************************************************
* MODULE32_LookupHMODULE
@@ -502,8 +473,7 @@
* Note that .COM and .PIF files are only recognized by their
* file name extension; but Windows does it the same way ...
*/
-static BOOL MODULE_GetBinaryType( HANDLE hfile, LPCSTR filename,
- LPDWORD lpBinaryType )
+BOOL MODULE_GetBinaryType( HANDLE hfile, LPCSTR filename, LPDWORD lpBinaryType )
{
IMAGE_DOS_HEADER mz_header;
char magic[4], *ptr;
@@ -690,13 +660,59 @@
*/
HINSTANCE16 WINAPI WinExec16( LPCSTR lpCmdLine, UINT16 nCmdShow )
{
- HINSTANCE16 hInst;
+ LPCSTR p;
+ LPSTR name, cmdline;
+ int len;
+ HINSTANCE16 ret;
+ char buffer[MAX_PATH];
- SYSLEVEL_ReleaseWin16Lock();
- hInst = WinExec( lpCmdLine, nCmdShow );
- SYSLEVEL_RestoreWin16Lock();
+ if ((p = strchr( lpCmdLine, ' ' )))
+ {
+ if (!(name = HeapAlloc( GetProcessHeap(), 0, p - lpCmdLine + 1 )))
+ return ERROR_NOT_ENOUGH_MEMORY;
+ memcpy( name, lpCmdLine, p - lpCmdLine );
+ name[p - lpCmdLine] = 0;
+ p++;
+ len = strlen(p);
+ cmdline = SEGPTR_ALLOC( len + 2 );
+ cmdline[0] = (BYTE)len;
+ strcpy( cmdline + 1, p );
+ }
+ else
+ {
+ name = (LPSTR)lpCmdLine;
+ cmdline = SEGPTR_ALLOC(2);
+ cmdline[0] = cmdline[1] = 0;
+ }
- return hInst;
+ if (SearchPathA( NULL, name, ".exe", sizeof(buffer), buffer, NULL ))
+ {
+ LOADPARAMS16 params;
+ WORD *showCmd = SEGPTR_ALLOC( 2*sizeof(WORD) );
+ showCmd[0] = 2;
+ showCmd[1] = nCmdShow;
+
+ params.hEnvironment = 0;
+ params.cmdLine = SEGPTR_GET(cmdline);
+ params.showCmd = SEGPTR_GET(showCmd);
+ params.reserved = 0;
+
+ ret = LoadModule16( buffer, ¶ms );
+
+ SEGPTR_FREE( showCmd );
+ SEGPTR_FREE( cmdline );
+ }
+ else ret = GetLastError();
+
+ if (name != lpCmdLine) HeapFree( GetProcessHeap(), 0, name );
+
+ if (ret == 21) /* 32-bit module */
+ {
+ SYSLEVEL_ReleaseWin16Lock();
+ ret = WinExec( lpCmdLine, nCmdShow );
+ SYSLEVEL_RestoreWin16Lock();
+ }
+ return ret;
}
/***********************************************************************
@@ -719,14 +735,7 @@
/* Give 30 seconds to the app to come up */
if (Callout.WaitForInputIdle ( info.hProcess, 30000 ) == 0xFFFFFFFF)
WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
-
- /* Get 16-bit hInstance/hTask from process */
- hInstance = GetProcessDword( info.dwProcessId, GPD_HINSTANCE16 );
- /* If there is no hInstance (32-bit process) return a dummy value
- * that must be > 31
- * FIXME: should do this in all cases and fix Win16 callers */
- if (!hInstance) hInstance = 33;
-
+ hInstance = 33;
/* Close off the handles */
CloseHandle( info.hThread );
CloseHandle( info.hProcess );
@@ -783,13 +792,7 @@
/* Give 30 seconds to the app to come up */
if ( Callout.WaitForInputIdle ( info.hProcess, 30000 ) == 0xFFFFFFFF )
WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
-
- /* Get 16-bit hInstance/hTask from process */
- hInstance = GetProcessDword( info.dwProcessId, GPD_HINSTANCE16 );
- /* If there is no hInstance (32-bit process) return a dummy value
- * that must be > 31
- * FIXME: should do this in all cases and fix Win16 callers */
- if (!hInstance) hInstance = 33;
+ hInstance = 33;
/* Close off the handles */
CloseHandle( info.hThread );
CloseHandle( info.hProcess );
@@ -905,6 +908,8 @@
/* Process the AppName and/or CmdLine to get module name and path */
+ TRACE("app '%s' cmdline '%s'\n", lpApplicationName, lpCommandLine );
+
if (!(tidy_cmdline = get_file_name( lpApplicationName, lpCommandLine, name, sizeof(name) )))
return FALSE;
@@ -972,11 +977,10 @@
if ( !MODULE_GetBinaryType( hFile, name, &type ) )
{
CloseHandle( hFile );
- /* FIXME: Try Unix executable only when appropriate! */
- retv = PROCESS_CreateUnixProcess( name, tidy_cmdline, lpEnvironment,
- lpProcessAttributes, lpThreadAttributes,
- bInheritHandles, dwCreationFlags,
- lpStartupInfo, lpProcessInfo );
+ retv = PROCESS_Create( -1, name, tidy_cmdline, lpEnvironment,
+ lpProcessAttributes, lpThreadAttributes,
+ bInheritHandles, dwCreationFlags,
+ lpStartupInfo, lpProcessInfo );
goto done;
}
@@ -985,24 +989,12 @@
switch ( type )
{
case SCS_32BIT_BINARY:
- retv = PE_CreateProcess( hFile, name, tidy_cmdline, lpEnvironment,
- lpProcessAttributes, lpThreadAttributes,
- bInheritHandles, dwCreationFlags,
- lpStartupInfo, lpProcessInfo );
- break;
-
- case SCS_DOS_BINARY:
- retv = MZ_CreateProcess( hFile, name, tidy_cmdline, lpEnvironment,
- lpProcessAttributes, lpThreadAttributes,
- bInheritHandles, dwCreationFlags,
- lpStartupInfo, lpProcessInfo );
- break;
-
case SCS_WOW_BINARY:
- retv = NE_CreateProcess( hFile, name, tidy_cmdline, lpEnvironment,
- lpProcessAttributes, lpThreadAttributes,
- bInheritHandles, dwCreationFlags,
- lpStartupInfo, lpProcessInfo );
+ case SCS_DOS_BINARY:
+ retv = PROCESS_Create( hFile, name, tidy_cmdline, lpEnvironment,
+ lpProcessAttributes, lpThreadAttributes,
+ bInheritHandles, dwCreationFlags,
+ lpStartupInfo, lpProcessInfo );
break;
case SCS_PIF_BINARY:
diff --git a/loader/ne/module.c b/loader/ne/module.c
index e1fec11..45a879b 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -29,8 +29,9 @@
#include "debugtools.h"
#include "loadorder.h"
#include "elfdll.h"
+#include "server.h"
-DEFAULT_DEBUG_CHANNEL(module)
+DEFAULT_DEBUG_CHANNEL(module);
#define hFirstModule (pThhook->hExeHead)
@@ -38,6 +39,7 @@
static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only );
static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
+static HINSTANCE16 NE_InitProcess( NE_MODULE *pModule, HTASK hTask );
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only );
@@ -991,15 +993,16 @@
*/
HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
{
+ struct new_thread_request *req = get_req_buffer();
+ TEB *teb = NULL;
BOOL lib_only = !paramBlock || (paramBlock == (LPVOID)-1);
LOADPARAMS16 *params;
- LPSTR cmd_line, new_cmd_line;
- LPCVOID env = NULL;
- STARTUPINFOA startup;
- PROCESS_INFORMATION info;
+ HINSTANCE16 instance;
HMODULE16 hModule;
NE_MODULE *pModule;
- PDB *pdb;
+ LPSTR cmdline;
+ WORD cmdShow;
+ int socket;
/* Load module */
@@ -1037,128 +1040,52 @@
* has already been incremented (to avoid having the module vanish
* in the meantime), or else to a stub module which contains only header
* information.
- *
- * All remaining initialization (really loading the module in the second
- * case, and creating the new instance in both cases) are to be done in
- * the context of the new process. This happens in the NE_InitProcess
- * routine, which will be called from the 32-bit process initialization.
*/
+ /* Create the main thread */
+
+ req->suspend = 0;
+ req->inherit = 0;
+ if (server_call_fd( REQ_NEW_THREAD, -1, &socket )) return 0;
+ CloseHandle( req->handle );
+
+ if (!(teb = THREAD_Create( socket, 0, FALSE ))) goto error;
+ teb->startup = TASK_CallToStart;
+
+ /* Create a task for this process */
params = (LOADPARAMS16 *)paramBlock;
- cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
- if (!cmd_line) cmd_line = "";
- else if (*cmd_line) cmd_line++; /* skip the length byte */
+ cmdShow = ((WORD *)PTR_SEG_TO_LIN(params->showCmd))[1];
+ cmdline = PTR_SEG_TO_LIN( params->cmdLine );
+ if (!TASK_Create( pModule, cmdShow, teb, cmdline + 1, *cmdline )) goto error;
- if (!(new_cmd_line = HeapAlloc( GetProcessHeap(), 0,
- strlen(cmd_line)+strlen(name)+2 )))
- return 0;
- strcpy( new_cmd_line, name );
- strcat( new_cmd_line, " " );
- strcat( new_cmd_line, cmd_line );
+ if ((instance = NE_InitProcess( pModule, teb->htask16 )) < 32) goto error;
- if (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
+ if (SYSDEPS_SpawnThread( teb ) == -1) goto error;
- memset( &info, '\0', sizeof(info) );
- memset( &startup, '\0', sizeof(startup) );
- startup.cb = sizeof(startup);
- if (params->showCmd)
- {
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = ((UINT16 *)PTR_SEG_TO_LIN(params->showCmd))[1];
- }
+ /* Post event to start the task */
+ PostEvent16( teb->htask16 );
+ OldYield16();
- SYSLEVEL_ReleaseWin16Lock();
- pdb = PROCESS_Create( pModule, -1, new_cmd_line, env,
- NULL, NULL, TRUE, 0, &startup, &info );
- SYSLEVEL_RestoreWin16Lock();
-
- CloseHandle( info.hThread );
- CloseHandle( info.hProcess );
-
- if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
- HeapFree( GetProcessHeap(), 0, new_cmd_line );
-
- return GetProcessDword( info.dwProcessId, GPD_HINSTANCE16 );
-}
-
-/**********************************************************************
- * NE_CreateProcess
- */
-BOOL NE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
- BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
- LPPROCESS_INFORMATION info )
-{
- HMODULE16 hModule;
- NE_MODULE *pModule;
-
- SYSLEVEL_EnterWin16Lock();
-
- /* Special case: second instance of an already loaded NE module
- * FIXME: maybe we should mark the module in a special way during
- * "second instance" loading stage ?
- * NE_CreateSegment and NE_LoadSegment might get confused without it,
- * especially when it comes to self-loaders */
-
- if ( ( hModule = NE_GetModuleByFilename( filename ) ) != 0 )
- {
- if ( !( pModule = NE_GetPtr( hModule) )
- || ( pModule->flags & NE_FFLAGS_LIBMODULE )
- || pModule->module32 )
- {
- SetLastError( ERROR_BAD_FORMAT );
- goto error;
- }
-
- pModule->count++;
- }
-
- /* Main case: load first instance of NE module */
- else
- {
- /* Load module */
-
- hModule = NE_LoadExeHeader( filename );
- if ( hModule < 32 )
- {
- SetLastError( hModule );
- goto error;
- }
-
- if ( !( pModule = NE_GetPtr( hModule ) )
- || ( pModule->flags & NE_FFLAGS_LIBMODULE) )
- {
- GlobalFreeAll16( hModule );
- SetLastError( ERROR_BAD_FORMAT );
- goto error;
- }
- }
-
- SYSLEVEL_LeaveWin16Lock();
-
- if ( !PROCESS_Create( pModule, hFile, cmd_line, env,
- psa, tsa, inherit, flags, startup, info ) )
- return FALSE;
-
- return TRUE;
+ return instance;
error:
- SYSLEVEL_LeaveWin16Lock();
- return FALSE;
+ /* FIXME: free TEB and task */
+ close( socket );
+ return 0; /* FIXME */
}
+
/**********************************************************************
* NE_InitProcess
*/
-BOOL NE_InitProcess( NE_MODULE *pModule )
+static HINSTANCE16 NE_InitProcess( NE_MODULE *pModule, HTASK hTask )
{
HINSTANCE16 hInstance, hPrevInstance;
- BOOL retv = TRUE;
+ TDB *pTask;
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
WORD sp;
- TDB *pTask;
SYSLEVEL_EnterWin16Lock();
@@ -1187,30 +1114,25 @@
hPrevInstance = 0;
}
- if ( hInstance < 32 )
+ if ( hInstance >= 32 )
{
- SYSLEVEL_LeaveWin16Lock();
+ /* Enter instance handles into task struct */
- SetLastError( hInstance );
- return FALSE;
+ pTask = (TDB *)GlobalLock16( hTask );
+ pTask->hInstance = hInstance;
+ pTask->hPrevInstance = hPrevInstance;
+
+ /* Use DGROUP for 16-bit stack */
+
+ if (!(sp = pModule->sp))
+ sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
+ sp &= ~1;
+ sp -= sizeof(STACK16FRAME);
+ pTask->teb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel16(hInstance), sp );
}
- /* Enter instance handles into task struct */
-
- pTask = (TDB *)GlobalLock16( GetCurrentTask() );
- pTask->hInstance = hInstance;
- pTask->hPrevInstance = hPrevInstance;
-
- /* Use DGROUP for 16-bit stack */
-
- if (!(sp = pModule->sp))
- sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
- sp &= ~1; sp -= sizeof(STACK16FRAME);
- pTask->teb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel16(hInstance), sp );
-
SYSLEVEL_LeaveWin16Lock();
-
- return retv;
+ return hInstance;
}
/***********************************************************************
diff --git a/loader/pe_image.c b/loader/pe_image.c
index f0df822..0957062 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -572,6 +572,7 @@
filename, aoep, lowest_va );
+#if 0
/* FIXME: Hack! While we don't really support shared sections yet,
* this checks for those special cases where the whole DLL
* consists only of shared sections and is mapped into the
@@ -599,7 +600,7 @@
return sharedMod;
}
}
-
+#endif
/* Allocate memory for module */
load_addr = nt->OptionalHeader.ImageBase;
@@ -983,53 +984,6 @@
HeapFree( GetProcessHeap(), 0, wm );
}
-/*****************************************************************************
- * Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA
- * FIXME: this function should use PE_LoadLibraryExA, but currently can't
- * due to the PROCESS_Create stuff.
- */
-BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
- BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
- LPPROCESS_INFORMATION info )
-{
- HMODULE16 hModule16;
- HMODULE hModule32;
- NE_MODULE *pModule;
-
- /* Load file */
- if ( (hModule32 = PE_LoadImage( hFile, filename )) < 32 )
- {
- SetLastError( hModule32 );
- return FALSE;
- }
-#if 0
- if (PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL)
- {
- SetLastError( 20 ); /* FIXME: not the right error code */
- return FALSE;
- }
-#endif
-
- /* Create 16-bit dummy module */
- if ( (hModule16 = MODULE_CreateDummyModule( filename, hModule32 )) < 32 )
- {
- SetLastError( hModule16 );
- return FALSE;
- }
- pModule = (NE_MODULE *)GlobalLock16( hModule16 );
-
- /* Create new process */
- if ( !PROCESS_Create( pModule, hFile, cmd_line, env,
- psa, tsa, inherit, flags, startup, info ) )
- return FALSE;
-
- /* Note: PE_CreateModule and the remaining process initialization will
- be done in the context of the new process, in TASK_CallToStart */
-
- return TRUE;
-}
-
/* Called if the library is loaded or freed.
* NOTE: if a thread attaches a DLL, the current thread will only do
diff --git a/loader/task.c b/loader/task.c
index cce67b5..7725545 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -274,11 +274,10 @@
* by entering the Win16Lock while linking the task into the
* global task list.
*/
-BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow)
+BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline, BYTE len )
{
HTASK16 hTask;
TDB *pTask;
- LPSTR cmd_line;
char name[10];
PDB *pdb32 = PROCESS_Current();
@@ -310,7 +309,7 @@
pTask->hParent = GetCurrentTask();
pTask->magic = TDB_MAGIC;
pTask->nCmdShow = cmdShow;
- pTask->teb = NtCurrentTeb();
+ pTask->teb = teb;
pTask->curdrive = DRIVE_GetCurrentDrive() | 0x80;
strcpy( pTask->curdir, "\\" );
lstrcpynA( pTask->curdir + 1, DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() ),
@@ -349,11 +348,17 @@
/* Fill the command line */
- cmd_line = pdb32->env_db->cmd_line;
- while (*cmd_line && (*cmd_line != ' ') && (*cmd_line != '\t')) cmd_line++;
- while ((*cmd_line == ' ') || (*cmd_line == '\t')) cmd_line++;
- lstrcpynA( pTask->pdb.cmdLine+1, cmd_line, sizeof(pTask->pdb.cmdLine)-1);
- pTask->pdb.cmdLine[0] = strlen( pTask->pdb.cmdLine + 1 );
+ if (!cmdline)
+ {
+ cmdline = pdb32->env_db->cmd_line;
+ while (*cmdline && (*cmdline != ' ') && (*cmdline != '\t')) cmdline++;
+ while ((*cmdline == ' ') || (*cmdline == '\t')) cmdline++;
+ len = strlen(cmdline);
+ }
+ if (len >= sizeof(pTask->pdb.cmdLine)) len = sizeof(pTask->pdb.cmdLine)-1;
+ pTask->pdb.cmdLine[0] = len;
+ memcpy( pTask->pdb.cmdLine + 1, cmdline, len );
+ /* pTask->pdb.cmdLine[len+1] = 0; */
/* Get the compatibility flags */
@@ -384,10 +389,10 @@
/* Enter task handle into thread and process */
- pTask->teb->htask16 = pTask->teb->process->task = hTask;
+ teb->htask16 = hTask;
if (!initial_task) initial_task = hTask;
- TRACE("module='%s' cmdline='%s' task=%04x\n", name, cmd_line, hTask );
+ TRACE("module='%s' cmdline='%.*s' task=%04x\n", name, *cmdline, cmdline+1, hTask );
/* Add the task to the linked list */
@@ -932,7 +937,7 @@
hInstanceSelector = GlobalHandleToSel16(hInstance);
- TRACE("(%08lx, %04x);", (DWORD)func, hInstance);
+ TRACE("(%08lx, %04x);\n", (DWORD)func, hInstance);
if (!HIWORD(func)) {
/* Win95 actually protects via SEH, but this is better for debugging */
@@ -1168,8 +1173,8 @@
{
teb->queue = hQueue;
- if ( GetTaskQueue16( teb->process->task ) == oldQueue )
- SetTaskQueue16( teb->process->task, hQueue );
+ if ( GetTaskQueue16( teb->htask16 ) == oldQueue )
+ SetTaskQueue16( teb->htask16, hQueue );
}
return oldQueue;
@@ -1334,7 +1339,7 @@
*/
HTASK16 WINAPI GetCurrentTask(void)
{
- return PROCESS_Current()->task;
+ return NtCurrentTeb()->htask16;
}
DWORD WINAPI WIN16_GetCurrentTask(void)
diff --git a/memory/environ.c b/memory/environ.c
index 2fa96b3..d3eb41d 100644
--- a/memory/environ.c
+++ b/memory/environ.c
@@ -82,6 +82,8 @@
if (!(p = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
PROCESS_Current()->env_db->environ = p;
+ PROCESS_Current()->env_db->env_sel = SELECTOR_AllocBlock( p, 0x10000, SEGMENT_DATA,
+ FALSE, FALSE );
/* And fill it with the Unix environment */
@@ -99,68 +101,6 @@
/***********************************************************************
- * 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)
diff --git a/misc/main.c b/misc/main.c
index 9a919b8..c661e0d 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -80,21 +80,6 @@
WORD WINE_LanguageId = 0x409; /* english as default */
-struct options Options =
-{ /* default options */
- 0, /* argc */
- NULL, /* argv */
- NULL, /* desktopGeometry */
- NULL, /* display */
- NULL, /* dllFlags */
- FALSE, /* synchronous */
- 0, /* language */
- FALSE, /* Managed windows */
- NULL /* Alternate config file name */
-};
-
-const char *argv0;
-
/***********************************************************************
* MAIN_ParseDebugOptions
*
@@ -636,7 +621,7 @@
*
* Wine initialisation and command-line parsing
*/
-BOOL MAIN_WineInit( int argc, char *argv[] )
+void MAIN_WineInit(void)
{
struct timeval tv;
@@ -662,10 +647,7 @@
gettimeofday( &tv, NULL);
MSG_WineStartTicks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
- OPTIONS_ParseOptions( argc, argv );
-
atexit(called_at_exit);
- return TRUE;
}
/***********************************************************************
diff --git a/misc/options.c b/misc/options.c
index ff47176..37cc31c 100644
--- a/misc/options.c
+++ b/misc/options.c
@@ -27,6 +27,20 @@
int _ARGC;
char **_ARGV;
+/* default options */
+struct options Options =
+{
+ NULL, /* desktopGeometry */
+ NULL, /* display */
+ NULL, /* dllFlags */
+ FALSE, /* synchronous */
+ 0, /* language */
+ FALSE, /* Managed windows */
+ NULL /* Alternate config file name */
+};
+
+const char *argv0;
+
static void do_config( const char *arg );
static void do_desktop( const char *arg );
static void do_display( const char *arg );
@@ -116,10 +130,9 @@
Options.configFileName = strdup( arg );
}
-static inline void remove_options( int *argc, char *argv[], int pos, int count )
+static inline void remove_options( char *argv[], int pos, int count )
{
while ((argv[pos] = argv[pos+count])) pos++;
- *argc -= count;
}
/***********************************************************************
@@ -128,7 +141,7 @@
void OPTIONS_Usage(void)
{
const struct option *opt;
- MESSAGE( "Usage: %s [options] \"program_name [arguments]\"\n\n", argv0 );
+ MESSAGE( "Usage: %s [options] program_name [arguments]\n\n", argv0 );
MESSAGE( "Options:\n" );
for (opt = option_table; opt->longname; opt++) MESSAGE( " %s\n", opt->usage );
ExitProcess(0);
@@ -137,7 +150,7 @@
/***********************************************************************
* OPTIONS_ParseOptions
*/
-void OPTIONS_ParseOptions( int argc, char *argv[] )
+void OPTIONS_ParseOptions( char *argv[] )
{
const struct option *opt;
int i;
@@ -163,12 +176,12 @@
if (opt->has_arg && argv[i+1])
{
opt->func( argv[i+1] );
- remove_options( &argc, argv, i, 2 );
+ remove_options( argv, i, 2 );
}
else
{
opt->func( "" );
- remove_options( &argc, argv, i, 1 );
+ remove_options( argv, i, 1 );
}
i--;
}
@@ -178,7 +191,7 @@
{
if (!strcmp( argv[i], "--" ))
{
- remove_options( &argc, argv, i, 1 );
+ remove_options( argv, i, 1 );
break;
}
if (argv[i][0] == '-')
@@ -187,8 +200,9 @@
OPTIONS_Usage();
}
}
- Options.argc = argc;
- Options.argv = argv;
- _ARGC = argc;
+
+ /* count the resulting arguments */
_ARGV = argv;
+ _ARGC = 0;
+ while (argv[_ARGC]) _ARGC++;
}
diff --git a/miscemu/main.c b/miscemu/main.c
index f4550c4..b35d94d 100644
--- a/miscemu/main.c
+++ b/miscemu/main.c
@@ -3,89 +3,40 @@
*
*/
-#include <stdlib.h>
-#include <assert.h>
+#include "winbase.h"
#include "wine/winbase16.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+#include "builtin32.h"
#include "callback.h"
-#include "main.h"
-#include "miscemu.h"
-#include "module.h"
#include "options.h"
#include "process.h"
-#include "thread.h"
-#include "task.h"
-#include "stackframe.h"
-#include "wine/exception.h"
#include "debugtools.h"
-static BOOL exec_program( LPCSTR cmdline )
-{
- HINSTANCE handle = WinExec( cmdline, SW_SHOWNORMAL );
- if (handle < 32)
- {
- MESSAGE( "%s: can't exec '%s': ", argv0, cmdline );
- switch (handle)
- {
- case 2: MESSAGE("file not found\n" ); break;
- case 11: MESSAGE("invalid exe file\n" ); break;
- default: MESSAGE("error=%d\n", handle ); break;
- }
- }
- return (handle >= 32);
-}
-
/***********************************************************************
* Main loop of initial task
*/
-void MAIN_EmulatorRun( void )
+static void initial_task(void)
{
- char startProg[256], defProg[256];
- int i, tasks = 0;
MSG msg;
- char szGraphicsDriver[MAX_PATH];
+ HINSTANCE16 instance;
+ STARTUPINFOA info;
- if (PROFILE_GetWineIniString( "Wine", "GraphicsDriver",
- "x11drv", szGraphicsDriver, sizeof(szGraphicsDriver)))
+ GetStartupInfoA( &info );
+ if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = SW_SHOWNORMAL;
+
+ if ((instance = WinExec16( GetCommandLineA(), info.wShowWindow )) < 32)
{
- if (!LoadLibraryA( szGraphicsDriver )) ExitProcess(1);
- }
-
- /* Load system DLLs into the initial process (and initialize them) */
- if ( !LoadLibrary16("GDI.EXE" ) || !LoadLibraryA("GDI32.DLL" )
- || !LoadLibrary16("USER.EXE") || !LoadLibraryA("USER32.DLL"))
- ExitProcess( 1 );
-
- /* Get pointers to USER routines called by KERNEL */
- THUNK_InitCallout();
-
- /* Call FinalUserInit routine */
- Callout.FinalUserInit16();
-
- /* Call InitApp for initial task */
- Callout.InitApp16( MapHModuleLS( 0 ) );
-
- /* Add the Startup Program to the run list */
- PROFILE_GetWineIniString( "programs", "Startup", "",
- startProg, sizeof(startProg) );
- if (startProg[0]) tasks += exec_program( startProg );
-
- /* Add the Default Program if no program on the command line */
- if (!Options.argv[1])
- {
- PROFILE_GetWineIniString( "programs", "Default", "",
- defProg, sizeof(defProg) );
- if (defProg[0]) tasks += exec_program( defProg );
- else if (!tasks && !startProg[0]) OPTIONS_Usage();
- }
- else
- {
- /* Load and run executables given on command line */
- for (i = 1; Options.argv[i]; i++)
+ MESSAGE( "%s: can't exec '%s': ", argv0, GetCommandLineA() );
+ switch (instance)
{
- tasks += exec_program( Options.argv[i] );
+ case 2: MESSAGE("file not found\n" ); break;
+ case 11: MESSAGE("invalid exe file\n" ); break;
+ default: MESSAGE("error=%d\n", instance ); break;
}
+ ExitProcess(instance);
}
- if (!tasks) ExitProcess( 0 );
/* Start message loop for desktop window */
@@ -104,28 +55,13 @@
*/
int main( int argc, char *argv[] )
{
- NE_MODULE *pModule;
+ BUILTIN32_DESCRIPTOR descriptor;
- /* Initialize everything */
- if (!MAIN_MainInit( argc, argv, FALSE )) return 1;
+ memset( &descriptor, 0, sizeof(descriptor) );
+ descriptor.filename = argv[0];
+ descriptor.dllentrypoint = initial_task;
+ BUILTIN32_RegisterDLL( &descriptor );
- if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) return 1;
- SIGNAL_Init(); /* reinitialize signal stack */
-
- /* Initialize KERNEL */
- if (!LoadLibraryA( "KERNEL32" )) return FALSE;
-
- /* Create initial task */
- if ( !(pModule = NE_GetPtr( GetModuleHandle16( "KERNEL" ) )) ) return 1;
- if ( !TASK_Create( pModule, FALSE ) ) return 1;
-
- /* Switch to initial task */
- PostEvent16( PROCESS_Current()->task );
- TASK_Reschedule();
-
- /* Switch stacks and jump to MAIN_EmulatorRun */
- CALL32_Init( &IF1632_CallLargeStack, MAIN_EmulatorRun, NtCurrentTeb()->stack_top );
-
- MESSAGE( "main: Should never happen: returned from CALL32_Init()\n" );
- return 0;
+ PROCESS_InitWine( argc, argv );
+ return 1; /* not reached */
}
diff --git a/msdos/int20.c b/msdos/int20.c
index a818acf..232ad65 100644
--- a/msdos/int20.c
+++ b/msdos/int20.c
@@ -16,5 +16,5 @@
*/
void WINAPI INT_Int20Handler( CONTEXT86 *context )
{
- ExitProcess( 0 );
+ ExitThread( 0 );
}
diff --git a/msdos/int21.c b/msdos/int21.c
index 0910fa5..8f1a94f 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -1146,7 +1146,7 @@
case 0x00: /* TERMINATE PROGRAM */
TRACE("TERMINATE PROGRAM\n");
- ExitProcess( 0 );
+ ExitThread( 0 );
break;
case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */
@@ -1841,7 +1841,7 @@
case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
TRACE("EXIT with return code %d\n",AL_reg(context));
- ExitProcess( AL_reg(context) );
+ ExitThread( AL_reg(context) );
break;
case 0x4d: /* GET RETURN CODE */
diff --git a/scheduler/client.c b/scheduler/client.c
index 4aa2a63..ffb33fc 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -504,7 +504,6 @@
close( fd );
if (teb->buffer == (void*)-1) server_perror( "mmap" );
first_req = teb->buffer;
- teb->process->server_pid = first_req->pid;
teb->pid = first_req->pid;
teb->tid = first_req->tid;
if (first_req->version != SERVER_PROTOCOL_VERSION)
diff --git a/scheduler/process.c b/scheduler/process.c
index 14e0864..dd55f7d 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -39,10 +39,10 @@
static ENVDB initial_envdb;
static STARTUPINFOA initial_startup;
+static char **main_exe_argv;
+static char *main_exe_name;
static HFILE main_exe_file = -1;
-static PDB *PROCESS_First;
-
/***********************************************************************
* PROCESS_IdToPDB
@@ -51,16 +51,7 @@
*/
PDB *PROCESS_IdToPDB( DWORD pid )
{
- PDB *pdb;
-
- if (!pid) return PROCESS_Current();
- pdb = PROCESS_First;
- while (pdb)
- {
- if ((DWORD)pdb->server_pid == pid) return pdb;
- pdb = pdb->next;
- }
- SetLastError( ERROR_INVALID_PARAMETER );
+ if (!pid || pid == GetCurrentProcessId()) return PROCESS_Current();
return NULL;
}
@@ -178,87 +169,11 @@
}
}
-/***********************************************************************
- * PROCESS_CreateEnvDB
- *
- * Create the env DB for a newly started process.
- */
-static BOOL PROCESS_CreateEnvDB(void)
-{
- struct init_process_request *req = get_req_buffer();
- PDB *pdb = PROCESS_Current();
- ENVDB *env_db = pdb->env_db;
- STARTUPINFOA *startup = env_db->startup_info;
-
- /* Retrieve startup info from the server */
-
- req->ldt_copy = ldt_copy;
- req->ldt_flags = ldt_flags_copy;
- req->ppid = getppid();
- if (server_call( REQ_INIT_PROCESS )) return FALSE;
- startup->dwFlags = req->start_flags;
- startup->wShowWindow = req->cmd_show;
- env_db->hStdin = startup->hStdInput = req->hstdin;
- env_db->hStdout = startup->hStdOutput = req->hstdout;
- env_db->hStderr = startup->hStdError = req->hstderr;
-
- return TRUE;
-}
-
-
-/***********************************************************************
- * PROCESS_FreePDB
- *
- * Free a PDB and all associated storage.
- */
-static void PROCESS_FreePDB( PDB *pdb )
-{
- PDB **pptr = &PROCESS_First;
-
- ENV_FreeEnvironment( pdb );
- while (*pptr && (*pptr != pdb)) pptr = &(*pptr)->next;
- if (*pptr) *pptr = pdb->next;
- HeapFree( GetProcessHeap(), 0, pdb );
-}
-
-
-/***********************************************************************
- * PROCESS_CreatePDB
- *
- * Allocate and fill a PDB structure.
- * Runs in the context of the parent process.
- */
-static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
-{
- PDB *pdb = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(PDB) + sizeof(ENVDB) + sizeof(STARTUPINFOA) );
-
- if (!pdb) return NULL;
- pdb->exit_code = STILL_ACTIVE;
- pdb->heap = GetProcessHeap();
- pdb->threads = 1;
- pdb->running_threads = 1;
- pdb->ring0_threads = 1;
- pdb->parent = parent;
- pdb->group = pdb;
- pdb->priority = 8; /* Normal */
- pdb->next = PROCESS_First;
- pdb->winver = 0xffff; /* to be determined */
- pdb->main_queue = INVALID_HANDLE_VALUE16;
- pdb->env_db = (ENVDB *)(pdb + 1);
- pdb->env_db->startup_info = (STARTUPINFOA *)(pdb->env_db + 1);
-
- InitializeCriticalSection( &pdb->env_db->section );
-
- PROCESS_First = pdb;
- return pdb;
-}
-
/***********************************************************************
* PROCESS_Init
*/
-BOOL PROCESS_Init( BOOL win32 )
+BOOL PROCESS_Init(void)
{
struct init_process_request *req;
PDB *pdb = PROCESS_Current();
@@ -274,13 +189,6 @@
pdb->winver = 0xffff; /* to be determined */
pdb->main_queue = INVALID_HANDLE_VALUE16;
initial_envdb.startup_info = &initial_startup;
- PROCESS_First = pdb;
-
- if (!win32)
- {
- pdb->flags = PDB32_WIN16_PROC;
- NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
- }
/* Setup the server connection */
NtCurrentTeb()->socket = CLIENT_InitServer();
@@ -293,12 +201,12 @@
req->ppid = getppid();
if (server_call( REQ_INIT_PROCESS )) return FALSE;
main_exe_file = req->exe_file;
+ if (req->filename[0]) main_exe_name = strdup( req->filename );
initial_startup.dwFlags = req->start_flags;
initial_startup.wShowWindow = req->cmd_show;
initial_envdb.hStdin = initial_startup.hStdInput = req->hstdin;
initial_envdb.hStdout = initial_startup.hStdOutput = req->hstdout;
initial_envdb.hStderr = initial_startup.hStdError = req->hstderr;
- initial_envdb.cmd_line = "";
/* Initialize signal handling */
if (!SIGNAL_Init()) return FALSE;
@@ -328,6 +236,9 @@
InitializeCriticalSection( &pdb->crit_section );
InitializeCriticalSection( &initial_envdb.section );
+ /* Initialize syslevel handling */
+ SYSLEVEL_Init();
+
return TRUE;
}
@@ -337,7 +248,7 @@
*
* Load system DLLs into the initial process (and initialize them)
*/
-static inline int load_system_dlls(void)
+static int load_system_dlls(void)
{
char driver[MAX_PATH];
@@ -350,55 +261,8 @@
return 0;
}
- if (!LoadLibraryA("GDI32.DLL")) return 0;
- if (!LoadLibrary16("GDI.EXE")) return 0;
- if (!LoadLibrary16("USER.EXE")) return 0;
if (!LoadLibraryA("USER32.DLL")) return 0;
- return 1;
-}
-
-
-/***********************************************************************
- * start_process
- *
- * Startup routine of a new Win32 process. Runs on the new process stack.
- */
-static void start_process(void)
-{
- struct init_process_done_request *req = get_req_buffer();
- int debugged;
- HMODULE16 hModule16;
- UINT cmdShow = SW_SHOWNORMAL;
- LPTHREAD_START_ROUTINE entry;
- PDB *pdb = PROCESS_Current();
- HMODULE main_module = pdb->exe_modref->module;
-
- /* Increment EXE refcount */
- pdb->exe_modref->refCount++;
-
- /* Retrieve entry point address */
- entry = (LPTHREAD_START_ROUTINE)RVA_PTR( main_module, OptionalHeader.AddressOfEntryPoint );
-
- /* Create 16-bit dummy module */
- if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, main_module )) < 32)
- ExitProcess( hModule16 );
-
- if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
- cmdShow = pdb->env_db->startup_info->wShowWindow;
- if (!TASK_Create( (NE_MODULE *)GlobalLock16( hModule16 ), cmdShow )) goto error;
-
- /* Signal the parent process to continue */
- req->module = (void *)main_module;
- req->entry = entry;
- server_call( REQ_INIT_PROCESS_DONE );
- debugged = req->debugged;
-
- if (pdb->flags & PDB32_CONSOLE_PROC) AllocConsole();
-
- /* Load the system dlls */
- if (!load_system_dlls()) goto error;
-
/* Get pointers to USER routines called by KERNEL */
THUNK_InitCallout();
@@ -413,67 +277,238 @@
* 16-bit stack must be set up, which it is only after TASK_Create
* in the case of a 16-bit process. Thus, we send the signal here.
*/
-
PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0 );
PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0 );
- EnterCriticalSection( &pdb->crit_section );
- PE_InitTls();
- MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 );
- LeaveCriticalSection( &pdb->crit_section );
-
- /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
- if (pdb->flags & PDB32_CONSOLE_PROC)
- PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
-
- TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
- if (debugged) DbgBreakPoint();
- /* FIXME: should use _PEB as parameter for NT 3.5 programs !
- * Dunno about other OSs */
- ExitProcess( entry(NULL) );
-
- error:
- ExitProcess( GetLastError() );
+ return 1;
}
/***********************************************************************
- * PROCESS_Init32
+ * build_command_line
*
- * Initialisation of a new Win32 process.
+ * Build the command-line of a process from the argv array.
*/
-void PROCESS_Init32( HFILE hFile, LPCSTR filename, LPCSTR cmd_line )
+static inline char *build_command_line( char **argv )
{
- HMODULE main_module;
- PDB *pdb = PROCESS_Current();
+ int len, quote;
+ char *cmdline, *p, **arg;
- pdb->env_db->cmd_line = HEAP_strdupA( GetProcessHeap(), 0, cmd_line );
-
- /* load main module */
- if ((main_module = PE_LoadImage( hFile, filename )) < 32)
- ExitProcess( main_module );
-#if 0
- if (PE_HEADER(main_module)->FileHeader.Characteristics & IMAGE_FILE_DLL)
+ for (arg = argv, len = 0; *arg; arg++) len += strlen(*arg) + 1;
+ if ((quote = (strchr( argv[0], ' ' ) != NULL))) len += 2;
+ if (!(p = cmdline = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
+ arg = argv;
+ if (quote)
{
- SetLastError( 20 ); /* FIXME: not the right error code */
- goto error;
+ *p++ = '\"';
+ strcpy( p, *arg );
+ p += strlen(p);
+ *p++ = '\"';
+ *p++ = ' ';
+ arg++;
}
-#endif
+ while (*arg)
+ {
+ strcpy( p, *arg );
+ p += strlen(p);
+ *p++ = ' ';
+ arg++;
+ }
+ if (p > cmdline) p--; /* remove last space */
+ *p = 0;
+ return cmdline;
+}
+
+
+/***********************************************************************
+ * start_process
+ *
+ * Startup routine of a new process. Runs on the new process stack.
+ */
+static void start_process(void)
+{
+ __TRY
+ {
+ struct init_process_done_request *req = get_req_buffer();
+ int debugged;
+ HMODULE16 hModule16;
+ UINT cmdShow = SW_SHOWNORMAL;
+ LPTHREAD_START_ROUTINE entry;
+ PDB *pdb = PROCESS_Current();
+ HMODULE module = pdb->exe_modref->module;
+
+ /* Increment EXE refcount */
+ pdb->exe_modref->refCount++;
+
+ /* build command line */
+ if (!(pdb->env_db->cmd_line = build_command_line( main_exe_argv ))) goto error;
+
+ /* Retrieve entry point address */
+ entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint );
+
+ /* Create 16-bit dummy module */
+ if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32)
+ ExitProcess( hModule16 );
+
+ if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
+ cmdShow = pdb->env_db->startup_info->wShowWindow;
+ if (!TASK_Create( (NE_MODULE *)GlobalLock16( hModule16 ), cmdShow,
+ NtCurrentTeb(), NULL, 0 ))
+ goto error;
+
+ if (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
+ pdb->flags |= PDB32_CONSOLE_PROC;
+
+ /* Signal the parent process to continue */
+ req->module = (void *)module;
+ req->entry = entry;
+ server_call( REQ_INIT_PROCESS_DONE );
+ debugged = req->debugged;
+
+ /* Load the system dlls */
+ if (!load_system_dlls()) goto error;
+
+ EnterCriticalSection( &pdb->crit_section );
+ PE_InitTls();
+ MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 );
+ LeaveCriticalSection( &pdb->crit_section );
+
+ /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
+ if (pdb->flags & PDB32_CONSOLE_PROC)
+ PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
+
+ TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
+ if (debugged) DbgBreakPoint();
+ /* FIXME: should use _PEB as parameter for NT 3.5 programs !
+ * Dunno about other OSs */
+ ExitThread( entry(NULL) );
+
+ error:
+ ExitProcess( GetLastError() );
+
+ }
+ __EXCEPT(UnhandledExceptionFilter)
+ {
+ TerminateThread( GetCurrentThread(), GetExceptionCode() );
+ }
+ __ENDTRY
+}
+
+
+/***********************************************************************
+ * PROCESS_Start
+ *
+ * Startup routine of a new Win32 process once the main module has been loaded.
+ */
+static void PROCESS_Start( HMODULE main_module, LPCSTR filename ) WINE_NORETURN;
+static void PROCESS_Start( HMODULE main_module, LPCSTR filename )
+{
+ /* load main module */
+ if (PE_HEADER(main_module)->FileHeader.Characteristics & IMAGE_FILE_DLL)
+ ExitProcess( ERROR_BAD_EXE_FORMAT );
/* Create 32-bit MODREF */
- if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
+ if (!PE_CreateModule( main_module, filename, 0, FALSE ))
+ ExitProcess( GetLastError() );
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(),
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
- goto error;
+ ExitProcess( GetLastError() );
SIGNAL_Init(); /* reinitialize signal stack */
/* switch to the new stack */
CALL32_Init( &IF1632_CallLargeStack, start_process, NtCurrentTeb()->stack_top );
+}
+
+
+/***********************************************************************
+ * PROCESS_InitWine
+ *
+ * Wine initialisation: load and start the main exe file.
+ */
+void PROCESS_InitWine( int argc, char *argv[] )
+{
+ DWORD type;
+
+ /* Initialize everything */
+ if (!MAIN_MainInit( argv )) exit(1);
+
+ main_exe_argv = ++argv; /* remove argv[0] (wine itself) */
+
+ if (!main_exe_name)
+ {
+ char buffer[MAX_PATH];
+ if (!argv[0]) OPTIONS_Usage();
+
+ /* open the exe file */
+ if (!SearchPathA( NULL, argv[0], ".exe", sizeof(buffer), buffer, NULL ) &&
+ !SearchPathA( NULL, argv[0], NULL, sizeof(buffer), buffer, NULL ))
+ {
+ MESSAGE( "%s: cannot find '%s'\n", argv0, argv[0] );
+ goto error;
+ }
+ if (!(main_exe_name = strdup(buffer)))
+ {
+ MESSAGE( "%s: out of memory\n", argv0 );
+ ExitProcess(1);
+ }
+ }
+
+ if (main_exe_file == INVALID_HANDLE_VALUE)
+ {
+ if ((main_exe_file = CreateFileA( main_exe_name, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, -1 )) == INVALID_HANDLE_VALUE)
+ {
+ MESSAGE( "%s: cannot open '%s'\n", argv0, main_exe_name );
+ goto error;
+ }
+ }
+
+ if (!MODULE_GetBinaryType( main_exe_file, main_exe_name, &type ))
+ {
+ MESSAGE( "%s: unrecognized executable '%s'\n", argv0, main_exe_name );
+ goto error;
+ }
+
+ switch (type)
+ {
+ case SCS_32BIT_BINARY:
+ {
+ HMODULE main_module = PE_LoadImage( main_exe_file, main_exe_name );
+ if (main_module) PROCESS_Start( main_module, main_exe_name );
+ }
+ break;
+
+ case SCS_WOW_BINARY:
+ {
+ HMODULE main_module;
+ LPCSTR filename;
+ /* create 32-bit module for main exe */
+ if (!(main_module = BUILTIN32_LoadExeModule( &filename ))) goto error;
+ NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
+ PROCESS_Current()->flags |= PDB32_WIN16_PROC;
+ SYSLEVEL_EnterWin16Lock();
+ PROCESS_Start( main_module, filename );
+ }
+ break;
+
+ case SCS_DOS_BINARY:
+ FIXME( "DOS binaries support is broken at the moment; feel free to fix it...\n" );
+ SetLastError( ERROR_BAD_FORMAT );
+ break;
+
+ case SCS_PIF_BINARY:
+ case SCS_POSIX_BINARY:
+ case SCS_OS216_BINARY:
+ default:
+ MESSAGE( "%s: unrecognized executable '%s'\n", argv0, main_exe_name );
+ SetLastError( ERROR_BAD_FORMAT );
+ break;
+ }
error:
ExitProcess( GetLastError() );
}
@@ -486,45 +521,17 @@
*/
void PROCESS_InitWinelib( int argc, char *argv[] )
{
- PDB *pdb;
HMODULE main_module;
LPCSTR filename;
- LPSTR cmdline, p;
- int i, len = 0;
- if (!MAIN_MainInit( argc, argv, TRUE )) exit(1);
- pdb = PROCESS_Current();
+ if (!MAIN_MainInit( argv )) exit(1);
- /* build command-line */
- for (i = 0; Options.argv[i]; i++) len += strlen(Options.argv[i]) + 1;
- if (!(cmdline = HeapAlloc( GetProcessHeap(), 0, len ))) goto error;
- for (p = cmdline, i = 0; Options.argv[i]; i++)
- {
- strcpy( p, Options.argv[i] );
- p += strlen(p);
- *p++ = ' ';
- }
- if (p > cmdline) p--;
- *p = 0;
- pdb->env_db->cmd_line = cmdline;
+ main_exe_argv = argv;
/* create 32-bit module for main exe */
- if ((main_module = BUILTIN32_LoadExeModule( &filename )) < 32 ) goto error;
+ if (!(main_module = BUILTIN32_LoadExeModule( &filename ))) ExitProcess( GetLastError() );
- /* Create 32-bit MODREF */
- if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
-
- /* allocate main thread stack */
- if (!THREAD_InitStack( NtCurrentTeb(),
- PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
- goto error;
-
- SIGNAL_Init(); /* reinitialize signal stack */
-
- /* switch to the new stack */
- CALL32_Init( &IF1632_CallLargeStack, start_process, NtCurrentTeb()->stack_top );
- error:
- ExitProcess( GetLastError() );
+ PROCESS_Start( main_module, filename );
}
@@ -533,13 +540,24 @@
*
* Build an argv array from a command-line.
* The command-line is modified to insert nulls.
+ * 'reserved' is the number of args to reserve before the first one.
*/
-static char **build_argv( char *cmdline, char *argv0 )
+static char **build_argv( char *cmdline, int reserved )
{
char **argv;
- int count = 1;
+ int count = reserved + 1;
char *p = cmdline;
+ /* if first word is quoted store it as a single arg */
+ if (*cmdline == '\"')
+ {
+ if ((p = strchr( cmdline + 1, '\"' )))
+ {
+ p++;
+ count++;
+ }
+ else p = cmdline;
+ }
while (*p)
{
while (*p && isspace(*p)) p++;
@@ -547,12 +565,20 @@
count++;
while (*p && !isspace(*p)) p++;
}
- if (argv0) count++;
+
if ((argv = malloc( count * sizeof(*argv) )))
{
- char **argvptr = argv;
- if (argv0) *argvptr++ = argv0;
+ char **argvptr = argv + reserved;
p = cmdline;
+ if (*cmdline == '\"')
+ {
+ if ((p = strchr( cmdline + 1, '\"' )))
+ {
+ *argvptr++ = cmdline + 1;
+ *p++ = 0;
+ }
+ else p = cmdline;
+ }
while (*p)
{
while (*p && isspace(*p)) *p++ = 0;
@@ -654,7 +680,8 @@
*
* Fork and exec a new Unix process, checking for errors.
*/
-static int fork_and_exec( const char *filename, const char *cmdline, const char *env )
+static int fork_and_exec( const char *filename, const char *cmdline,
+ const char *env, int use_wine )
{
int fd[2];
int pid, err;
@@ -667,10 +694,18 @@
fcntl( fd[1], F_SETFD, 1 ); /* set close on exec */
if (!(pid = fork())) /* child */
{
- char **argv = build_argv( (char *)cmdline, NULL );
+ char **argv = build_argv( (char *)cmdline, use_wine ? 2 : 0 );
char **envp = build_envp( env );
close( fd[0] );
- if (argv && envp) execve( filename, argv, envp );
+ if (argv && envp)
+ {
+ if (use_wine)
+ {
+ argv[1] = "--";
+ exec_wine_binary( argv, envp );
+ }
+ else execve( filename, argv, envp );
+ }
err = errno;
write( fd[1], &err, sizeof(err) );
_exit(1);
@@ -688,12 +723,16 @@
/***********************************************************************
- * PROCESS_CreateUnixProcess
+ * PROCESS_Create
+ *
+ * Create a new process. If hFile is a valid handle we have an exe
+ * file, and we exec a new copy of wine to load it; otherwise we
+ * simply exec the specified filename as a Unix process.
*/
-BOOL PROCESS_CreateUnixProcess( LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
- BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
- LPPROCESS_INFORMATION info )
+BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
+ LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
+ BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
+ LPPROCESS_INFORMATION info )
{
int pid;
const char *unixfilename = filename;
@@ -711,7 +750,7 @@
req->inherit_all = inherit;
req->create_flags = flags;
req->start_flags = startup->dwFlags;
- req->exe_file = -1;
+ req->exe_file = hFile;
if (startup->dwFlags & STARTF_USESTDHANDLES)
{
req->hstdin = startup->hStdInput;
@@ -731,7 +770,8 @@
/* fork and execute */
- pid = fork_and_exec( unixfilename, cmd_line, env ? env : GetEnvironmentStringsA() );
+ pid = fork_and_exec( unixfilename, cmd_line,
+ env ? env : GetEnvironmentStringsA(), (hFile != -1) );
wait_req->cancel = (pid == -1);
wait_req->pinherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
@@ -774,271 +814,6 @@
/***********************************************************************
- * PROCESS_Start
- *
- * Startup routine of a new process. Called in the context of the new process.
- */
-void PROCESS_Start(void)
-{
- struct init_process_done_request *req = get_req_buffer();
- int debugged;
- UINT cmdShow = SW_SHOWNORMAL;
- LPTHREAD_START_ROUTINE entry = NULL;
- PDB *pdb = PROCESS_Current();
- NE_MODULE *pModule = NE_GetPtr( pdb->module );
- LPCSTR filename = ((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName;
-
- /* Get process type */
- enum { PROC_DOS, PROC_WIN16, PROC_WIN32 } type;
- if ( pdb->flags & PDB32_DOS_PROC )
- type = PROC_DOS;
- else if ( pdb->flags & PDB32_WIN16_PROC )
- type = PROC_WIN16;
- else
- type = PROC_WIN32;
-
- /* Initialize the critical section */
- InitializeCriticalSection( &pdb->crit_section );
-
- /* Create the environment db */
- if (!PROCESS_CreateEnvDB()) goto error;
-
- /* Create a task for this process */
- if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
- cmdShow = pdb->env_db->startup_info->wShowWindow;
- if (!TASK_Create( pModule, cmdShow ))
- goto error;
-
- /* Load all process modules */
- switch ( type )
- {
- case PROC_WIN16:
- if ( !NE_InitProcess( pModule ) )
- goto error;
- break;
-
- case PROC_WIN32:
- /* Create 32-bit MODREF */
- if ( !PE_CreateModule( pModule->module32, filename, 0, FALSE ) )
- goto error;
-
- /* Increment EXE refcount */
- assert( pdb->exe_modref );
- pdb->exe_modref->refCount++;
-
- /* Retrieve entry point address */
- entry = (LPTHREAD_START_ROUTINE)RVA_PTR(pModule->module32,
- OptionalHeader.AddressOfEntryPoint);
- break;
-
- case PROC_DOS:
- /* FIXME: move DOS startup code here */
- break;
- }
-
-
- /* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
- * context of the parent process. Actually, the USER signal proc
- * doesn't really care about that, but it *does* require that the
- * startup parameters are correctly set up, so that GetProcessDword
- * works. Furthermore, before calling the USER signal proc the
- * 16-bit stack must be set up, which it is only after TASK_Create
- * in the case of a 16-bit process. Thus, we send the signal here.
- */
-
- PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0 );
- PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
- PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
- PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0 );
-
- /* Signal the parent process to continue */
- req->module = (void *)pModule->module32;
- req->entry = entry;
- server_call( REQ_INIT_PROCESS_DONE );
- debugged = req->debugged;
-
- if ( (pdb->flags & PDB32_CONSOLE_PROC) || (pdb->flags & PDB32_DOS_PROC) )
- AllocConsole();
-
- /* Perform Win32 specific process initialization */
- if ( type == PROC_WIN32 )
- {
- EnterCriticalSection( &pdb->crit_section );
-
- PE_InitTls();
- MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 );
-
- LeaveCriticalSection( &pdb->crit_section );
- }
-
- /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
- if ( type != PROC_WIN16 && (pdb->flags & PDB32_CONSOLE_PROC))
- PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
-
- switch ( type )
- {
- case PROC_DOS:
- TRACE_(relay)( "Starting DOS process\n" );
- DOSVM_Enter( NULL );
- ERR_(relay)( "DOSVM_Enter returned; should not happen!\n" );
- ExitProcess( 0 );
-
- case PROC_WIN16:
- TRACE_(relay)( "Starting Win16 process\n" );
- TASK_CallToStart();
- ERR_(relay)( "TASK_CallToStart returned; should not happen!\n" );
- ExitProcess( 0 );
-
- case PROC_WIN32:
- TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
- if (debugged) DbgBreakPoint();
- /* FIXME: should use _PEB as parameter for NT 3.5 programs !
- * Dunno about other OSs */
- ExitProcess( entry(NULL) );
- }
-
- error:
- ExitProcess( GetLastError() );
-}
-
-
-/***********************************************************************
- * PROCESS_Create
- *
- * Create a new process database and associated info.
- */
-PDB *PROCESS_Create( NE_MODULE *pModule, HFILE hFile, LPCSTR cmd_line, LPCSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
- BOOL inherit, DWORD flags, STARTUPINFOA *startup,
- PROCESS_INFORMATION *info )
-{
- HANDLE handles[2], load_done_evt = -1;
- DWORD exitcode, size;
- BOOL alloc_stack16;
- int fd = -1;
- struct new_process_request *req = get_req_buffer();
- struct wait_process_request *wait_req = get_req_buffer();
- TEB *teb = NULL;
- PDB *parent = PROCESS_Current();
- PDB *pdb = PROCESS_CreatePDB( parent, inherit );
-
- if (!pdb) return NULL;
- info->hThread = info->hProcess = INVALID_HANDLE_VALUE;
-
- if (!(pdb->env_db->cmd_line = HEAP_strdupA( GetProcessHeap(), 0, cmd_line ))) goto error;
- if (!ENV_InheritEnvironment( pdb, env ? env : GetEnvironmentStringsA() )) goto error;
-
- /* Create the process on the server side */
-
- req->inherit_all = 2 /*inherit*/; /* HACK! */
- req->create_flags = flags;
- req->start_flags = startup->dwFlags;
- req->exe_file = hFile;
- if (startup->dwFlags & STARTF_USESTDHANDLES)
- {
- req->hstdin = startup->hStdInput;
- req->hstdout = startup->hStdOutput;
- req->hstderr = startup->hStdError;
- }
- else
- {
- req->hstdin = GetStdHandle( STD_INPUT_HANDLE );
- req->hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
- req->hstderr = GetStdHandle( STD_ERROR_HANDLE );
- }
- req->cmd_show = startup->wShowWindow;
- req->alloc_fd = 1;
- req->filename[0] = 0;
- if (server_call_fd( REQ_NEW_PROCESS, -1, &fd )) goto error;
-
- if (pModule->module32) /* Win32 process */
- {
- IMAGE_OPTIONAL_HEADER *header = &PE_HEADER(pModule->module32)->OptionalHeader;
- size = header->SizeOfStackReserve;
- if (header->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
- pdb->flags |= PDB32_CONSOLE_PROC;
- alloc_stack16 = TRUE;
- }
- else if (!pModule->dos_image) /* Win16 process */
- {
- alloc_stack16 = FALSE;
- size = 0;
- pdb->flags |= PDB32_WIN16_PROC;
- }
- else /* DOS process */
- {
- alloc_stack16 = FALSE;
- size = 0;
- pdb->flags |= PDB32_DOS_PROC;
- }
-
- /* Create the main thread */
-
- if ((teb = THREAD_Create( pdb, fd, size, alloc_stack16 )))
- {
- teb->startup = PROCESS_Start;
- fd = -1; /* don't close it */
-
- /* Pass module to new process (FIXME: hack) */
- pdb->module = pModule->self;
- SYSDEPS_SpawnThread( teb );
- }
-
- wait_req->cancel = !teb;
- wait_req->pinherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
- wait_req->tinherit = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle);
- wait_req->timeout = 2000;
- if (server_call( REQ_WAIT_PROCESS ) || !teb) goto error;
- info->dwProcessId = (DWORD)wait_req->pid;
- info->dwThreadId = (DWORD)wait_req->tid;
- info->hProcess = wait_req->phandle;
- info->hThread = wait_req->thandle;
- load_done_evt = wait_req->event;
-
- /* Wait until process is initialized (or initialization failed) */
- handles[0] = info->hProcess;
- handles[1] = load_done_evt;
-
- switch ( WaitForMultipleObjects( 2, handles, FALSE, INFINITE ) )
- {
- default:
- ERR( "WaitForMultipleObjects failed\n" );
- break;
-
- case 0:
- /* Child initialization code returns error condition as exitcode */
- if ( GetExitCodeProcess( info->hProcess, &exitcode ) )
- SetLastError( exitcode );
- goto error;
-
- case 1:
- /* Get 16-bit task up and running */
- if ( pdb->flags & PDB32_WIN16_PROC )
- {
- /* Post event to start the task */
- PostEvent16( pdb->task );
-
- /* If we ourselves are a 16-bit task, we Yield() directly. */
- if ( parent->flags & PDB32_WIN16_PROC )
- OldYield16();
- }
- break;
- }
-
- CloseHandle( load_done_evt );
- return pdb;
-
-error:
- if (load_done_evt != -1) CloseHandle( load_done_evt );
- if (info->hThread != INVALID_HANDLE_VALUE) CloseHandle( info->hThread );
- if (info->hProcess != INVALID_HANDLE_VALUE) CloseHandle( info->hProcess );
- PROCESS_FreePDB( pdb );
- if (fd != -1) close( fd );
- return NULL;
-}
-
-
-/***********************************************************************
* ExitProcess (KERNEL32.100)
*/
void WINAPI ExitProcess( DWORD status )
@@ -1046,15 +821,11 @@
struct terminate_process_request *req = get_req_buffer();
MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
- TASK_KillTask( 0 );
-
/* send the exit code to the server */
req->handle = GetCurrentProcess();
req->exit_code = status;
server_call( REQ_TERMINATE_PROCESS );
- /* FIXME: need separate address spaces for that */
- /* exit( status ); */
- SYSDEPS_ExitThread( status );
+ exit( status );
}
/***********************************************************************
@@ -1091,23 +862,27 @@
DWORD x, y;
TRACE_(win32)("(%ld, %d)\n", dwProcessID, offset );
- if ( !process ) return 0;
+ if ( !process )
+ {
+ ERR("%d: process %lx not accessible\n", offset, dwProcessID);
+ return 0;
+ }
switch ( offset )
{
case GPD_APP_COMPAT_FLAGS:
- pTask = (TDB *)GlobalLock16( process->task );
+ pTask = (TDB *)GlobalLock16( GetCurrentTask() );
return pTask? pTask->compat_flags : 0;
case GPD_LOAD_DONE_EVENT:
return process->load_done_evt;
case GPD_HINSTANCE16:
- pTask = (TDB *)GlobalLock16( process->task );
+ pTask = (TDB *)GlobalLock16( GetCurrentTask() );
return pTask? pTask->hInstance : 0;
case GPD_WINDOWS_VERSION:
- pTask = (TDB *)GlobalLock16( process->task );
+ pTask = (TDB *)GlobalLock16( GetCurrentTask() );
return pTask? pTask->version : 0;
case GPD_THDB:
@@ -1144,7 +919,7 @@
return process->env_db->startup_info->dwFlags;
case GPD_PARENT:
- return process->parent? (DWORD)process->parent->server_pid : 0;
+ return 0;
case GPD_FLAGS:
return process->flags;
@@ -1167,7 +942,11 @@
PDB *process = PROCESS_IdToPDB( dwProcessID );
TRACE_(win32)("(%ld, %d)\n", dwProcessID, offset );
- if ( !process ) return;
+ if ( !process )
+ {
+ ERR("%d: process %lx not accessible\n", offset, dwProcessID);
+ return;
+ }
switch ( offset )
{
diff --git a/scheduler/thread.c b/scheduler/thread.c
index f9d7105..40cf44c 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -229,14 +229,14 @@
* THREAD_Create
*
*/
-TEB *THREAD_Create( PDB *pdb, int fd, DWORD stack_size, BOOL alloc_stack16 )
+TEB *THREAD_Create( int fd, DWORD stack_size, BOOL alloc_stack16 )
{
TEB *teb;
if ((teb = THREAD_InitStack( NULL, stack_size, alloc_stack16 )))
{
- teb->tibflags = (pdb->flags & PDB32_WIN16_PROC) ? 0 : TEBF_WIN32;
- teb->process = pdb;
+ teb->tibflags = (PROCESS_Current()->flags & PDB32_WIN16_PROC) ? 0 : TEBF_WIN32;
+ teb->process = PROCESS_Current();
teb->socket = fd;
fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
TRACE("(%p) succeeded\n", teb);
@@ -287,7 +287,7 @@
handle = req->handle;
tid = req->tid;
- if (!(teb = THREAD_Create( PROCESS_Current(), socket, stack, TRUE )))
+ if (!(teb = THREAD_Create( socket, stack, TRUE )))
{
close( socket );
return 0;
@@ -296,6 +296,7 @@
teb->entry_point = start;
teb->entry_arg = param;
teb->startup = THREAD_Start;
+ teb->htask16 = GetCurrentTask();
if (id) *id = (DWORD)tid;
if (SYSDEPS_SpawnThread( teb ) == -1)
{
@@ -347,13 +348,12 @@
if (req->last)
{
MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
- TASK_KillTask( 0 );
exit( code );
}
else
{
MODULE_DllThreadDetach( NULL );
- PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );
+ if (!(NtCurrentTeb()->tibflags & TEBF_WIN32)) TASK_KillTask( 0 );
SYSDEPS_ExitThread( code );
}
}
diff --git a/win32/except.c b/win32/except.c
index 31966b3..d83521e 100644
--- a/win32/except.c
+++ b/win32/except.c
@@ -132,7 +132,7 @@
TRACE("Starting debugger (fmt=%s)\n", format);
hEvent = ConvertToGlobalHandle(CreateEventA(NULL, FALSE, FALSE, NULL));
- sprintf(buffer, format, (unsigned long)pdb->server_pid, hEvent);
+ sprintf(buffer, format, GetCurrentProcessId(), hEvent);
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW;
diff --git a/windows/nonclient.c b/windows/nonclient.c
index a2bf12d..8a7b6c5 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -2225,6 +2225,13 @@
((msg.message == WM_KEYDOWN) &&
((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
+ if (msg.message == WM_PAINT)
+ {
+ if(!iconic) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
+ UpdateWindow( msg.hwnd );
+ if(!iconic) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
+ continue;
+ }
if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
continue; /* We are not interested in other messages */
diff --git a/windows/queue.c b/windows/queue.c
index 34249e1..67fabc5 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -404,10 +404,10 @@
WARN_(msg)("Bad queue handle %04x\n", hQueue );
return;
}
- if (!GetModuleName16( queue->teb->process->task, module, sizeof(module )))
+ if (!GetModuleName16( queue->teb->htask16, module, sizeof(module )))
strcpy( module, "???" );
DPRINTF( "%04x %4d %p %04x %s\n", hQueue,queue->msgCount,
- queue->teb, queue->teb->process->task, module );
+ queue->teb, queue->teb->htask16, module );
hQueue = queue->next;
QUEUE_Unlock( queue );
}
@@ -640,7 +640,7 @@
if ( THREAD_IsWin16( queue->teb ) )
{
int iWndsLock = WIN_SuspendWndsLock();
- PostEvent16( queue->teb->process->task );
+ PostEvent16( queue->teb->htask16 );
WIN_RestoreWndsLock( iWndsLock );
}
else
@@ -1274,7 +1274,7 @@
if (queue)
{
- hTask = queue->teb->process->task;
+ hTask = queue->teb->htask16;
QUEUE_Unlock( queue );
}
diff --git a/windows/user.c b/windows/user.c
index 697ee08..c427c17 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -271,7 +271,7 @@
break;
case USIG_PROCESS_DESTROY:
- hInst = GetProcessDword( dwThreadOrProcessID, GPD_HINSTANCE16 );
+ hInst = ((TDB *)GlobalLock16( GetCurrentTask() ))->hInstance;
USER_AppExit( hInst );
pdb = PROCESS_Current();