#endif
#include <ctype.h>
-#include "ntstatus.h"
#include "windef.h"
-#include "winbase.h"
#include "wine/winbase16.h"
-#include "winerror.h"
#include "wownt32.h"
-#include "wine/library.h"
#include "module.h"
#include "toolhelp.h"
-#include "global.h"
-#include "file.h"
-#include "task.h"
#include "builtin16.h"
#include "stackframe.h"
#include "excpt.h"
-#include "wine/unicode.h"
#include "wine/exception.h"
#include "wine/debug.h"
}
+/***********************************************************************
+ * NE_strcasecmp
+ *
+ * locale-independent case conversion for module lookups
+ */
+static int NE_strcasecmp( const char *str1, const char *str2 )
+{
+ int ret = 0;
+ for ( ; ; str1++, str2++)
+ if ((ret = RtlUpperChar(*str1) - RtlUpperChar(*str2)) || !*str1) break;
+ return ret;
+}
+
+
+/***********************************************************************
+ * NE_strncasecmp
+ *
+ * locale-independent case conversion for module lookups
+ */
+static int NE_strncasecmp( const char *str1, const char *str2, int len )
+{
+ int ret = 0;
+ for ( ; len > 0; len--, str1++, str2++)
+ if ((ret = RtlUpperChar(*str1) - RtlUpperChar(*str2)) || !*str1) break;
+ return ret;
+}
+
+
/***********************************************************************
* find_dll_descr
*
BYTE *name_table = (BYTE *)pModule + pModule->name_table;
/* check the dll file name */
- if (!FILE_strcasecmp( pOfs->szPathName, dllname )) return descr;
+ if (!NE_strcasecmp( pOfs->szPathName, dllname )) return descr;
/* check the dll module name (without extension) */
- if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) &&
+ if (!NE_strncasecmp( dllname, name_table+1, *name_table ) &&
!strcmp( dllname + *name_table, ".dll" ))
return descr;
}
}
-/***********************************************************************
- * is_builtin_present
- *
- * Check if a builtin dll descriptor is present (because we loaded its 32-bit counterpart).
- */
-static BOOL is_builtin_present( LPCSTR name )
-{
- char dllname[20], *p;
-
- if (strlen(name) >= sizeof(dllname)-4) return FALSE;
- strcpy( dllname, name );
- p = strrchr( dllname, '.' );
- if (!p) strcat( dllname, ".dll" );
- for (p = dllname; *p; p++) *p = FILE_tolower(*p);
-
- return (find_dll_descr( dllname ) != NULL);
-}
-
-
/***********************************************************************
* __wine_register_dll_16 (KERNEL32.@)
*
/* Now copy and uppercase the string */
strcpy( buffer, name );
- for (cpnt = buffer; *cpnt; cpnt++) *cpnt = FILE_toupper(*cpnt);
+ for (cpnt = buffer; *cpnt; cpnt++) *cpnt = RtlUpperChar(*cpnt);
len = cpnt - buffer;
/* First search the resident names */
NE_MODULE *pModule;
BYTE *pData, *pTempEntryTable;
char *buffer, *fastload = NULL;
- int fastload_offset = 0, fastload_length = 0;
+ unsigned int fastload_offset = 0, fastload_length = 0;
ET_ENTRY *entry;
ET_BUNDLE *bundle, *oldbundle;
OFSTRUCT *ofs;
if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21; /* win32 exe */
if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
- MESSAGE("Sorry, this is an OS/2 linear executable (LX) file !\n");
+ MESSAGE("Sorry, this is an OS/2 linear executable (LX) file!\n");
return (HMODULE16)12;
}
if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11; /* invalid exe */
/* We now have a valid NE header */
+ /* check to be able to fall back to loading OS/2 programs as DOS
+ * FIXME: should this check be reversed in order to be less strict?
+ * (only fail for OS/2 ne_exetyp 0x01 here?) */
+ if ((ne_header.ne_exetyp != 0x02 /* Windows */)
+ && (ne_header.ne_exetyp != 0x04) /* Windows 386 */)
+ return (HMODULE16)11; /* invalid exe */
+
size = sizeof(NE_MODULE) +
/* segment table */
ne_header.ne_cseg * sizeof(SEGTABLEENTRY) +
buffer ))
{
HeapFree( GetProcessHeap(), 0, buffer );
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
}
else
{
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
ne_header.ne_modtab - ne_header.ne_restab,
pData ))
{
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
ne_header.ne_cmod * sizeof(WORD),
pData ))
{
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
ne_header.ne_enttab - ne_header.ne_imptab,
pData ))
{
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
ne_header.ne_cbenttab, pTempEntryTable ))
{
HeapFree( GetProcessHeap(), 0, pTempEntryTable );
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
bundle->first = bundle->last =
oldbundle->last + nr_entries;
bundle->next = 0;
- (BYTE *)entry += sizeof(ET_BUNDLE);
+ entry = (ET_ENTRY*)(((BYTE*)entry)+sizeof(ET_BUNDLE));
}
}
}
}
else
{
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
GlobalFree16( hModule );
return (HMODULE16)11; /* invalid exe */
}
/* Free the fast-load area */
#undef READ
- if (fastload) HeapFree( GetProcessHeap(), 0, fastload );
+ HeapFree( GetProcessHeap(), 0, fastload );
/* Get the non-resident names table */
/* Open file */
if ((hFile = OpenFile16( name, &ofs, OF_READ|OF_SHARE_DENY_WRITE )) == HFILE_ERROR16)
- return (HMODULE16)2; /* File not found */
+ return ERROR_FILE_NOT_FOUND;
hModule = NE_LoadExeHeader( DosFileHandleToWin32Handle(hFile), ofs.szPathName );
if (hModule < 32)
hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
descr->module_size, 0, WINE_LDT_FLAGS_DATA );
- if (!hModule) return 0;
+ if (!hModule) return ERROR_NOT_ENOUGH_MEMORY;
FarSetOwner16( hModule, hModule );
pModule = (NE_MODULE *)GlobalLock16( hModule );
pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
pSegTable->minsize, hModule,
WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
- if (!pSegTable->hSeg) return 0;
+ if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY;
patch_code_segment( descr->code_start );
pSegTable++;
minsize += pModule->heap_size;
if (minsize > 0x10000) minsize = 0x10000;
pSegTable->hSeg = GlobalAlloc16( GMEM_FIXED, minsize );
- if (!pSegTable->hSeg) return 0;
+ if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY;
FarSetOwner16( pSegTable->hSeg, hModule );
if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
descr->data_start, pSegTable->minsize);
NE_RegisterModule( pModule );
- /* make sure the 32-bit library containing this one is loaded too */
- LoadLibraryA( descr->owner );
-
return hModule;
}
-/***********************************************************************
- * NE_LoadBuiltinModule
- *
- * Load a built-in module.
- */
-static HMODULE16 NE_LoadBuiltinModule( LPCSTR name )
-{
- const BUILTIN16_DESCRIPTOR *descr;
- char error[256], dllname[20], *p;
- int file_exists;
- void *handle;
-
- /* Fix the name in case we have a full path and extension */
-
- if ((p = strrchr( name, '\\' ))) name = p + 1;
- if ((p = strrchr( name, '/' ))) name = p + 1;
-
- if (strlen(name) >= sizeof(dllname)-4) return (HMODULE16)2;
-
- strcpy( dllname, name );
- p = strrchr( dllname, '.' );
- if (!p) strcat( dllname, ".dll" );
- for (p = dllname; *p; p++) *p = FILE_tolower(*p);
-
- if ((descr = find_dll_descr( dllname )))
- return NE_DoLoadBuiltinModule( descr );
-
- if ((handle = wine_dll_load( dllname, error, sizeof(error), &file_exists )))
- {
- if ((descr = find_dll_descr( dllname )))
- return NE_DoLoadBuiltinModule( descr );
-
- ERR( "loaded .so but dll %s still not found\n", dllname );
- }
- else
- {
- if (!file_exists) WARN("cannot open .so lib for 16-bit builtin %s: %s\n", name, error);
- else ERR("failed to load .so lib for 16-bit builtin %s: %s\n", name, error );
- }
- return (HMODULE16)2;
-}
-
-
/**********************************************************************
* MODULE_LoadModule16
*
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only )
{
HINSTANCE16 hinst = 2;
- enum loadorder_type loadorder[LOADORDER_NTYPES];
- int i;
- const char *filetype = "";
- const char *ptr, *basename;
+ HMODULE16 hModule;
+ NE_MODULE *pModule;
+ const BUILTIN16_DESCRIPTOR *descr = NULL;
+ char dllname[20], owner[20], *p;
+ const char *basename;
/* strip path information */
basename = libname;
if (basename[0] && basename[1] == ':') basename += 2; /* strip drive specification */
- if ((ptr = strrchr( basename, '\\' ))) basename = ptr + 1;
- if ((ptr = strrchr( basename, '/' ))) basename = ptr + 1;
+ if ((p = strrchr( basename, '\\' ))) basename = p + 1;
+ if ((p = strrchr( basename, '/' ))) basename = p + 1;
- if (is_builtin_present(basename))
+ if (strlen(basename) < sizeof(dllname)-4)
{
- TRACE( "forcing loadorder to builtin for %s\n", debugstr_a(basename) );
- /* force builtin loadorder since the dll is already in memory */
- loadorder[0] = LOADORDER_BI;
- loadorder[1] = LOADORDER_INVALID;
- }
- else
- {
- WCHAR buffer[MAX_PATH], *p;
-
- if (!GetModuleFileNameW( 0, buffer, MAX_PATH )) p = NULL;
- else
- {
- if ((p = strrchrW( buffer, '\\' ))) p++;
- else p = buffer;
- }
- MODULE_GetLoadOrderA(loadorder, p, basename, FALSE);
- }
+ int file_exists;
- for(i = 0; i < LOADORDER_NTYPES; i++)
- {
- if (loadorder[i] == LOADORDER_INVALID) break;
+ strcpy( dllname, basename );
+ p = strrchr( dllname, '.' );
+ if (!p) strcat( dllname, ".dll" );
+ for (p = dllname; *p; p++) if (*p >= 'A' && *p <= 'Z') *p += 32;
- switch(loadorder[i])
+ if (wine_dll_get_owner( dllname, owner, sizeof(owner), &file_exists ) == -1)
{
- case LOADORDER_DLL:
- TRACE("Trying native dll '%s'\n", libname);
- hinst = NE_LoadModule(libname, lib_only);
- filetype = "native";
- break;
-
- case LOADORDER_BI:
- TRACE("Trying built-in '%s'\n", libname);
- hinst = NE_LoadBuiltinModule(libname);
- filetype = "builtin";
- break;
-
- default:
- hinst = 2;
- break;
+ if (file_exists) return 21; /* it may be a Win32 module then */
}
-
- if(hinst >= 32)
+ else /* found 32-bit owner, try to load it */
{
- TRACE_(loaddll)("Loaded module '%s' : %s\n", libname, filetype);
- if(!implicit)
+ HMODULE mod32 = LoadLibraryA( owner );
+ if (mod32)
{
- HMODULE16 hModule;
- NE_MODULE *pModule;
-
- hModule = GetModuleHandle16(libname);
- if(!hModule)
+ if (!(descr = find_dll_descr( dllname ))) FreeLibrary( mod32 );
+ /* loading the 32-bit library can have the side effect of loading the module */
+ /* if so, simply incr the ref count and return the module */
+ if ((hModule = GetModuleHandle16( libname )))
{
- ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get module handle. Filename too long ?\n",
- libname, hinst);
- return 6; /* ERROR_INVALID_HANDLE seems most appropriate */
+ TRACE( "module %s already loaded by owner\n", libname );
+ pModule = NE_GetPtr( hModule );
+ if (pModule) pModule->count++;
+ return hModule;
}
+ }
+ else
+ {
+ /* it's probably disabled by the load order config */
+ WARN( "couldn't load owner %s for 16-bit dll %s\n", owner, dllname );
+ return ERROR_FILE_NOT_FOUND;
+ }
+ }
+ }
- pModule = NE_GetPtr(hModule);
- if(!pModule)
- {
- ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get NE_MODULE pointer\n",
- libname, hinst);
- return 6; /* ERROR_INVALID_HANDLE seems most appropriate */
- }
+ if (descr)
+ {
+ TRACE("Trying built-in '%s'\n", libname);
+ hinst = NE_DoLoadBuiltinModule( descr );
+ if (hinst > 32) TRACE_(loaddll)("Loaded module %s : builtin\n", debugstr_a(libname));
+ }
+ else
+ {
+ TRACE("Trying native dll '%s'\n", libname);
+ hinst = NE_LoadModule(libname, lib_only);
+ if (hinst > 32) TRACE_(loaddll)("Loaded module %s : native\n", debugstr_a(libname));
+ }
- TRACE("Loaded module '%s' at 0x%04x.\n", libname, hinst);
+ if (hinst > 32 && !implicit)
+ {
+ hModule = GetModuleHandle16(libname);
+ if(!hModule)
+ {
+ ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get module handle. Filename too long ?\n",
+ libname, hinst);
+ return ERROR_INVALID_HANDLE;
+ }
- /*
- * Call initialization routines for all loaded DLLs. Note that
- * when we load implicitly linked DLLs this will be done by InitTask().
- */
- if(pModule->flags & NE_FFLAGS_LIBMODULE)
- {
- NE_InitializeDLLs(hModule);
- NE_DllProcessAttach(hModule);
- }
- }
- return hinst;
+ pModule = NE_GetPtr(hModule);
+ if(!pModule)
+ {
+ ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get NE_MODULE pointer\n",
+ libname, hinst);
+ return ERROR_INVALID_HANDLE;
}
- if(hinst != 2)
+ TRACE("Loaded module '%s' at 0x%04x.\n", libname, hinst);
+
+ /*
+ * Call initialization routines for all loaded DLLs. Note that
+ * when we load implicitly linked DLLs this will be done by InitTask().
+ */
+ if(pModule->flags & NE_FFLAGS_LIBMODULE)
{
- /* We quit searching when we get another error than 'File not found' */
- break;
+ NE_InitializeDLLs(hModule);
+ NE_DllProcessAttach(hModule);
}
}
return hinst; /* The last error that occurred */
/* If uppercased 'name' matches exactly the module name of a module:
* Return its handle
*/
- for (s = tmpstr; *s; s++) *s = FILE_toupper(*s);
+ for (s = tmpstr; *s; s++) *s = RtlUpperChar(*s);
for (hModule = hFirstModule; hModule ; hModule = pModule->next)
{
* 'i' compare is just a quickfix until the loader handles that
* correctly. -MM 990705
*/
- if ((*name_table == len) && !FILE_strncasecmp(tmpstr, name_table+1, len))
+ if ((*name_table == len) && !NE_strncasecmp(tmpstr, name_table+1, len))
return hModule;
}
loadedfn--;
}
/* case insensitive compare ... */
- if (!FILE_strcasecmp(loadedfn, s))
+ if (!NE_strcasecmp(loadedfn, s))
return hModule;
}
return 0;
loadedfn--;
}
/* case insensitive compare ... */
- if (!FILE_strcasecmp(loadedfn, s))
+ if (!NE_strcasecmp(loadedfn, s))
return hModule;
}
/* If basename (without ext) matches the module name of a module:
if (pModule->flags & NE_FFLAGS_WIN32) continue;
name_table = (BYTE *)pModule + pModule->name_table;
- if ((*name_table == len) && !FILE_strncasecmp(s, name_table+1, len))
+ if ((*name_table == len) && !NE_strncasecmp(s, name_table+1, len))
return hModule;
}
if (!nt) return (HMODULE16)11; /* invalid exe */
/* Extract base filename */
- GetModuleFileNameA( module32, filename, sizeof(filename) );
+ len = GetModuleFileNameA( module32, filename, sizeof(filename) );
+ if (!len || len >= sizeof(filename)) return (HMODULE16)11; /* invalid exe */
basename = strrchr(filename, '\\');
if (!basename) basename = filename;
else basename++;
* MapHInstLS (KERNEL32.@)
* MapHInstLS (KERNEL.472)
*/
-void WINAPI MapHInstLS( CONTEXT86 *context )
+void MapHInstLS( CONTEXT86 *context )
{
context->Eax = MapHModuleLS( (HMODULE)context->Eax );
}
* MapHInstSL (KERNEL32.@)
* MapHInstSL (KERNEL.473)
*/
-void WINAPI MapHInstSL( CONTEXT86 *context )
+void MapHInstSL( CONTEXT86 *context )
{
context->Eax = (DWORD)MapHModuleSL( context->Eax );
}
/***************************************************************************
* MapHInstLS_PN (KERNEL32.@)
*/
-void WINAPI MapHInstLS_PN( CONTEXT86 *context )
+void MapHInstLS_PN( CONTEXT86 *context )
{
if (context->Eax) context->Eax = MapHModuleLS( (HMODULE)context->Eax );
}
/***************************************************************************
* MapHInstSL_PN (KERNEL32.@)
*/
-void WINAPI MapHInstSL_PN( CONTEXT86 *context )
+void MapHInstSL_PN( CONTEXT86 *context )
{
if (context->Eax) context->Eax = (DWORD)MapHModuleSL( context->Eax );
}