4 * Copyright 1996 Alexandre Julliard
12 #include "wine/winbase16.h"
13 #include "wine/winestring.h"
14 #include "builtin16.h"
19 #include "stackframe.h"
21 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(module
);
26 /* Table of all built-in DLLs */
30 static const BUILTIN16_DESCRIPTOR
*builtin_dlls
[MAX_DLLS
];
34 /***********************************************************************
35 * BUILTIN_DoLoadModule16
37 * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule.
39 static HMODULE16
BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR
*descr
)
43 SEGTABLEENTRY
*pSegTable
;
46 hModule
= GLOBAL_CreateBlock( GMEM_MOVEABLE
, descr
->module_start
,
47 descr
->module_size
, 0,
48 FALSE
, FALSE
, FALSE
);
49 if (!hModule
) return 0;
50 FarSetOwner16( hModule
, hModule
);
52 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
53 pModule
->self
= hModule
;
54 /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
55 pModule
->hRsrcMap
= (void *)descr
->rsrc
;
57 TRACE( "Built-in %s: hmodule=%04x\n", descr
->name
, hModule
);
59 /* Allocate the code segment */
61 pSegTable
= NE_SEG_TABLE( pModule
);
62 pSegTable
->hSeg
= GLOBAL_CreateBlock( GMEM_FIXED
, descr
->code_start
,
63 pSegTable
->minsize
, hModule
, TRUE
, TRUE
, FALSE
);
64 if (!pSegTable
->hSeg
) return 0;
67 /* Allocate the data segment */
69 minsize
= pSegTable
->minsize
? pSegTable
->minsize
: 0x10000;
70 minsize
+= pModule
->heap_size
;
71 if (minsize
> 0x10000) minsize
= 0x10000;
72 pSegTable
->hSeg
= GLOBAL_Alloc( GMEM_FIXED
, minsize
,
73 hModule
, FALSE
, FALSE
, FALSE
);
74 if (!pSegTable
->hSeg
) return 0;
75 if (pSegTable
->minsize
) memcpy( GlobalLock16( pSegTable
->hSeg
),
76 descr
->data_start
, pSegTable
->minsize
);
77 if (pModule
->heap_size
)
78 LocalInit16( GlobalHandleToSel16(pSegTable
->hSeg
),
79 pSegTable
->minsize
, minsize
);
81 if (descr
->rsrc
) NE_InitResourceHandler(hModule
);
83 NE_RegisterModule( pModule
);
88 /***********************************************************************
91 * Load a built-in module.
93 HMODULE16
BUILTIN_LoadModule( LPCSTR name
)
99 /* Fix the name in case we have a full path and extension */
101 if ((p
= strrchr( name
, '\\' ))) name
= p
+ 1;
102 if ((p
= strrchr( name
, '/' ))) name
= p
+ 1;
104 if (strlen(name
) >= sizeof(dllname
)-4) return (HMODULE16
)2;
106 strcpy( dllname
, name
);
107 p
= strrchr( dllname
, '.' );
108 if (!p
) strcat( dllname
, ".dll" );
110 for (i
= 0; i
< nb_dlls
; i
++)
112 const BUILTIN16_DESCRIPTOR
*descr
= builtin_dlls
[i
];
113 NE_MODULE
*pModule
= (NE_MODULE
*)descr
->module_start
;
114 OFSTRUCT
*pOfs
= (OFSTRUCT
*)((LPBYTE
)pModule
+ pModule
->fileinfo
);
115 if (!strcasecmp( pOfs
->szPathName
, dllname
))
116 return BUILTIN_DoLoadModule16( descr
);
119 if ((handle
= BUILTIN32_dlopen( dllname
)))
121 for (i
= 0; i
< nb_dlls
; i
++)
123 const BUILTIN16_DESCRIPTOR
*descr
= builtin_dlls
[i
];
124 NE_MODULE
*pModule
= (NE_MODULE
*)descr
->module_start
;
125 OFSTRUCT
*pOfs
= (OFSTRUCT
*)((LPBYTE
)pModule
+ pModule
->fileinfo
);
126 if (!strcasecmp( pOfs
->szPathName
, dllname
))
127 return BUILTIN_DoLoadModule16( descr
);
129 ERR( "loaded .so but dll %s still not found\n", dllname
);
130 BUILTIN32_dlclose( handle
);
137 /***********************************************************************
138 * BUILTIN_GetEntryPoint16
140 * Return the ordinal, name, and type info corresponding to a CS:IP address.
141 * This is used only by relay debugging.
143 LPCSTR
BUILTIN_GetEntryPoint16( STACK16FRAME
*frame
, LPSTR name
, WORD
*pOrd
)
151 if (!(pModule
= NE_GetPtr( FarGetOwner16( GlobalHandle16( frame
->module_cs
) ))))
156 bundle
= (ET_BUNDLE
*)((BYTE
*)pModule
+ pModule
->entry_table
);
159 entry
= (ET_ENTRY
*)((BYTE
*)bundle
+6);
160 for (i
= bundle
->first
+ 1; i
<= bundle
->last
; i
++)
162 if ((entry
->offs
< frame
->entry_ip
)
163 && (entry
->segnum
== 1) /* code segment ? */
164 && (entry
->offs
>= max_offset
))
166 max_offset
= entry
->offs
;
171 } while ( (bundle
->next
)
172 && (bundle
= (ET_BUNDLE
*)((BYTE
*)pModule
+bundle
->next
)));
174 /* Search for the name in the resident names table */
175 /* (built-in modules have no non-resident table) */
177 p
= (BYTE
*)pModule
+ pModule
->name_table
;
180 p
+= *p
+ 1 + sizeof(WORD
);
181 if (*(WORD
*)(p
+ *p
+ 1) == *pOrd
) break;
184 sprintf( name
, "%.*s.%d: %.*s",
185 *((BYTE
*)pModule
+ pModule
->name_table
),
186 (char *)pModule
+ pModule
->name_table
+ 1,
187 *pOrd
, *p
, (char *)(p
+ 1) );
189 /* Retrieve type info string */
190 return *(LPCSTR
*)((LPBYTE
)PTR_SEG_OFF_TO_LIN( frame
->module_cs
, frame
->callfrom_ip
) + 4);
194 /***********************************************************************
195 * BUILTIN_RegisterDLL
197 * Register a built-in DLL descriptor.
199 void BUILTIN_RegisterDLL( const BUILTIN16_DESCRIPTOR
*descr
)
201 assert( nb_dlls
< MAX_DLLS
);
202 builtin_dlls
[nb_dlls
++] = descr
;