From 61206bd8a0337855e83b85fac611a18eecda8083 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Sun, 21 Nov 1999 00:50:30 +0000 Subject: [PATCH] Simplified hInstance creation/handling. Fixes problems with self-loaders creating DGROUP themselves. --- include/module.h | 7 +- loader/ne/module.c | 35 ++++------ loader/ne/segment.c | 167 ++++++++++++++++---------------------------- 3 files changed, 75 insertions(+), 134 deletions(-) diff --git a/include/module.h b/include/module.h index af743f64f66..5b86affcc85 100644 --- a/include/module.h +++ b/include/module.h @@ -222,11 +222,10 @@ extern NE_NAMEINFO *NE_FindResourceFromType( LPBYTE pResTab, NE_TYPEINFO *pTypeI /* 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 04f6c05f2aa..a948e978d30 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -799,12 +799,9 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule ) */ 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 @@ static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule ) 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 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock ) /* 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 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock ) 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 @@ BOOL NE_InitProcess( NE_MODULE *pModule ) /* 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 69834385265..af59970ed73 100644 --- a/loader/ne/segment.c +++ b/loader/ne/segment.c @@ -36,6 +36,8 @@ DECLARE_DEBUG_CHANNEL(segment) #define SEL(x) ((x)|1) +static void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum); + /*********************************************************************** * NE_GetRelocAddrName */ @@ -97,14 +99,12 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) /* 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 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) 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 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) } 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 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) 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 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) 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 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) * * 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 @@ DWORD WINAPI PatchCodeHandle16(HANDLE16 hSeg) 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 @@ static WORD NE_Ne2MemFlags(WORD flags) 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 @@ DWORD WINAPI NE_AllocateSegment( WORD wFlags, WORD wSize, WORD wElem ) 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;