4 * Copyright 1996 Alexandre Julliard
12 #include "wine/winbase16.h"
13 #include "wine/winestring.h"
14 #include "builtin16.h"
15 #include "builtin32.h"
21 #include "stackframe.h"
25 #include "debugtools.h"
28 DEFAULT_DEBUG_CHANNEL(module
);
32 LPVOID res_start
; /* address of resource data */
34 DWORD res_size
; /* size of resource data */
38 /* Table of all built-in DLLs */
42 static const BUILTIN16_DESCRIPTOR
*builtin_dlls
[MAX_DLLS
];
45 /* list of DLLs that should always be loaded at startup */
46 static const char * const always_load
[] =
48 "system", "display", "wprocs", "wineps", NULL
51 /* Ordinal number for interrupt 0 handler in WPROCS.DLL */
52 #define FIRST_INTERRUPT_ORDINAL 100
55 /***********************************************************************
56 * BUILTIN_DoLoadModule16
58 * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule
61 static HMODULE16
BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR
*descr
)
65 SEGTABLEENTRY
*pSegTable
;
67 const BUILTIN16_RESOURCE
*rsrc
= descr
->rsrc
;
71 hModule
= GLOBAL_CreateBlock( GMEM_MOVEABLE
, descr
->module_start
,
72 descr
->module_size
, 0,
73 FALSE
, FALSE
, FALSE
, NULL
);
74 if (!hModule
) return 0;
75 FarSetOwner16( hModule
, hModule
);
77 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
83 hModule
= GLOBAL_Alloc( GMEM_MOVEABLE
,
84 descr
->module_size
+ rsrc
->res_size
,
85 0, FALSE
, FALSE
, FALSE
);
86 if (!hModule
) return 0;
87 FarSetOwner16( hModule
, hModule
);
89 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
90 res_off
= ((NE_MODULE
*)descr
->module_start
)->res_table
;
92 memcpy( (LPBYTE
)pModule
, descr
->module_start
, res_off
);
93 memcpy( (LPBYTE
)pModule
+ res_off
, rsrc
->res_start
, rsrc
->res_size
);
94 memcpy( (LPBYTE
)pModule
+ res_off
+ rsrc
->res_size
,
95 (LPBYTE
)descr
->module_start
+ res_off
, descr
->module_size
- res_off
);
97 /* Have to fix up various pModule-based near pointers. Ugh! */
98 pModule
->name_table
+= rsrc
->res_size
;
99 pModule
->modref_table
+= rsrc
->res_size
;
100 pModule
->import_table
+= rsrc
->res_size
;
101 pModule
->entry_table
+= rsrc
->res_size
;
103 for ( bundle
= (ET_BUNDLE
*)((LPBYTE
)pModule
+ pModule
->entry_table
);
105 bundle
= (ET_BUNDLE
*)((LPBYTE
)pModule
+ bundle
->next
) )
106 bundle
->next
+= rsrc
->res_size
;
108 /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
109 pModule
->hRsrcMap
= rsrc
->res_start
;
111 pModule
->self
= hModule
;
113 TRACE( "Built-in %s: hmodule=%04x\n", descr
->name
, hModule
);
115 /* Allocate the code segment */
117 pSegTable
= NE_SEG_TABLE( pModule
);
118 pSegTable
->hSeg
= GLOBAL_CreateBlock( GMEM_FIXED
, descr
->code_start
,
119 pSegTable
->minsize
, hModule
,
120 TRUE
, TRUE
, FALSE
, NULL
);
121 if (!pSegTable
->hSeg
) return 0;
124 /* Allocate the data segment */
126 minsize
= pSegTable
->minsize
? pSegTable
->minsize
: 0x10000;
127 minsize
+= pModule
->heap_size
;
128 if (minsize
> 0x10000) minsize
= 0x10000;
129 pSegTable
->hSeg
= GLOBAL_Alloc( GMEM_FIXED
, minsize
,
130 hModule
, FALSE
, FALSE
, FALSE
);
131 if (!pSegTable
->hSeg
) return 0;
132 if (pSegTable
->minsize
) memcpy( GlobalLock16( pSegTable
->hSeg
),
133 descr
->data_start
, pSegTable
->minsize
);
134 if (pModule
->heap_size
)
135 LocalInit16( GlobalHandleToSel16(pSegTable
->hSeg
),
136 pSegTable
->minsize
, minsize
);
139 NE_InitResourceHandler(hModule
);
141 NE_RegisterModule( pModule
);
146 /***********************************************************************
149 * Load all built-in modules marked as 'always used'.
151 BOOL
BUILTIN_Init(void)
155 const char * const *ptr
= always_load
;
159 if (!BUILTIN_LoadModule( *ptr
)) return FALSE
;
163 /* Set interrupt vectors from entry points in WPROCS.DLL */
165 hModule
= GetModuleHandle16( "WPROCS" );
166 for (vector
= 0; vector
< 256; vector
++)
168 FARPROC16 proc
= NE_GetEntryPoint( hModule
,
169 FIRST_INTERRUPT_ORDINAL
+ vector
);
171 INT_SetPMHandler( vector
, proc
);
178 /***********************************************************************
181 * Load a built-in module.
183 HMODULE16
BUILTIN_LoadModule( LPCSTR name
)
185 char dllname
[16], *p
;
188 /* Fix the name in case we have a full path and extension */
190 if ((p
= strrchr( name
, '\\' ))) name
= p
+ 1;
191 lstrcpynA( dllname
, name
, sizeof(dllname
) );
192 p
= strrchr( dllname
, '.' );
194 if (!p
) strcat( dllname
, ".dll" );
196 for (i
= 0; i
< nb_dlls
; i
++)
198 const BUILTIN16_DESCRIPTOR
*descr
= builtin_dlls
[i
];
199 NE_MODULE
*pModule
= (NE_MODULE
*)descr
->module_start
;
200 OFSTRUCT
*pOfs
= (OFSTRUCT
*)((LPBYTE
)pModule
+ pModule
->fileinfo
);
201 if (!lstrcmpiA( pOfs
->szPathName
, dllname
))
202 return BUILTIN_DoLoadModule16( descr
);
208 /***********************************************************************
209 * BUILTIN_GetEntryPoint16
211 * Return the ordinal, name, and type info corresponding to a CS:IP address.
212 * This is used only by relay debugging.
214 LPCSTR
BUILTIN_GetEntryPoint16( STACK16FRAME
*frame
, LPSTR name
, WORD
*pOrd
)
222 if (!(pModule
= NE_GetPtr( FarGetOwner16( GlobalHandle16( frame
->module_cs
) ))))
227 bundle
= (ET_BUNDLE
*)((BYTE
*)pModule
+ pModule
->entry_table
);
230 entry
= (ET_ENTRY
*)((BYTE
*)bundle
+6);
231 for (i
= bundle
->first
+ 1; i
<= bundle
->last
; i
++)
233 if ((entry
->offs
< frame
->entry_ip
)
234 && (entry
->segnum
== 1) /* code segment ? */
235 && (entry
->offs
>= max_offset
))
237 max_offset
= entry
->offs
;
242 } while ( (bundle
->next
)
243 && (bundle
= (ET_BUNDLE
*)((BYTE
*)pModule
+bundle
->next
)));
245 /* Search for the name in the resident names table */
246 /* (built-in modules have no non-resident table) */
248 p
= (BYTE
*)pModule
+ pModule
->name_table
;
251 p
+= *p
+ 1 + sizeof(WORD
);
252 if (*(WORD
*)(p
+ *p
+ 1) == *pOrd
) break;
255 sprintf( name
, "%.*s.%d: %.*s",
256 *((BYTE
*)pModule
+ pModule
->name_table
),
257 (char *)pModule
+ pModule
->name_table
+ 1,
258 *pOrd
, *p
, (char *)(p
+ 1) );
260 /* Retrieve type info string */
261 return *(LPCSTR
*)((LPBYTE
)PTR_SEG_OFF_TO_LIN( frame
->module_cs
, frame
->callfrom_ip
) + 4);
265 /***********************************************************************
266 * BUILTIN_RegisterDLL
268 * Register a built-in DLL descriptor.
270 void BUILTIN_RegisterDLL( const BUILTIN16_DESCRIPTOR
*descr
)
272 assert( nb_dlls
< MAX_DLLS
);
273 builtin_dlls
[nb_dlls
++] = descr
;
277 /**********************************************************************
278 * BUILTIN_DefaultIntHandler
280 * Default interrupt handler.
282 void WINAPI
BUILTIN_DefaultIntHandler( CONTEXT86
*context
)
286 BUILTIN_GetEntryPoint16( CURRENT_STACK16
, name
, &ordinal
);
287 INT_BARF( context
, ordinal
- FIRST_INTERRUPT_ORDINAL
);