4 * Copyright 1996 Alexandre Julliard
12 #include "wine/winbase16.h"
13 #include "builtin16.h"
18 #include "stackframe.h"
19 #include "debugtools.h"
22 DEFAULT_DEBUG_CHANNEL(module
);
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 */
38 static const BUILTIN16_DESCRIPTOR
*builtin_dlls
[MAX_DLLS
];
42 /* patch all the flat cs references of the code segment if necessary */
43 inline static void patch_code_segment( void *code_segment
)
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();
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
)
66 SEGTABLEENTRY
*pSegTable
;
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
);
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
);
114 /***********************************************************************
117 * Find a descriptor in the list
119 static const BUILTIN16_DESCRIPTOR
*find_dll_descr( const char *dllname
)
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
))
132 /* check the dll module name (without extension) */
133 if (!FILE_strncasecmp( dllname
, name_table
+1, *name_table
) &&
134 !strcmp( dllname
+ *name_table
, ".dll" ))
141 /***********************************************************************
144 * Load a built-in module.
146 HMODULE16
BUILTIN_LoadModule( LPCSTR name
)
148 const BUILTIN16_DESCRIPTOR
*descr
;
149 char dllname
[20], *p
;
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
);
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
;