NE modules adapted to CreateProcess changes.
LoadModule16/LoadLibrary16 reorganization.
This commit is contained in:
parent
6e0d38603e
commit
fe14b6603d
@ -10,6 +10,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
|
#include "winerror.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "neexe.h"
|
#include "neexe.h"
|
||||||
#include "peexe.h"
|
#include "peexe.h"
|
||||||
@ -708,7 +709,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
|
|||||||
/* its handle in the list of DLLs to initialize. */
|
/* its handle in the list of DLLs to initialize. */
|
||||||
HMODULE16 hDLL;
|
HMODULE16 hDLL;
|
||||||
|
|
||||||
if ((hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE )) == 2)
|
if ((hDLL = NE_LoadModule( buffer, TRUE )) == 2)
|
||||||
{
|
{
|
||||||
/* file not found */
|
/* file not found */
|
||||||
char *p;
|
char *p;
|
||||||
@ -718,7 +719,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
|
|||||||
if (!(p = strrchr( buffer, '\\' ))) p = buffer;
|
if (!(p = strrchr( buffer, '\\' ))) p = buffer;
|
||||||
memcpy( p + 1, pstr + 1, *pstr );
|
memcpy( p + 1, pstr + 1, *pstr );
|
||||||
strcpy( p + 1 + *pstr, ".dll" );
|
strcpy( p + 1 + *pstr, ".dll" );
|
||||||
hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE );
|
hDLL = NE_LoadModule( buffer, TRUE );
|
||||||
}
|
}
|
||||||
if (hDLL < 32)
|
if (hDLL < 32)
|
||||||
{
|
{
|
||||||
@ -743,63 +744,29 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
|
|||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* NE_LoadModule
|
* NE_LoadFileModule
|
||||||
*
|
*
|
||||||
* Implementation of LoadModule16().
|
* Load first instance of NE module from file.
|
||||||
|
* (Note: caller is responsible for ensuring the module isn't
|
||||||
|
* already loaded!)
|
||||||
*/
|
*/
|
||||||
HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
|
static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs,
|
||||||
BOOL implicit, BOOL lib_only )
|
BOOL implicit )
|
||||||
{
|
{
|
||||||
HMODULE16 hModule;
|
|
||||||
HINSTANCE16 hInstance;
|
HINSTANCE16 hInstance;
|
||||||
|
HMODULE16 hModule;
|
||||||
NE_MODULE *pModule;
|
NE_MODULE *pModule;
|
||||||
HFILE16 hFile;
|
|
||||||
OFSTRUCT ofs;
|
|
||||||
|
|
||||||
/* Check if the module is already loaded */
|
|
||||||
|
|
||||||
if ((hModule = GetModuleHandle16( name )) != 0)
|
|
||||||
{
|
|
||||||
HINSTANCE16 prev;
|
|
||||||
pModule = NE_GetPtr( hModule );
|
|
||||||
if ( pModule->module32 ) return (HINSTANCE16)21;
|
|
||||||
|
|
||||||
hInstance = NE_CreateInstance( pModule, &prev, lib_only );
|
|
||||||
if (hInstance != prev) /* not a library */
|
|
||||||
NE_LoadSegment( pModule, pModule->dgroup );
|
|
||||||
pModule->count++;
|
|
||||||
if (hPrevInstance) *hPrevInstance = prev;
|
|
||||||
return hInstance;
|
|
||||||
}
|
|
||||||
if (hPrevInstance) *hPrevInstance = 0;
|
|
||||||
|
|
||||||
/* Try to load the built-in first if not disabled */
|
|
||||||
|
|
||||||
if ((hModule = fnBUILTIN_LoadModule( name, FALSE ))) return hModule;
|
|
||||||
|
|
||||||
if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
|
|
||||||
{
|
|
||||||
/* Now try the built-in even if disabled */
|
|
||||||
if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
|
|
||||||
{
|
|
||||||
MSG( "Could not load Windows DLL '%s', using built-in module.\n",
|
|
||||||
name );
|
|
||||||
return hModule;
|
|
||||||
}
|
|
||||||
return 2; /* File not found */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the module structure */
|
/* Create the module structure */
|
||||||
|
|
||||||
hModule = NE_LoadExeHeader( hFile, &ofs );
|
hModule = NE_LoadExeHeader( hFile, ofs );
|
||||||
_lclose16( hFile );
|
|
||||||
if (hModule < 32) return hModule;
|
if (hModule < 32) return hModule;
|
||||||
pModule = NE_GetPtr( hModule );
|
pModule = NE_GetPtr( hModule );
|
||||||
|
|
||||||
/* Allocate the segments for this module */
|
/* Allocate the segments for this module */
|
||||||
|
|
||||||
if (!NE_CreateSegments( pModule ) ||
|
if (!NE_CreateSegments( pModule ) ||
|
||||||
!(hInstance = NE_CreateInstance( pModule, NULL, lib_only )))
|
!(hInstance = NE_CreateInstance( pModule, NULL, FALSE )))
|
||||||
{
|
{
|
||||||
GlobalFreeAll16( hModule );
|
GlobalFreeAll16( hModule );
|
||||||
return 8; /* Insufficient memory */
|
return 8; /* Insufficient memory */
|
||||||
@ -833,35 +800,233 @@ HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
|
|||||||
return hInstance;
|
return hInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* NE_LoadModule
|
||||||
|
*
|
||||||
|
* Load first instance of NE module, deciding whether to use
|
||||||
|
* built-in module or load module from file.
|
||||||
|
* (Note: caller is responsible for ensuring the module isn't
|
||||||
|
* already loaded!)
|
||||||
|
*/
|
||||||
|
HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit )
|
||||||
|
{
|
||||||
|
HINSTANCE16 hInstance;
|
||||||
|
HMODULE16 hModule;
|
||||||
|
HFILE16 hFile;
|
||||||
|
OFSTRUCT ofs;
|
||||||
|
|
||||||
|
/* Try to load the built-in first if not disabled */
|
||||||
|
|
||||||
|
if ((hModule = fnBUILTIN_LoadModule( name, FALSE ))) return hModule;
|
||||||
|
|
||||||
|
if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
|
||||||
|
{
|
||||||
|
/* Now try the built-in even if disabled */
|
||||||
|
if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
|
||||||
|
{
|
||||||
|
MSG( "Could not load Windows DLL '%s', using built-in module.\n",
|
||||||
|
name );
|
||||||
|
return hModule;
|
||||||
|
}
|
||||||
|
return 2; /* File not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
hInstance = NE_LoadFileModule( hFile, &ofs, implicit );
|
||||||
|
_lclose16( hFile );
|
||||||
|
|
||||||
|
return hInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* LoadModule16 (KERNEL.45)
|
||||||
|
*/
|
||||||
|
HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||||
|
{
|
||||||
|
BOOL lib_only = !paramBlock || (paramBlock == (LPVOID)-1);
|
||||||
|
LOADPARAMS16 *params;
|
||||||
|
LPSTR cmd_line, new_cmd_line;
|
||||||
|
LPCVOID env = NULL;
|
||||||
|
STARTUPINFOA startup;
|
||||||
|
PROCESS_INFORMATION info;
|
||||||
|
HINSTANCE16 hInstance, hPrevInstance = 0;
|
||||||
|
HMODULE16 hModule;
|
||||||
|
NE_MODULE *pModule;
|
||||||
|
PDB *pdb;
|
||||||
|
|
||||||
|
|
||||||
|
/* Load module */
|
||||||
|
|
||||||
|
if ( ( hModule = GetModuleHandle16( name ) ) != 0 )
|
||||||
|
{
|
||||||
|
/* Special case: second instance of an already loaded NE module */
|
||||||
|
|
||||||
|
if ( !( pModule = NE_GetPtr( hModule ) ) ) return (HINSTANCE16)11;
|
||||||
|
if ( pModule->module32 ) return (HINSTANCE16)21;
|
||||||
|
|
||||||
|
hInstance = NE_CreateInstance( pModule, &hPrevInstance, lib_only );
|
||||||
|
if ( hInstance != hPrevInstance ) /* not a library */
|
||||||
|
NE_LoadSegment( pModule, pModule->dgroup );
|
||||||
|
|
||||||
|
pModule->count++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Main case: load first instance of NE module */
|
||||||
|
|
||||||
|
if ( (hInstance = NE_LoadModule( name, FALSE )) < 32 );
|
||||||
|
return hInstance;
|
||||||
|
|
||||||
|
if ( !(pModule = NE_GetPtr( hInstance )) )
|
||||||
|
return (HINSTANCE16)11;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If library module, we're finished */
|
||||||
|
|
||||||
|
if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
|
||||||
|
return hInstance;
|
||||||
|
|
||||||
|
/* Create a task for this instance */
|
||||||
|
|
||||||
|
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
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 (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
pdb = PROCESS_Create( pModule, new_cmd_line, env,
|
||||||
|
hInstance, hPrevInstance, TRUE, &startup, &info );
|
||||||
|
|
||||||
|
CloseHandle( info.hThread );
|
||||||
|
CloseHandle( info.hProcess );
|
||||||
|
|
||||||
|
if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
|
||||||
|
HeapFree( GetProcessHeap(), 0, new_cmd_line );
|
||||||
|
|
||||||
|
/* Start task */
|
||||||
|
|
||||||
|
if (pdb) TASK_StartTask( pdb->task );
|
||||||
|
|
||||||
|
return hInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* NE_CreateProcess
|
||||||
|
*/
|
||||||
|
BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
|
||||||
|
LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
|
||||||
|
LPPROCESS_INFORMATION info )
|
||||||
|
{
|
||||||
|
HINSTANCE16 hInstance, hPrevInstance = 0;
|
||||||
|
HMODULE16 hModule;
|
||||||
|
NE_MODULE *pModule;
|
||||||
|
HFILE16 hFile16;
|
||||||
|
|
||||||
|
/* Special case: second instance of an already loaded NE module */
|
||||||
|
|
||||||
|
if ( ( hModule = GetModuleHandle16( ofs->szPathName ) ) != 0 )
|
||||||
|
{
|
||||||
|
if ( !( pModule = NE_GetPtr( hModule) )
|
||||||
|
|| ( pModule->flags & NE_FFLAGS_LIBMODULE )
|
||||||
|
|| pModule->module32 )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_BAD_FORMAT );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE );
|
||||||
|
if ( hInstance != hPrevInstance ) /* not a library */
|
||||||
|
NE_LoadSegment( pModule, pModule->dgroup );
|
||||||
|
|
||||||
|
pModule->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main case: load first instance of NE module */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If we didn't get a file handle, return */
|
||||||
|
|
||||||
|
if ( hFile == HFILE_ERROR )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Allocate temporary HFILE16 for NE_LoadFileModule */
|
||||||
|
|
||||||
|
if (!DuplicateHandle( GetCurrentProcess(), hFile,
|
||||||
|
GetCurrentProcess(), &hFile,
|
||||||
|
0, FALSE, DUPLICATE_SAME_ACCESS ))
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_HANDLE );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
hFile16 = FILE_AllocDosHandle( hFile );
|
||||||
|
|
||||||
|
/* Load module */
|
||||||
|
|
||||||
|
hInstance = NE_LoadFileModule( hFile16, ofs, TRUE );
|
||||||
|
_lclose16( hFile16 );
|
||||||
|
|
||||||
|
if ( hInstance < 32 )
|
||||||
|
{
|
||||||
|
SetLastError( hInstance );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !( pModule = NE_GetPtr( hInstance ) )
|
||||||
|
|| ( pModule->flags & NE_FFLAGS_LIBMODULE) )
|
||||||
|
{
|
||||||
|
/* FIXME: cleanup */
|
||||||
|
SetLastError( ERROR_BAD_FORMAT );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a task for this instance */
|
||||||
|
|
||||||
|
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
|
||||||
|
|
||||||
|
if ( !PROCESS_Create( pModule, cmd_line, env,
|
||||||
|
hInstance, hPrevInstance, inherit, startup, info ) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* LoadLibrary (KERNEL.95)
|
* LoadLibrary16 (KERNEL.95)
|
||||||
*/
|
*/
|
||||||
HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
|
HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
|
||||||
{
|
{
|
||||||
HINSTANCE16 handle;
|
char dllname[256], *p;
|
||||||
LPCSTR p;
|
|
||||||
char *new_name;
|
|
||||||
|
|
||||||
TRACE(module, "(%08x) %s\n", (int)libname, libname);
|
TRACE( module, "(%08x) %s\n", (int)libname, libname );
|
||||||
|
|
||||||
/* Check for an extension */
|
/* Append .DLL to name if no extension present */
|
||||||
|
|
||||||
if ((p = strrchr( libname, '.')) && !strchr( p, '/' ) && !strchr( p, '\\'))
|
strcpy( dllname, libname );
|
||||||
{
|
if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
|
||||||
/* An extension is present -> use the name as is */
|
strcat( dllname, ".DLL" );
|
||||||
return NE_LoadModule( libname, NULL, FALSE, TRUE );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now append .dll before loading */
|
/* Load library module */
|
||||||
|
|
||||||
if (!(new_name = HeapAlloc( GetProcessHeap(), 0, strlen(libname) + 4 )))
|
return LoadModule16( dllname, (LPVOID)-1 );
|
||||||
return 0;
|
|
||||||
strcpy( new_name, libname );
|
|
||||||
strcat( new_name, ".dll" );
|
|
||||||
handle = NE_LoadModule( new_name, NULL, FALSE, TRUE );
|
|
||||||
HeapFree( GetProcessHeap(), 0, new_name );
|
|
||||||
return handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1163,7 +1328,7 @@ HMODULE WINAPI MapHModuleSL(HMODULE16 hmod) {
|
|||||||
if (!hmod) {
|
if (!hmod) {
|
||||||
TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
|
TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
|
||||||
|
|
||||||
hmod = pTask->hInstance;
|
hmod = pTask->hModule;
|
||||||
}
|
}
|
||||||
pModule = (NE_MODULE*)GlobalLock16(hmod);
|
pModule = (NE_MODULE*)GlobalLock16(hmod);
|
||||||
if ( (pModule->magic!=IMAGE_OS2_SIGNATURE) ||
|
if ( (pModule->magic!=IMAGE_OS2_SIGNATURE) ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user