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;