Fixed vm86_enter race conditions.
[wine/hacks.git] / if1632 / builtin.c
blobd8a2df1ff8841bbbb6fc7f1b8b0d611fb518155f
1 /*
2 * Built-in modules
4 * Copyright 1996 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <ctype.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include "winbase.h"
12 #include "wine/winbase16.h"
13 #include "builtin16.h"
14 #include "global.h"
15 #include "file.h"
16 #include "module.h"
17 #include "miscemu.h"
18 #include "stackframe.h"
19 #include "debugtools.h"
20 #include "toolhelp.h"
22 DEFAULT_DEBUG_CHANNEL(module);
24 typedef struct
26 void *module_start; /* 32-bit address of the module data */
27 int module_size; /* Size of the module data */
28 void *code_start; /* 32-bit address of DLL code */
29 void *data_start; /* 32-bit address of DLL data */
30 const char *owner; /* 32-bit dll that contains this dll */
31 const void *rsrc; /* resources data */
32 } BUILTIN16_DESCRIPTOR;
34 /* Table of all built-in DLLs */
36 #define MAX_DLLS 50
38 static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
39 static int nb_dlls;
42 /* patch all the flat cs references of the code segment if necessary */
43 inline static void patch_code_segment( void *code_segment )
45 #ifdef __i386__
46 CALLFROM16 *call = code_segment;
47 if (call->flatcs == __get_cs()) return; /* nothing to patch */
48 while (call->pushl == 0x68)
50 call->flatcs = __get_cs();
51 call++;
53 #endif
57 /***********************************************************************
58 * BUILTIN_DoLoadModule16
60 * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule.
62 static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
64 NE_MODULE *pModule;
65 int minsize;
66 SEGTABLEENTRY *pSegTable;
67 HMODULE16 hModule;
69 hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
70 descr->module_size, 0, WINE_LDT_FLAGS_DATA );
71 if (!hModule) return 0;
72 FarSetOwner16( hModule, hModule );
74 pModule = (NE_MODULE *)GlobalLock16( hModule );
75 pModule->self = hModule;
76 /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
77 pModule->hRsrcMap = (void *)descr->rsrc;
79 /* Allocate the code segment */
81 pSegTable = NE_SEG_TABLE( pModule );
82 pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
83 pSegTable->minsize, hModule,
84 WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
85 if (!pSegTable->hSeg) return 0;
86 patch_code_segment( descr->code_start );
87 pSegTable++;
89 /* Allocate the data segment */
91 minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
92 minsize += pModule->heap_size;
93 if (minsize > 0x10000) minsize = 0x10000;
94 pSegTable->hSeg = GlobalAlloc16( GMEM_FIXED, minsize );
95 if (!pSegTable->hSeg) return 0;
96 FarSetOwner16( pSegTable->hSeg, hModule );
97 if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
98 descr->data_start, pSegTable->minsize);
99 if (pModule->heap_size)
100 LocalInit16( GlobalHandleToSel16(pSegTable->hSeg),
101 pSegTable->minsize, minsize );
103 if (descr->rsrc) NE_InitResourceHandler(hModule);
105 NE_RegisterModule( pModule );
107 /* make sure the 32-bit library containing this one is loaded too */
108 LoadLibraryA( descr->owner );
110 return hModule;
114 /***********************************************************************
115 * find_dll_descr
117 * Find a descriptor in the list
119 static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname )
121 int i;
122 for (i = 0; i < nb_dlls; i++)
124 const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
125 NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
126 OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
127 BYTE *name_table = (BYTE *)pModule + pModule->name_table;
129 /* check the dll file name */
130 if (!FILE_strcasecmp( pOfs->szPathName, dllname ))
131 return descr;
132 /* check the dll module name (without extension) */
133 if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) &&
134 !strcmp( dllname + *name_table, ".dll" ))
135 return descr;
137 return NULL;
141 /***********************************************************************
142 * BUILTIN_LoadModule
144 * Load a built-in module.
146 HMODULE16 BUILTIN_LoadModule( LPCSTR name )
148 const BUILTIN16_DESCRIPTOR *descr;
149 char dllname[20], *p;
150 void *handle;
152 /* Fix the name in case we have a full path and extension */
154 if ((p = strrchr( name, '\\' ))) name = p + 1;
155 if ((p = strrchr( name, '/' ))) name = p + 1;
157 if (strlen(name) >= sizeof(dllname)-4) return (HMODULE16)2;
159 strcpy( dllname, name );
160 p = strrchr( dllname, '.' );
161 if (!p) strcat( dllname, ".dll" );
162 for (p = dllname; *p; p++) *p = FILE_tolower(*p);
164 if ((descr = find_dll_descr( dllname )))
165 return BUILTIN_DoLoadModule16( descr );
167 if ((handle = BUILTIN32_dlopen( dllname )))
169 if ((descr = find_dll_descr( dllname )))
170 return BUILTIN_DoLoadModule16( descr );
172 ERR( "loaded .so but dll %s still not found\n", dllname );
173 BUILTIN32_dlclose( handle );
176 return (HMODULE16)2;
180 /***********************************************************************
181 * __wine_register_dll_16 (KERNEL32.@)
183 * Register a built-in DLL descriptor.
185 void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr )
187 assert( nb_dlls < MAX_DLLS );
188 builtin_dlls[nb_dlls++] = descr;