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
;