static void fill_init_list( struct ne_init_list *list, HMODULE16 hModule ) { NE_MODULE *pModule; HMODULE16 *pModRef; int i; if (!(pModule = NE_GetPtr( hModule ))) return; assert( !(pModule->ne_flags & NE_FFLAGS_WIN32) ); /* Never add a module twice */ for ( i = 0; i < list->count; i++ ) if ( list->module[i] == pModule ) return; /* Check for recursive call */ if ( pModule->ne_flagsothers & 0x80 ) return; TRACE_(dll)("(%s) - START\n", NE_MODULE_NAME(pModule) ); /* Tag current module to prevent recursive loop */ pModule->ne_flagsothers |= 0x80; /* Recursively attach all DLLs this one depends on */ pModRef = (HMODULE16 *)((char *)pModule + pModule->ne_modtab); for ( i = 0; i < pModule->ne_cmod; i++ ) if ( pModRef[i] ) fill_init_list( list, pModRef[i] ); /* Add current module */ add_to_init_list( list, pModule ); /* Remove recursion flag */ pModule->ne_flagsothers &= ~0x80; TRACE_(dll)("(%s) - END\n", NE_MODULE_NAME(pModule) ); }
/* allocate the win16 TIB for a new 16-bit task */ static WIN16_SUBSYSTEM_TIB *allocate_win16_tib( TDB *pTask ) { WCHAR path[MAX_PATH]; WIN16_SUBSYSTEM_TIB *tib; UNICODE_STRING *curdir; NE_MODULE *pModule = NE_GetPtr( pTask->hModule ); if (!(tib = HeapAlloc( GetProcessHeap(), 0, sizeof(*tib) ))) return NULL; MultiByteToWideChar( CP_ACP, 0, NE_MODULE_NAME(pModule), -1, path, MAX_PATH ); GetLongPathNameW( path, path, MAX_PATH ); if (RtlCreateUnicodeString( &tib->exe_str, path )) tib->exe_name = &tib->exe_str; else tib->exe_name = NULL; RtlAcquirePebLock(); if (NtCurrentTeb()->Tib.SubSystemTib) curdir = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath; else curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath; tib->curdir.DosPath.MaximumLength = sizeof(tib->curdir_buffer); tib->curdir.DosPath.Length = min( curdir->Length, tib->curdir.DosPath.MaximumLength-sizeof(WCHAR) ); tib->curdir.DosPath.Buffer = tib->curdir_buffer; tib->curdir.Handle = 0; memcpy( tib->curdir_buffer, curdir->Buffer, tib->curdir.DosPath.Length ); tib->curdir_buffer[tib->curdir.DosPath.Length/sizeof(WCHAR)] = 0; RtlReleasePebLock(); return tib; }
/*********************************************************************** * NE_OpenFile */ static HFILE16 NE_OpenFile( NE_MODULE *pModule ) { char *name = NE_MODULE_NAME( pModule ); HANDLE handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); if (handle == INVALID_HANDLE_VALUE) { ERR( "Can't open file '%s' for module %04x\n", name, pModule->self ); return HFILE_ERROR; } return Win32HandleToDosFileHandle( handle ); }
static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason ) { WORD hInst, ds, heap; FARPROC16 entryPoint; if (!(pModule->ne_flags & NE_FFLAGS_LIBMODULE)) return; if (!(pModule->ne_flags & NE_FFLAGS_BUILTIN) && pModule->ne_expver < 0x0400) return; if (!(entryPoint = GetProcAddress16( pModule->self, "DllEntryPoint" ))) return; NE_GetDLLInitParams( pModule, &hInst, &ds, &heap ); TRACE_(dll)( "Calling %s DllEntryPoint, cs:ip=%04x:%04x\n", NE_MODULE_NAME( pModule ), SELECTOROF(entryPoint), OFFSETOF(entryPoint) ); if ( pModule->ne_flags & NE_FFLAGS_BUILTIN ) { WinNEEntryProc entryProc = (WinNEEntryProc)((ENTRYPOINT16 *)MapSL( (SEGPTR)entryPoint ))->target; entryProc( dwReason, hInst, ds, heap, 0, 0 ); } else { CONTEXT context; WORD args[8]; memset( &context, 0, sizeof(context) ); context.SegDs = ds; context.SegEs = ds; /* who knows ... */ context.SegFs = wine_get_fs(); context.SegGs = wine_get_gs(); context.SegCs = HIWORD(entryPoint); context.Eip = LOWORD(entryPoint); context.Ebp = OFFSETOF(getWOW32Reserved()) + FIELD_OFFSET(STACK16FRAME,bp); args[7] = HIWORD(dwReason); args[6] = LOWORD(dwReason); args[5] = hInst; args[4] = ds; args[3] = heap; args[2] = 0; /* HIWORD(dwReserved1) */ args[1] = 0; /* LOWORD(dwReserved1) */ args[0] = 0; /* wReserved2 */ WOWCallback16Ex( 0, WCB16_REGS, sizeof(args), args, (DWORD *)&context ); } }
/********************************************************************** * AccessResource (KERNEL.64) */ INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) { HFILE16 fd; NE_MODULE *pModule = NE_GetPtr( hModule ); if (!pModule || !pModule->ne_rsrctab || !hRsrc) return -1; TRACE("module=%04x res=%04x\n", pModule->self, hRsrc ); if ((fd = _lopen16( NE_MODULE_NAME(pModule), OF_READ )) != HFILE_ERROR16) { WORD sizeShift = *(WORD *)((char *)pModule + pModule->ne_rsrctab); NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); _llseek16( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET ); } return fd; }
static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason ) { WORD hInst, ds, heap; FARPROC16 entryPoint; if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) return; if (!(pModule->flags & NE_FFLAGS_BUILTIN) && pModule->expected_version < 0x0400) return; if (!(entryPoint = GetProcAddress16( pModule->self, "DllEntryPoint" ))) return; NE_GetDLLInitParams( pModule, &hInst, &ds, &heap ); TRACE_(dll)( "Calling %s DllEntryPoint, cs:ip=%04x:%04x\n", NE_MODULE_NAME( pModule ), SELECTOROF(entryPoint), OFFSETOF(entryPoint) ); if ( pModule->flags & NE_FFLAGS_BUILTIN ) { WinNEEntryProc entryProc = (WinNEEntryProc)((ENTRYPOINT16 *)MapSL( (SEGPTR)entryPoint ))->target; entryProc( dwReason, hInst, ds, heap, 0, 0 ); } else { LPBYTE stack = (LPBYTE)CURRENT_STACK16; CONTEXT86 context; memset( &context, 0, sizeof(context) ); context.SegDs = ds; context.SegEs = ds; /* who knows ... */ context.SegCs = HIWORD(entryPoint); context.Eip = LOWORD(entryPoint); context.Ebp = OFFSETOF( NtCurrentTeb()->WOW32Reserved ) + (WORD)&((STACK16FRAME*)0)->bp; *(DWORD *)(stack - 4) = dwReason; /* dwReason */ *(WORD *) (stack - 6) = hInst; /* hInst */ *(WORD *) (stack - 8) = ds; /* wDS */ *(WORD *) (stack - 10) = heap; /* wHeapSize */ *(DWORD *)(stack - 14) = 0; /* dwReserved1 */ *(WORD *) (stack - 16) = 0; /* wReserved2 */ wine_call_to_16_regs_short( &context, 16 ); } }