mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
Simplified hInstance creation/handling.
Fixes problems with self-loaders creating DGROUP themselves.
This commit is contained in:
parent
f64e0d7e37
commit
61206bd8a0
@ -222,11 +222,10 @@ extern NE_NAMEINFO *NE_FindResourceFromType( LPBYTE pResTab, NE_TYPEINFO *pTypeI
|
|||||||
/* loader/ne/segment.c */
|
/* loader/ne/segment.c */
|
||||||
extern BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum );
|
extern BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum );
|
||||||
extern BOOL NE_LoadAllSegments( NE_MODULE *pModule );
|
extern BOOL NE_LoadAllSegments( NE_MODULE *pModule );
|
||||||
extern void NE_FixupPrologs( NE_MODULE *pModule );
|
extern BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum );
|
||||||
|
extern BOOL NE_CreateAllSegments( NE_MODULE *pModule );
|
||||||
|
extern HINSTANCE16 NE_GetInstance( NE_MODULE *pModule );
|
||||||
extern void NE_InitializeDLLs( HMODULE16 hModule );
|
extern void NE_InitializeDLLs( HMODULE16 hModule );
|
||||||
extern BOOL NE_CreateSegments( NE_MODULE *pModule );
|
|
||||||
extern HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev,
|
|
||||||
BOOL lib_only );
|
|
||||||
|
|
||||||
/* loader/ne/convert.c */
|
/* loader/ne/convert.c */
|
||||||
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size );
|
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size );
|
||||||
|
@ -799,12 +799,9 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
|
|||||||
*/
|
*/
|
||||||
static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule )
|
static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule )
|
||||||
{
|
{
|
||||||
HINSTANCE16 hInstance;
|
|
||||||
|
|
||||||
/* Allocate the segments for this module */
|
/* Allocate the segments for this module */
|
||||||
|
|
||||||
if (!NE_CreateSegments( pModule ) ||
|
if (!NE_CreateAllSegments( pModule ))
|
||||||
!(hInstance = NE_CreateInstance( pModule, NULL, FALSE )))
|
|
||||||
return 8; /* Insufficient memory */
|
return 8; /* Insufficient memory */
|
||||||
|
|
||||||
/* Load the referenced DLLs */
|
/* Load the referenced DLLs */
|
||||||
@ -816,16 +813,12 @@ static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule )
|
|||||||
|
|
||||||
NE_LoadAllSegments( pModule );
|
NE_LoadAllSegments( pModule );
|
||||||
|
|
||||||
/* Fixup the functions prologs */
|
|
||||||
|
|
||||||
NE_FixupPrologs( pModule );
|
|
||||||
|
|
||||||
/* Make sure the usage count is 1 on the first loading of */
|
/* Make sure the usage count is 1 on the first loading of */
|
||||||
/* the module, even if it contains circular DLL references */
|
/* the module, even if it contains circular DLL references */
|
||||||
|
|
||||||
pModule->count = 1;
|
pModule->count = 1;
|
||||||
|
|
||||||
return hInstance;
|
return NE_GetInstance( pModule );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
@ -1002,11 +995,6 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
|||||||
/* Increment refcount */
|
/* Increment refcount */
|
||||||
|
|
||||||
pModule->count++;
|
pModule->count++;
|
||||||
|
|
||||||
/* If library module, we just retrieve the instance handle */
|
|
||||||
|
|
||||||
if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
|
|
||||||
return NE_CreateInstance( pModule, NULL, TRUE );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1017,13 +1005,12 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
|||||||
|
|
||||||
if ( !(pModule = NE_GetPtr( hModule )) )
|
if ( !(pModule = NE_GetPtr( hModule )) )
|
||||||
return (HINSTANCE16)11;
|
return (HINSTANCE16)11;
|
||||||
|
|
||||||
/* If library module, we're finished */
|
|
||||||
|
|
||||||
if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
|
|
||||||
return hModule;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If library module, we just retrieve the instance handle */
|
||||||
|
|
||||||
|
if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
|
||||||
|
return NE_GetInstance( pModule );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we need to create a new process.
|
* At this point, we need to create a new process.
|
||||||
@ -1177,9 +1164,13 @@ BOOL NE_InitProcess( NE_MODULE *pModule )
|
|||||||
/* Second instance of an already loaded NE module */
|
/* Second instance of an already loaded NE module */
|
||||||
/* Note that the refcount was already incremented by the parent */
|
/* Note that the refcount was already incremented by the parent */
|
||||||
|
|
||||||
hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE );
|
hPrevInstance = NE_GetInstance( pModule );
|
||||||
if ( hInstance != hPrevInstance ) /* not a library */
|
|
||||||
NE_LoadSegment( pModule, pModule->dgroup );
|
if ( pModule->dgroup )
|
||||||
|
if ( NE_CreateSegment( pModule, pModule->dgroup ) )
|
||||||
|
NE_LoadSegment( pModule, pModule->dgroup );
|
||||||
|
|
||||||
|
hInstance = NE_GetInstance( pModule );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,8 @@ DECLARE_DEBUG_CHANNEL(segment)
|
|||||||
|
|
||||||
#define SEL(x) ((x)|1)
|
#define SEL(x) ((x)|1)
|
||||||
|
|
||||||
|
static void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* NE_GetRelocAddrName
|
* NE_GetRelocAddrName
|
||||||
*/
|
*/
|
||||||
@ -97,14 +99,12 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
|
|||||||
/* Implement self-loading segments */
|
/* Implement self-loading segments */
|
||||||
SELFLOADHEADER *selfloadheader;
|
SELFLOADHEADER *selfloadheader;
|
||||||
DWORD oldstack;
|
DWORD oldstack;
|
||||||
WORD old_hSeg, new_hSeg;
|
|
||||||
HFILE hFile32;
|
HFILE hFile32;
|
||||||
HFILE16 hFile16;
|
HFILE16 hFile16;
|
||||||
|
|
||||||
selfloadheader = (SELFLOADHEADER *)
|
selfloadheader = (SELFLOADHEADER *)
|
||||||
PTR_SEG_OFF_TO_LIN(SEL(pSegTable->hSeg),0);
|
PTR_SEG_OFF_TO_LIN(SEL(pSegTable->hSeg),0);
|
||||||
oldstack = NtCurrentTeb()->cur_stack;
|
oldstack = NtCurrentTeb()->cur_stack;
|
||||||
old_hSeg = pSeg->hSeg;
|
|
||||||
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
|
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
|
||||||
0xff00 - sizeof(STACK16FRAME));
|
0xff00 - sizeof(STACK16FRAME));
|
||||||
|
|
||||||
@ -113,29 +113,11 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
|
|||||||
DuplicateHandle( GetCurrentProcess(), hf, GetCurrentProcess(), &hFile32,
|
DuplicateHandle( GetCurrentProcess(), hf, GetCurrentProcess(), &hFile32,
|
||||||
0, FALSE, DUPLICATE_SAME_ACCESS );
|
0, FALSE, DUPLICATE_SAME_ACCESS );
|
||||||
hFile16 = FILE_AllocDosHandle( hFile32 );
|
hFile16 = FILE_AllocDosHandle( hFile32 );
|
||||||
new_hSeg = Callbacks->CallLoadAppSegProc(selfloadheader->LoadAppSeg,
|
pSeg->hSeg = Callbacks->CallLoadAppSegProc( selfloadheader->LoadAppSeg,
|
||||||
pModule->self, hFile16,
|
pModule->self, hFile16,
|
||||||
segnum );
|
segnum );
|
||||||
TRACE_(dll)("Ret CallLoadAppSegProc: hSeg = 0x%04x\n",new_hSeg);
|
TRACE_(dll)("Ret CallLoadAppSegProc: hSeg = 0x%04x\n", pSeg->hSeg);
|
||||||
_lclose16( hFile16 );
|
_lclose16( hFile16 );
|
||||||
if (SEL(new_hSeg) != SEL(old_hSeg)) {
|
|
||||||
/* Self loaders like creating their own selectors;
|
|
||||||
* they love asking for trouble to Wine developers
|
|
||||||
*/
|
|
||||||
if (segnum == pModule->dgroup) {
|
|
||||||
memcpy(PTR_SEG_OFF_TO_LIN(SEL(old_hSeg),0),
|
|
||||||
PTR_SEG_OFF_TO_LIN(SEL(new_hSeg),0),
|
|
||||||
pSeg->minsize ? pSeg->minsize : 0x10000);
|
|
||||||
FreeSelector16(SEL(new_hSeg));
|
|
||||||
pSeg->hSeg = old_hSeg;
|
|
||||||
TRACE_(module)("New hSeg allocated for dgroup segment:Old=%d,New=%d\n",
|
|
||||||
old_hSeg, new_hSeg);
|
|
||||||
} else {
|
|
||||||
FreeSelector16(SEL(pSeg->hSeg));
|
|
||||||
pSeg->hSeg = new_hSeg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NtCurrentTeb()->cur_stack = oldstack;
|
NtCurrentTeb()->cur_stack = oldstack;
|
||||||
}
|
}
|
||||||
else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED))
|
else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED))
|
||||||
@ -165,6 +147,10 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
|
|||||||
}
|
}
|
||||||
|
|
||||||
pSeg->flags |= NE_SEGFLAGS_LOADED;
|
pSeg->flags |= NE_SEGFLAGS_LOADED;
|
||||||
|
|
||||||
|
/* Perform exported function prolog fixups */
|
||||||
|
NE_FixupSegmentPrologs( pModule, segnum );
|
||||||
|
|
||||||
if (!(pSeg->flags & NE_SEGFLAGS_RELOC_DATA))
|
if (!(pSeg->flags & NE_SEGFLAGS_RELOC_DATA))
|
||||||
return TRUE; /* No relocation data, we are done */
|
return TRUE; /* No relocation data, we are done */
|
||||||
|
|
||||||
@ -396,7 +382,6 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
|
|||||||
SELFLOADHEADER *selfloadheader;
|
SELFLOADHEADER *selfloadheader;
|
||||||
HMODULE16 hselfload = GetModuleHandle16("WPROCS");
|
HMODULE16 hselfload = GetModuleHandle16("WPROCS");
|
||||||
DWORD oldstack;
|
DWORD oldstack;
|
||||||
WORD saved_hSeg = pSegTable[pModule->dgroup - 1].hSeg;
|
|
||||||
|
|
||||||
TRACE_(module)("%.*s is a self-loading module!\n",
|
TRACE_(module)("%.*s is a self-loading module!\n",
|
||||||
*((BYTE*)pModule + pModule->name_table),
|
*((BYTE*)pModule + pModule->name_table),
|
||||||
@ -420,8 +405,6 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
|
|||||||
Callbacks->CallBootAppProc(selfloadheader->BootApp, pModule->self,hFile16);
|
Callbacks->CallBootAppProc(selfloadheader->BootApp, pModule->self,hFile16);
|
||||||
TRACE_(dll)("Return from CallBootAppProc\n");
|
TRACE_(dll)("Return from CallBootAppProc\n");
|
||||||
_lclose16(hf);
|
_lclose16(hf);
|
||||||
/* some BootApp procs overwrite the segment handle of dgroup */
|
|
||||||
pSegTable[pModule->dgroup - 1].hSeg = saved_hSeg;
|
|
||||||
NtCurrentTeb()->cur_stack = oldstack;
|
NtCurrentTeb()->cur_stack = oldstack;
|
||||||
|
|
||||||
for (i = 2; i <= pModule->seg_count; i++)
|
for (i = 2; i <= pModule->seg_count; i++)
|
||||||
@ -441,7 +424,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
|
|||||||
*
|
*
|
||||||
* Fixup exported functions prologs of one segment
|
* Fixup exported functions prologs of one segment
|
||||||
*/
|
*/
|
||||||
void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum)
|
static void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum)
|
||||||
{
|
{
|
||||||
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
|
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
|
||||||
ET_BUNDLE *bundle;
|
ET_BUNDLE *bundle;
|
||||||
@ -537,23 +520,6 @@ DWORD WINAPI PatchCodeHandle16(HANDLE16 hSeg)
|
|||||||
return MAKELONG(hSeg, sel);
|
return MAKELONG(hSeg, sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* NE_FixupPrologs
|
|
||||||
*
|
|
||||||
* Fixup the exported functions prologs.
|
|
||||||
*/
|
|
||||||
void NE_FixupPrologs( NE_MODULE *pModule )
|
|
||||||
{
|
|
||||||
WORD segnum;
|
|
||||||
|
|
||||||
TRACE_(module)("(%04x)\n", pModule->self );
|
|
||||||
|
|
||||||
if (pModule->flags & NE_FFLAGS_SELFLOAD)
|
|
||||||
NE_FixupSegmentPrologs(pModule, 1);
|
|
||||||
else
|
|
||||||
for (segnum=1; segnum <= pModule->seg_count; segnum++)
|
|
||||||
NE_FixupSegmentPrologs(pModule, segnum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* NE_GetDLLInitParams
|
* NE_GetDLLInitParams
|
||||||
@ -746,49 +712,6 @@ static WORD NE_Ne2MemFlags(WORD flags)
|
|||||||
return memflags;
|
return memflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* NE_CreateInstance
|
|
||||||
*
|
|
||||||
* If lib_only is TRUE, handle the module like a library even if it is a .EXE
|
|
||||||
*/
|
|
||||||
HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev,
|
|
||||||
BOOL lib_only )
|
|
||||||
{
|
|
||||||
SEGTABLEENTRY *pSegment;
|
|
||||||
int minsize;
|
|
||||||
HINSTANCE16 hNewSeg;
|
|
||||||
|
|
||||||
if (pModule->dgroup == 0)
|
|
||||||
{
|
|
||||||
if (prev) *prev = pModule->self;
|
|
||||||
return pModule->self;
|
|
||||||
}
|
|
||||||
|
|
||||||
pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
|
|
||||||
if (prev) *prev = SEL(pSegment->hSeg);
|
|
||||||
|
|
||||||
/* if it's a library, create a new instance only the first time */
|
|
||||||
if (pSegment->hSeg)
|
|
||||||
{
|
|
||||||
if (pModule->flags & NE_FFLAGS_LIBMODULE) return SEL(pSegment->hSeg);
|
|
||||||
if (lib_only) return SEL(pSegment->hSeg);
|
|
||||||
}
|
|
||||||
|
|
||||||
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
|
|
||||||
if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
|
|
||||||
minsize += pModule->heap_size;
|
|
||||||
hNewSeg = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags), minsize,
|
|
||||||
pModule->self, FALSE, FALSE, FALSE );
|
|
||||||
if (!hNewSeg) return 0;
|
|
||||||
pSegment->hSeg = hNewSeg;
|
|
||||||
pSegment->flags |= NE_SEGFLAGS_ALLOCATED;
|
|
||||||
|
|
||||||
/* a HINSTANCE is the selector of the DSEG */
|
|
||||||
return (HINSTANCE16)SEL(hNewSeg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* NE_AllocateSegment (WPROCS.26)
|
* NE_AllocateSegment (WPROCS.26)
|
||||||
*
|
*
|
||||||
@ -817,37 +740,65 @@ DWORD WINAPI NE_AllocateSegment( WORD wFlags, WORD wSize, WORD wElem )
|
|||||||
return MAKELONG( 0, hMem );
|
return MAKELONG( 0, hMem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NE_GetInstance
|
||||||
|
*/
|
||||||
|
HINSTANCE16 NE_GetInstance( NE_MODULE *pModule )
|
||||||
|
{
|
||||||
|
if ( !pModule->dgroup )
|
||||||
|
return pModule->self;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SEGTABLEENTRY *pSegment;
|
||||||
|
pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
|
||||||
|
|
||||||
|
return SEL(pSegment->hSeg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* NE_CreateSegments
|
* NE_CreateSegment
|
||||||
*/
|
*/
|
||||||
BOOL NE_CreateSegments( NE_MODULE *pModule )
|
BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum )
|
||||||
{
|
{
|
||||||
SEGTABLEENTRY *pSegment;
|
SEGTABLEENTRY *pSegment = NE_SEG_TABLE( pModule ) + segnum - 1;
|
||||||
int i, minsize, seg_count;
|
int minsize;
|
||||||
|
|
||||||
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
|
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
|
||||||
|
|
||||||
pSegment = NE_SEG_TABLE( pModule );
|
if ( segnum < 1 || segnum > pModule->seg_count )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (pModule->flags & NE_FFLAGS_SELFLOAD)
|
if ( (pModule->flags & NE_FFLAGS_SELFLOAD) && segnum != 1 )
|
||||||
seg_count = 1;
|
return TRUE; /* selfloader allocates segment itself */
|
||||||
else
|
|
||||||
seg_count = pModule->seg_count;
|
if ( (pSegment->flags & NE_SEGFLAGS_ALLOCATED) && segnum != pModule->dgroup )
|
||||||
for (i = 1; i <= seg_count; i++, pSegment++)
|
return TRUE; /* all but DGROUP only allocated once */
|
||||||
{
|
|
||||||
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
|
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
|
||||||
if (i == pModule->ss) minsize += pModule->stack_size;
|
if ( segnum == pModule->ss ) minsize += pModule->stack_size;
|
||||||
/* The DGROUP is allocated by NE_CreateInstance */
|
if ( segnum == pModule->dgroup ) minsize += pModule->heap_size;
|
||||||
if (i == pModule->dgroup) continue;
|
|
||||||
pSegment->hSeg = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
|
pSegment->hSeg = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
|
||||||
minsize, pModule->self,
|
minsize, pModule->self,
|
||||||
!(pSegment->flags & NE_SEGFLAGS_DATA),
|
!(pSegment->flags & NE_SEGFLAGS_DATA),
|
||||||
(pSegment->flags & NE_SEGFLAGS_32BIT) != 0,
|
(pSegment->flags & NE_SEGFLAGS_32BIT) != 0,
|
||||||
FALSE /*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
|
FALSE /*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
|
||||||
if (!pSegment->hSeg) return FALSE;
|
if (!pSegment->hSeg) return FALSE;
|
||||||
pSegment->flags |= NE_SEGFLAGS_ALLOCATED;
|
|
||||||
}
|
pSegment->flags |= NE_SEGFLAGS_ALLOCATED;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NE_CreateAllSegments
|
||||||
|
*/
|
||||||
|
BOOL NE_CreateAllSegments( NE_MODULE *pModule )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for ( i = 1; i <= pModule->seg_count; i++ )
|
||||||
|
if ( !NE_CreateSegment( pModule, i ) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
pModule->dgroup_entry = pModule->dgroup ? pModule->seg_table +
|
pModule->dgroup_entry = pModule->dgroup ? pModule->seg_table +
|
||||||
(pModule->dgroup - 1) * sizeof(SEGTABLEENTRY) : 0;
|
(pModule->dgroup - 1) * sizeof(SEGTABLEENTRY) : 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user