Use the exe name and file handle we got from the server also when
starting Win16 or DOS programs, to avoid depending on the contents of
the command-line.
diff --git a/dlls/winedos/module.c b/dlls/winedos/module.c
index 2688f65..372397a 100644
--- a/dlls/winedos/module.c
+++ b/dlls/winedos/module.c
@@ -333,33 +333,9 @@
return FALSE;
}
-BOOL WINAPI MZ_LoadImage( LPCSTR cmdline )
+void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile )
{
- HFILE hFile;
- char *name, buffer[MAX_PATH];
- LPCSTR p = strchr( cmdline, ' ' );
-
- if (p)
- {
- if (!(name = HeapAlloc( GetProcessHeap(), 0, p - cmdline + 1 ))) return FALSE;
- memcpy( name, cmdline, p - cmdline );
- name[p - cmdline] = 0;
- }
- else name = (char *)cmdline;
-
- if (!SearchPathA( NULL, name, ".exe", sizeof(buffer), buffer, NULL )) goto error;
- if ((hFile = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
- goto error;
- if (!MZ_DoLoadImage( hFile, buffer, NULL ))
- {
- CloseHandle( hFile );
- goto error;
- }
- MZ_Launch();
- error:
- if (name != cmdline) HeapFree( GetProcessHeap(), 0, name );
- return FALSE;
+ if (MZ_DoLoadImage( hFile, filename, NULL )) MZ_Launch();
}
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
@@ -609,11 +585,10 @@
#else /* !MZ_SUPPORTED */
-BOOL WINAPI MZ_LoadImage( LPCSTR cmdline )
+void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile )
{
WARN("DOS executables not supported on this platform\n");
SetLastError(ERROR_BAD_FORMAT);
- return FALSE;
}
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
diff --git a/dlls/winedos/winedos.spec b/dlls/winedos/winedos.spec
index 2997fa8..e75d6d6 100644
--- a/dlls/winedos/winedos.spec
+++ b/dlls/winedos/winedos.spec
@@ -7,7 +7,7 @@
@ stdcall GetCurrent() MZ_Current
@ stdcall LoadDPMI() MZ_AllocDPMITask
-@ stdcall LoadDosExe(str) MZ_LoadImage
+@ stdcall LoadDosExe(str long) MZ_LoadImage
@ stdcall Exec(ptr str long ptr) MZ_Exec
@ stdcall Exit(ptr long long) MZ_Exit
diff --git a/include/callback.h b/include/callback.h
index 89dc255..9453fec 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -52,7 +52,7 @@
typedef struct {
struct _DOSTASK* WINAPI (*Current)( void );
struct _DOSTASK* WINAPI (*LoadDPMI)( void );
- BOOL WINAPI (*LoadDosExe)( LPCSTR cmdline );
+ void WINAPI (*LoadDosExe)( LPCSTR filename, HANDLE hFile );
BOOL WINAPI (*Exec)( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk );
void WINAPI (*Exit)( CONTEXT86 *context, BOOL cs_psp, WORD retval );
int WINAPI (*Enter)( CONTEXT86 *context );
diff --git a/include/dosexe.h b/include/dosexe.h
index 9a78522..de1069d 100644
--- a/include/dosexe.h
+++ b/include/dosexe.h
@@ -30,7 +30,7 @@
#define V86_FLAG 0x00020000
-extern BOOL WINAPI MZ_LoadImage( LPCSTR cmdline );
+extern void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile );
extern BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk );
extern void WINAPI MZ_Exit( CONTEXT86 *context, BOOL cs_psp, WORD retval );
extern LPDOSTASK WINAPI MZ_Current( void );
diff --git a/loader/ne/module.c b/loader/ne/module.c
index d66e638..6f4faa3 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -404,11 +404,8 @@
/***********************************************************************
* NE_LoadExeHeader
- *
- * We always have to close hFile upon exit.
- * Otherwise we get file sharing trouble !
*/
-static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
+static HMODULE16 NE_LoadExeHeader( HANDLE hFile, LPCSTR path )
{
IMAGE_DOS_HEADER mz_header;
IMAGE_OS2_HEADER ne_header;
@@ -420,51 +417,31 @@
int fastload_offset = 0, fastload_length = 0;
ET_ENTRY *entry;
ET_BUNDLE *bundle, *oldbundle;
- HFILE16 hFile;
- OFSTRUCT ofs;
-
- /* Open file */
- if ((hFile = OpenFile16( filename, &ofs, OF_READ )) == HFILE_ERROR16)
- return (HMODULE16)2; /* File not found */
+ OFSTRUCT *ofs;
/* Read a block from either the file or the fast-load area. */
#define READ(offset,size,buffer) \
((fastload && ((offset) >= fastload_offset) && \
((offset)+(size) <= fastload_offset+fastload_length)) ? \
(memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
- (_llseek16( hFile, (offset), SEEK_SET), \
- _hread16( hFile, (buffer), (size) ) == (size)))
+ (_llseek( hFile, (offset), SEEK_SET), \
+ _lread( hFile, (buffer), (size) ) == (size)))
- _llseek16( hFile, 0, SEEK_SET );
- if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
+ _llseek( hFile, 0, SEEK_SET );
+ if ((_lread(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
(mz_header.e_magic != IMAGE_DOS_SIGNATURE))
- {
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
- }
- _llseek16( hFile, mz_header.e_lfanew, SEEK_SET );
- if (_hread16( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
- {
- _lclose16( hFile );
+ _llseek( hFile, mz_header.e_lfanew, SEEK_SET );
+ if (_lread( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
return (HMODULE16)11; /* invalid exe */
- }
- if (ne_header.ne_magic == IMAGE_NT_SIGNATURE)
- {
- _lclose16( hFile );
- return (HMODULE16)21; /* win32 exe */
- }
+ if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21; /* win32 exe */
if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
MESSAGE("Sorry, this is an OS/2 linear executable (LX) file !\n");
- _lclose16( hFile );
return (HMODULE16)12;
}
- if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE)
- {
- _lclose16( hFile );
- return (HMODULE16)11; /* invalid exe */
- }
+ if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11; /* invalid exe */
/* We now have a valid NE header */
@@ -485,14 +462,10 @@
sizeof(ET_BUNDLE) +
2 * (ne_header.ne_cbenttab - ne_header.ne_cmovent*6) +
/* loaded file info */
- sizeof(OFSTRUCT)-sizeof(ofs.szPathName)+strlen(ofs.szPathName)+1;
+ sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path) + 1;
hModule = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, size );
- if (!hModule)
- {
- _lclose16( hFile );
- return (HMODULE16)11; /* invalid exe */
- }
+ if (!hModule) return (HMODULE16)11; /* invalid exe */
FarSetOwner16( hModule, hModule );
pModule = (NE_MODULE *)GlobalLock16( hModule );
@@ -521,8 +494,8 @@
fastload_offset, fastload_length );
if ((fastload = HeapAlloc( GetProcessHeap(), 0, fastload_length )) != NULL)
{
- _llseek16( hFile, fastload_offset, SEEK_SET);
- if (_hread16(hFile, fastload, fastload_length) != fastload_length)
+ _llseek( hFile, fastload_offset, SEEK_SET);
+ if (_lread(hFile, fastload, fastload_length) != fastload_length)
{
HeapFree( GetProcessHeap(), 0, fastload );
WARN("Error reading fast-load area!\n");
@@ -533,7 +506,7 @@
/* Get the segment table */
- pModule->seg_table = (int)pData - (int)pModule;
+ pModule->seg_table = pData - (BYTE *)pModule;
buffer = HeapAlloc( GetProcessHeap(), 0, ne_header.ne_cseg *
sizeof(struct ne_segment_table_entry_s));
if (buffer)
@@ -549,7 +522,6 @@
if (fastload)
HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
pSeg = (struct ne_segment_table_entry_s *)buffer;
@@ -565,7 +537,6 @@
if (fastload)
HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
@@ -573,14 +544,11 @@
if (ne_header.ne_rsrctab < ne_header.ne_restab)
{
- pModule->res_table = (int)pData - (int)pModule;
+ pModule->res_table = pData - (BYTE *)pModule;
if (!READ(mz_header.e_lfanew + ne_header.ne_rsrctab,
ne_header.ne_restab - ne_header.ne_rsrctab,
pData ))
- {
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
- }
pData += ne_header.ne_restab - ne_header.ne_rsrctab;
NE_InitResourceHandler( hModule );
}
@@ -588,7 +556,7 @@
/* Get the resident names table */
- pModule->name_table = (int)pData - (int)pModule;
+ pModule->name_table = pData - (BYTE *)pModule;
if (!READ( mz_header.e_lfanew + ne_header.ne_restab,
ne_header.ne_modtab - ne_header.ne_restab,
pData ))
@@ -596,7 +564,6 @@
if (fastload)
HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
pData += ne_header.ne_modtab - ne_header.ne_restab;
@@ -605,7 +572,7 @@
if (ne_header.ne_cmod > 0)
{
- pModule->modref_table = (int)pData - (int)pModule;
+ pModule->modref_table = pData - (BYTE *)pModule;
if (!READ( mz_header.e_lfanew + ne_header.ne_modtab,
ne_header.ne_cmod * sizeof(WORD),
pData ))
@@ -613,7 +580,6 @@
if (fastload)
HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
pData += ne_header.ne_cmod * sizeof(WORD);
@@ -622,7 +588,7 @@
/* Get the imported names table */
- pModule->import_table = (int)pData - (int)pModule;
+ pModule->import_table = pData - (BYTE *)pModule;
if (!READ( mz_header.e_lfanew + ne_header.ne_imptab,
ne_header.ne_enttab - ne_header.ne_imptab,
pData ))
@@ -630,7 +596,6 @@
if (fastload)
HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
pData += ne_header.ne_enttab - ne_header.ne_imptab;
@@ -642,7 +607,7 @@
BYTE nr_entries, type, *s;
TRACE("Converting entry table.\n");
- pModule->entry_table = (int)pData - (int)pModule;
+ pModule->entry_table = pData - (BYTE *)pModule;
if (!READ( mz_header.e_lfanew + ne_header.ne_enttab,
ne_header.ne_cbenttab, pTempEntryTable ))
{
@@ -650,7 +615,6 @@
if (fastload)
HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
@@ -716,7 +680,6 @@
if (fastload)
HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
@@ -728,10 +691,12 @@
/* Store the filename information */
- pModule->fileinfo = (int)pData - (int)pModule;
- size = sizeof(OFSTRUCT)-sizeof(ofs.szPathName)+strlen(ofs.szPathName)+1;
- ofs.cBytes = size - 1;
- memcpy( pData, &ofs, size );
+ pModule->fileinfo = pData - (BYTE *)pModule;
+ size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path) + 1;
+ ofs = (OFSTRUCT *)pData;
+ ofs->cBytes = size - 1;
+ ofs->fFixedDisk = 1;
+ strcpy( ofs->szPathName, path );
pData += size;
/* Free the fast-load area */
@@ -749,17 +714,15 @@
if (!pModule->nrname_handle)
{
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
buffer = GlobalLock16( pModule->nrname_handle );
- _llseek16( hFile, ne_header.ne_nrestab, SEEK_SET );
- if (_hread16( hFile, buffer, ne_header.ne_cbnrestab )
+ _llseek( hFile, ne_header.ne_nrestab, SEEK_SET );
+ if (_lread( hFile, buffer, ne_header.ne_cbnrestab )
!= ne_header.ne_cbnrestab)
{
GlobalFree16( pModule->nrname_handle );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
}
@@ -776,16 +739,13 @@
{
if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
GlobalFree16( hModule );
- _lclose16( hFile );
return (HMODULE16)11; /* invalid exe */
}
}
else pModule->dlls_to_init = 0;
NE_RegisterModule( pModule );
- SNOOP16_RegisterDLL(pModule,ofs.szPathName);
-
- _lclose16( hFile );
+ SNOOP16_RegisterDLL(pModule,path);
return hModule;
}
@@ -896,8 +856,15 @@
NE_MODULE *pModule;
HMODULE16 hModule;
HINSTANCE16 hInstance;
+ HFILE16 hFile;
+ OFSTRUCT ofs;
- hModule = NE_LoadExeHeader( name );
+ /* Open file */
+ if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
+ return (HMODULE16)2; /* File not found */
+
+ hModule = NE_LoadExeHeader( DosFileHandleToWin32Handle(hFile), ofs.szPathName );
+ _lclose16( hFile );
if (hModule < 32) return hModule;
pModule = NE_GetPtr( hModule );
@@ -1005,22 +972,84 @@
/**********************************************************************
+ * NE_CreateThread
+ *
+ * Create the thread for a 16-bit module.
+ */
+static HINSTANCE16 NE_CreateThread( NE_MODULE *pModule, WORD cmdShow, LPCSTR cmdline )
+{
+ TEB *teb = NULL;
+ HANDLE hThread = 0;
+ int socket = -1;
+ HTASK hTask;
+ TDB *pTask;
+ HINSTANCE16 instance = 0;
+
+ SERVER_START_REQ
+ {
+ struct new_thread_request *req = server_alloc_req( sizeof(*req), 0 );
+ req->suspend = 0;
+ req->inherit = 0;
+ if (!server_call( REQ_NEW_THREAD ))
+ {
+ hThread = req->handle;
+ socket = wine_server_recv_fd( hThread, 0 );
+ }
+ }
+ SERVER_END_REQ;
+ if (!hThread) return 0;
+
+ if (!(teb = THREAD_Create( socket, 0, FALSE ))) goto error;
+ teb->tibflags &= ~TEBF_WIN32;
+ teb->startup = NE_InitProcess;
+
+ /* Create a task for this process */
+
+ if (!TASK_Create( pModule, cmdShow, teb, cmdline + 1, *cmdline )) goto error;
+ hTask = teb->htask16;
+ if (SYSDEPS_SpawnThread( teb ) == -1) goto error;
+
+ /* Post event to start the task */
+ PostEvent16( hTask );
+
+ /* Wait until we get the instance handle */
+ do
+ {
+ DirectedYield16( hTask );
+ if (!IsTask16( hTask )) /* thread has died */
+ {
+ DWORD exit_code;
+ WaitForSingleObject( hThread, INFINITE );
+ GetExitCodeThread( hThread, &exit_code );
+ CloseHandle( hThread );
+ return exit_code;
+ }
+ if (!(pTask = (TDB *)GlobalLock16( hTask ))) break;
+ instance = pTask->hInstance;
+ GlobalUnlock16( hTask );
+ } while (!instance);
+
+ return instance;
+
+ error:
+ /* FIXME: free TEB and task */
+ close( socket );
+ CloseHandle( hThread );
+ return 0; /* FIXME */
+}
+
+
+/**********************************************************************
* LoadModule16 (KERNEL.45)
*/
HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
{
- TEB *teb = NULL;
BOOL lib_only = !paramBlock || (paramBlock == (LPVOID)-1);
LOADPARAMS16 *params;
- HINSTANCE16 instance = 0;
HMODULE16 hModule;
NE_MODULE *pModule;
- HTASK hTask;
- TDB *pTask;
LPSTR cmdline;
WORD cmdShow;
- HANDLE hThread = 0;
- int socket = -1;
/* Load module */
@@ -1059,65 +1088,40 @@
* in the meantime), or else to a stub module which contains only header
* information.
*/
-
- /* Create the main thread */
-
- SERVER_START_REQ
- {
- struct new_thread_request *req = server_alloc_req( sizeof(*req), 0 );
- req->suspend = 0;
- req->inherit = 0;
- if (!server_call( REQ_NEW_THREAD ))
- {
- hThread = req->handle;
- socket = wine_server_recv_fd( hThread, 0 );
- }
- }
- SERVER_END_REQ;
- if (!hThread) return 0;
-
- if (!(teb = THREAD_Create( socket, 0, FALSE ))) goto error;
- teb->tibflags &= ~TEBF_WIN32;
- teb->startup = NE_InitProcess;
-
- /* Create a task for this process */
-
params = (LOADPARAMS16 *)paramBlock;
cmdShow = ((WORD *)MapSL(params->showCmd))[1];
cmdline = MapSL( params->cmdLine );
- if (!TASK_Create( pModule, cmdShow, teb, cmdline + 1, *cmdline )) goto error;
+ return NE_CreateThread( pModule, cmdShow, cmdline );
+}
- hTask = teb->htask16;
- if (SYSDEPS_SpawnThread( teb ) == -1) goto error;
+/**********************************************************************
+ * NE_StartMain
+ *
+ * Start the main NE task.
+ */
+HINSTANCE16 NE_StartMain( LPCSTR name, HANDLE file )
+{
+ STARTUPINFOA info;
+ HMODULE16 hModule;
+ NE_MODULE *pModule;
+ LPSTR cmdline = GetCommandLineA();
- /* Post event to start the task */
- PostEvent16( hTask );
+ if ((hModule = NE_LoadExeHeader( file, name )) < 32) return hModule;
- /* Wait until we get the instance handle */
- do
+ if (!(pModule = NE_GetPtr( hModule ))) return (HINSTANCE16)11;
+ if (pModule->flags & NE_FFLAGS_LIBMODULE)
{
- DirectedYield16( hTask );
- if (!IsTask16( hTask )) /* thread has died */
- {
- DWORD exit_code;
- WaitForSingleObject( hThread, INFINITE );
- GetExitCodeThread( hThread, &exit_code );
- CloseHandle( hThread );
- return exit_code;
- }
- if (!(pTask = (TDB *)GlobalLock16( hTask ))) break;
- instance = pTask->hInstance;
- GlobalUnlock16( hTask );
- } while (!instance);
+ MESSAGE( "%s is not a valid Win16 executable\n", name );
+ ExitProcess( ERROR_BAD_EXE_FORMAT );
+ }
- return instance;
+ while (*cmdline && *cmdline != ' ') cmdline++;
+ if (*cmdline) cmdline++;
+ GetStartupInfoA( &info );
+ if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = 1;
- error:
- /* FIXME: free TEB and task */
- close( socket );
- CloseHandle( hThread );
- return 0; /* FIXME */
+ return NE_CreateThread( pModule, info.wShowWindow, cmdline );
}
diff --git a/miscemu/main.c b/miscemu/main.c
index 1fa6f92..43bb028 100644
--- a/miscemu/main.c
+++ b/miscemu/main.c
@@ -14,7 +14,12 @@
#include "dosexe.h"
#include "debugtools.h"
-extern void PROCESS_InitWine( int argc, char *argv[] ) WINE_NORETURN;
+static char main_exe_name[MAX_PATH];
+static HANDLE main_exe_file;
+
+extern void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name,
+ HANDLE *win16_exe_file ) WINE_NORETURN;
+extern HINSTANCE16 NE_StartMain( LPCSTR name, HANDLE file );
/***********************************************************************
* Main loop of initial task
@@ -31,12 +36,12 @@
}
THUNK_InitCallout();
- if ((instance = WinExec16( GetCommandLineA(), show )) < 32)
+ if ((instance = NE_StartMain( main_exe_name, main_exe_file )) < 32)
{
if (instance == 11) /* try DOS format */
{
if (DPMI_LoadDosSystem())
- Dosvm.LoadDosExe( GetCommandLineA() );
+ Dosvm.LoadDosExe( main_exe_name, main_exe_file );
/* if we get back here it failed */
instance = GetLastError();
}
@@ -50,6 +55,7 @@
}
ExitProcess(instance);
}
+ CloseHandle( main_exe_file ); /* avoid file sharing problems */
/* Start message loop for desktop window */
@@ -68,6 +74,6 @@
*/
int main( int argc, char *argv[] )
{
- PROCESS_InitWine( argc, argv );
+ PROCESS_InitWine( argc, argv, main_exe_name, &main_exe_file );
return 1; /* not reached */
}
diff --git a/scheduler/process.c b/scheduler/process.c
index a2224c4..9c58826 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -437,7 +437,7 @@
*
* Wine initialisation: load and start the main exe file.
*/
-void PROCESS_InitWine( int argc, char *argv[] )
+void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win16_exe_file )
{
DWORD stack_size = 0;
@@ -483,8 +483,9 @@
/* it must be 16-bit or DOS format */
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
current_process.flags |= PDB32_WIN16_PROC;
+ strcpy( win16_exe_name, main_exe_name );
main_exe_name[0] = 0;
- CloseHandle( main_exe_file );
+ *win16_exe_file = main_exe_file;
main_exe_file = 0;
_EnterWin16Lock();