diff --git a/include/dosexe.h b/include/dosexe.h index f8e365ffe36..e9484c1d1ed 100644 --- a/include/dosexe.h +++ b/include/dosexe.h @@ -62,7 +62,7 @@ extern LPDOSTASK MZ_AllocDPMITask( HMODULE16 hModule ); #define V86_FLAG 0x00020000 -extern BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env, +extern BOOL MZ_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ); diff --git a/include/elfdll.h b/include/elfdll.h index c546f4efd1b..65718aa2bf6 100644 --- a/include/elfdll.h +++ b/include/elfdll.h @@ -5,7 +5,7 @@ #include "windef.h" WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR libname, DWORD flags, DWORD *err); -HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname, BOOL implicit); +HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname); void ELFDLL_UnloadLibrary(WINE_MODREF *wm); #if defined(HAVE_DL_API) diff --git a/include/module.h b/include/module.h index 5b86affcc85..509c0794907 100644 --- a/include/module.h +++ b/include/module.h @@ -146,9 +146,10 @@ typedef struct _wine_modref int flags; int refCount; + char *filename; char *modname; - char *shortname; - char *longname; + char *short_filename; + char *short_modname; } WINE_MODREF; #define WINE_MODREF_INTERNAL 0x00000001 @@ -183,7 +184,7 @@ extern void MODULE_DllThreadDetach( LPVOID lpReserved ); extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ); extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm ); extern WINE_MODREF *MODULE_FindModule( LPCSTR path ); -extern HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName, WORD version ); +extern HMODULE MODULE_CreateDummyModule( LPCSTR filename, WORD version ); extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name ); extern SEGPTR WINAPI HasGPHandler16( SEGPTR address ); extern void MODULE_WalkModref( DWORD id ); @@ -201,7 +202,7 @@ extern FARPROC16 WINAPI NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal ); extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop ); extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset ); extern HANDLE NE_OpenFile( NE_MODULE *pModule ); -extern BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, +extern BOOL NE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ); @@ -231,7 +232,6 @@ extern void NE_InitializeDLLs( HMODULE16 hModule ); HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ); /* relay32/builtin.c */ -extern HMODULE BUILTIN32_LoadImage(LPCSTR name, OFSTRUCT *ofs); extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, DWORD *err); extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm); diff --git a/include/pe_image.h b/include/pe_image.h index 28323aa32e3..fc2262b8fdf 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -28,10 +28,10 @@ extern DWORD PE_SizeofResource(HMODULE,HRSRC); extern struct _wine_modref *PE_LoadLibraryExA(LPCSTR, DWORD, DWORD *); extern void PE_UnloadLibrary(struct _wine_modref *); extern HGLOBAL PE_LoadResource(struct _wine_modref *wm,HRSRC); -extern HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName, WORD *version ); -extern struct _wine_modref *PE_CreateModule( HMODULE hModule, OFSTRUCT *ofs, +extern HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename, WORD *version ); +extern struct _wine_modref *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, BOOL builtin ); -extern BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, +extern BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ); diff --git a/loader/dos/module.c b/loader/dos/module.c index 12612f3413f..b48806315b9 100644 --- a/loader/dos/module.c +++ b/loader/dos/module.c @@ -221,7 +221,7 @@ static BOOL MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule ) return TRUE; } -static BOOL MZ_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, +static BOOL MZ_LoadImage( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, LPCSTR env, LPDOSTASK lpDosTask, NE_MODULE *pModule ) { IMAGE_DOS_HEADER mz_header; @@ -230,10 +230,12 @@ static BOOL MZ_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, int x,old_com=0; SEGPTR reloc; WORD env_seg; + DWORD len; - _llseek(hFile,0,FILE_BEGIN); - if ((_lread(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) || - (mz_header.e_magic != IMAGE_DOS_SIGNATURE)) { + SetFilePointer(hFile,0,NULL,FILE_BEGIN); + if ( !ReadFile(hFile,&mz_header,sizeof(mz_header),&len,NULL) + || len != sizeof(mz_header) + || mz_header.e_magic != IMAGE_DOS_SIGNATURE) { old_com=1; /* assume .COM file */ image_start=0; image_size=GetFileSize(hFile,NULL); @@ -254,7 +256,7 @@ static BOOL MZ_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, MZ_InitMemory(lpDosTask,pModule); /* allocate environment block */ - env_seg=MZ_InitEnvironment(lpDosTask,env,ofs->szPathName); + env_seg=MZ_InitEnvironment(lpDosTask,env,filename); /* allocate memory for the executable */ TRACE("Allocating DOS memory (min=%ld, max=%ld)\n",min_size,max_size); @@ -277,8 +279,8 @@ static BOOL MZ_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, /* load executable image */ TRACE("loading DOS %s image, %08lx bytes\n",old_com?"COM":"EXE",image_size); - _llseek(hFile,image_start,FILE_BEGIN); - if ((_lread(hFile,load_start,image_size)) != image_size) { + SetFilePointer(hFile,image_start,NULL,FILE_BEGIN); + if (!ReadFile(hFile,load_start,image_size,&len,NULL) || len != image_size) { SetLastError(ERROR_BAD_FORMAT); return FALSE; } @@ -287,9 +289,9 @@ static BOOL MZ_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, /* load relocation table */ TRACE("loading DOS EXE relocation table, %d entries\n",mz_header.e_crlc); /* FIXME: is this too slow without read buffering? */ - _llseek(hFile,mz_header.e_lfarlc,FILE_BEGIN); + SetFilePointer(hFile,mz_header.e_lfarlc,NULL,FILE_BEGIN); for (x=0; xenv_db->environ; if (alloc) { - if ((hModule = MODULE_CreateDummyModule(ofs, NULL, 0)) < 32) { + if ((hModule = MODULE_CreateDummyModule(filename, 0)) < 32) { SetLastError(hModule); return FALSE; } @@ -480,7 +482,7 @@ BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env, lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1; } else lpDosTask=pModule->lpDosTask; - if (!MZ_LoadImage( hFile, ofs, cmdline, env, lpDosTask, pModule )) { + if (!MZ_LoadImage( hFile, filename, cmdline, env, lpDosTask, pModule )) { if (alloc) { if (lpDosTask->mm_name[0]!=0) { if (lpDosTask->img!=NULL) munmap(lpDosTask->img,0x110000-START_OFFSET); @@ -558,7 +560,7 @@ LPDOSTASK MZ_Current( void ) #else /* !MZ_SUPPORTED */ -BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env, +BOOL MZ_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ) diff --git a/loader/elf.c b/loader/elf.c index d4f9af6aebf..eb49890299f 100644 --- a/loader/elf.c +++ b/loader/elf.c @@ -45,7 +45,9 @@ WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname ) PROCESS_Current()->modref_list = wm; wm->modname = HEAP_strdupA( GetProcessHeap(), 0, modname ); - wm->longname = HEAP_strdupA( GetProcessHeap(), 0, libname ); + wm->filename = HEAP_strdupA( GetProcessHeap(), 0, libname ); + wm->short_modname = wm->modname; + wm->short_filename = wm->filename; hmod = (HMODULE)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMAGE_DOS_HEADER) + diff --git a/loader/elfdll.c b/loader/elfdll.c index f54a6b6a0ca..e3aab966996 100644 --- a/loader/elfdll.c +++ b/loader/elfdll.c @@ -190,57 +190,67 @@ static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path) if(dir->Size) wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress); - wm->modname = HEAP_strdupA(procheap, 0, (char *)RVA(hModule, wm->binfmt.pe.pe_export->Name)); - len = GetLongPathNameA(path, NULL, 0); - wm->longname = (char *)HeapAlloc(procheap, 0, len+1); - GetLongPathNameA(path, wm->longname, len+1); + wm->filename = HEAP_strdupA( procheap, 0, path ); + wm->modname = strrchr( wm->filename, '\\' ); + if (!wm->modname) wm->modname = wm->filename; + else wm->modname++; - wm->shortname = HEAP_strdupA(procheap, 0, path); + len = GetShortPathNameA( wm->filename, NULL, 0 ); + wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 ); + GetShortPathNameA( wm->filename, wm->short_filename, len+1 ); + wm->short_modname = strrchr( wm->short_filename, '\\' ); + if (!wm->short_modname) wm->short_modname = wm->short_filename; + else wm->short_modname++; /* Link MODREF into process list */ + + EnterCriticalSection( &PROCESS_Current()->crit_section ); + wm->next = PROCESS_Current()->modref_list; PROCESS_Current()->modref_list = wm; + if ( wm->next ) wm->next->prev = wm; + + if ( !( nt->FileHeader.Characteristics & IMAGE_FILE_DLL ) + && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) ) - if(!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL)) { - if(PROCESS_Current()->exe_modref) - FIXME_(elfdll)("overwriting old exe_modref... arrgh\n"); - PROCESS_Current()->exe_modref = wm; + if ( PROCESS_Current()->exe_modref ) + FIXME_(elfdll)( "Trying to load second .EXE file: %s\n", path ); + else + PROCESS_Current()->exe_modref = wm; } - /* Fixup Imports */ - if(pe_import && fixup_imports(wm)) - { - /* Error in this module or its dependencies - * remove entry from modref chain - */ - WINE_MODREF **xwm; - for(xwm = &(PROCESS_Current()->modref_list); *xwm; xwm = &((*xwm)->next)) - { - if ( *xwm == wm ) - { - *xwm = wm->next; - break; - } - } - if(wm == PROCESS_Current()->exe_modref) - ERR_(elfdll)("Have to delete current exe_modref. Expect crash now\n"); - HeapFree(procheap, 0, wm->shortname); - HeapFree(procheap, 0, wm->longname); - HeapFree(procheap, 0, wm->modname); - HeapFree(procheap, 0, wm); - return NULL; + LeaveCriticalSection( &PROCESS_Current()->crit_section ); - /* FIXME: We should traverse back in the recursion - * with an error to unload everything that got loaded - * before this error occurred. - * Too dificult for now though and we don't care at the - * moment. But, it *MUST* be implemented someday because - * we won't be able to map the elf-dll twice in this - * address-space which can cause some unexpected and - * weird problems later on. + /* Fixup Imports */ + + if ( pe_import + && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) + && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) + && fixup_imports( wm ) ) + { + /* remove entry from modref chain */ + EnterCriticalSection( &PROCESS_Current()->crit_section ); + + if ( !wm->prev ) + PROCESS_Current()->modref_list = wm->next; + else + wm->prev->next = wm->next; + + if ( wm->next ) wm->next->prev = wm->prev; + wm->next = wm->prev = NULL; + + LeaveCriticalSection( &PROCESS_Current()->crit_section ); + + /* FIXME: there are several more dangling references + * left. Including dlls loaded by this dll before the + * failed one. Unrolling is rather difficult with the + * current structure and we can leave it them lying + * around with no problems, so we don't care. + * As these might reference our wm, we don't free it. */ + return NULL; } return wm; @@ -352,7 +362,7 @@ void ELFDLL_UnloadLibrary(WINE_MODREF *wm) * * Implementation of elf-dll loading for NE modules */ -HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname, BOOL implicit) +HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname) { return (HINSTANCE16)ERROR_FILE_NOT_FOUND; } @@ -374,7 +384,7 @@ void ELFDLL_UnloadLibrary(WINE_MODREF *wm) { } -HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname, BOOL implicit) +HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname) { return (HINSTANCE16)ERROR_FILE_NOT_FOUND; } diff --git a/loader/main.c b/loader/main.c index 7e801b5e5a1..9be7476970b 100644 --- a/loader/main.c +++ b/loader/main.c @@ -291,7 +291,6 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] ) { WINE_MODREF *wm; NE_MODULE *pModule; - OFSTRUCT ofs; HMODULE16 hModule; /* Main initialization */ @@ -302,8 +301,7 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] ) return 0; PROCESS_Current()->exe_modref = wm; - strcpy( ofs.szPathName, wm->modname ); - if ((hModule = MODULE_CreateDummyModule( &ofs, NULL, 0 )) < 32) return 0; + if ((hModule = MODULE_CreateDummyModule( wm->filename, 0 )) < 32) return 0; pModule = (NE_MODULE *)GlobalLock16( hModule ); pModule->flags = NE_FFLAGS_WIN32; pModule->module32 = wm->module; diff --git a/loader/module.c b/loader/module.c index f0173231bba..9e5445853c6 100644 --- a/loader/module.c +++ b/loader/module.c @@ -333,7 +333,7 @@ BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule ) * * Create a dummy NE module for Win32 or Winelib. */ -HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName, WORD version ) +HMODULE MODULE_CreateDummyModule( LPCSTR filename, WORD version ) { HMODULE hModule; NE_MODULE *pModule; @@ -341,16 +341,26 @@ HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName, WORD vers char *pStr,*s; int len; const char* basename; + OFSTRUCT *ofs; + int of_size, size; - INT of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) - + strlen(ofs->szPathName) + 1; - INT size = sizeof(NE_MODULE) + + /* Extract base filename */ + basename = strrchr(filename, '\\'); + if (!basename) basename = filename; + else basename++; + len = strlen(basename); + if ((s = strchr(basename, '.'))) len = s - basename; + + /* Allocate module */ + of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + + strlen(filename) + 1; + size = sizeof(NE_MODULE) + /* loaded file info */ of_size + /* segment table: DS,CS */ 2 * sizeof(SEGTABLEENTRY) + /* name table */ - 9 + + len + 2 + /* several empty tables */ 8; @@ -379,8 +389,10 @@ HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName, WORD vers pModule->self = hModule; /* Set loaded file information */ - memcpy( pModule + 1, ofs, of_size ); - ((OFSTRUCT *)(pModule+1))->cBytes = of_size - 1; + ofs = (OFSTRUCT *)(pModule + 1); + memset( ofs, 0, of_size ); + ofs->cBytes = of_size < 256 ? of_size : 255; /* FIXME */ + strcpy( ofs->szPathName, filename ); pSegment = (SEGTABLEENTRY*)((char*)(pModule + 1) + of_size); pModule->seg_table = (int)pSegment - (int)pModule; @@ -396,21 +408,10 @@ HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName, WORD vers /* Module name */ pStr = (char *)pSegment; pModule->name_table = (int)pStr - (int)pModule; - if ( modName ) - basename = modName; - else - { - basename = strrchr(ofs->szPathName,'\\'); - if (!basename) basename = ofs->szPathName; - else basename++; - } - len = strlen(basename); - if ((s = strchr(basename,'.'))) len = s - basename; - if (len > 8) len = 8; *pStr = len; strncpy( pStr+1, basename, len ); - if (len < 8) pStr[len+1] = 0; - pStr += 9; + pStr[len+1] = 0; + pStr += len+2; /* All tables zero terminated */ pModule->res_table = pModule->import_table = pModule->entry_table = @@ -425,9 +426,6 @@ HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName, WORD vers * MODULE_FindModule32 * * Find a (loaded) win32 module depending on path - * The handling of '.' is a bit weird, but we need it that way, - * for sometimes the programs use '.exe' and '.dll' and - * this is the only way to differentiate. (mainly hypertrm.exe) * * RETURNS * the module handle if found @@ -436,66 +434,27 @@ HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName, WORD vers WINE_MODREF *MODULE_FindModule( LPCSTR path /* [in] pathname of module/library to be found */ ) { - LPSTR filename; - LPSTR dotptr; WINE_MODREF *wm; + char dllname[260], *p; - if (!(filename = strrchr( path, '\\' ))) - filename = HEAP_strdupA( GetProcessHeap(), 0, path ); - else - filename = HEAP_strdupA( GetProcessHeap(), 0, filename+1 ); - dotptr=strrchr(filename,'.'); + /* Append .DLL to name if no extension present */ + strcpy( dllname, path ); + if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\')) + strcat( dllname, ".DLL" ); - for ( wm = PROCESS_Current()->modref_list; wm; wm=wm->next ) { - LPSTR xmodname,xdotptr; - - assert (wm->modname); - xmodname = HEAP_strdupA( GetProcessHeap(), 0, wm->modname ); - xdotptr=strrchr(xmodname,'.'); - if ( (xdotptr && !dotptr) || - (!xdotptr && dotptr) - ) { - if (dotptr) *dotptr = '\0'; - if (xdotptr) *xdotptr = '\0'; - } - if (!strcasecmp( filename, xmodname)) { - HeapFree( GetProcessHeap(), 0, filename ); - HeapFree( GetProcessHeap(), 0, xmodname ); - return wm; - } - if (dotptr) *dotptr='.'; - /* FIXME: add paths, shortname */ - HeapFree( GetProcessHeap(), 0, xmodname ); + for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next ) + { + if ( !strcasecmp( dllname, wm->modname ) ) + break; + if ( !strcasecmp( dllname, wm->filename ) ) + break; + if ( !strcasecmp( dllname, wm->short_modname ) ) + break; + if ( !strcasecmp( dllname, wm->short_filename ) ) + break; } - /* if that fails, try looking for the filename... */ - for ( wm = PROCESS_Current()->modref_list; wm; wm=wm->next ) { - LPSTR xlname,xdotptr; - assert (wm->longname); - xlname = strrchr(wm->longname,'\\'); - if (!xlname) - xlname = wm->longname; - else - xlname++; - xlname = HEAP_strdupA( GetProcessHeap(), 0, xlname ); - xdotptr=strrchr(xlname,'.'); - if ( (xdotptr && !dotptr) || - (!xdotptr && dotptr) - ) { - if (dotptr) *dotptr = '\0'; - if (xdotptr) *xdotptr = '\0'; - } - if (!strcasecmp( filename, xlname)) { - HeapFree( GetProcessHeap(), 0, filename ); - HeapFree( GetProcessHeap(), 0, xlname ); - return wm; - } - if (dotptr) *dotptr='.'; - /* FIXME: add paths, shortname */ - HeapFree( GetProcessHeap(), 0, xlname ); - } - HeapFree( GetProcessHeap(), 0, filename ); - return NULL; + return wm; } /*********************************************************************** @@ -528,16 +487,18 @@ WINE_MODREF *MODULE_FindModule( * Note that .COM and .PIF files are only recognized by their * file name extension; but Windows does it the same way ... */ -static BOOL MODULE_GetBinaryType( HFILE hfile, OFSTRUCT *ofs, +static BOOL MODULE_GetBinaryType( HANDLE hfile, LPCSTR filename, LPDWORD lpBinaryType ) { IMAGE_DOS_HEADER mz_header; char magic[4], *ptr; + DWORD len; /* Seek to the start of the file and read the DOS header information. */ - if ( _llseek( hfile, 0, SEEK_SET ) >= 0 && - _lread( hfile, &mz_header, sizeof(mz_header) ) == sizeof(mz_header) ) + if ( SetFilePointer( hfile, 0, NULL, SEEK_SET ) != -1 + && ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL ) + && len == sizeof(mz_header) ) { /* Now that we have the header check the e_magic field * to see if this is a dos image. @@ -559,9 +520,10 @@ static BOOL MODULE_GetBinaryType( HFILE hfile, OFSTRUCT *ofs, if ( (mz_header.e_cparhdr<<4) >= sizeof(IMAGE_DOS_HEADER) ) if ( ( mz_header.e_crlc == 0 ) || ( mz_header.e_lfarlc >= sizeof(IMAGE_DOS_HEADER) ) ) - if ( mz_header.e_lfanew >= sizeof(IMAGE_DOS_HEADER) && - _llseek( hfile, mz_header.e_lfanew, SEEK_SET ) >= 0 && - _lread( hfile, magic, sizeof(magic) ) == sizeof(magic) ) + if ( mz_header.e_lfanew >= sizeof(IMAGE_DOS_HEADER) + && SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ) != -1 + && ReadFile( hfile, magic, sizeof(magic), &len, NULL ) + && len == sizeof(magic) ) lfanewValid = TRUE; if ( !lfanewValid ) @@ -595,8 +557,9 @@ static BOOL MODULE_GetBinaryType( HFILE hfile, OFSTRUCT *ofs, */ IMAGE_OS2_HEADER ne; - if ( _llseek( hfile, mz_header.e_lfanew, SEEK_SET ) >= 0 && - _lread( hfile, &ne, sizeof(ne) ) == sizeof(ne) ) + if ( SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ) != -1 + && ReadFile( hfile, &ne, sizeof(ne), &len, NULL ) + && len == sizeof(ne) ) { switch ( ne.operating_system ) { @@ -621,7 +584,7 @@ static BOOL MODULE_GetBinaryType( HFILE hfile, OFSTRUCT *ofs, /* If we get here, we don't even have a correct MZ header. * Try to check the file extension for known types ... */ - ptr = strrchr( ofs->szPathName, '.' ); + ptr = strrchr( filename, '.' ); if ( ptr && !strchr( ptr, '\\' ) && !strchr( ptr, '/' ) ) { if ( !lstrcmpiA( ptr, ".COM" ) ) @@ -646,8 +609,7 @@ static BOOL MODULE_GetBinaryType( HFILE hfile, OFSTRUCT *ofs, BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ) { BOOL ret = FALSE; - HFILE hfile; - OFSTRUCT ofs; + HANDLE hfile; TRACE_(win32)("%s\n", lpApplicationName ); @@ -658,12 +620,14 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ) /* Open the file indicated by lpApplicationName for reading. */ - if ( (hfile = OpenFile( lpApplicationName, &ofs, OF_READ )) == HFILE_ERROR ) + hfile = CreateFileA( lpApplicationName, GENERIC_READ, 0, + NULL, OPEN_EXISTING, 0, -1 ); + if ( hfile == INVALID_HANDLE_VALUE ) return FALSE; /* Check binary type */ - ret = MODULE_GetBinaryType( hfile, &ofs, lpBinaryType ); + ret = MODULE_GetBinaryType( hfile, lpApplicationName, lpBinaryType ); /* Close the file. */ @@ -997,10 +961,10 @@ static BOOL make_lpApplicationName_name( LPCSTR line, LPSTR name, int namelen) { LPCSTR from; LPSTR to, to_end, to_old; - DOS_FULL_NAME full_name; + char buffer[260]; - to = name; - to_end = to + namelen - 1; + to = buffer; + to_end = to + sizeof(buffer) - 1; to_old = to; while ( *line == ' ' ) line++; /* point to beginning of string */ @@ -1037,17 +1001,10 @@ static BOOL make_lpApplicationName_name( LPCSTR line, LPSTR name, int namelen) break; /* exit if out of input string */ } while (1); - if (!DOSFS_GetFullName(name, TRUE, &full_name)) { - TRACE_(module)("file not found '%s'\n", name ); + if (!SearchPathA( NULL, buffer, ".exe", namelen, name, NULL )) { + TRACE_(module)("file not found '%s'\n", buffer ); return FALSE; - } - - if (strlen(full_name.long_name) >= namelen ) { - FIXME_(module)("name longer than buffer (len=%d), file=%s\n", - namelen, full_name.long_name); - return FALSE; } - strcpy(name, full_name.long_name); TRACE_(module)("selected as file name '%s'\n", name ); return TRUE; @@ -1066,8 +1023,7 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, { BOOL retv = FALSE; BOOL found_file = FALSE; - HFILE hFile; - OFSTRUCT ofs; + HANDLE hFile; DWORD type; char name[256], dummy[256]; LPCSTR cmdline = NULL; @@ -1167,13 +1123,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, if (lpStartupInfo->dwFlags & STARTF_USEHOTKEY) FIXME_(module)("(%s,...): STARTF_USEHOTKEY ignored\n", name); - /* Check for special case: second instance of NE module */ - - lstrcpynA( ofs.szPathName, name, sizeof( ofs.szPathName ) ); - retv = NE_CreateProcess( HFILE_ERROR, &ofs, tidy_cmdline, lpEnvironment, - lpProcessAttributes, lpThreadAttributes, - bInheritHandles, dwCreationFlags, - lpStartupInfo, lpProcessInfo ); /* Load file and create process */ @@ -1181,14 +1130,16 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, { /* Open file and determine executable type */ - if ( (hFile = OpenFile( name, &ofs, OF_READ )) == HFILE_ERROR ) + hFile = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, 0, -1 ); + if ( hFile == INVALID_HANDLE_VALUE ) { SetLastError( ERROR_FILE_NOT_FOUND ); HeapFree( GetProcessHeap(), 0, tidy_cmdline ); return FALSE; } - if ( !MODULE_GetBinaryType( hFile, &ofs, &type ) ) + if ( !MODULE_GetBinaryType( hFile, name, &type ) ) { CloseHandle( hFile ); @@ -1210,21 +1161,21 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, switch ( type ) { case SCS_32BIT_BINARY: - retv = PE_CreateProcess( hFile, &ofs, tidy_cmdline, lpEnvironment, + retv = PE_CreateProcess( hFile, name, tidy_cmdline, lpEnvironment, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpStartupInfo, lpProcessInfo ); break; case SCS_DOS_BINARY: - retv = MZ_CreateProcess( hFile, &ofs, tidy_cmdline, lpEnvironment, + retv = MZ_CreateProcess( hFile, name, tidy_cmdline, lpEnvironment, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpStartupInfo, lpProcessInfo ); break; case SCS_WOW_BINARY: - retv = NE_CreateProcess( hFile, &ofs, tidy_cmdline, lpEnvironment, + retv = NE_CreateProcess( hFile, name, tidy_cmdline, lpEnvironment, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpStartupInfo, lpProcessInfo ); @@ -1329,9 +1280,9 @@ DWORD WINAPI GetModuleFileNameA( return 0; if (PE_HEADER(wm->module)->OptionalHeader.MajorOperatingSystemVersion >= 4.0) - lstrcpynA( lpFileName, wm->longname, size ); + lstrcpynA( lpFileName, wm->filename, size ); else - lstrcpynA( lpFileName, wm->shortname, size ); + lstrcpynA( lpFileName, wm->short_filename, size ); TRACE_(module)("%s\n", lpFileName ); return strlen(lpFileName); diff --git a/loader/ne/module.c b/loader/ne/module.c index cf979145b6e..26f083e9e1b 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -36,6 +36,7 @@ DEFAULT_DEBUG_CHANNEL(module) static NE_MODULE *pCachedModule = 0; /* Module cached by NE_OpenFile */ +static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only ); static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep ); static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only ); @@ -394,7 +395,7 @@ HANDLE NE_OpenFile( NE_MODULE *pModule ) /*********************************************************************** * NE_LoadExeHeader */ -static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) +static HMODULE16 NE_LoadExeHeader( LPCSTR filename ) { IMAGE_DOS_HEADER mz_header; IMAGE_OS2_HEADER ne_header; @@ -406,6 +407,12 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) int fastload_offset = 0, fastload_length = 0; ET_ENTRY *entry; ET_BUNDLE *bundle, *oldbundle; + HFILE16 hFile; + OFSTRUCT ofs; + + /* Open file */ + if ((hFile = OpenFile16( filename, &ofs, OF_READ )) == HFILE_ERROR16) + return (HMODULE16)2; /* File not found */ /* Read a block from either the file or the fast-load area. */ #define READ(offset,size,buffer) \ @@ -418,17 +425,24 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) _llseek16( hFile, 0, SEEK_SET ); if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) || (mz_header.e_magic != IMAGE_DOS_SIGNATURE)) + { + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ + } _llseek16( hFile, mz_header.e_lfanew, SEEK_SET ); if (_hread16( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header)) + { + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ + } if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21; /* win32 exe */ if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11; /* invalid exe */ if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) { MESSAGE("Sorry, this is an OS/2 linear executable (LX) file !\n"); + _lclose16( hFile ); return (HMODULE16)12; } @@ -451,10 +465,15 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) sizeof(ET_BUNDLE) + 2 * (ne_header.entry_tab_length - ne_header.n_mov_entry_points*6) + /* loaded file info */ - sizeof(OFSTRUCT)-sizeof(ofs->szPathName)+strlen(ofs->szPathName)+1; + sizeof(OFSTRUCT)-sizeof(ofs.szPathName)+strlen(ofs.szPathName)+1; hModule = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, size ); - if (!hModule) return (HMODULE16)11; /* invalid exe */ + if (!hModule) + { + _lclose16( hFile ); + return (HMODULE16)11; /* invalid exe */ + } + FarSetOwner16( hModule, hModule ); pModule = (NE_MODULE *)GlobalLock16( hModule ); memcpy( pModule, &ne_header, sizeof(ne_header) ); @@ -510,6 +529,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (fastload) HeapFree( SystemHeap, 0, fastload ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } pSeg = (struct ne_segment_table_entry_s *)buffer; @@ -525,6 +545,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (fastload) HeapFree( SystemHeap, 0, fastload ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } @@ -535,7 +556,11 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) pModule->res_table = (int)pData - (int)pModule; if (!READ(mz_header.e_lfanew + ne_header.resource_tab_offset, ne_header.rname_tab_offset - ne_header.resource_tab_offset, - pData )) return (HMODULE16)11; /* invalid exe */ + pData )) + { + _lclose16( hFile ); + return (HMODULE16)11; /* invalid exe */ + } pData += ne_header.rname_tab_offset - ne_header.resource_tab_offset; NE_InitResourceHandler( hModule ); } @@ -551,6 +576,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (fastload) HeapFree( SystemHeap, 0, fastload ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } pData += ne_header.moduleref_tab_offset - ne_header.rname_tab_offset; @@ -567,6 +593,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (fastload) HeapFree( SystemHeap, 0, fastload ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } pData += ne_header.n_mod_ref_tab * sizeof(WORD); @@ -583,6 +610,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (fastload) HeapFree( SystemHeap, 0, fastload ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } pData += ne_header.entry_tab_offset - ne_header.iname_tab_offset; @@ -602,6 +630,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (fastload) HeapFree( SystemHeap, 0, fastload ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } @@ -667,6 +696,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (fastload) HeapFree( SystemHeap, 0, fastload ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } @@ -679,9 +709,9 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) /* Store the filename information */ pModule->fileinfo = (int)pData - (int)pModule; - size = sizeof(OFSTRUCT)-sizeof(ofs->szPathName)+strlen(ofs->szPathName)+1; - memcpy( pData, ofs, size ); - ((OFSTRUCT *)pData)->cBytes = size - 1; + size = sizeof(OFSTRUCT)-sizeof(ofs.szPathName)+strlen(ofs.szPathName)+1; + ofs.cBytes = size - 1; + memcpy( pData, &ofs, size ); pData += size; /* Free the fast-load area */ @@ -699,6 +729,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) if (!pModule->nrname_handle) { GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } buffer = GlobalLock16( pModule->nrname_handle ); @@ -708,6 +739,7 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) { GlobalFree16( pModule->nrname_handle ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } } @@ -724,14 +756,16 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) { if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle ); GlobalFree16( hModule ); + _lclose16( hFile ); return (HMODULE16)11; /* invalid exe */ } } else pModule->dlls_to_init = 0; NE_RegisterModule( pModule ); - SNOOP16_RegisterDLL(pModule,ofs->szPathName); + SNOOP16_RegisterDLL(pModule,ofs.szPathName); + _lclose16( hFile ); return hModule; } @@ -749,10 +783,10 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule ) for (i = 0; i < pModule->modref_count; i++, pModRef++) { - char buffer[260]; + char buffer[260], *p; BYTE *pstr = (BYTE *)pModule + pModule->import_table + *pModRef; memcpy( buffer, pstr + 1, *pstr ); - *(buffer + *pstr) = 0; /* terminate it */ + *(buffer + *pstr) = 0; /* terminate it */ TRACE("Loading '%s'\n", buffer ); if (!(*pModRef = GetModuleHandle16( buffer ))) @@ -761,6 +795,10 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule ) /* its handle in the list of DLLs to initialize. */ HMODULE16 hDLL; + /* Append .DLL to name if no extension present */ + if (!(p = strrchr( buffer, '.')) || strchr( p, '/' ) || strchr( p, '\\')) + strcat( buffer, ".DLL" ); + if ((hDLL = MODULE_LoadModule16( buffer, TRUE, TRUE )) < 32) { /* FIXME: cleanup what was done */ @@ -833,32 +871,15 @@ static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule ) * like a DLL module, even if it is an executable module. * */ -HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit, BOOL lib_only ) +static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only ) { NE_MODULE *pModule; HMODULE16 hModule; HINSTANCE16 hInstance; - HFILE16 hFile; - OFSTRUCT ofs; - - if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16) - { - char buffer[260]; - - if(implicit) - { - /* 4 == strlen(".dll") */ - strncpy(buffer, name, sizeof(buffer) - 1 - 4); - strcat(buffer, ".dll"); - if ((hFile = OpenFile16( buffer, &ofs, OF_READ )) == HFILE_ERROR16) - return 2; /* File not found */ - } - } - - hModule = NE_LoadExeHeader( hFile, &ofs ); - _lclose16( hFile ); + hModule = NE_LoadExeHeader( name ); if (hModule < 32) return hModule; + pModule = NE_GetPtr( hModule ); if ( !pModule ) return hModule; @@ -897,12 +918,12 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_ { case MODULE_LOADORDER_DLL: TRACE("Trying native dll '%s'\n", libname); - hinst = NE_LoadModule(libname, implicit, lib_only); + hinst = NE_LoadModule(libname, lib_only); break; case MODULE_LOADORDER_ELFDLL: TRACE("Trying elfdll '%s'\n", libname); - hinst = ELFDLL_LoadModule16(libname, implicit); + hinst = ELFDLL_LoadModule16(libname); break; case MODULE_LOADORDER_BI: @@ -1064,20 +1085,19 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock ) /********************************************************************** * NE_CreateProcess */ -BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, +BOOL NE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ) { HMODULE16 hModule; NE_MODULE *pModule; - HFILE16 hFile16; SYSLEVEL_EnterWin16Lock(); /* Special case: second instance of an already loaded NE module */ - if ( ( hModule = NE_GetModuleByFilename( ofs->szPathName ) ) != 0 ) + if ( ( hModule = NE_GetModuleByFilename( filename ) ) != 0 ) { if ( !( pModule = NE_GetPtr( hModule) ) || ( pModule->flags & NE_FFLAGS_LIBMODULE ) @@ -1093,27 +1113,9 @@ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, /* Main case: load first instance of NE module */ else { - /* If we didn't get a file handle, return */ - - if ( hFile == HFILE_ERROR ) - goto error; - - /* Allocate temporary HFILE16 for NE_LoadFileModule */ - - if (!DuplicateHandle( GetCurrentProcess(), hFile, - GetCurrentProcess(), &hFile, - 0, FALSE, DUPLICATE_SAME_ACCESS )) - { - SetLastError( ERROR_INVALID_HANDLE ); - goto error; - } - hFile16 = FILE_AllocDosHandle( hFile ); - /* Load module */ - hModule = NE_LoadExeHeader( hFile16, ofs ); - _lclose16( hFile16 ); - + hModule = NE_LoadExeHeader( filename ); if ( hModule < 32 ) { SetLastError( hModule ); diff --git a/loader/pe_image.c b/loader/pe_image.c index 65a38623561..df01966abd9 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -278,18 +278,7 @@ DWORD fixup_imports( WINE_MODREF *wm ) if (characteristics_detection && !pe_imp->u.Characteristics) break; - /* don't use MODULE_Load, Win32 creates new task differently */ wmImp = MODULE_LoadLibraryExA( name, 0, 0 ); - if (!wmImp) { - char *p,buffer[2000]; - - /* GetModuleFileName would use the wrong process, so don't use it */ - strcpy(buffer,wm->shortname); - if (!(p = strrchr (buffer, '\\'))) - p = buffer; - strcpy (p + 1, name); - wmImp = MODULE_LoadLibraryExA( buffer, 0, 0 ); - } if (!wmImp) { ERR_(module)("Module %s not found\n", name); return 1; @@ -459,7 +448,7 @@ static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r ) * BUT we have to map the whole image anyway, for Win32 programs sometimes * want to access them. (HMODULE32 point to the start of it) */ -HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName, WORD *version ) +HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename, WORD *version ) { HMODULE hModule; HANDLE mapping; @@ -549,7 +538,7 @@ HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName, WORD *version FIXME_(win32)("WARNING: '%s' has an invalid entrypoint (0x%08lx) " "below the first virtual address (0x%08x) " "(possible Virus Infection or broken binary)!\n", - ofs->szPathName, aoep, lowest_va ); + filename, aoep, lowest_va ); /* FIXME: Hack! While we don't really support shared sections yet, @@ -598,7 +587,7 @@ HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName, WORD *version { FIXME_(win32)( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n", - ofs->szPathName, + filename, (nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)? "stripped during link" : "unknown reason" ); goto error; @@ -619,7 +608,7 @@ HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName, WORD *version TRACE_(win32)("Load addr is %lx (base %lx), range %x\n", load_addr, nt->OptionalHeader.ImageBase, vma_size ); TRACE_(segment)("Loading %s at %lx, range %x\n", - ofs->szPathName, load_addr, vma_size ); + filename, load_addr, vma_size ); /* Store the NT header at the load addr */ *(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule; @@ -658,11 +647,6 @@ HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName, WORD *version if ( reloc ) do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) ); - /* Get module name */ - dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; - if (dir->Size) - *modName = (LPCSTR)RVA(((PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress))->Name); - /* Get expected OS / Subsystem version */ *version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | (nt->OptionalHeader.MinorSubsystemVersion & 0xff); @@ -690,7 +674,7 @@ error: * process that is to own the module to be created. */ WINE_MODREF *PE_CreateModule( HMODULE hModule, - OFSTRUCT *ofs, DWORD flags, BOOL builtin ) + LPCSTR filename, DWORD flags, BOOL builtin ) { DWORD load_addr = (DWORD)hModule; /* for RVA */ IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); @@ -700,7 +684,6 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL; WINE_MODREF *wm; int result; - char *modname; /* Retrieve DataDirectory entries */ @@ -799,22 +782,17 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, wm->binfmt.pe.pe_resource = pe_resource; wm->binfmt.pe.tlsindex = -1; - if ( pe_export ) - modname = (char *)RVA( pe_export->Name ); - else - { - /* try to find out the name from the OFSTRUCT */ - char *s; - modname = ofs->szPathName; - if ((s=strrchr(modname,'\\'))) modname = s+1; - } - wm->modname = HEAP_strdupA( GetProcessHeap(), 0, modname ); + wm->filename = HEAP_strdupA( GetProcessHeap(), 0, filename ); + wm->modname = strrchr( wm->filename, '\\' ); + if (!wm->modname) wm->modname = wm->filename; + else wm->modname++; - result = GetLongPathNameA( ofs->szPathName, NULL, 0 ); - wm->longname = (char *)HeapAlloc( GetProcessHeap(), 0, result+1 ); - GetLongPathNameA( ofs->szPathName, wm->longname, result+1 ); - - wm->shortname = HEAP_strdupA( GetProcessHeap(), 0, ofs->szPathName ); + result = GetShortPathNameA( wm->filename, NULL, 0 ); + wm->short_filename = (char *)HeapAlloc( GetProcessHeap(), 0, result+1 ); + GetShortPathNameA( wm->filename, wm->short_filename, result+1 ); + wm->short_modname = strrchr( wm->short_filename, '\\' ); + if (!wm->short_modname) wm->short_modname = wm->short_filename; + else wm->short_modname++; /* Link MODREF into process list */ @@ -824,11 +802,14 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, PROCESS_Current()->modref_list = wm; if ( wm->next ) wm->next->prev = wm; - if ( !(nt->FileHeader.Characteristics & IMAGE_FILE_DLL) ) + if ( !( nt->FileHeader.Characteristics & IMAGE_FILE_DLL ) + && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) ) + { if ( PROCESS_Current()->exe_modref ) - FIXME_(win32)("overwriting old exe_modref... arrgh\n" ); - PROCESS_Current()->exe_modref = wm; + FIXME_(win32)( "Trying to load second .EXE file: %s\n", filename ); + else + PROCESS_Current()->exe_modref = wm; } LeaveCriticalSection( &PROCESS_Current()->crit_section ); @@ -878,41 +859,41 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, */ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags, DWORD *err) { - LPCSTR modName = NULL; - OFSTRUCT ofs; HMODULE hModule32; HMODULE16 hModule16; NE_MODULE *pModule; WINE_MODREF *wm; - char dllname[256], *p; - HFILE hFile; + char filename[256]; + HANDLE hFile; WORD version = 0; - /* Append .DLL to name if no extension present */ - strcpy( dllname, name ); - if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\')) - strcat( dllname, ".DLL" ); - - /* Load PE module */ - hFile = OpenFile( dllname, &ofs, OF_READ | OF_SHARE_DENY_WRITE ); - if ( hFile != HFILE_ERROR ) - { - hModule32 = PE_LoadImage( hFile, &ofs, &modName, &version ); - CloseHandle( hFile ); - if(!hModule32) - { - *err = ERROR_OUTOFMEMORY; /* Not entirely right, but good enough */ - return NULL; - } - } - else + /* Search for and open PE file */ + if ( SearchPathA( NULL, name, ".DLL", + sizeof(filename), filename, NULL ) == 0 ) { *err = ERROR_FILE_NOT_FOUND; return NULL; } + + hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, 0, -1 ); + if ( hFile == INVALID_HANDLE_VALUE ) + { + *err = ERROR_FILE_NOT_FOUND; + return NULL; + } + + /* Load PE module */ + hModule32 = PE_LoadImage( hFile, filename, &version ); + CloseHandle( hFile ); + if (!hModule32) + { + *err = ERROR_OUTOFMEMORY; /* Not entirely right, but good enough */ + return NULL; + } /* Create 16-bit dummy module */ - if ((hModule16 = MODULE_CreateDummyModule( &ofs, modName, version )) < 32) + if ((hModule16 = MODULE_CreateDummyModule( filename, version )) < 32) { *err = (DWORD)hModule16; /* This should give the correct error */ return NULL; @@ -922,9 +903,9 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags, DWORD *err) pModule->module32 = hModule32; /* Create 32-bit MODREF */ - if ( !(wm = PE_CreateModule( hModule32, &ofs, flags, FALSE )) ) + if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) ) { - ERR_(win32)("can't load %s\n",ofs.szPathName); + ERR_(win32)( "can't load %s\n", filename ); FreeLibrary16( hModule16 ); *err = ERROR_OUTOFMEMORY; return NULL; @@ -953,19 +934,18 @@ void PE_UnloadLibrary(WINE_MODREF *wm) * FIXME: this function should use PE_LoadLibraryExA, but currently can't * due to the PROCESS_Create stuff. */ -BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, +BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ) { - LPCSTR modName = NULL; WORD version = 0; HMODULE16 hModule16; HMODULE hModule32; NE_MODULE *pModule; /* Load file */ - if ( (hModule32 = PE_LoadImage( hFile, ofs, &modName, &version )) < 32 ) + if ( (hModule32 = PE_LoadImage( hFile, filename, &version )) < 32 ) { SetLastError( hModule32 ); return FALSE; @@ -979,7 +959,7 @@ BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, #endif /* Create 16-bit dummy module */ - if ( (hModule16 = MODULE_CreateDummyModule( ofs, modName, version )) < 32 ) + if ( (hModule16 = MODULE_CreateDummyModule( filename, version )) < 32 ) { SetLastError( hModule16 ); return FALSE; diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 6f769789d15..7944c2e9a17 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -410,107 +410,78 @@ static HMODULE BUILTIN32_DoLoadImage( BUILTIN32_DLL *dll ) return (HMODULE)addr; } -/*********************************************************************** - * BUILTIN32_LoadImage - * - * Load a built-in module. - */ -HMODULE BUILTIN32_LoadImage( LPCSTR name, OFSTRUCT *ofs) -{ - BUILTIN32_DLL *table; - char dllname[16], *p; - - /* Fix the name in case we have a full path and extension */ - - if ((p = strrchr( name, '\\' ))) name = p + 1; - lstrcpynA( dllname, name, sizeof(dllname) ); - - p = strrchr( dllname, '.' ); - - if (!p) strcat( dllname, ".dll" ); - - for (table = BuiltinDLLs; table->descr; table++) - { - if (!lstrcmpiA( table->descr->filename, dllname )) break; - } - - if (!table->descr) return 0; - - if ( (table->flags & BI32_INSTANTIATED) && (table->flags & BI32_DANGER) ) - { - ERR_(module)("Attemp to instantiate built-in dll '%s' twice in the same address-space. Expect trouble!\n", - table->descr->name); - } - - strcpy( ofs->szPathName, table->descr->filename ); - - if ( !table->hModule ) - table->hModule = BUILTIN32_DoLoadImage( table ); - - if ( table->hModule ) - table->flags |= BI32_INSTANTIATED; - - return table->hModule; -} - - /*********************************************************************** * BUILTIN32_LoadLibraryExA * * Partly copied from the original PE_ version. * - * Note: This implementation is not very nice and should be one with - * the BUILTIN32_LoadImage function. But, we don't care too much - * because this code will obsolete itself shortly when we get the - * modularization of wine implemented (BS 05-Mar-1999). */ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err) { - LPCSTR modName = NULL; - OFSTRUCT ofs; - HMODULE hModule32; - HMODULE16 hModule16; - NE_MODULE *pModule; - WINE_MODREF *wm; - char dllname[256], *p; + BUILTIN32_DLL *table; + HMODULE16 hModule16; + NE_MODULE *pModule; + WINE_MODREF *wm; + char dllname[256], *p; - /* Append .DLL to name if no extension present */ - strcpy( dllname, path ); - if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\')) - strcat( dllname, ".DLL" ); + /* Fix the name in case we have a full path and extension */ + if ((p = strrchr( path, '\\' ))) path = p + 1; + lstrcpynA( dllname, path, sizeof(dllname) ); - hModule32 = BUILTIN32_LoadImage(path, &ofs); - if(!hModule32) - { - *err = ERROR_FILE_NOT_FOUND; - return NULL; - } + p = strrchr( dllname, '.' ); + if (!p) strcat( dllname, ".dll" ); - /* Create 16-bit dummy module */ - if ((hModule16 = MODULE_CreateDummyModule( &ofs, modName, 0 )) < 32) - { - *err = (DWORD)hModule16; - return NULL; /* FIXME: Should unload the builtin module */ - } + /* Search built-in descriptor */ + for ( table = BuiltinDLLs; table->descr; table++ ) + if (!lstrcmpiA( table->descr->filename, dllname )) break; - pModule = (NE_MODULE *)GlobalLock16( hModule16 ); - pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN; - pModule->module32 = hModule32; + if ( !table->descr ) + { + *err = ERROR_FILE_NOT_FOUND; + return NULL; + } - /* Create 32-bit MODREF */ - if ( !(wm = PE_CreateModule( hModule32, &ofs, flags, TRUE )) ) - { - ERR_(win32)("can't load %s\n",ofs.szPathName); - FreeLibrary16( hModule16 ); /* FIXME: Should unload the builtin module */ - *err = ERROR_OUTOFMEMORY; - return NULL; - } + /* Load built-in module */ + if ( (table->flags & BI32_INSTANTIATED) && (table->flags & BI32_DANGER) ) + ERR_(module)( "Attempt to instantiate built-in dll '%s' twice " + "in the same address-space. Expect trouble!\n", + table->descr->name ); - if (wm->binfmt.pe.pe_export) - SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions); + if ( !table->hModule ) + table->hModule = BUILTIN32_DoLoadImage( table ); + if ( table->hModule ) + table->flags |= BI32_INSTANTIATED; + else + { + *err = ERROR_FILE_NOT_FOUND; + return NULL; + } - *err = 0; - return wm; + /* Create 16-bit dummy module */ + if ((hModule16 = MODULE_CreateDummyModule( dllname, 0 )) < 32) + { + *err = (DWORD)hModule16; + return NULL; /* FIXME: Should unload the builtin module */ + } + + pModule = (NE_MODULE *)GlobalLock16( hModule16 ); + pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN; + pModule->module32 = table->hModule; + + /* Create 32-bit MODREF */ + if ( !(wm = PE_CreateModule( table->hModule, dllname, flags, TRUE )) ) + { + ERR_(win32)( "can't load %s\n", path ); + FreeLibrary16( hModule16 ); /* FIXME: Should unload the builtin module */ + *err = ERROR_OUTOFMEMORY; + return NULL; + } + + if (wm->binfmt.pe.pe_export) + SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions); + + *err = 0; + return wm; } diff --git a/scheduler/process.c b/scheduler/process.c index e128d630bd7..9aed121fbcc 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -9,6 +9,7 @@ #include #include #include "wine/winbase16.h" +#include "wine/exception.h" #include "process.h" #include "module.h" #include "neexe.h" @@ -55,7 +56,7 @@ void PROCESS_WalkProcess(void) if (pdb == &initial_pdb) name = "initial PDB"; else - name = (pdb->exe_modref) ? pdb->exe_modref->shortname : ""; + name = (pdb->exe_modref) ? pdb->exe_modref->filename : ""; MESSAGE( " %8p %8p %5d %8p %s\n", pdb->server_pid, pdb, pdb->threads, pdb->exe_modref, name); @@ -389,7 +390,7 @@ void PROCESS_Start(void) LPTHREAD_START_ROUTINE entry = NULL; PDB *pdb = PROCESS_Current(); NE_MODULE *pModule = NE_GetPtr( pdb->module ); - OFSTRUCT *ofs = (OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo); + LPCSTR filename = ((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName; IMAGE_OPTIONAL_HEADER *header = !pModule->module32? NULL : &PE_HEADER(pModule->module32)->OptionalHeader; @@ -457,7 +458,7 @@ void PROCESS_Start(void) DEBUG_SendCreateProcessEvent( -1 /*FIXME*/, pModule->module32, entry ); /* Create 32-bit MODREF */ - if (!PE_CreateModule( pModule->module32, ofs, 0, FALSE )) goto error; + if (!PE_CreateModule( pModule->module32, filename, 0, FALSE )) goto error; /* Increment EXE refcount */ assert( pdb->exe_modref );