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.
This commit is contained in:
parent
2362380b64
commit
105b0f4e64
|
@ -333,33 +333,9 @@ load_error:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI MZ_LoadImage( LPCSTR cmdline )
|
void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile )
|
||||||
{
|
{
|
||||||
HFILE hFile;
|
if (MZ_DoLoadImage( hFile, filename, NULL )) MZ_Launch();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
|
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
|
||||||
|
@ -609,11 +585,10 @@ void WINAPI MZ_Exit( CONTEXT86 *context, BOOL cs_psp, WORD retval )
|
||||||
|
|
||||||
#else /* !MZ_SUPPORTED */
|
#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");
|
WARN("DOS executables not supported on this platform\n");
|
||||||
SetLastError(ERROR_BAD_FORMAT);
|
SetLastError(ERROR_BAD_FORMAT);
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
|
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
|
||||||
|
|
|
@ -7,7 +7,7 @@ import ntdll.dll
|
||||||
|
|
||||||
@ stdcall GetCurrent() MZ_Current
|
@ stdcall GetCurrent() MZ_Current
|
||||||
@ stdcall LoadDPMI() MZ_AllocDPMITask
|
@ stdcall LoadDPMI() MZ_AllocDPMITask
|
||||||
@ stdcall LoadDosExe(str) MZ_LoadImage
|
@ stdcall LoadDosExe(str long) MZ_LoadImage
|
||||||
@ stdcall Exec(ptr str long ptr) MZ_Exec
|
@ stdcall Exec(ptr str long ptr) MZ_Exec
|
||||||
@ stdcall Exit(ptr long long) MZ_Exit
|
@ stdcall Exit(ptr long long) MZ_Exit
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ extern CALLOUT_TABLE Callout;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct _DOSTASK* WINAPI (*Current)( void );
|
struct _DOSTASK* WINAPI (*Current)( void );
|
||||||
struct _DOSTASK* WINAPI (*LoadDPMI)( 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 );
|
BOOL WINAPI (*Exec)( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk );
|
||||||
void WINAPI (*Exit)( CONTEXT86 *context, BOOL cs_psp, WORD retval );
|
void WINAPI (*Exit)( CONTEXT86 *context, BOOL cs_psp, WORD retval );
|
||||||
int WINAPI (*Enter)( CONTEXT86 *context );
|
int WINAPI (*Enter)( CONTEXT86 *context );
|
||||||
|
|
|
@ -30,7 +30,7 @@ typedef struct _DOSTASK {
|
||||||
|
|
||||||
#define V86_FLAG 0x00020000
|
#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 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 void WINAPI MZ_Exit( CONTEXT86 *context, BOOL cs_psp, WORD retval );
|
||||||
extern LPDOSTASK WINAPI MZ_Current( void );
|
extern LPDOSTASK WINAPI MZ_Current( void );
|
||||||
|
|
|
@ -404,11 +404,8 @@ HANDLE NE_OpenFile( NE_MODULE *pModule )
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* NE_LoadExeHeader
|
* 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_DOS_HEADER mz_header;
|
||||||
IMAGE_OS2_HEADER ne_header;
|
IMAGE_OS2_HEADER ne_header;
|
||||||
|
@ -420,51 +417,31 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
int fastload_offset = 0, fastload_length = 0;
|
int fastload_offset = 0, fastload_length = 0;
|
||||||
ET_ENTRY *entry;
|
ET_ENTRY *entry;
|
||||||
ET_BUNDLE *bundle, *oldbundle;
|
ET_BUNDLE *bundle, *oldbundle;
|
||||||
HFILE16 hFile;
|
OFSTRUCT *ofs;
|
||||||
OFSTRUCT ofs;
|
|
||||||
|
|
||||||
/* Open file */
|
|
||||||
if ((hFile = OpenFile16( filename, &ofs, OF_READ )) == HFILE_ERROR16)
|
|
||||||
return (HMODULE16)2; /* File not found */
|
|
||||||
|
|
||||||
/* Read a block from either the file or the fast-load area. */
|
/* Read a block from either the file or the fast-load area. */
|
||||||
#define READ(offset,size,buffer) \
|
#define READ(offset,size,buffer) \
|
||||||
((fastload && ((offset) >= fastload_offset) && \
|
((fastload && ((offset) >= fastload_offset) && \
|
||||||
((offset)+(size) <= fastload_offset+fastload_length)) ? \
|
((offset)+(size) <= fastload_offset+fastload_length)) ? \
|
||||||
(memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
|
(memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
|
||||||
(_llseek16( hFile, (offset), SEEK_SET), \
|
(_llseek( hFile, (offset), SEEK_SET), \
|
||||||
_hread16( hFile, (buffer), (size) ) == (size)))
|
_lread( hFile, (buffer), (size) ) == (size)))
|
||||||
|
|
||||||
_llseek16( hFile, 0, SEEK_SET );
|
_llseek( hFile, 0, SEEK_SET );
|
||||||
if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
|
if ((_lread(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
|
||||||
(mz_header.e_magic != IMAGE_DOS_SIGNATURE))
|
(mz_header.e_magic != IMAGE_DOS_SIGNATURE))
|
||||||
{
|
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
|
||||||
|
|
||||||
_llseek16( hFile, mz_header.e_lfanew, SEEK_SET );
|
_llseek( hFile, mz_header.e_lfanew, SEEK_SET );
|
||||||
if (_hread16( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
|
if (_lread( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
|
||||||
{
|
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
|
||||||
|
|
||||||
if (ne_header.ne_magic == IMAGE_NT_SIGNATURE)
|
if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21; /* win32 exe */
|
||||||
{
|
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)21; /* win32 exe */
|
|
||||||
}
|
|
||||||
if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
|
if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
|
||||||
MESSAGE("Sorry, this is an OS/2 linear executable (LX) file !\n");
|
MESSAGE("Sorry, this is an OS/2 linear executable (LX) file !\n");
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)12;
|
return (HMODULE16)12;
|
||||||
}
|
}
|
||||||
if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE)
|
if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11; /* invalid exe */
|
||||||
{
|
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We now have a valid NE header */
|
/* We now have a valid NE header */
|
||||||
|
|
||||||
|
@ -485,14 +462,10 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
sizeof(ET_BUNDLE) +
|
sizeof(ET_BUNDLE) +
|
||||||
2 * (ne_header.ne_cbenttab - ne_header.ne_cmovent*6) +
|
2 * (ne_header.ne_cbenttab - ne_header.ne_cmovent*6) +
|
||||||
/* loaded file info */
|
/* 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 );
|
hModule = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, size );
|
||||||
if (!hModule)
|
if (!hModule) return (HMODULE16)11; /* invalid exe */
|
||||||
{
|
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
|
||||||
}
|
|
||||||
|
|
||||||
FarSetOwner16( hModule, hModule );
|
FarSetOwner16( hModule, hModule );
|
||||||
pModule = (NE_MODULE *)GlobalLock16( hModule );
|
pModule = (NE_MODULE *)GlobalLock16( hModule );
|
||||||
|
@ -521,8 +494,8 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
fastload_offset, fastload_length );
|
fastload_offset, fastload_length );
|
||||||
if ((fastload = HeapAlloc( GetProcessHeap(), 0, fastload_length )) != NULL)
|
if ((fastload = HeapAlloc( GetProcessHeap(), 0, fastload_length )) != NULL)
|
||||||
{
|
{
|
||||||
_llseek16( hFile, fastload_offset, SEEK_SET);
|
_llseek( hFile, fastload_offset, SEEK_SET);
|
||||||
if (_hread16(hFile, fastload, fastload_length) != fastload_length)
|
if (_lread(hFile, fastload, fastload_length) != fastload_length)
|
||||||
{
|
{
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
WARN("Error reading fast-load area!\n");
|
WARN("Error reading fast-load area!\n");
|
||||||
|
@ -533,7 +506,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
|
|
||||||
/* Get the segment table */
|
/* 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 *
|
buffer = HeapAlloc( GetProcessHeap(), 0, ne_header.ne_cseg *
|
||||||
sizeof(struct ne_segment_table_entry_s));
|
sizeof(struct ne_segment_table_entry_s));
|
||||||
if (buffer)
|
if (buffer)
|
||||||
|
@ -549,7 +522,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (fastload)
|
if (fastload)
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
pSeg = (struct ne_segment_table_entry_s *)buffer;
|
pSeg = (struct ne_segment_table_entry_s *)buffer;
|
||||||
|
@ -565,7 +537,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (fastload)
|
if (fastload)
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,14 +544,11 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
|
|
||||||
if (ne_header.ne_rsrctab < ne_header.ne_restab)
|
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,
|
if (!READ(mz_header.e_lfanew + ne_header.ne_rsrctab,
|
||||||
ne_header.ne_restab - ne_header.ne_rsrctab,
|
ne_header.ne_restab - ne_header.ne_rsrctab,
|
||||||
pData ))
|
pData ))
|
||||||
{
|
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
|
||||||
pData += ne_header.ne_restab - ne_header.ne_rsrctab;
|
pData += ne_header.ne_restab - ne_header.ne_rsrctab;
|
||||||
NE_InitResourceHandler( hModule );
|
NE_InitResourceHandler( hModule );
|
||||||
}
|
}
|
||||||
|
@ -588,7 +556,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
|
|
||||||
/* Get the resident names table */
|
/* 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,
|
if (!READ( mz_header.e_lfanew + ne_header.ne_restab,
|
||||||
ne_header.ne_modtab - ne_header.ne_restab,
|
ne_header.ne_modtab - ne_header.ne_restab,
|
||||||
pData ))
|
pData ))
|
||||||
|
@ -596,7 +564,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (fastload)
|
if (fastload)
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
pData += ne_header.ne_modtab - ne_header.ne_restab;
|
pData += ne_header.ne_modtab - ne_header.ne_restab;
|
||||||
|
@ -605,7 +572,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
|
|
||||||
if (ne_header.ne_cmod > 0)
|
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,
|
if (!READ( mz_header.e_lfanew + ne_header.ne_modtab,
|
||||||
ne_header.ne_cmod * sizeof(WORD),
|
ne_header.ne_cmod * sizeof(WORD),
|
||||||
pData ))
|
pData ))
|
||||||
|
@ -613,7 +580,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (fastload)
|
if (fastload)
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
pData += ne_header.ne_cmod * sizeof(WORD);
|
pData += ne_header.ne_cmod * sizeof(WORD);
|
||||||
|
@ -622,7 +588,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
|
|
||||||
/* Get the imported names table */
|
/* 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,
|
if (!READ( mz_header.e_lfanew + ne_header.ne_imptab,
|
||||||
ne_header.ne_enttab - ne_header.ne_imptab,
|
ne_header.ne_enttab - ne_header.ne_imptab,
|
||||||
pData ))
|
pData ))
|
||||||
|
@ -630,7 +596,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (fastload)
|
if (fastload)
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
pData += ne_header.ne_enttab - ne_header.ne_imptab;
|
pData += ne_header.ne_enttab - ne_header.ne_imptab;
|
||||||
|
@ -642,7 +607,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
BYTE nr_entries, type, *s;
|
BYTE nr_entries, type, *s;
|
||||||
|
|
||||||
TRACE("Converting entry table.\n");
|
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,
|
if (!READ( mz_header.e_lfanew + ne_header.ne_enttab,
|
||||||
ne_header.ne_cbenttab, pTempEntryTable ))
|
ne_header.ne_cbenttab, pTempEntryTable ))
|
||||||
{
|
{
|
||||||
|
@ -650,7 +615,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (fastload)
|
if (fastload)
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,7 +680,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (fastload)
|
if (fastload)
|
||||||
HeapFree( GetProcessHeap(), 0, fastload );
|
HeapFree( GetProcessHeap(), 0, fastload );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,10 +691,12 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
|
|
||||||
/* Store the filename information */
|
/* Store the filename information */
|
||||||
|
|
||||||
pModule->fileinfo = (int)pData - (int)pModule;
|
pModule->fileinfo = pData - (BYTE *)pModule;
|
||||||
size = sizeof(OFSTRUCT)-sizeof(ofs.szPathName)+strlen(ofs.szPathName)+1;
|
size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path) + 1;
|
||||||
ofs.cBytes = size - 1;
|
ofs = (OFSTRUCT *)pData;
|
||||||
memcpy( pData, &ofs, size );
|
ofs->cBytes = size - 1;
|
||||||
|
ofs->fFixedDisk = 1;
|
||||||
|
strcpy( ofs->szPathName, path );
|
||||||
pData += size;
|
pData += size;
|
||||||
|
|
||||||
/* Free the fast-load area */
|
/* Free the fast-load area */
|
||||||
|
@ -749,17 +714,15 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
if (!pModule->nrname_handle)
|
if (!pModule->nrname_handle)
|
||||||
{
|
{
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
buffer = GlobalLock16( pModule->nrname_handle );
|
buffer = GlobalLock16( pModule->nrname_handle );
|
||||||
_llseek16( hFile, ne_header.ne_nrestab, SEEK_SET );
|
_llseek( hFile, ne_header.ne_nrestab, SEEK_SET );
|
||||||
if (_hread16( hFile, buffer, ne_header.ne_cbnrestab )
|
if (_lread( hFile, buffer, ne_header.ne_cbnrestab )
|
||||||
!= ne_header.ne_cbnrestab)
|
!= ne_header.ne_cbnrestab)
|
||||||
{
|
{
|
||||||
GlobalFree16( pModule->nrname_handle );
|
GlobalFree16( pModule->nrname_handle );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -776,16 +739,13 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||||
{
|
{
|
||||||
if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
|
if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
|
||||||
GlobalFree16( hModule );
|
GlobalFree16( hModule );
|
||||||
_lclose16( hFile );
|
|
||||||
return (HMODULE16)11; /* invalid exe */
|
return (HMODULE16)11; /* invalid exe */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else pModule->dlls_to_init = 0;
|
else pModule->dlls_to_init = 0;
|
||||||
|
|
||||||
NE_RegisterModule( pModule );
|
NE_RegisterModule( pModule );
|
||||||
SNOOP16_RegisterDLL(pModule,ofs.szPathName);
|
SNOOP16_RegisterDLL(pModule,path);
|
||||||
|
|
||||||
_lclose16( hFile );
|
|
||||||
return hModule;
|
return hModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,8 +856,15 @@ static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only )
|
||||||
NE_MODULE *pModule;
|
NE_MODULE *pModule;
|
||||||
HMODULE16 hModule;
|
HMODULE16 hModule;
|
||||||
HINSTANCE16 hInstance;
|
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;
|
if (hModule < 32) return hModule;
|
||||||
|
|
||||||
pModule = NE_GetPtr( hModule );
|
pModule = NE_GetPtr( hModule );
|
||||||
|
@ -1004,23 +971,85 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* 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)
|
* LoadModule16 (KERNEL.45)
|
||||||
*/
|
*/
|
||||||
HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||||
{
|
{
|
||||||
TEB *teb = NULL;
|
|
||||||
BOOL lib_only = !paramBlock || (paramBlock == (LPVOID)-1);
|
BOOL lib_only = !paramBlock || (paramBlock == (LPVOID)-1);
|
||||||
LOADPARAMS16 *params;
|
LOADPARAMS16 *params;
|
||||||
HINSTANCE16 instance = 0;
|
|
||||||
HMODULE16 hModule;
|
HMODULE16 hModule;
|
||||||
NE_MODULE *pModule;
|
NE_MODULE *pModule;
|
||||||
HTASK hTask;
|
|
||||||
TDB *pTask;
|
|
||||||
LPSTR cmdline;
|
LPSTR cmdline;
|
||||||
WORD cmdShow;
|
WORD cmdShow;
|
||||||
HANDLE hThread = 0;
|
|
||||||
int socket = -1;
|
|
||||||
|
|
||||||
/* Load module */
|
/* Load module */
|
||||||
|
|
||||||
|
@ -1059,65 +1088,40 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||||
* in the meantime), or else to a stub module which contains only header
|
* in the meantime), or else to a stub module which contains only header
|
||||||
* information.
|
* 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;
|
params = (LOADPARAMS16 *)paramBlock;
|
||||||
cmdShow = ((WORD *)MapSL(params->showCmd))[1];
|
cmdShow = ((WORD *)MapSL(params->showCmd))[1];
|
||||||
cmdline = MapSL( params->cmdLine );
|
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 */
|
if ((hModule = NE_LoadExeHeader( file, name )) < 32) return hModule;
|
||||||
PostEvent16( hTask );
|
|
||||||
|
|
||||||
/* Wait until we get the instance handle */
|
if (!(pModule = NE_GetPtr( hModule ))) return (HINSTANCE16)11;
|
||||||
do
|
if (pModule->flags & NE_FFLAGS_LIBMODULE)
|
||||||
{
|
{
|
||||||
DirectedYield16( hTask );
|
MESSAGE( "%s is not a valid Win16 executable\n", name );
|
||||||
if (!IsTask16( hTask )) /* thread has died */
|
ExitProcess( ERROR_BAD_EXE_FORMAT );
|
||||||
{
|
}
|
||||||
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;
|
while (*cmdline && *cmdline != ' ') cmdline++;
|
||||||
|
if (*cmdline) cmdline++;
|
||||||
|
GetStartupInfoA( &info );
|
||||||
|
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = 1;
|
||||||
|
|
||||||
error:
|
return NE_CreateThread( pModule, info.wShowWindow, cmdline );
|
||||||
/* FIXME: free TEB and task */
|
|
||||||
close( socket );
|
|
||||||
CloseHandle( hThread );
|
|
||||||
return 0; /* FIXME */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,12 @@
|
||||||
#include "dosexe.h"
|
#include "dosexe.h"
|
||||||
#include "debugtools.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
|
* Main loop of initial task
|
||||||
|
@ -31,12 +36,12 @@ int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT
|
||||||
}
|
}
|
||||||
THUNK_InitCallout();
|
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 (instance == 11) /* try DOS format */
|
||||||
{
|
{
|
||||||
if (DPMI_LoadDosSystem())
|
if (DPMI_LoadDosSystem())
|
||||||
Dosvm.LoadDosExe( GetCommandLineA() );
|
Dosvm.LoadDosExe( main_exe_name, main_exe_file );
|
||||||
/* if we get back here it failed */
|
/* if we get back here it failed */
|
||||||
instance = GetLastError();
|
instance = GetLastError();
|
||||||
}
|
}
|
||||||
|
@ -50,6 +55,7 @@ int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT
|
||||||
}
|
}
|
||||||
ExitProcess(instance);
|
ExitProcess(instance);
|
||||||
}
|
}
|
||||||
|
CloseHandle( main_exe_file ); /* avoid file sharing problems */
|
||||||
|
|
||||||
/* Start message loop for desktop window */
|
/* Start message loop for desktop window */
|
||||||
|
|
||||||
|
@ -68,6 +74,6 @@ int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT
|
||||||
*/
|
*/
|
||||||
int main( int argc, char *argv[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
PROCESS_InitWine( argc, argv );
|
PROCESS_InitWine( argc, argv, main_exe_name, &main_exe_file );
|
||||||
return 1; /* not reached */
|
return 1; /* not reached */
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,7 +437,7 @@ void *open_winelib_app( char *argv[] )
|
||||||
*
|
*
|
||||||
* Wine initialisation: load and start the main exe file.
|
* 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;
|
DWORD stack_size = 0;
|
||||||
|
|
||||||
|
@ -483,8 +483,9 @@ void PROCESS_InitWine( int argc, char *argv[] )
|
||||||
/* it must be 16-bit or DOS format */
|
/* it must be 16-bit or DOS format */
|
||||||
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
||||||
current_process.flags |= PDB32_WIN16_PROC;
|
current_process.flags |= PDB32_WIN16_PROC;
|
||||||
|
strcpy( win16_exe_name, main_exe_name );
|
||||||
main_exe_name[0] = 0;
|
main_exe_name[0] = 0;
|
||||||
CloseHandle( main_exe_file );
|
*win16_exe_file = main_exe_file;
|
||||||
main_exe_file = 0;
|
main_exe_file = 0;
|
||||||
_EnterWin16Lock();
|
_EnterWin16Lock();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue