diff --git a/loader/ne/module.c b/loader/ne/module.c index 5a02442ab9c..e061794c915 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -1098,7 +1098,11 @@ BOOL NE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR en SYSLEVEL_EnterWin16Lock(); - /* Special case: second instance of an already loaded NE module */ + /* Special case: second instance of an already loaded NE module + * FIXME: maybe we should mark the module in a special way during + * "second instance" loading stage ? + * NE_CreateSegment and NE_LoadSegment might get confused without it, + * especially when it comes to self-loaders */ if ( ( hModule = NE_GetModuleByFilename( filename ) ) != 0 ) { @@ -1173,6 +1177,8 @@ BOOL NE_InitProcess( NE_MODULE *pModule ) NE_LoadSegment( pModule, pModule->dgroup ); hInstance = NE_GetInstance( pModule ); + TRACE("created second instance %04x[%d] of instance %04x.\n", hInstance, pModule->dgroup, hPrevInstance); + } else { @@ -1390,13 +1396,19 @@ WORD WINAPI GetExpWinVer16( HMODULE16 hModule ) * GetModuleFileName16 (KERNEL.49) * * Comment: see GetModuleFileNameA + * + * Even if invoked by second instance of a program, + * it still returns path of first one. */ INT16 WINAPI GetModuleFileName16( HINSTANCE16 hModule, LPSTR lpFileName, INT16 nSize ) { NE_MODULE *pModule; + /* Win95 does not query hModule if set to 0 ! + * Is this wrong or maybe Win3.1 only ? */ if (!hModule) hModule = GetCurrentTask(); + if (!(pModule = NE_GetPtr( hModule ))) return 0; if (pModule->expected_version >= 0x400) GetLongPathNameA(NE_MODULE_NAME(pModule), lpFileName, nSize); diff --git a/loader/ne/segment.c b/loader/ne/segment.c index c51fa25cb39..87e9b7eca90 100644 --- a/loader/ne/segment.c +++ b/loader/ne/segment.c @@ -81,8 +81,16 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) pSegTable = NE_SEG_TABLE( pModule ); pSeg = pSegTable + segnum - 1; - if (pSeg->flags & NE_SEGFLAGS_LOADED) /* already loaded ? */ - return TRUE; + if (pSeg->flags & NE_SEGFLAGS_LOADED) + { + /* self-loader ? -> already loaded it */ + if (pModule->flags & NE_FFLAGS_SELFLOAD) + return TRUE; + + /* leave, except for DGROUP, as this may be the second instance */ + if (segnum != pModule->dgroup) + return TRUE; + } if (!pSeg->filepos) return TRUE; /* No file image, just return */ @@ -815,10 +823,10 @@ HINSTANCE16 NE_GetInstance( NE_MODULE *pModule ) return pModule->self; else { - SEGTABLEENTRY *pSegment; - pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1; + SEGTABLEENTRY *pSeg; + pSeg = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1; - return SEL(pSegment->hSeg); + return SEL(pSeg->hSeg); } } @@ -827,7 +835,7 @@ HINSTANCE16 NE_GetInstance( NE_MODULE *pModule ) */ BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum ) { - SEGTABLEENTRY *pSegment = NE_SEG_TABLE( pModule ) + segnum - 1; + SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ) + segnum - 1; int minsize; assert( !(pModule->flags & NE_FFLAGS_WIN32) ); @@ -838,21 +846,21 @@ BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum ) if ( (pModule->flags & NE_FFLAGS_SELFLOAD) && segnum != 1 ) return TRUE; /* selfloader allocates segment itself */ - if ( (pSegment->flags & NE_SEGFLAGS_ALLOCATED) && segnum != pModule->dgroup ) + if ( (pSeg->flags & NE_SEGFLAGS_ALLOCATED) && segnum != pModule->dgroup ) return TRUE; /* all but DGROUP only allocated once */ - minsize = pSegment->minsize ? pSegment->minsize : 0x10000; + minsize = pSeg->minsize ? pSeg->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), + pSeg->hSeg = GLOBAL_Alloc( NE_Ne2MemFlags(pSeg->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; + !(pSeg->flags & NE_SEGFLAGS_DATA), + (pSeg->flags & NE_SEGFLAGS_32BIT) != 0, + FALSE /*pSeg->flags & NE_SEGFLAGS_READONLY*/ ); + if (!pSeg->hSeg) return FALSE; - pSegment->flags |= NE_SEGFLAGS_ALLOCATED; + pSeg->flags |= NE_SEGFLAGS_ALLOCATED; return TRUE; }