Simplified hInstance creation/handling.
Fixes problems with self-loaders creating DGROUP themselves.
diff --git a/include/module.h b/include/module.h
index af743f6..5b86aff 100644
--- a/include/module.h
+++ b/include/module.h
@@ -222,11 +222,10 @@
/* loader/ne/segment.c */
extern BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum );
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 BOOL NE_CreateSegments( NE_MODULE *pModule );
-extern HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev,
- BOOL lib_only );
/* loader/ne/convert.c */
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size );
diff --git a/loader/ne/module.c b/loader/ne/module.c
index 04f6c05..a948e97 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -799,12 +799,9 @@
*/
static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule )
{
- HINSTANCE16 hInstance;
-
/* Allocate the segments for this module */
- if (!NE_CreateSegments( pModule ) ||
- !(hInstance = NE_CreateInstance( pModule, NULL, FALSE )))
+ if (!NE_CreateAllSegments( pModule ))
return 8; /* Insufficient memory */
/* Load the referenced DLLs */
@@ -816,16 +813,12 @@
NE_LoadAllSegments( pModule );
- /* Fixup the functions prologs */
-
- NE_FixupPrologs( pModule );
-
/* Make sure the usage count is 1 on the first loading of */
/* the module, even if it contains circular DLL references */
pModule->count = 1;
- return hInstance;
+ return NE_GetInstance( pModule );
}
/**********************************************************************
@@ -1002,11 +995,6 @@
/* Increment refcount */
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
{
@@ -1017,13 +1005,12 @@
if ( !(pModule = NE_GetPtr( hModule )) )
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.
@@ -1177,9 +1164,13 @@
/* Second instance of an already loaded NE module */
/* Note that the refcount was already incremented by the parent */
- hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE );
- if ( hInstance != hPrevInstance ) /* not a library */
- NE_LoadSegment( pModule, pModule->dgroup );
+ hPrevInstance = NE_GetInstance( pModule );
+
+ if ( pModule->dgroup )
+ if ( NE_CreateSegment( pModule, pModule->dgroup ) )
+ NE_LoadSegment( pModule, pModule->dgroup );
+
+ hInstance = NE_GetInstance( pModule );
}
else
{
diff --git a/loader/ne/segment.c b/loader/ne/segment.c
index 6983438..af59970 100644
--- a/loader/ne/segment.c
+++ b/loader/ne/segment.c
@@ -36,6 +36,8 @@
#define SEL(x) ((x)|1)
+static void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum);
+
/***********************************************************************
* NE_GetRelocAddrName
*/
@@ -97,14 +99,12 @@
/* Implement self-loading segments */
SELFLOADHEADER *selfloadheader;
DWORD oldstack;
- WORD old_hSeg, new_hSeg;
HFILE hFile32;
HFILE16 hFile16;
selfloadheader = (SELFLOADHEADER *)
PTR_SEG_OFF_TO_LIN(SEL(pSegTable->hSeg),0);
oldstack = NtCurrentTeb()->cur_stack;
- old_hSeg = pSeg->hSeg;
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
0xff00 - sizeof(STACK16FRAME));
@@ -113,29 +113,11 @@
DuplicateHandle( GetCurrentProcess(), hf, GetCurrentProcess(), &hFile32,
0, FALSE, DUPLICATE_SAME_ACCESS );
hFile16 = FILE_AllocDosHandle( hFile32 );
- new_hSeg = Callbacks->CallLoadAppSegProc(selfloadheader->LoadAppSeg,
+ pSeg->hSeg = Callbacks->CallLoadAppSegProc( selfloadheader->LoadAppSeg,
pModule->self, hFile16,
segnum );
- TRACE_(dll)("Ret CallLoadAppSegProc: hSeg = 0x%04x\n",new_hSeg);
+ TRACE_(dll)("Ret CallLoadAppSegProc: hSeg = 0x%04x\n", pSeg->hSeg);
_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;
}
else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED))
@@ -165,6 +147,10 @@
}
pSeg->flags |= NE_SEGFLAGS_LOADED;
+
+ /* Perform exported function prolog fixups */
+ NE_FixupSegmentPrologs( pModule, segnum );
+
if (!(pSeg->flags & NE_SEGFLAGS_RELOC_DATA))
return TRUE; /* No relocation data, we are done */
@@ -396,7 +382,6 @@
SELFLOADHEADER *selfloadheader;
HMODULE16 hselfload = GetModuleHandle16("WPROCS");
DWORD oldstack;
- WORD saved_hSeg = pSegTable[pModule->dgroup - 1].hSeg;
TRACE_(module)("%.*s is a self-loading module!\n",
*((BYTE*)pModule + pModule->name_table),
@@ -420,8 +405,6 @@
Callbacks->CallBootAppProc(selfloadheader->BootApp, pModule->self,hFile16);
TRACE_(dll)("Return from CallBootAppProc\n");
_lclose16(hf);
- /* some BootApp procs overwrite the segment handle of dgroup */
- pSegTable[pModule->dgroup - 1].hSeg = saved_hSeg;
NtCurrentTeb()->cur_stack = oldstack;
for (i = 2; i <= pModule->seg_count; i++)
@@ -441,7 +424,7 @@
*
* 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 );
ET_BUNDLE *bundle;
@@ -537,23 +520,6 @@
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
@@ -746,49 +712,6 @@
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)
*
@@ -817,37 +740,65 @@
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;
- int i, minsize, seg_count;
+ SEGTABLEENTRY *pSegment = NE_SEG_TABLE( pModule ) + segnum - 1;
+ int minsize;
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)
- seg_count = 1;
- else
- seg_count = pModule->seg_count;
- for (i = 1; i <= seg_count; i++, pSegment++)
- {
- minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
- if (i == pModule->ss) minsize += pModule->stack_size;
- /* The DGROUP is allocated by NE_CreateInstance */
- if (i == pModule->dgroup) continue;
- pSegment->hSeg = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
- minsize, pModule->self,
- !(pSegment->flags & NE_SEGFLAGS_DATA),
- (pSegment->flags & NE_SEGFLAGS_32BIT) != 0,
+ if ( (pModule->flags & NE_FFLAGS_SELFLOAD) && segnum != 1 )
+ return TRUE; /* selfloader allocates segment itself */
+
+ if ( (pSegment->flags & NE_SEGFLAGS_ALLOCATED) && segnum != pModule->dgroup )
+ return TRUE; /* all but DGROUP only allocated once */
+
+ minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
+ if ( segnum == pModule->ss ) minsize += pModule->stack_size;
+ if ( segnum == pModule->dgroup ) minsize += pModule->heap_size;
+
+ pSegment->hSeg = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
+ minsize, pModule->self,
+ !(pSegment->flags & NE_SEGFLAGS_DATA),
+ (pSegment->flags & NE_SEGFLAGS_32BIT) != 0,
FALSE /*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
- if (!pSegment->hSeg) return FALSE;
- pSegment->flags |= NE_SEGFLAGS_ALLOCATED;
- }
+ if (!pSegment->hSeg) return FALSE;
+
+ 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 - 1) * sizeof(SEGTABLEENTRY) : 0;