Increment suspend count before attempting attach in suspend_for_ptrace.
[wine] / relay32 / builtin32.c
1 /*
2  * Win32 builtin functions
3  *
4  * Copyright 1997 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <ctype.h>
11 #include "windef.h"
12 #include "wingdi.h"
13 #include "winuser.h"
14 #include "builtin32.h"
15 #include "peexe.h"
16 #include "neexe.h"
17 #include "heap.h"
18 #include "main.h"
19 #include "snoop.h"
20 #include "winerror.h"
21 #include "server.h"
22 #include "debugtools.h"
23
24 DEFAULT_DEBUG_CHANNEL(module);
25 DECLARE_DEBUG_CHANNEL(relay);
26
27 typedef struct
28 {
29     BYTE  call;                    /* 0xe8 call callfrom32 (relative) */
30     DWORD callfrom32 WINE_PACKED;  /* RELAY_CallFrom32 relative addr */
31     BYTE  ret;                     /* 0xc2 ret $n  or  0xc3 ret */
32     WORD  args;                    /* nb of args to remove from the stack */
33 } DEBUG_ENTRY_POINT;
34
35 typedef struct
36 {
37         const BYTE                      *restab;
38         const DWORD                     nresources;
39         const DWORD                     restabsize;
40         const IMAGE_RESOURCE_DATA_ENTRY *entries;
41 } BUILTIN32_RESOURCE;
42
43 #define MAX_DLLS 60
44
45 static const BUILTIN32_DESCRIPTOR *builtin_dlls[MAX_DLLS];
46 static HMODULE dll_modules[MAX_DLLS];
47 static int nb_dlls;
48
49 extern void RELAY_CallFrom32();
50 extern void RELAY_CallFrom32Regs();
51
52
53 /***********************************************************************
54  *           BUILTIN32_WarnSecondInstance
55  *
56  * Emit a warning when we are creating a second instance for a DLL
57  * that is known to not support this.
58  */
59 static void BUILTIN32_WarnSecondInstance( const char *name )
60 {
61     static const char * const warning_list[] =
62     { "comctl32", "comdlg32", "crtdll", "imagehlp", "msacm32", "shell32", NULL };
63
64     const char * const *ptr = warning_list;
65
66     while (*ptr)
67     {
68         if (!strcasecmp( *ptr, name ))
69         {
70             ERR( "Attempt to instantiate built-in dll '%s' twice "
71                  "in the same address space. Expect trouble!\n", name );
72             return;
73         }
74         ptr++;
75     }
76 }
77
78 /***********************************************************************
79  *           BUILTIN32_DoLoadImage
80  *
81  * Load a built-in Win32 module. Helper function for BUILTIN32_LoadImage.
82  */
83 static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
84 {
85
86     IMAGE_DATA_DIRECTORY *dir;
87     IMAGE_DOS_HEADER *dos;
88     IMAGE_NT_HEADERS *nt;
89     IMAGE_SECTION_HEADER *sec;
90     IMAGE_EXPORT_DIRECTORY *exp;
91     IMAGE_IMPORT_DESCRIPTOR *imp;
92     const BUILTIN32_RESOURCE *rsrc = descr->rsrc;
93     LPVOID *funcs;
94     LPSTR *names;
95     LPSTR pfwd, rtab;
96     DEBUG_ENTRY_POINT *debug;
97     INT i, size, nb_sections;
98     BYTE *addr;
99
100     /* Allocate the module */
101
102     nb_sections = 2;  /* exports + code */
103     if (descr->nb_imports) nb_sections++;
104     size = (sizeof(IMAGE_DOS_HEADER)
105             + sizeof(IMAGE_NT_HEADERS)
106             + nb_sections * sizeof(IMAGE_SECTION_HEADER)
107             + (descr->nb_imports+1) * sizeof(IMAGE_IMPORT_DESCRIPTOR)
108             + sizeof(IMAGE_EXPORT_DIRECTORY)
109             + descr->nb_funcs * sizeof(LPVOID)
110             + descr->nb_names * sizeof(LPSTR)
111             + descr->fwd_size);
112 #ifdef __i386__
113     if (WARN_ON(relay) || TRACE_ON(relay))
114         size += descr->nb_funcs * sizeof(DEBUG_ENTRY_POINT);
115 #endif
116     if (rsrc) size += rsrc->restabsize;
117     addr  = VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
118     if (!addr) return 0;
119     dos   = (IMAGE_DOS_HEADER *)addr;
120     nt    = (IMAGE_NT_HEADERS *)(dos + 1);
121     sec   = (IMAGE_SECTION_HEADER *)(nt + 1);
122     imp   = (IMAGE_IMPORT_DESCRIPTOR *)(sec + nb_sections);
123     exp   = (IMAGE_EXPORT_DIRECTORY *)(imp + descr->nb_imports + 1);
124     funcs = (LPVOID *)(exp + 1);
125     names = (LPSTR *)(funcs + descr->nb_funcs);
126     pfwd  = (LPSTR)(names + descr->nb_names);
127     rtab  = pfwd + descr->fwd_size;
128     debug = (DEBUG_ENTRY_POINT *)(rtab + (rsrc ? rsrc->restabsize : 0));
129
130     /* Build the DOS and NT headers */
131
132     dos->e_magic  = IMAGE_DOS_SIGNATURE;
133     dos->e_lfanew = sizeof(*dos);
134
135     nt->Signature                       = IMAGE_NT_SIGNATURE;
136     nt->FileHeader.Machine              = IMAGE_FILE_MACHINE_I386;
137     nt->FileHeader.NumberOfSections     = nb_sections;
138     nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader);
139     nt->FileHeader.Characteristics      = descr->characteristics;
140
141     nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
142     nt->OptionalHeader.SizeOfCode                  = 0x1000;
143     nt->OptionalHeader.SizeOfInitializedData       = 0;
144     nt->OptionalHeader.SizeOfUninitializedData     = 0;
145     nt->OptionalHeader.ImageBase                   = (DWORD)addr;
146     nt->OptionalHeader.SectionAlignment            = 0x1000;
147     nt->OptionalHeader.FileAlignment               = 0x1000;
148     nt->OptionalHeader.MajorOperatingSystemVersion = 1;
149     nt->OptionalHeader.MinorOperatingSystemVersion = 0;
150     nt->OptionalHeader.MajorSubsystemVersion       = 4;
151     nt->OptionalHeader.MinorSubsystemVersion       = 0;
152     nt->OptionalHeader.SizeOfImage                 = size;
153     nt->OptionalHeader.SizeOfHeaders               = (BYTE *)exp - addr;
154     nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
155     if (descr->dllentrypoint) 
156         nt->OptionalHeader.AddressOfEntryPoint = (DWORD)descr->dllentrypoint - (DWORD)addr;
157     
158     /* Build the code section */
159
160     strcpy( sec->Name, ".code" );
161     sec->SizeOfRawData = 0;
162 #ifdef __i386__
163     if (WARN_ON(relay) || TRACE_ON(relay))
164         sec->SizeOfRawData += descr->nb_funcs * sizeof(DEBUG_ENTRY_POINT);
165 #endif
166     sec->Misc.VirtualSize = sec->SizeOfRawData;
167     sec->VirtualAddress   = (BYTE *)debug - addr;
168     sec->PointerToRawData = (BYTE *)debug - addr;
169     sec->Characteristics  = (IMAGE_SCN_CNT_INITIALIZED_DATA |
170                              IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ);
171     sec++;
172
173     /* Build the import directory */
174
175     if (descr->nb_imports)
176     {
177         dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY];
178         dir->VirtualAddress = (BYTE *)imp - addr;
179         dir->Size = sizeof(*imp) * (descr->nb_imports + 1);
180
181         /* Build the imports section */
182         strcpy( sec->Name, ".idata" );
183         sec->Misc.VirtualSize = dir->Size;
184         sec->VirtualAddress   = (BYTE *)imp - addr;
185         sec->SizeOfRawData    = dir->Size;
186         sec->PointerToRawData = (BYTE *)imp - addr;
187         sec->Characteristics  = (IMAGE_SCN_CNT_INITIALIZED_DATA |
188                                  IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
189                                  IMAGE_SCN_MEM_WRITE);
190         sec++;
191
192         /* Build the imports */
193         for (i = 0; i < descr->nb_imports; i++)
194         {
195             imp[i].u.Characteristics = 0;
196             imp[i].ForwarderChain = -1;
197             imp[i].Name = (BYTE *)descr->imports[i] - addr;
198             /* hack: make first thunk point to some zero value */
199             imp[i].FirstThunk = (PIMAGE_THUNK_DATA)((BYTE *)&imp[i].u.Characteristics - addr);
200         }
201     }
202
203     /* Build the export directory */
204
205     dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
206     dir->VirtualAddress = (BYTE *)exp - addr;
207     dir->Size = sizeof(*exp)
208                 + descr->nb_funcs * sizeof(LPVOID)
209                 + descr->nb_names * sizeof(LPSTR)
210                 + descr->fwd_size;
211
212     /* Build the exports section */
213
214     strcpy( sec->Name, ".edata" );
215     sec->Misc.VirtualSize = dir->Size;
216     sec->VirtualAddress   = (BYTE *)exp - addr;
217     sec->SizeOfRawData    = dir->Size;
218     sec->PointerToRawData = (BYTE *)exp - addr;
219     sec->Characteristics  = (IMAGE_SCN_CNT_INITIALIZED_DATA |
220                              IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
221                              IMAGE_SCN_MEM_WRITE);
222     sec++;
223
224     /* Build the resource directory */
225
226     if (rsrc)
227     {
228         IMAGE_RESOURCE_DATA_ENTRY *rdep;
229
230         /*
231          * The resource directory has to be copied because it contains
232          * RVAs. These would be invalid if the dll is instantiated twice.
233          */
234         memcpy(rtab, rsrc->restab, rsrc->restabsize);
235
236         dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY];
237         dir->VirtualAddress = (BYTE *)rtab - addr;
238         dir->Size = rsrc->restabsize;
239         rdep = (IMAGE_RESOURCE_DATA_ENTRY *)((DWORD)rtab + (DWORD)rsrc->entries - (DWORD)rsrc->restab);
240         for(i = 0; i < rsrc->nresources; i++)
241         {
242                 rdep[i].OffsetToData += (DWORD)rsrc->restab - (DWORD)addr;
243         }
244     }
245
246     /* Build the exports section data */
247
248     exp->Name                  = ((BYTE *)descr->name) - addr;  /*??*/
249     exp->Base                  = descr->base;
250     exp->NumberOfFunctions     = descr->nb_funcs;
251     exp->NumberOfNames         = descr->nb_names;
252     exp->AddressOfFunctions    = (LPDWORD *)((BYTE *)funcs - addr);
253     exp->AddressOfNames        = (LPDWORD *)((BYTE *)names - addr);
254     exp->AddressOfNameOrdinals = (LPWORD *)((BYTE *)descr->ordinals - addr);
255
256     /* Build the funcs table */
257
258     for (i = 0; i < descr->nb_funcs; i++, funcs++, debug++)
259     {
260         BYTE args = descr->args[i];
261         int j;
262
263         if (!descr->functions[i]) continue;
264
265         if (args == 0xfd)  /* forward func */
266         {
267             strcpy( pfwd, (LPSTR)descr->functions[i] );
268             *funcs = (LPVOID)((BYTE *)pfwd - addr);
269             pfwd += strlen(pfwd) + 1;
270         }
271         else *funcs = (LPVOID)((BYTE *)descr->functions[i] - addr);
272
273 #ifdef __i386__
274         if (!(WARN_ON(relay) || TRACE_ON(relay))) continue;
275         for (j=0;j<descr->nb_names;j++)
276             if (descr->ordinals[j] == i)
277                 break;
278         if (j<descr->nb_names) {
279             if (descr->names[j]) {
280                 char buffer[200];
281                 sprintf(buffer,"%s.%d: %s",descr->name,i,descr->names[j]);
282                 if (!RELAY_ShowDebugmsgRelay(buffer))
283                     continue;
284             }
285         }
286         switch(args)
287         {
288         case 0xfd:  /* forward */
289         case 0xff:  /* stub or extern */
290             break;
291         default:  /* normal function (stdcall or cdecl or register) */
292             if (TRACE_ON(relay)) {
293                 debug->call       = 0xe8; /* lcall relative */
294                 if (args & 0x40)  /* register func */
295                     debug->callfrom32 = (DWORD)RELAY_CallFrom32Regs -
296                         (DWORD)&debug->ret;
297                 else
298                     debug->callfrom32 = (DWORD)RELAY_CallFrom32 -
299                         (DWORD)&debug->ret;
300             } else {
301                 debug->call       = 0xe9; /* ljmp relative */
302                 debug->callfrom32 = (DWORD)descr->functions[i] -
303                                     (DWORD)&debug->ret;
304             }
305             debug->ret        = (args & 0x80) ? 0xc3 : 0xc2; /*ret/ret $n*/
306             debug->args       = (args & 0x3f) * sizeof(int);
307             *funcs = (LPVOID)((BYTE *)debug - addr);
308             break;
309         }
310 #endif  /* __i386__ */
311     }
312
313     /* Build the names table */
314
315     for (i = 0; i < exp->NumberOfNames; i++, names++)
316         if (descr->names[i])
317             *names = (LPSTR)((BYTE *)descr->names[i] - addr);
318
319     return (HMODULE)addr;
320 }
321
322 /***********************************************************************
323  *           BUILTIN32_LoadLibraryExA
324  *
325  * Partly copied from the original PE_ version.
326  *
327  */
328 WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
329 {
330     struct load_dll_request *req = get_req_buffer();
331     HMODULE16      hModule16;
332     NE_MODULE     *pModule;
333     WINE_MODREF   *wm;
334     char           dllname[MAX_PATH], *p;
335     int i;
336
337     /* Fix the name in case we have a full path and extension */
338     if ((p = strrchr( path, '\\' ))) path = p + 1;
339     lstrcpynA( dllname, path, sizeof(dllname) );
340
341     p = strrchr( dllname, '.' );
342     if (!p) strcat( dllname, ".dll" );
343
344     /* Search built-in descriptor */
345     for (i = 0; i < nb_dlls; i++)
346         if (!lstrcmpiA( builtin_dlls[i]->filename, dllname )) break;
347
348     if (i == nb_dlls)
349     {
350         SetLastError( ERROR_FILE_NOT_FOUND );
351         return NULL;
352     }
353
354     /* Load built-in module */
355     if (!dll_modules[i])
356     {
357         if (!(dll_modules[i] = BUILTIN32_DoLoadImage( builtin_dlls[i] ))) return NULL;
358     }
359     else BUILTIN32_WarnSecondInstance( builtin_dlls[i]->name );
360
361     /* Create 16-bit dummy module */
362     if ((hModule16 = MODULE_CreateDummyModule( dllname, 0 )) < 32)
363     {
364         SetLastError( (DWORD)hModule16 );
365         return NULL;    /* FIXME: Should unload the builtin module */
366     }
367
368     pModule = (NE_MODULE *)GlobalLock16( hModule16 );
369     pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN;
370     pModule->module32 = dll_modules[i];
371
372     /* Create 32-bit MODREF */
373     if ( !(wm = PE_CreateModule( pModule->module32, dllname, flags, TRUE )) )
374     {
375         ERR( "can't load %s\n", path );
376         FreeLibrary16( hModule16 );     /* FIXME: Should unload the builtin module */
377         SetLastError( ERROR_OUTOFMEMORY );
378         return NULL;
379     }
380
381     if (wm->binfmt.pe.pe_export)
382         SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions);
383
384     req->handle     = -1;
385     req->base       = (void *)pModule->module32;
386     req->dbg_offset = 0;
387     req->dbg_size   = 0;
388     req->name       = &wm->modname;
389     server_call_noerr( REQ_LOAD_DLL );
390     return wm;
391 }
392
393 /***********************************************************************
394  *           BUILTIN32_LoadExeModule
395  */
396 HMODULE16 BUILTIN32_LoadExeModule( void )
397 {
398     HMODULE16 hModule16;
399     NE_MODULE *pModule;
400     int i, exe = -1;
401
402     /* Search built-in EXE descriptor */
403     for ( i = 0; i < nb_dlls; i++ )
404         if ( !(builtin_dlls[i]->characteristics & IMAGE_FILE_DLL) ) 
405         {
406             if ( exe != -1 )
407             {
408                 MESSAGE( "More than one built-in EXE module loaded!\n" );
409                 break;
410             }
411
412             exe = i;
413         }
414
415     if ( exe == -1 ) 
416     {
417         MESSAGE( "No built-in EXE module loaded!  Did you create a .spec file?\n" );
418         return 0;
419     }
420
421     /* Load built-in module */
422     if ( !dll_modules[exe] )
423         if ( !(dll_modules[exe] = BUILTIN32_DoLoadImage( builtin_dlls[exe] )) )
424             return 0;
425
426     /* Create 16-bit dummy module */
427     hModule16 = MODULE_CreateDummyModule( builtin_dlls[exe]->filename, 0 );
428     if ( hModule16 < 32 ) return 0;
429     pModule = (NE_MODULE *)GlobalLock16( hModule16 );
430     pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN;
431     pModule->module32 = dll_modules[exe];
432
433     return hModule16;
434 }
435
436
437 /***********************************************************************
438  *      BUILTIN32_UnloadLibrary
439  *
440  * Unload the built-in library and free the modref.
441  */
442 void BUILTIN32_UnloadLibrary(WINE_MODREF *wm)
443 {
444         /* FIXME: do something here */
445 }
446
447
448 /***********************************************************************
449  *           BUILTIN32_GetEntryPoint
450  *
451  * Return the name of the DLL entry point corresponding
452  * to a relay entry point address. This is used only by relay debugging.
453  *
454  * This function _must_ return the real entry point to call
455  * after the debug info is printed.
456  */
457 ENTRYPOINT32 BUILTIN32_GetEntryPoint( char *buffer, void *relay,
458                                       unsigned int *typemask )
459 {
460     const BUILTIN32_DESCRIPTOR *descr = NULL;
461     int ordinal = 0, i;
462
463     /* First find the module */
464
465     for (i = 0; i < nb_dlls; i++)
466         if (dll_modules[i])
467         {
468             IMAGE_SECTION_HEADER *sec = PE_SECTIONS(dll_modules[i]);
469             DEBUG_ENTRY_POINT *debug = 
470                  (DEBUG_ENTRY_POINT *)((DWORD)dll_modules[i] + sec[0].VirtualAddress);
471             DEBUG_ENTRY_POINT *func = (DEBUG_ENTRY_POINT *)relay;
472             descr = builtin_dlls[i];
473             if (debug <= func && func < debug + descr->nb_funcs)
474             {
475                 ordinal = func - debug;
476                 break;
477             }
478         }
479     
480     if (!descr) return NULL;
481
482     /* Now find the function */
483
484     for (i = 0; i < descr->nb_names; i++)
485         if (descr->ordinals[i] == ordinal) break;
486
487     sprintf( buffer, "%s.%d: %s", descr->name, ordinal + descr->base,
488              (i < descr->nb_names) ? descr->names[i] : "@" );
489     *typemask = descr->argtypes[ordinal];
490     return descr->functions[ordinal];
491 }
492
493 /***********************************************************************
494  *           BUILTIN32_SwitchRelayDebug
495  *
496  * FIXME: enhance to do it module relative.
497  */
498 void BUILTIN32_SwitchRelayDebug(BOOL onoff)
499 {
500     const BUILTIN32_DESCRIPTOR *descr;
501     IMAGE_SECTION_HEADER *sec;
502     DEBUG_ENTRY_POINT *debug;
503     int i, j;
504
505 #ifdef __i386__
506     if (!(TRACE_ON(relay) || WARN_ON(relay)))
507         return;
508     for (j = 0; j < nb_dlls; j++)
509     {
510         if (!dll_modules[j]) continue;
511         sec = PE_SECTIONS(dll_modules[j]);
512         debug = (DEBUG_ENTRY_POINT *)((DWORD)dll_modules[j] + sec[1].VirtualAddress);
513         descr = builtin_dlls[j];
514         for (i = 0; i < descr->nb_funcs; i++,debug++) {
515             if (!descr->functions[i]) continue;
516             if ((descr->args[i]==0xff) || (descr->args[i]==0xfe))
517                 continue;
518             if (onoff) {
519                 debug->call       = 0xe8; /* lcall relative */
520                 debug->callfrom32 = (DWORD)RELAY_CallFrom32 -
521                                     (DWORD)&debug->ret;
522             } else {
523                 debug->call       = 0xe9; /* ljmp relative */
524                 debug->callfrom32 = (DWORD)descr->functions[i] -
525                                     (DWORD)&debug->ret;
526             }
527         }
528     }
529 #endif /* __i386__ */
530     return;
531 }
532
533 /***********************************************************************
534  *           BUILTIN32_RegisterDLL
535  *
536  * Register a built-in DLL descriptor.
537  */
538 void BUILTIN32_RegisterDLL( const BUILTIN32_DESCRIPTOR *descr )
539 {
540     assert( nb_dlls < MAX_DLLS );
541     builtin_dlls[nb_dlls++] = descr;
542 }
543
544 /***********************************************************************
545  *           BUILTIN32_Unimplemented
546  *
547  * This function is called for unimplemented 32-bit entry points (declared
548  * as 'stub' in the spec file).
549  */
550 void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR *descr, int ordinal )
551 {
552     const char *func_name = "???";
553     int i;
554
555     __RESTORE_ES;  /* Just in case */
556
557     for (i = 0; i < descr->nb_names; i++)
558         if (descr->ordinals[i] + descr->base == ordinal) break;
559     if (i < descr->nb_names) func_name = descr->names[i];
560
561     MESSAGE( "No handler for Win32 routine %s.%d: %s",
562              descr->name, ordinal, func_name );
563 #ifdef __GNUC__
564     MESSAGE( " (called from %p)", __builtin_return_address(1) );
565 #endif
566     MESSAGE( "\n" );
567     ExitProcess(1);
568 }