4 * Copyright 1996 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
29 #include "wine/winbase16.h"
30 #include "builtin16.h"
35 #include "stackframe.h"
36 #include "wine/library.h"
37 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(module);
44 void *module_start; /* 32-bit address of the module data */
45 int module_size; /* Size of the module data */
46 void *code_start; /* 32-bit address of DLL code */
47 void *data_start; /* 32-bit address of DLL data */
48 const char *owner; /* 32-bit dll that contains this dll */
49 const void *rsrc; /* resources data */
50 } BUILTIN16_DESCRIPTOR;
52 /* Table of all built-in DLLs */
56 static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
59 /* patch all the flat cs references of the code segment if necessary */
60 inline static void patch_code_segment( void *code_segment )
63 CALLFROM16 *call = code_segment;
64 if (call->flatcs == wine_get_cs()) return; /* nothing to patch */
65 while (call->pushl == 0x68)
67 call->flatcs = wine_get_cs();
74 /***********************************************************************
75 * BUILTIN_DoLoadModule16
77 * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule.
79 static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
83 SEGTABLEENTRY *pSegTable;
86 hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
87 descr->module_size, 0, WINE_LDT_FLAGS_DATA );
88 if (!hModule) return 0;
89 FarSetOwner16( hModule, hModule );
91 pModule = (NE_MODULE *)GlobalLock16( hModule );
92 pModule->self = hModule;
93 /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
94 pModule->hRsrcMap = (void *)descr->rsrc;
96 /* Allocate the code segment */
98 pSegTable = NE_SEG_TABLE( pModule );
99 pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
100 pSegTable->minsize, hModule,
101 WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
102 if (!pSegTable->hSeg) return 0;
103 patch_code_segment( descr->code_start );
106 /* Allocate the data segment */
108 minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
109 minsize += pModule->heap_size;
110 if (minsize > 0x10000) minsize = 0x10000;
111 pSegTable->hSeg = GlobalAlloc16( GMEM_FIXED, minsize );
112 if (!pSegTable->hSeg) return 0;
113 FarSetOwner16( pSegTable->hSeg, hModule );
114 if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
115 descr->data_start, pSegTable->minsize);
116 if (pModule->heap_size)
117 LocalInit16( GlobalHandleToSel16(pSegTable->hSeg),
118 pSegTable->minsize, minsize );
120 if (descr->rsrc) NE_InitResourceHandler(hModule);
122 NE_RegisterModule( pModule );
124 /* make sure the 32-bit library containing this one is loaded too */
125 LoadLibraryA( descr->owner );
131 /***********************************************************************
134 * Find a descriptor in the list
136 static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname )
139 for (i = 0; i < MAX_DLLS; i++)
141 const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
144 NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
145 OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
146 BYTE *name_table = (BYTE *)pModule + pModule->name_table;
148 /* check the dll file name */
149 if (!FILE_strcasecmp( pOfs->szPathName, dllname )) return descr;
150 /* check the dll module name (without extension) */
151 if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) &&
152 !strcmp( dllname + *name_table, ".dll" ))
160 /***********************************************************************
163 * Check if a builtin dll descriptor is present (because we loaded its 32-bit counterpart).
165 BOOL BUILTIN_IsPresent( LPCSTR name )
167 char dllname[20], *p;
169 if (strlen(name) >= sizeof(dllname)-4) return FALSE;
170 strcpy( dllname, name );
171 p = strrchr( dllname, '.' );
172 if (!p) strcat( dllname, ".dll" );
173 for (p = dllname; *p; p++) *p = FILE_tolower(*p);
175 return (find_dll_descr( dllname ) != NULL);
179 /***********************************************************************
182 * Load a built-in module.
184 HMODULE16 BUILTIN_LoadModule( LPCSTR name )
186 const BUILTIN16_DESCRIPTOR *descr;
187 char dllname[20], *p;
190 /* Fix the name in case we have a full path and extension */
192 if ((p = strrchr( name, '\\' ))) name = p + 1;
193 if ((p = strrchr( name, '/' ))) name = p + 1;
195 if (strlen(name) >= sizeof(dllname)-4) return (HMODULE16)2;
197 strcpy( dllname, name );
198 p = strrchr( dllname, '.' );
199 if (!p) strcat( dllname, ".dll" );
200 for (p = dllname; *p; p++) *p = FILE_tolower(*p);
202 if ((descr = find_dll_descr( dllname )))
203 return BUILTIN_DoLoadModule16( descr );
205 if ((handle = BUILTIN32_dlopen( dllname )))
207 if ((descr = find_dll_descr( dllname )))
208 return BUILTIN_DoLoadModule16( descr );
210 ERR( "loaded .so but dll %s still not found\n", dllname );
211 BUILTIN32_dlclose( handle );
218 /***********************************************************************
219 * __wine_register_dll_16 (KERNEL32.@)
221 * Register a built-in DLL descriptor.
223 void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr )
227 for (i = 0; i < MAX_DLLS; i++)
229 if (builtin_dlls[i]) continue;
230 builtin_dlls[i] = descr;
233 assert( i < MAX_DLLS );
237 /***********************************************************************
238 * __wine_unregister_dll_16 (KERNEL32.@)
240 * Unregister a built-in DLL descriptor.
242 void __wine_unregister_dll_16( const BUILTIN16_DESCRIPTOR *descr )
246 for (i = 0; i < MAX_DLLS; i++)
248 if (builtin_dlls[i] != descr) continue;
249 builtin_dlls[i] = NULL;