Moved the functionality of starting Win16 and DOS programs from the
common process startup into a separate winevdm application.
This commit is contained in:
parent
8f6727c57d
commit
fedc411743
|
@ -1523,6 +1523,7 @@ programs/winedbg/Makefile
|
|||
programs/winefile/Makefile
|
||||
programs/winemine/Makefile
|
||||
programs/winepath/Makefile
|
||||
programs/winevdm/Makefile
|
||||
programs/winhelp/Makefile
|
||||
programs/winver/Makefile
|
||||
server/Makefile
|
||||
|
|
|
@ -105,7 +105,7 @@ static WORD init_cs,init_ip,init_ss,init_sp;
|
|||
static HANDLE dosvm_thread, loop_thread;
|
||||
static DWORD dosvm_tid, loop_tid;
|
||||
|
||||
static void MZ_Launch(void);
|
||||
static void MZ_Launch( LPCSTR cmdline );
|
||||
static BOOL MZ_InitTask(void);
|
||||
|
||||
static void MZ_CreatePSP( LPVOID lpPSP, WORD env, WORD par )
|
||||
|
@ -124,7 +124,7 @@ static void MZ_CreatePSP( LPVOID lpPSP, WORD env, WORD par )
|
|||
/* FIXME: more PSP stuff */
|
||||
}
|
||||
|
||||
static void MZ_FillPSP( LPVOID lpPSP, LPBYTE cmdline, int length )
|
||||
static void MZ_FillPSP( LPVOID lpPSP, LPCSTR cmdline, int length )
|
||||
{
|
||||
PDB16 *psp = lpPSP;
|
||||
|
||||
|
@ -346,15 +346,18 @@ load_error:
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LoadDosExe (WINEDOS.@)
|
||||
* wine_load_dos_exe (WINEDOS.@)
|
||||
*
|
||||
* Called from Wine loader when a new real-mode DOS process is started.
|
||||
* Called from WineVDM when a new real-mode DOS process is started.
|
||||
* Loads DOS program into memory and executes the program.
|
||||
*/
|
||||
void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile )
|
||||
void WINAPI wine_load_dos_exe( LPCSTR filename, LPCSTR cmdline )
|
||||
{
|
||||
HANDLE hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
if (hFile == INVALID_HANDLE_VALUE) return;
|
||||
DOSVM_isdosexe = TRUE;
|
||||
if (MZ_DoLoadImage( hFile, filename, NULL )) MZ_Launch();
|
||||
if (MZ_DoLoadImage( hFile, filename, NULL )) MZ_Launch( cmdline );
|
||||
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -557,11 +560,10 @@ static BOOL MZ_InitTask(void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void MZ_Launch(void)
|
||||
static void MZ_Launch( LPCSTR cmdline )
|
||||
{
|
||||
TDB *pTask = GlobalLock16( GetCurrentTask() );
|
||||
BYTE *psp_start = PTR_REAL_TO_LIN( DOSVM_psp, 0 );
|
||||
LPSTR cmdline = GetCommandLineA();
|
||||
DWORD rv;
|
||||
SYSLEVEL *lock;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@ stdcall LoadDosExe(str long) MZ_LoadImage
|
||||
@ stdcall wine_load_dos_exe(str str)
|
||||
|
||||
@ stdcall EmulateInterruptPM(ptr long) DOSVM_EmulateInterruptPM
|
||||
@ stdcall CallBuiltinHandler(ptr long) DOSVM_CallBuiltinHandler
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "winnt.h"
|
||||
|
||||
typedef struct {
|
||||
void (WINAPI *LoadDosExe)( LPCSTR filename, HANDLE hFile );
|
||||
void (WINAPI *EmulateInterruptPM)( CONTEXT86 *context, BYTE intnum );
|
||||
void (WINAPI *CallBuiltinHandler)( CONTEXT86 *context, BYTE intnum );
|
||||
|
||||
|
|
|
@ -414,6 +414,21 @@ void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, int
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* wine_init
|
||||
*
|
||||
* Main Wine initialisation.
|
||||
*/
|
||||
void wine_init( int argc, char *argv[], char *error, int error_size )
|
||||
{
|
||||
void *ntdll;
|
||||
void (*init_func)(int, char **);
|
||||
|
||||
if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0 ))) return;
|
||||
if (!(init_func = wine_dlsym( ntdll, "__wine_process_init", error, error_size ))) return;
|
||||
init_func( argc, argv );
|
||||
}
|
||||
|
||||
|
||||
#if defined(__svr4__) || defined(__NetBSD__)
|
||||
/***********************************************************************
|
||||
|
|
|
@ -1107,44 +1107,6 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* NE_StartMain
|
||||
*
|
||||
* Start the main NE task.
|
||||
*/
|
||||
HINSTANCE16 NE_StartMain( LPCSTR name, HANDLE file )
|
||||
{
|
||||
STARTUPINFOA info;
|
||||
HMODULE16 hModule;
|
||||
NE_MODULE *pModule;
|
||||
INT len;
|
||||
LPSTR pCmdLine, cmdline = GetCommandLineA();
|
||||
|
||||
if ((hModule = NE_LoadExeHeader( file, name )) < 32) return hModule;
|
||||
|
||||
if (!(pModule = NE_GetPtr( hModule ))) return (HINSTANCE16)11;
|
||||
if (pModule->flags & NE_FFLAGS_LIBMODULE)
|
||||
{
|
||||
MESSAGE( "%s is not a valid Win16 executable\n", name );
|
||||
ExitProcess( ERROR_BAD_EXE_FORMAT );
|
||||
}
|
||||
|
||||
while (*cmdline && *cmdline != ' ') cmdline++;
|
||||
if (*cmdline) cmdline++;
|
||||
len = strlen(cmdline);
|
||||
pCmdLine = HeapAlloc(GetProcessHeap(), 0, len+2);
|
||||
if (pCmdLine)
|
||||
{
|
||||
strcpy(pCmdLine+1, cmdline);
|
||||
*pCmdLine = len;
|
||||
}
|
||||
GetStartupInfoA( &info );
|
||||
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = 1;
|
||||
|
||||
return NE_CreateThread( pModule, info.wShowWindow, pCmdLine );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* NE_StartTask
|
||||
*
|
||||
|
|
|
@ -720,15 +720,9 @@ void WINAPI DirectedYield16( HTASK16 hTask )
|
|||
{
|
||||
TDB *pCurTask = TASK_GetCurrent();
|
||||
|
||||
if (!pCurTask) OldYield16();
|
||||
if (!pCurTask || (pCurTask->flags & TDBF_WIN32)) OldYield16();
|
||||
else
|
||||
{
|
||||
if (pCurTask->flags & TDBF_WIN32)
|
||||
{
|
||||
FIXME("called for Win32 thread (%04x)!\n", NtCurrentTeb()->teb_sel);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("%04x: DirectedYield(%04x)\n", pCurTask->hSelf, hTask );
|
||||
pCurTask->hYieldTo = hTask;
|
||||
OldYield16();
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
Makefile
|
||||
wine
|
||||
wine.spec.c
|
||||
|
|
|
@ -3,8 +3,6 @@ TOPOBJDIR = ..
|
|||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = wine
|
||||
IMPORTS = ntdll
|
||||
LDIMPORTS = ntdll.dll
|
||||
|
||||
C_SRCS = \
|
||||
main.c
|
||||
|
@ -13,14 +11,10 @@ all: $(MODULE)
|
|||
|
||||
@MAKE_RULES@
|
||||
|
||||
ALL_OBJS = $(MODULE).spec.o $(OBJS)
|
||||
LDEXECFLAGS = @LDEXECFLAGS@
|
||||
|
||||
$(MODULE): $(ALL_OBJS)
|
||||
$(CC) -o $@ $(LDEXECFLAGS) $(ALL_OBJS) -L$(DLLDIR) $(LDIMPORTS:%=-l%) $(LIBWINE) $(LIBUNICODE) $(LIBPORT) $(LIBS) $(LDFLAGS)
|
||||
|
||||
$(MODULE).spec.c: $(WINEBUILD)
|
||||
$(WINEBUILD) $(DEFS) -o $@ --exe $(MODULE) --exe-mode gui --entry wine_initial_task -L$(DLLDIR) $(IMPORTS:%=-l%)
|
||||
$(MODULE): $(OBJS)
|
||||
$(CC) -o $@ $(LDEXECFLAGS) $(OBJS) $(LIBWINE) $(LIBPORT) $(LDFLAGS)
|
||||
|
||||
install:: $(MODULE)
|
||||
$(MKINSTALLDIRS) $(bindir)
|
||||
|
|
|
@ -18,87 +18,18 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "winbase.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#include "miscemu.h"
|
||||
#include "callback.h"
|
||||
#include "options.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
static char main_exe_name[MAX_PATH];
|
||||
static HANDLE main_exe_file;
|
||||
|
||||
static BOOL (WINAPI *pGetMessageA)(LPMSG,HWND,UINT,UINT);
|
||||
static BOOL (WINAPI *pTranslateMessage)(const MSG*);
|
||||
static LONG (WINAPI *pDispatchMessageA)(const MSG*);
|
||||
|
||||
extern void DECLSPEC_NORETURN PROCESS_InitWine(
|
||||
int argc, char *argv[], LPSTR win16_exe_name,
|
||||
HANDLE *win16_exe_file );
|
||||
extern HINSTANCE16 NE_StartMain( LPCSTR name, HANDLE file );
|
||||
|
||||
/***********************************************************************
|
||||
* Main loop of initial task
|
||||
*/
|
||||
int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT show )
|
||||
{
|
||||
MSG msg;
|
||||
HINSTANCE16 instance;
|
||||
HMODULE user32;
|
||||
|
||||
/* some programs assume mmsystem is always present */
|
||||
LoadLibrary16( "mmsystem.dll" );
|
||||
|
||||
if ((instance = NE_StartMain( main_exe_name, main_exe_file )) < 32)
|
||||
{
|
||||
if (instance == 11) /* try DOS format */
|
||||
{
|
||||
if (DPMI_LoadDosSystem())
|
||||
Dosvm.LoadDosExe( main_exe_name, main_exe_file );
|
||||
/* if we get back here it failed */
|
||||
instance = GetLastError();
|
||||
}
|
||||
|
||||
WINE_MESSAGE( "%s: can't exec '%s': ", argv0, GetCommandLineA() );
|
||||
switch (instance)
|
||||
{
|
||||
case 2: WINE_MESSAGE("file not found\n" ); break;
|
||||
case 11: WINE_MESSAGE("invalid exe file\n" ); break;
|
||||
default: WINE_MESSAGE("error=%d\n", instance ); break;
|
||||
}
|
||||
ExitProcess(instance);
|
||||
}
|
||||
CloseHandle( main_exe_file ); /* avoid file sharing problems */
|
||||
|
||||
/* Start message loop for desktop window */
|
||||
|
||||
if (!(user32 = LoadLibraryA( "user32.dll" )))
|
||||
{
|
||||
WINE_MESSAGE( "Cannot load user32.dll\n" );
|
||||
ExitProcess( GetLastError() );
|
||||
}
|
||||
pGetMessageA = (void *)GetProcAddress( user32, "GetMessageA" );
|
||||
pTranslateMessage = (void *)GetProcAddress( user32, "TranslateMessage" );
|
||||
pDispatchMessageA = (void *)GetProcAddress( user32, "DispatchMessageA" );
|
||||
|
||||
while ( GetNumTasks16() > 1 && pGetMessageA( &msg, 0, 0, 0 ) )
|
||||
{
|
||||
pTranslateMessage( &msg );
|
||||
pDispatchMessageA( &msg );
|
||||
}
|
||||
|
||||
ExitProcess( 0 );
|
||||
}
|
||||
#include <stdio.h>
|
||||
|
||||
extern void wine_init( int argc, char *argv[], char *error, int error_size );
|
||||
|
||||
/**********************************************************************
|
||||
* main
|
||||
*/
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
PROCESS_InitWine( argc, argv, main_exe_name, &main_exe_file );
|
||||
return 1; /* not reached */
|
||||
char error[1024];
|
||||
|
||||
wine_init( argc, argv, error, sizeof(error) );
|
||||
fprintf( stderr, "wine: failed to initialize: %s\n", error );
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ BOOL DPMI_LoadDosSystem(void)
|
|||
}
|
||||
#define GET_ADDR(func) Dosvm.func = (void *)GetProcAddress(DosModule, #func);
|
||||
|
||||
GET_ADDR(LoadDosExe);
|
||||
GET_ADDR(SetTimer);
|
||||
GET_ADDR(GetTimer);
|
||||
GET_ADDR(inport);
|
||||
|
|
|
@ -30,6 +30,7 @@ SUBDIRS = \
|
|||
winefile \
|
||||
winemine \
|
||||
winepath \
|
||||
winevdm \
|
||||
winhelp \
|
||||
winver
|
||||
|
||||
|
@ -82,6 +83,7 @@ SYMLINKS = \
|
|||
wcmd.exe \
|
||||
wineconsole.exe \
|
||||
winedbg.exe \
|
||||
winevdm.exe \
|
||||
winhelp.exe
|
||||
|
||||
@MAKE_RULES@
|
||||
|
@ -139,12 +141,16 @@ wineconsole.exe$(DLLEXT): wineconsole/wineconsole.exe$(DLLEXT)
|
|||
winedbg.exe$(DLLEXT): winedbg/winedbg.exe$(DLLEXT)
|
||||
$(RM) $@ && $(LN_S) winedbg/winedbg.exe$(DLLEXT) $@
|
||||
|
||||
winevdm.exe$(DLLEXT): winevdm/winevdm.exe$(DLLEXT)
|
||||
$(RM) $@ && $(LN_S) winevdm/winevdm.exe$(DLLEXT) $@
|
||||
|
||||
winhelp.exe$(DLLEXT): winhelp/winhelp.exe$(DLLEXT)
|
||||
$(RM) $@ && $(LN_S) winhelp/winhelp.exe$(DLLEXT) $@
|
||||
|
||||
wcmd/wcmd.exe$(DLLEXT): wcmd
|
||||
wineconsole/wineconsole.exe$(DLLEXT): wineconsole
|
||||
winedbg/winedbg.exe$(DLLEXT): winedbg
|
||||
winevdm/winevdm.exe$(DLLEXT): winevdm
|
||||
winhelp/winhelp.exe$(DLLEXT): winhelp
|
||||
|
||||
### Dependencies:
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
winevdm.exe.dbg.c
|
||||
winevdm.exe.spec.c
|
|
@ -0,0 +1,14 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = winevdm.exe
|
||||
APPMODE = cui
|
||||
IMPORTS = winedos kernel32
|
||||
|
||||
C_SRCS = \
|
||||
winevdm.c
|
||||
|
||||
@MAKE_PROG_RULES@
|
||||
|
||||
### Dependencies:
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Wine virtual DOS machine
|
||||
*
|
||||
* Copyright 2003 Alexandre Julliard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "winbase.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winevdm);
|
||||
|
||||
extern void WINAPI wine_load_dos_exe( LPCSTR filename, LPCSTR cmdline );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_command_line
|
||||
*
|
||||
* Build the command line of a process from the argv array.
|
||||
* Copied from ENV_BuildCommandLine.
|
||||
*/
|
||||
static char *build_command_line( char **argv )
|
||||
{
|
||||
int len;
|
||||
char *p, **arg, *cmd_line;
|
||||
|
||||
len = 0;
|
||||
for (arg = argv; *arg; arg++)
|
||||
{
|
||||
int has_space,bcount;
|
||||
char* a;
|
||||
|
||||
has_space=0;
|
||||
bcount=0;
|
||||
a=*arg;
|
||||
while (*a!='\0') {
|
||||
if (*a=='\\') {
|
||||
bcount++;
|
||||
} else {
|
||||
if (*a==' ' || *a=='\t') {
|
||||
has_space=1;
|
||||
} else if (*a=='"') {
|
||||
/* doubling of '\' preceeding a '"',
|
||||
* plus escaping of said '"'
|
||||
*/
|
||||
len+=2*bcount+1;
|
||||
}
|
||||
bcount=0;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
len+=(a-*arg)+1 /* for the separating space */;
|
||||
if (has_space)
|
||||
len+=2; /* for the quotes */
|
||||
}
|
||||
|
||||
if (!(cmd_line = HeapAlloc( GetProcessHeap(), 0, len + 1 ))) return NULL;
|
||||
|
||||
p = cmd_line;
|
||||
*p++ = len;
|
||||
for (arg = argv; *arg; arg++)
|
||||
{
|
||||
int has_space,has_quote;
|
||||
char* a;
|
||||
|
||||
/* Check for quotes and spaces in this argument */
|
||||
has_space=has_quote=0;
|
||||
a=*arg;
|
||||
while (*a!='\0') {
|
||||
if (*a==' ' || *a=='\t') {
|
||||
has_space=1;
|
||||
if (has_quote)
|
||||
break;
|
||||
} else if (*a=='"') {
|
||||
has_quote=1;
|
||||
if (has_space)
|
||||
break;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
|
||||
/* Now transfer it to the command line */
|
||||
if (has_space)
|
||||
*p++='"';
|
||||
if (has_quote) {
|
||||
int bcount;
|
||||
char* a;
|
||||
|
||||
bcount=0;
|
||||
a=*arg;
|
||||
while (*a!='\0') {
|
||||
if (*a=='\\') {
|
||||
*p++=*a;
|
||||
bcount++;
|
||||
} else {
|
||||
if (*a=='"') {
|
||||
int i;
|
||||
|
||||
/* Double all the '\\' preceeding this '"', plus one */
|
||||
for (i=0;i<=bcount;i++)
|
||||
*p++='\\';
|
||||
*p++='"';
|
||||
} else {
|
||||
*p++=*a;
|
||||
}
|
||||
bcount=0;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
} else {
|
||||
strcpy(p,*arg);
|
||||
p+=strlen(*arg);
|
||||
}
|
||||
if (has_space)
|
||||
*p++='"';
|
||||
*p++=' ';
|
||||
}
|
||||
if (p > cmd_line) p--; /* remove last space */
|
||||
*p = '\0';
|
||||
return cmd_line;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* usage
|
||||
*/
|
||||
static void usage(void)
|
||||
{
|
||||
WINE_MESSAGE( "Usage: winevdm.exe [--app-name app.exe] command line\n\n" );
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* main
|
||||
*/
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
DWORD count;
|
||||
HINSTANCE16 instance;
|
||||
LOADPARAMS16 params;
|
||||
WORD showCmd[2];
|
||||
char buffer[MAX_PATH];
|
||||
STARTUPINFOA info;
|
||||
char *cmdline, *appname, **first_arg;
|
||||
|
||||
if (!argv[1]) usage();
|
||||
|
||||
if (!strcmp( argv[1], "--app-name" ))
|
||||
{
|
||||
if (!(appname = argv[2])) usage();
|
||||
first_arg = argv + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SearchPathA( NULL, argv[1], ".exe", sizeof(buffer), buffer, NULL ))
|
||||
{
|
||||
WINE_MESSAGE( "winevdm: can't exec '%s': file not found\n", argv[1] );
|
||||
ExitProcess(1);
|
||||
}
|
||||
appname = buffer;
|
||||
first_arg = argv + 1;
|
||||
}
|
||||
|
||||
if (*first_arg) first_arg++; /* skip program name */
|
||||
cmdline = build_command_line( first_arg );
|
||||
|
||||
if (WINE_TRACE_ON(winevdm))
|
||||
{
|
||||
int i;
|
||||
WINE_TRACE( "GetCommandLine = '%s'\n", GetCommandLineA() );
|
||||
WINE_TRACE( "appname = '%s'\n", appname );
|
||||
WINE_TRACE( "cmdline = '%.*s'\n", cmdline[0], cmdline+1 );
|
||||
for (i = 0; argv[i]; i++) WINE_TRACE( "argv[%d]: '%s'\n", i, argv[i] );
|
||||
}
|
||||
|
||||
GetStartupInfoA( &info );
|
||||
showCmd[0] = 2;
|
||||
showCmd[1] = (info.dwFlags & STARTF_USESHOWWINDOW) ? info.wShowWindow : SW_SHOWNORMAL;
|
||||
|
||||
params.hEnvironment = 0;
|
||||
params.cmdLine = MapLS( cmdline );
|
||||
params.showCmd = MapLS( showCmd );
|
||||
params.reserved = 0;
|
||||
|
||||
RestoreThunkLock(1); /* grab the Win16 lock */
|
||||
|
||||
/* some programs assume mmsystem is always present */
|
||||
LoadLibrary16( "mmsystem.dll" );
|
||||
|
||||
if ((instance = LoadModule16( appname, ¶ms )) < 32)
|
||||
{
|
||||
if (instance == 11) /* try DOS format */
|
||||
{
|
||||
wine_load_dos_exe( appname, cmdline );
|
||||
/* if we get back here it failed */
|
||||
instance = GetLastError();
|
||||
}
|
||||
|
||||
WINE_MESSAGE( "winevdm: can't exec '%s': ", appname );
|
||||
switch (instance)
|
||||
{
|
||||
case 2: WINE_MESSAGE("file not found\n" ); break;
|
||||
case 11: WINE_MESSAGE("invalid exe file\n" ); break;
|
||||
default: WINE_MESSAGE("error=%d\n", instance ); break;
|
||||
}
|
||||
ExitProcess(instance);
|
||||
}
|
||||
|
||||
/* wait forever; the process will be killed when the last task exits */
|
||||
ReleaseThunkLock( &count );
|
||||
Sleep( INFINITE );
|
||||
return 0;
|
||||
}
|
|
@ -572,11 +572,11 @@ static void start_process(void)
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* PROCESS_InitWine
|
||||
* __wine_process_init
|
||||
*
|
||||
* Wine initialisation: load and start the main exe file.
|
||||
*/
|
||||
void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win16_exe_file )
|
||||
void __wine_process_init( int argc, char *argv[] )
|
||||
{
|
||||
char error[1024], *p;
|
||||
DWORD stack_size = 0;
|
||||
|
@ -636,14 +636,15 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win
|
|||
case BINARY_WIN16:
|
||||
case BINARY_DOS:
|
||||
TRACE( "starting Win16/DOS binary %s\n", debugstr_a(main_exe_name) );
|
||||
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
||||
current_process.flags |= PDB32_WIN16_PROC;
|
||||
strcpy( win16_exe_name, main_exe_name );
|
||||
main_exe_name[0] = 0;
|
||||
*win16_exe_file = main_exe_file;
|
||||
CloseHandle( main_exe_file );
|
||||
main_exe_file = 0;
|
||||
_EnterWin16Lock();
|
||||
goto found;
|
||||
argv--;
|
||||
argv[0] = "winevdm.exe";
|
||||
if (open_builtin_exe_file( "winevdm.exe", error, sizeof(error), 0 ))
|
||||
goto found;
|
||||
MESSAGE( "%s: trying to run '%s', cannot open builtin library for 'winevdm.exe': %s\n",
|
||||
argv0, main_exe_name, error );
|
||||
ExitProcess(1);
|
||||
case BINARY_OS216:
|
||||
MESSAGE( "%s: '%s' is an OS/2 binary, not supported\n", argv0, main_exe_name );
|
||||
ExitProcess(1);
|
||||
|
@ -1132,6 +1133,32 @@ static BOOL create_process( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCST
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* create_vdm_process
|
||||
*
|
||||
* Create a new VDM process for a 16-bit or DOS application.
|
||||
*/
|
||||
static BOOL create_vdm_process( LPCSTR filename, LPSTR cmd_line, LPCSTR env,
|
||||
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
||||
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
||||
LPPROCESS_INFORMATION info, LPCSTR unixdir )
|
||||
{
|
||||
BOOL ret;
|
||||
LPSTR new_cmd_line = HeapAlloc( GetProcessHeap(), 0, strlen(filename) + strlen(cmd_line) + 30 );
|
||||
|
||||
if (!new_cmd_line)
|
||||
{
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
return FALSE;
|
||||
}
|
||||
sprintf( new_cmd_line, "winevdm.exe --app-name \"%s\" %s", filename, cmd_line );
|
||||
ret = create_process( 0, "winevdm.exe", new_cmd_line, env, psa, tsa, inherit,
|
||||
flags, startup, info, unixdir );
|
||||
HeapFree( GetProcessHeap(), 0, new_cmd_line );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_file_name
|
||||
*
|
||||
|
@ -1310,12 +1337,16 @@ BOOL WINAPI CreateProcessA( LPCSTR app_name, LPSTR cmd_line, LPSECURITY_ATTRIBUT
|
|||
switch( MODULE_GetBinaryType( hFile ))
|
||||
{
|
||||
case BINARY_PE_EXE:
|
||||
case BINARY_WIN16:
|
||||
case BINARY_DOS:
|
||||
TRACE( "starting %s as Windows binary\n", debugstr_a(name) );
|
||||
TRACE( "starting %s as Win32 binary\n", debugstr_a(name) );
|
||||
retv = create_process( hFile, name, tidy_cmdline, env, process_attr, thread_attr,
|
||||
inherit, flags, startup_info, info, unixdir );
|
||||
break;
|
||||
case BINARY_WIN16:
|
||||
case BINARY_DOS:
|
||||
TRACE( "starting %s as Win16/DOS binary\n", debugstr_a(name) );
|
||||
retv = create_vdm_process( name, tidy_cmdline, env, process_attr, thread_attr,
|
||||
inherit, flags, startup_info, info, unixdir );
|
||||
break;
|
||||
case BINARY_OS216:
|
||||
FIXME( "%s is OS/2 binary, not supported\n", debugstr_a(name) );
|
||||
SetLastError( ERROR_BAD_EXE_FORMAT );
|
||||
|
@ -1336,8 +1367,8 @@ BOOL WINAPI CreateProcessA( LPCSTR app_name, LPSTR cmd_line, LPSECURITY_ATTRIBUT
|
|||
if (!FILE_strcasecmp( p, ".com" ))
|
||||
{
|
||||
TRACE( "starting %s as DOS binary\n", debugstr_a(name) );
|
||||
retv = create_process( hFile, name, tidy_cmdline, env, process_attr, thread_attr,
|
||||
inherit, flags, startup_info, info, unixdir );
|
||||
retv = create_vdm_process( name, tidy_cmdline, env, process_attr, thread_attr,
|
||||
inherit, flags, startup_info, info, unixdir );
|
||||
break;
|
||||
}
|
||||
if (!FILE_strcasecmp( p, ".bat" ))
|
||||
|
|
Loading…
Reference in New Issue