CoGetClassObject: for CLSCTX_LOCAL_SERVER at least look up the server
[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 "builtin16.h"
14 #include "global.h"
15 #include "file.h"
16 #include "module.h"
17 #include "miscemu.h"
18 #include "stackframe.h"
19 #include "debugtools.h"
20 #include "toolhelp.h"
21
22 DEFAULT_DEBUG_CHANNEL(module);
23
24 typedef struct
25 {
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;
33
34 /* Table of all built-in DLLs */
35
36 #define MAX_DLLS 50
37
38 static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
39 static int nb_dlls;
40
41
42 /* patch all the flat cs references of the code segment if necessary */
43 inline static void patch_code_segment( void *code_segment )
44 {
45 #ifdef __i386__
46     CALLFROM16 *call = code_segment;
47     if (call->flatcs == __get_cs()) return;  /* nothing to patch */
48     while (call->pushl == 0x68)
49     {
50         call->flatcs = __get_cs();
51         call++;
52     }
53 #endif
54 }
55
56
57 /***********************************************************************
58  *           BUILTIN_DoLoadModule16
59  *
60  * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule.
61  */
62 static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
63 {
64     NE_MODULE *pModule;
65     int minsize;
66     SEGTABLEENTRY *pSegTable;
67     HMODULE16 hModule;
68
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 );
73
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;
78
79     /* Allocate the code segment */
80
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 );
87     pSegTable++;
88
89     /* Allocate the data segment */
90
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 );
102
103     if (descr->rsrc) NE_InitResourceHandler(hModule);
104
105     NE_RegisterModule( pModule );
106
107     /* make sure the 32-bit library containing this one is loaded too */
108     LoadLibraryA( descr->owner );
109
110     return hModule;
111 }
112
113
114 /***********************************************************************
115  *           find_dll_descr
116  *
117  * Find a descriptor in the list
118  */
119 static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname )
120 {
121     int i;
122     for (i = 0; i < nb_dlls; i++)
123     {
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;
128
129         /* check the dll file name */
130         if (!FILE_strcasecmp( pOfs->szPathName, dllname ))
131             return descr;
132         /* check the dll module name (without extension) */
133         if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) &&
134             !strcmp( dllname + *name_table, ".dll" ))
135             return descr;
136     }
137     return NULL;
138 }
139
140
141 /***********************************************************************
142  *           BUILTIN_LoadModule
143  *
144  * Load a built-in module.
145  */
146 HMODULE16 BUILTIN_LoadModule( LPCSTR name )
147 {
148     const BUILTIN16_DESCRIPTOR *descr;
149     char dllname[20], *p;
150     void *handle;
151
152     /* Fix the name in case we have a full path and extension */
153
154     if ((p = strrchr( name, '\\' ))) name = p + 1;
155     if ((p = strrchr( name, '/' ))) name = p + 1;
156
157     if (strlen(name) >= sizeof(dllname)-4) return (HMODULE16)2;
158
159     strcpy( dllname, name );
160     p = strrchr( dllname, '.' );
161     if (!p) strcat( dllname, ".dll" );
162     for (p = dllname; *p; p++) *p = FILE_tolower(*p);
163
164     if ((descr = find_dll_descr( dllname )))
165         return BUILTIN_DoLoadModule16( descr );
166
167     if ((handle = BUILTIN32_dlopen( dllname )))
168     {
169         if ((descr = find_dll_descr( dllname )))
170             return BUILTIN_DoLoadModule16( descr );
171
172         ERR( "loaded .so but dll %s still not found\n", dllname );
173         BUILTIN32_dlclose( handle );
174     }
175
176     return (HMODULE16)2;
177 }
178
179
180 /***********************************************************************
181  *           __wine_register_dll_16 (KERNEL32.@)
182  *
183  * Register a built-in DLL descriptor.
184  */
185 void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr )
186 {
187     assert( nb_dlls < MAX_DLLS );
188     builtin_dlls[nb_dlls++] = descr;
189 }