Added support for loading .res files for 16-bit resources.
[wine] / if1632 / builtin.c
1 /*
2  * Built-in modules
3  *
4  * Copyright 1996 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <ctype.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include "winbase.h"
12 #include "wine/winbase16.h"
13 #include "wine/winestring.h"
14 #include "builtin16.h"
15 #include "global.h"
16 #include "heap.h"
17 #include "module.h"
18 #include "miscemu.h"
19 #include "stackframe.h"
20 #include "task.h"
21 #include "debugtools.h"
22 #include "toolhelp.h"
23
24 DEFAULT_DEBUG_CHANNEL(module);
25
26 /* Table of all built-in DLLs */
27
28 #define MAX_DLLS 50
29
30 static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
31 static int nb_dlls;
32
33
34 /***********************************************************************
35  *           BUILTIN_DoLoadModule16
36  *
37  * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule.
38  */
39 static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
40 {
41     NE_MODULE *pModule;
42     int minsize;
43     SEGTABLEENTRY *pSegTable;
44     HMODULE16 hModule;
45
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 );
51
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;
56
57     TRACE( "Built-in %s: hmodule=%04x\n", descr->name, hModule );
58
59     /* Allocate the code segment */
60
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;
65     pSegTable++;
66
67     /* Allocate the data segment */
68
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 );
80
81     if (descr->rsrc) NE_InitResourceHandler(hModule);
82
83     NE_RegisterModule( pModule );
84     return hModule;
85 }
86
87
88 /***********************************************************************
89  *           BUILTIN_LoadModule
90  *
91  * Load a built-in module.
92  */
93 HMODULE16 BUILTIN_LoadModule( LPCSTR name )
94 {
95     char dllname[20], *p;
96     void *handle;
97     int i;
98
99     /* Fix the name in case we have a full path and extension */
100
101     if ((p = strrchr( name, '\\' ))) name = p + 1;
102     if ((p = strrchr( name, '/' ))) name = p + 1;
103
104     if (strlen(name) >= sizeof(dllname)-4) return (HMODULE16)2;
105
106     strcpy( dllname, name );
107     p = strrchr( dllname, '.' );
108     if (!p) strcat( dllname, ".dll" );
109
110     for (i = 0; i < nb_dlls; i++)
111     {
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 );
117     }
118
119     if ((handle = BUILTIN32_dlopen( dllname )))
120     {
121         for (i = 0; i < nb_dlls; i++)
122         {
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 );
128         }
129         ERR( "loaded .so but dll %s still not found\n", dllname );
130         BUILTIN32_dlclose( handle );
131     }
132
133     return (HMODULE16)2;
134 }
135
136
137 /***********************************************************************
138  *           BUILTIN_GetEntryPoint16
139  *
140  * Return the ordinal, name, and type info corresponding to a CS:IP address.
141  * This is used only by relay debugging.
142  */
143 LPCSTR BUILTIN_GetEntryPoint16( STACK16FRAME *frame, LPSTR name, WORD *pOrd )
144 {
145     WORD i, max_offset;
146     register BYTE *p;
147     NE_MODULE *pModule;
148     ET_BUNDLE *bundle;
149     ET_ENTRY *entry;
150
151     if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16( frame->module_cs ) ))))
152         return NULL;
153
154     max_offset = 0;
155     *pOrd = 0;
156     bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table);
157     do 
158     {
159         entry = (ET_ENTRY *)((BYTE *)bundle+6);
160         for (i = bundle->first + 1; i <= bundle->last; i++)
161         {
162             if ((entry->offs < frame->entry_ip)
163             && (entry->segnum == 1) /* code segment ? */
164             && (entry->offs >= max_offset))
165             {
166                 max_offset = entry->offs;
167                 *pOrd = i;
168             }
169             entry++;
170         }
171     } while ( (bundle->next)
172            && (bundle = (ET_BUNDLE *)((BYTE *)pModule+bundle->next)));
173
174     /* Search for the name in the resident names table */
175     /* (built-in modules have no non-resident table)   */
176     
177     p = (BYTE *)pModule + pModule->name_table;
178     while (*p)
179     {
180         p += *p + 1 + sizeof(WORD);
181         if (*(WORD *)(p + *p + 1) == *pOrd) break;
182     }
183
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) );
188
189     /* Retrieve type info string */
190     return *(LPCSTR *)((LPBYTE)PTR_SEG_OFF_TO_LIN( frame->module_cs, frame->callfrom_ip ) + 4);
191 }
192
193
194 /***********************************************************************
195  *           BUILTIN_RegisterDLL
196  *
197  * Register a built-in DLL descriptor.
198  */
199 void BUILTIN_RegisterDLL( const BUILTIN16_DESCRIPTOR *descr )
200 {
201     assert( nb_dlls < MAX_DLLS );
202     builtin_dlls[nb_dlls++] = descr;
203 }