2 * Win32 builtin functions
4 * Copyright 1997 Alexandre Julliard
11 #include "builtin32.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(module
);
21 DECLARE_DEBUG_CHANNEL(relay
);
25 BYTE call
; /* 0xe8 call callfrom32 (relative) */
26 DWORD callfrom32 WINE_PACKED
; /* RELAY_CallFrom32 relative addr */
27 BYTE ret
; /* 0xc2 ret $n or 0xc3 ret */
28 WORD args
; /* nb of args to remove from the stack */
34 const DWORD nresources
;
35 const DWORD restabsize
;
36 const IMAGE_RESOURCE_DATA_ENTRY
*entries
;
41 const BUILTIN32_DESCRIPTOR
*descr
; /* DLL descriptor */
45 extern const BUILTIN32_DESCRIPTOR ADVAPI32_Descriptor
;
46 extern const BUILTIN32_DESCRIPTOR AVIFIL32_Descriptor
;
47 extern const BUILTIN32_DESCRIPTOR COMCTL32_Descriptor
;
48 extern const BUILTIN32_DESCRIPTOR COMDLG32_Descriptor
;
49 extern const BUILTIN32_DESCRIPTOR CRTDLL_Descriptor
;
50 extern const BUILTIN32_DESCRIPTOR DCIMAN32_Descriptor
;
51 extern const BUILTIN32_DESCRIPTOR DDRAW_Descriptor
;
52 extern const BUILTIN32_DESCRIPTOR DINPUT_Descriptor
;
53 extern const BUILTIN32_DESCRIPTOR DPLAY_Descriptor
;
54 extern const BUILTIN32_DESCRIPTOR DPLAYX_Descriptor
;
55 extern const BUILTIN32_DESCRIPTOR DSOUND_Descriptor
;
56 extern const BUILTIN32_DESCRIPTOR GDI32_Descriptor
;
57 extern const BUILTIN32_DESCRIPTOR ICMP_Descriptor
;
58 extern const BUILTIN32_DESCRIPTOR IMAGEHLP_Descriptor
;
59 extern const BUILTIN32_DESCRIPTOR IMM32_Descriptor
;
60 extern const BUILTIN32_DESCRIPTOR KERNEL32_Descriptor
;
61 extern const BUILTIN32_DESCRIPTOR LZ32_Descriptor
;
62 extern const BUILTIN32_DESCRIPTOR MPR_Descriptor
;
63 extern const BUILTIN32_DESCRIPTOR MCIANIM_Descriptor
;
64 extern const BUILTIN32_DESCRIPTOR MCIAVI_Descriptor
;
65 extern const BUILTIN32_DESCRIPTOR MCICDA_Descriptor
;
66 extern const BUILTIN32_DESCRIPTOR MCISEQ_Descriptor
;
67 extern const BUILTIN32_DESCRIPTOR MCIWAVE_Descriptor
;
68 extern const BUILTIN32_DESCRIPTOR MIDIMAP_Descriptor
;
69 extern const BUILTIN32_DESCRIPTOR MSACM32_Descriptor
;
70 extern const BUILTIN32_DESCRIPTOR MSACMMAP_Descriptor
;
71 extern const BUILTIN32_DESCRIPTOR MSNET32_Descriptor
;
72 extern const BUILTIN32_DESCRIPTOR MSVFW32_Descriptor
;
73 extern const BUILTIN32_DESCRIPTOR NTDLL_Descriptor
;
74 extern const BUILTIN32_DESCRIPTOR ODBC32_Descriptor
;
75 extern const BUILTIN32_DESCRIPTOR OLE32_Descriptor
;
76 extern const BUILTIN32_DESCRIPTOR OLEAUT32_Descriptor
;
77 extern const BUILTIN32_DESCRIPTOR OLECLI32_Descriptor
;
78 extern const BUILTIN32_DESCRIPTOR OLEDLG_Descriptor
;
79 extern const BUILTIN32_DESCRIPTOR OLESVR32_Descriptor
;
80 extern const BUILTIN32_DESCRIPTOR PSAPI_Descriptor
;
81 extern const BUILTIN32_DESCRIPTOR RASAPI32_Descriptor
;
82 extern const BUILTIN32_DESCRIPTOR SHELL32_Descriptor
;
83 extern const BUILTIN32_DESCRIPTOR SHLWAPI_Descriptor
;
84 extern const BUILTIN32_DESCRIPTOR TAPI32_Descriptor
;
85 extern const BUILTIN32_DESCRIPTOR USER32_Descriptor
;
86 extern const BUILTIN32_DESCRIPTOR VERSION_Descriptor
;
87 extern const BUILTIN32_DESCRIPTOR W32SKRNL_Descriptor
;
88 extern const BUILTIN32_DESCRIPTOR WINEOSS_Descriptor
;
89 extern const BUILTIN32_DESCRIPTOR WINMM_Descriptor
;
90 extern const BUILTIN32_DESCRIPTOR WINSPOOL_Descriptor
;
91 extern const BUILTIN32_DESCRIPTOR WNASPI32_Descriptor
;
92 extern const BUILTIN32_DESCRIPTOR WOW32_Descriptor
;
93 extern const BUILTIN32_DESCRIPTOR WSOCK32_Descriptor
;
96 static BUILTIN32_DLL BuiltinDLLs
[] =
98 { &ADVAPI32_Descriptor
, 0 },
99 { &AVIFIL32_Descriptor
, 0 },
100 { &COMCTL32_Descriptor
, 0 },
101 { &COMDLG32_Descriptor
, 0 },
102 { &CRTDLL_Descriptor
, 0 },
103 { &DCIMAN32_Descriptor
, 0 },
104 { &DDRAW_Descriptor
, 0 },
105 { &DINPUT_Descriptor
, 0 },
106 { &DPLAY_Descriptor
, 0 },
107 { &DPLAYX_Descriptor
, 0 },
108 { &DSOUND_Descriptor
, 0 },
109 { &GDI32_Descriptor
, 0 },
110 { &ICMP_Descriptor
, 0 },
111 { &IMAGEHLP_Descriptor
, 0 },
112 { &IMM32_Descriptor
, 0 },
113 { &KERNEL32_Descriptor
, 0 },
114 { &LZ32_Descriptor
, 0 },
115 { &MCIANIM_Descriptor
, 0 },
116 { &MCIAVI_Descriptor
, 0 },
117 { &MCICDA_Descriptor
, 0 },
118 { &MCISEQ_Descriptor
, 0 },
119 { &MCIWAVE_Descriptor
, 0 },
120 { &MIDIMAP_Descriptor
, 0 },
121 { &MPR_Descriptor
, 0 },
122 { &MSACM32_Descriptor
, 0 },
123 { &MSACMMAP_Descriptor
, 0 },
124 { &MSNET32_Descriptor
, 0 },
125 { &MSVFW32_Descriptor
, 0 },
126 { &NTDLL_Descriptor
, 0 },
127 { &ODBC32_Descriptor
, 0 },
128 { &OLE32_Descriptor
, 0 },
129 { &OLEAUT32_Descriptor
, 0 },
130 { &OLECLI32_Descriptor
, 0 },
131 { &OLEDLG_Descriptor
, 0 },
132 { &OLESVR32_Descriptor
, 0 },
133 { &PSAPI_Descriptor
, 0 },
134 { &RASAPI32_Descriptor
, 0 },
135 { &SHELL32_Descriptor
, 0 },
136 { &SHLWAPI_Descriptor
, 0 },
137 { &TAPI32_Descriptor
, 0 },
138 { &USER32_Descriptor
, 0 },
139 { &VERSION_Descriptor
, 0 },
140 { &W32SKRNL_Descriptor
, 0 },
141 { &WINMM_Descriptor
, 0 },
142 { &WINSPOOL_Descriptor
, 0 },
143 { &WINEOSS_Descriptor
, 0 },
144 { &WNASPI32_Descriptor
, 0 },
145 { &WOW32_Descriptor
, 0 },
146 { &WSOCK32_Descriptor
, 0 },
151 extern void RELAY_CallFrom32();
152 extern void RELAY_CallFrom32Regs();
155 /***********************************************************************
156 * BUILTIN32_WarnSecondInstance
158 * Emit a warning when we are creating a second instance for a DLL
159 * that is known to not support this.
161 static void BUILTIN32_WarnSecondInstance( const char *name
)
163 static const char * const warning_list
[] =
164 { "comctl32", "comdlg32", "crtdll", "imagehlp", "msacm32", "shell32", NULL
};
166 const char * const *ptr
= warning_list
;
170 if (!strcasecmp( *ptr
, name
))
172 ERR( "Attempt to instantiate built-in dll '%s' twice "
173 "in the same address space. Expect trouble!\n", name
);
180 /***********************************************************************
181 * BUILTIN32_DoLoadImage
183 * Load a built-in Win32 module. Helper function for BUILTIN32_LoadImage.
185 static HMODULE
BUILTIN32_DoLoadImage( BUILTIN32_DLL
*dll
)
188 IMAGE_DATA_DIRECTORY
*dir
;
189 IMAGE_DOS_HEADER
*dos
;
190 IMAGE_NT_HEADERS
*nt
;
191 IMAGE_SECTION_HEADER
*sec
;
192 IMAGE_EXPORT_DIRECTORY
*exp
;
193 IMAGE_IMPORT_DESCRIPTOR
*imp
;
197 DEBUG_ENTRY_POINT
*debug
;
198 INT i
, size
, nb_sections
;
201 /* Allocate the module */
203 nb_sections
= 2; /* exports + code */
204 if (dll
->descr
->nb_imports
) nb_sections
++;
205 size
= (sizeof(IMAGE_DOS_HEADER
)
206 + sizeof(IMAGE_NT_HEADERS
)
207 + nb_sections
* sizeof(IMAGE_SECTION_HEADER
)
208 + (dll
->descr
->nb_imports
+1) * sizeof(IMAGE_IMPORT_DESCRIPTOR
)
209 + sizeof(IMAGE_EXPORT_DIRECTORY
)
210 + dll
->descr
->nb_funcs
* sizeof(LPVOID
)
211 + dll
->descr
->nb_names
* sizeof(LPSTR
)
212 + dll
->descr
->fwd_size
);
214 if (WARN_ON(relay
) || TRACE_ON(relay
))
215 size
+= dll
->descr
->nb_funcs
* sizeof(DEBUG_ENTRY_POINT
);
217 addr
= VirtualAlloc( NULL
, size
, MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
219 dos
= (IMAGE_DOS_HEADER
*)addr
;
220 nt
= (IMAGE_NT_HEADERS
*)(dos
+ 1);
221 sec
= (IMAGE_SECTION_HEADER
*)(nt
+ 1);
222 imp
= (IMAGE_IMPORT_DESCRIPTOR
*)(sec
+ nb_sections
);
223 exp
= (IMAGE_EXPORT_DIRECTORY
*)(imp
+ dll
->descr
->nb_imports
+ 1);
224 funcs
= (LPVOID
*)(exp
+ 1);
225 names
= (LPSTR
*)(funcs
+ dll
->descr
->nb_funcs
);
226 pfwd
= (LPSTR
)(names
+ dll
->descr
->nb_names
);
227 debug
= (DEBUG_ENTRY_POINT
*)(pfwd
+ dll
->descr
->fwd_size
);
229 /* Build the DOS and NT headers */
231 dos
->e_magic
= IMAGE_DOS_SIGNATURE
;
232 dos
->e_lfanew
= sizeof(*dos
);
234 nt
->Signature
= IMAGE_NT_SIGNATURE
;
235 nt
->FileHeader
.Machine
= IMAGE_FILE_MACHINE_I386
;
236 nt
->FileHeader
.NumberOfSections
= nb_sections
;
237 nt
->FileHeader
.SizeOfOptionalHeader
= sizeof(nt
->OptionalHeader
);
238 nt
->FileHeader
.Characteristics
= IMAGE_FILE_DLL
;
240 nt
->OptionalHeader
.Magic
= IMAGE_NT_OPTIONAL_HDR_MAGIC
;
241 nt
->OptionalHeader
.SizeOfCode
= 0x1000;
242 nt
->OptionalHeader
.SizeOfInitializedData
= 0;
243 nt
->OptionalHeader
.SizeOfUninitializedData
= 0;
244 nt
->OptionalHeader
.ImageBase
= (DWORD
)addr
;
245 nt
->OptionalHeader
.SectionAlignment
= 0x1000;
246 nt
->OptionalHeader
.FileAlignment
= 0x1000;
247 nt
->OptionalHeader
.MajorOperatingSystemVersion
= 1;
248 nt
->OptionalHeader
.MinorOperatingSystemVersion
= 0;
249 nt
->OptionalHeader
.MajorSubsystemVersion
= 4;
250 nt
->OptionalHeader
.MinorSubsystemVersion
= 0;
251 nt
->OptionalHeader
.SizeOfImage
= size
;
252 nt
->OptionalHeader
.SizeOfHeaders
= (BYTE
*)exp
- addr
;
253 nt
->OptionalHeader
.NumberOfRvaAndSizes
= IMAGE_NUMBEROF_DIRECTORY_ENTRIES
;
254 if (dll
->descr
->dllentrypoint
)
255 nt
->OptionalHeader
.AddressOfEntryPoint
= (DWORD
)dll
->descr
->dllentrypoint
- (DWORD
)addr
;
257 /* Build the code section */
259 strcpy( sec
->Name
, ".code" );
260 sec
->SizeOfRawData
= 0;
262 if (WARN_ON(relay
) || TRACE_ON(relay
))
263 sec
->SizeOfRawData
+= dll
->descr
->nb_funcs
* sizeof(DEBUG_ENTRY_POINT
);
265 sec
->Misc
.VirtualSize
= sec
->SizeOfRawData
;
266 sec
->VirtualAddress
= (BYTE
*)debug
- addr
;
267 sec
->PointerToRawData
= (BYTE
*)debug
- addr
;
268 sec
->Characteristics
= (IMAGE_SCN_CNT_INITIALIZED_DATA
|
269 IMAGE_SCN_MEM_EXECUTE
| IMAGE_SCN_MEM_READ
);
272 /* Build the import directory */
274 if (dll
->descr
->nb_imports
)
276 dir
= &nt
->OptionalHeader
.DataDirectory
[IMAGE_FILE_IMPORT_DIRECTORY
];
277 dir
->VirtualAddress
= (BYTE
*)imp
- addr
;
278 dir
->Size
= sizeof(*imp
) * (dll
->descr
->nb_imports
+ 1);
280 /* Build the imports section */
281 strcpy( sec
->Name
, ".idata" );
282 sec
->Misc
.VirtualSize
= dir
->Size
;
283 sec
->VirtualAddress
= (BYTE
*)imp
- addr
;
284 sec
->SizeOfRawData
= dir
->Size
;
285 sec
->PointerToRawData
= (BYTE
*)imp
- addr
;
286 sec
->Characteristics
= (IMAGE_SCN_CNT_INITIALIZED_DATA
|
287 IMAGE_SCN_MEM_EXECUTE
| IMAGE_SCN_MEM_READ
|
288 IMAGE_SCN_MEM_WRITE
);
291 /* Build the imports */
292 for (i
= 0; i
< dll
->descr
->nb_imports
; i
++)
294 imp
[i
].u
.Characteristics
= 0;
295 imp
[i
].ForwarderChain
= -1;
296 imp
[i
].Name
= (BYTE
*)dll
->descr
->imports
[i
] - addr
;
297 /* hack: make first thunk point to some zero value */
298 imp
[i
].FirstThunk
= (PIMAGE_THUNK_DATA
)((BYTE
*)&imp
[i
].u
.Characteristics
- addr
);
302 /* Build the export directory */
304 dir
= &nt
->OptionalHeader
.DataDirectory
[IMAGE_FILE_EXPORT_DIRECTORY
];
305 dir
->VirtualAddress
= (BYTE
*)exp
- addr
;
306 dir
->Size
= sizeof(*exp
)
307 + dll
->descr
->nb_funcs
* sizeof(LPVOID
)
308 + dll
->descr
->nb_names
* sizeof(LPSTR
)
309 + dll
->descr
->fwd_size
;
311 /* Build the exports section */
313 strcpy( sec
->Name
, ".edata" );
314 sec
->Misc
.VirtualSize
= dir
->Size
;
315 sec
->VirtualAddress
= (BYTE
*)exp
- addr
;
316 sec
->SizeOfRawData
= dir
->Size
;
317 sec
->PointerToRawData
= (BYTE
*)exp
- addr
;
318 sec
->Characteristics
= (IMAGE_SCN_CNT_INITIALIZED_DATA
|
319 IMAGE_SCN_MEM_EXECUTE
| IMAGE_SCN_MEM_READ
|
320 IMAGE_SCN_MEM_WRITE
);
323 /* Build the resource directory */
326 const BUILTIN32_RESOURCE
*rsrc
= dll
->descr
->rsrc
;
329 IMAGE_RESOURCE_DATA_ENTRY
*rdep
;
331 rtab
= HeapAlloc(GetProcessHeap(), 0, rsrc
->restabsize
);
334 ERR("Failed to get memory for resource directory\n");
335 VirtualFree(addr
, size
, MEM_RELEASE
);
340 * The resource directory has to be copied because it contains
341 * RVAs. These would be invalid if the dll is instantiated twice.
343 memcpy(rtab
, rsrc
->restab
, rsrc
->restabsize
);
345 dir
= &nt
->OptionalHeader
.DataDirectory
[IMAGE_FILE_RESOURCE_DIRECTORY
];
346 dir
->VirtualAddress
= (DWORD
)rtab
- (DWORD
)addr
;
347 dir
->Size
= rsrc
->restabsize
;
348 rdep
= (IMAGE_RESOURCE_DATA_ENTRY
*)((DWORD
)rtab
+ (DWORD
)rsrc
->entries
- (DWORD
)rsrc
->restab
);
349 for(i
= 0; i
< rsrc
->nresources
; i
++)
351 rdep
[i
].OffsetToData
+= (DWORD
)rsrc
->restab
- (DWORD
)addr
;
355 /* Build the exports section data */
357 exp
->Name
= ((BYTE
*)dll
->descr
->name
) - addr
; /*??*/
358 exp
->Base
= dll
->descr
->base
;
359 exp
->NumberOfFunctions
= dll
->descr
->nb_funcs
;
360 exp
->NumberOfNames
= dll
->descr
->nb_names
;
361 exp
->AddressOfFunctions
= (LPDWORD
*)((BYTE
*)funcs
- addr
);
362 exp
->AddressOfNames
= (LPDWORD
*)((BYTE
*)names
- addr
);
363 exp
->AddressOfNameOrdinals
= (LPWORD
*)((BYTE
*)dll
->descr
->ordinals
- addr
);
365 /* Build the funcs table */
367 for (i
= 0; i
< dll
->descr
->nb_funcs
; i
++, funcs
++, debug
++)
369 BYTE args
= dll
->descr
->args
[i
];
372 if (!dll
->descr
->functions
[i
]) continue;
374 if (args
== 0xfd) /* forward func */
376 strcpy( pfwd
, (LPSTR
)dll
->descr
->functions
[i
] );
377 *funcs
= (LPVOID
)((BYTE
*)pfwd
- addr
);
378 pfwd
+= strlen(pfwd
) + 1;
380 else *funcs
= (LPVOID
)((BYTE
*)dll
->descr
->functions
[i
] - addr
);
383 if (!(WARN_ON(relay
) || TRACE_ON(relay
))) continue;
384 for (j
=0;j
<dll
->descr
->nb_names
;j
++)
385 if (dll
->descr
->ordinals
[j
] == i
)
387 if (j
<dll
->descr
->nb_names
) {
388 if (dll
->descr
->names
[j
]) {
390 sprintf(buffer
,"%s.%d: %s",dll
->descr
->name
,i
,dll
->descr
->names
[j
]);
391 if (!RELAY_ShowDebugmsgRelay(buffer
))
397 case 0xfd: /* forward */
398 case 0xff: /* stub or extern */
400 default: /* normal function (stdcall or cdecl or register) */
401 if (TRACE_ON(relay
)) {
402 debug
->call
= 0xe8; /* lcall relative */
403 if (args
& 0x40) /* register func */
404 debug
->callfrom32
= (DWORD
)RELAY_CallFrom32Regs
-
407 debug
->callfrom32
= (DWORD
)RELAY_CallFrom32
-
410 debug
->call
= 0xe9; /* ljmp relative */
411 debug
->callfrom32
= (DWORD
)dll
->descr
->functions
[i
] -
414 debug
->ret
= (args
& 0x80) ? 0xc3 : 0xc2; /*ret/ret $n*/
415 debug
->args
= (args
& 0x3f) * sizeof(int);
416 *funcs
= (LPVOID
)((BYTE
*)debug
- addr
);
419 #endif /* __i386__ */
422 /* Build the names table */
424 for (i
= 0; i
< exp
->NumberOfNames
; i
++, names
++)
425 if (dll
->descr
->names
[i
])
426 *names
= (LPSTR
)((BYTE
*)dll
->descr
->names
[i
] - addr
);
428 return (HMODULE
)addr
;
431 /***********************************************************************
432 * BUILTIN32_LoadLibraryExA
434 * Partly copied from the original PE_ version.
437 WINE_MODREF
*BUILTIN32_LoadLibraryExA(LPCSTR path
, DWORD flags
, DWORD
*err
)
439 BUILTIN32_DLL
*table
;
443 char dllname
[MAX_PATH
], *p
;
445 /* Fix the name in case we have a full path and extension */
446 if ((p
= strrchr( path
, '\\' ))) path
= p
+ 1;
447 lstrcpynA( dllname
, path
, sizeof(dllname
) );
449 p
= strrchr( dllname
, '.' );
450 if (!p
) strcat( dllname
, ".dll" );
452 /* Search built-in descriptor */
453 for ( table
= BuiltinDLLs
; table
->descr
; table
++ )
454 if (!lstrcmpiA( table
->descr
->filename
, dllname
)) break;
458 *err
= ERROR_FILE_NOT_FOUND
;
462 /* Load built-in module */
465 if (!(table
->hModule
= BUILTIN32_DoLoadImage( table
)))
467 *err
= ERROR_FILE_NOT_FOUND
;
471 else BUILTIN32_WarnSecondInstance( table
->descr
->name
);
473 /* Create 16-bit dummy module */
474 if ((hModule16
= MODULE_CreateDummyModule( dllname
, 0 )) < 32)
476 *err
= (DWORD
)hModule16
;
477 return NULL
; /* FIXME: Should unload the builtin module */
480 pModule
= (NE_MODULE
*)GlobalLock16( hModule16
);
481 pModule
->flags
= NE_FFLAGS_LIBMODULE
| NE_FFLAGS_SINGLEDATA
| NE_FFLAGS_WIN32
| NE_FFLAGS_BUILTIN
;
482 pModule
->module32
= table
->hModule
;
484 /* Create 32-bit MODREF */
485 if ( !(wm
= PE_CreateModule( table
->hModule
, dllname
, flags
, TRUE
)) )
487 ERR( "can't load %s\n", path
);
488 FreeLibrary16( hModule16
); /* FIXME: Should unload the builtin module */
489 *err
= ERROR_OUTOFMEMORY
;
493 if (wm
->binfmt
.pe
.pe_export
)
494 SNOOP_RegisterDLL(wm
->module
,wm
->modname
,wm
->binfmt
.pe
.pe_export
->NumberOfFunctions
);
501 /***********************************************************************
502 * BUILTIN32_UnloadLibrary
504 * Unload the built-in library and free the modref.
506 void BUILTIN32_UnloadLibrary(WINE_MODREF
*wm
)
508 /* FIXME: do something here */
512 /***********************************************************************
513 * BUILTIN32_GetEntryPoint
515 * Return the name of the DLL entry point corresponding
516 * to a relay entry point address. This is used only by relay debugging.
518 * This function _must_ return the real entry point to call
519 * after the debug info is printed.
521 ENTRYPOINT32
BUILTIN32_GetEntryPoint( char *buffer
, void *relay
,
522 unsigned int *typemask
)
527 /* First find the module */
529 for (dll
= BuiltinDLLs
; dll
->descr
; dll
++)
532 IMAGE_SECTION_HEADER
*sec
= PE_SECTIONS(dll
->hModule
);
533 DEBUG_ENTRY_POINT
*debug
=
534 (DEBUG_ENTRY_POINT
*)((DWORD
)dll
->hModule
+ sec
[0].VirtualAddress
);
535 DEBUG_ENTRY_POINT
*func
= (DEBUG_ENTRY_POINT
*)relay
;
537 if (debug
<= func
&& func
< debug
+ dll
->descr
->nb_funcs
)
539 ordinal
= func
- debug
;
545 return (ENTRYPOINT32
)NULL
;
547 /* Now find the function */
549 for (i
= 0; i
< dll
->descr
->nb_names
; i
++)
550 if (dll
->descr
->ordinals
[i
] == ordinal
) break;
552 sprintf( buffer
, "%s.%d: %s", dll
->descr
->name
, ordinal
+ dll
->descr
->base
,
553 (i
< dll
->descr
->nb_names
) ? dll
->descr
->names
[i
] : "@" );
554 *typemask
= dll
->descr
->argtypes
[ordinal
];
555 return dll
->descr
->functions
[ordinal
];
558 /***********************************************************************
559 * BUILTIN32_SwitchRelayDebug
561 * FIXME: enhance to do it module relative.
563 void BUILTIN32_SwitchRelayDebug(BOOL onoff
) {
568 if (!(TRACE_ON(relay
) || WARN_ON(relay
)))
570 for (dll
= BuiltinDLLs
; dll
->descr
; dll
++) {
571 IMAGE_SECTION_HEADER
*sec
;
572 DEBUG_ENTRY_POINT
*debug
;
573 if (!dll
->hModule
) continue;
575 sec
= PE_SECTIONS(dll
->hModule
);
576 debug
= (DEBUG_ENTRY_POINT
*)((DWORD
)dll
->hModule
+ sec
[1].VirtualAddress
);
577 for (i
= 0; i
< dll
->descr
->nb_funcs
; i
++,debug
++) {
578 if (!dll
->descr
->functions
[i
]) continue;
579 if ((dll
->descr
->args
[i
]==0xff) || (dll
->descr
->args
[i
]==0xfe))
582 debug
->call
= 0xe8; /* lcall relative */
583 debug
->callfrom32
= (DWORD
)RELAY_CallFrom32
-
586 debug
->call
= 0xe9; /* ljmp relative */
587 debug
->callfrom32
= (DWORD
)dll
->descr
->functions
[i
] -
592 #endif /* __i386__ */
596 /***********************************************************************
597 * BUILTIN32_Unimplemented
599 * This function is called for unimplemented 32-bit entry points (declared
600 * as 'stub' in the spec file).
602 void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR
*descr
, int ordinal
)
604 const char *func_name
= "???";
607 __RESTORE_ES
; /* Just in case */
609 for (i
= 0; i
< descr
->nb_names
; i
++)
610 if (descr
->ordinals
[i
] + descr
->base
== ordinal
) break;
611 if (i
< descr
->nb_names
) func_name
= descr
->names
[i
];
613 MESSAGE( "No handler for Win32 routine %s.%d: %s",
614 descr
->name
, ordinal
, func_name
);
616 MESSAGE( " (called from %p)", __builtin_return_address(1) );