2 * Win32 builtin functions
4 * Copyright 1997 Alexandre Julliard
18 BYTE call
; /* 0xe8 call callfrom32 (relative) */
19 DWORD callfrom32 WINE_PACKED
; /* RELAY_CallFrom32 relative addr */
20 BYTE ret
; /* 0xc2 ret $n or 0xc3 ret */
21 WORD args
; /* nb of args to remove from the stack */
26 const BUILTIN32_DESCRIPTOR
*descr
; /* DLL descriptor */
27 BOOL32 used
; /* Used by default */
31 extern const BUILTIN32_DESCRIPTOR ADVAPI32_Descriptor
;
32 extern const BUILTIN32_DESCRIPTOR COMCTL32_Descriptor
;
33 extern const BUILTIN32_DESCRIPTOR COMDLG32_Descriptor
;
34 extern const BUILTIN32_DESCRIPTOR CRTDLL_Descriptor
;
35 extern const BUILTIN32_DESCRIPTOR DCIMAN32_Descriptor
;
36 extern const BUILTIN32_DESCRIPTOR DDRAW_Descriptor
;
37 extern const BUILTIN32_DESCRIPTOR DINPUT_Descriptor
;
38 extern const BUILTIN32_DESCRIPTOR DPLAY_Descriptor
;
39 extern const BUILTIN32_DESCRIPTOR DPLAYX_Descriptor
;
40 extern const BUILTIN32_DESCRIPTOR DSOUND_Descriptor
;
41 extern const BUILTIN32_DESCRIPTOR GDI32_Descriptor
;
42 extern const BUILTIN32_DESCRIPTOR IMM32_Descriptor
;
43 extern const BUILTIN32_DESCRIPTOR KERNEL32_Descriptor
;
44 extern const BUILTIN32_DESCRIPTOR LZ32_Descriptor
;
45 extern const BUILTIN32_DESCRIPTOR MPR_Descriptor
;
46 extern const BUILTIN32_DESCRIPTOR MSNET32_Descriptor
;
47 extern const BUILTIN32_DESCRIPTOR MSVFW32_Descriptor
;
48 extern const BUILTIN32_DESCRIPTOR NTDLL_Descriptor
;
49 extern const BUILTIN32_DESCRIPTOR OLE32_Descriptor
;
50 extern const BUILTIN32_DESCRIPTOR OLEAUT32_Descriptor
;
51 extern const BUILTIN32_DESCRIPTOR OLECLI32_Descriptor
;
52 extern const BUILTIN32_DESCRIPTOR OLEDLG_Descriptor
;
53 extern const BUILTIN32_DESCRIPTOR OLESVR32_Descriptor
;
54 extern const BUILTIN32_DESCRIPTOR PSAPI_Descriptor
;
55 extern const BUILTIN32_DESCRIPTOR RASAPI32_Descriptor
;
56 extern const BUILTIN32_DESCRIPTOR SHELL32_Descriptor
;
57 extern const BUILTIN32_DESCRIPTOR TAPI32_Descriptor
;
58 extern const BUILTIN32_DESCRIPTOR USER32_Descriptor
;
59 extern const BUILTIN32_DESCRIPTOR VERSION_Descriptor
;
60 extern const BUILTIN32_DESCRIPTOR W32SKRNL_Descriptor
;
61 extern const BUILTIN32_DESCRIPTOR WINMM_Descriptor
;
62 extern const BUILTIN32_DESCRIPTOR WINSPOOL_Descriptor
;
63 extern const BUILTIN32_DESCRIPTOR WNASPI32_Descriptor
;
64 extern const BUILTIN32_DESCRIPTOR WOW32_Descriptor
;
65 extern const BUILTIN32_DESCRIPTOR WSOCK32_Descriptor
;
67 static BUILTIN32_DLL BuiltinDLLs
[] =
69 { &ADVAPI32_Descriptor
, TRUE
},
70 { &COMCTL32_Descriptor
, FALSE
},
71 { &COMDLG32_Descriptor
, TRUE
},
72 { &CRTDLL_Descriptor
, TRUE
},
73 { &DCIMAN32_Descriptor
, FALSE
},
74 { &DDRAW_Descriptor
, TRUE
},
75 { &DINPUT_Descriptor
, TRUE
},
76 { &DPLAY_Descriptor
, TRUE
},
77 { &DPLAYX_Descriptor
, TRUE
},
78 { &DSOUND_Descriptor
, TRUE
},
79 { &GDI32_Descriptor
, TRUE
},
80 { &IMM32_Descriptor
, FALSE
},
81 { &KERNEL32_Descriptor
, TRUE
},
82 { &LZ32_Descriptor
, TRUE
},
83 { &MPR_Descriptor
, TRUE
},
84 { &MSNET32_Descriptor
, FALSE
},
85 { &MSVFW32_Descriptor
, FALSE
},
86 { &NTDLL_Descriptor
, TRUE
},
87 { &OLE32_Descriptor
, FALSE
},
88 { &OLEAUT32_Descriptor
, FALSE
},
89 { &OLECLI32_Descriptor
, FALSE
},
90 { &OLEDLG_Descriptor
, FALSE
},
91 { &OLESVR32_Descriptor
, FALSE
},
92 { &PSAPI_Descriptor
, FALSE
},
93 { &RASAPI32_Descriptor
, FALSE
},
94 { &SHELL32_Descriptor
, TRUE
},
95 { &TAPI32_Descriptor
, FALSE
},
96 { &USER32_Descriptor
, TRUE
},
97 { &VERSION_Descriptor
, TRUE
},
98 { &W32SKRNL_Descriptor
, TRUE
},
99 { &WINMM_Descriptor
, TRUE
},
100 { &WINSPOOL_Descriptor
, TRUE
},
101 { &WNASPI32_Descriptor
, TRUE
},
102 { &WOW32_Descriptor
, TRUE
},
103 { &WSOCK32_Descriptor
, TRUE
},
109 /***********************************************************************
110 * BUILTIN32_DoLoadModule
112 * Load a built-in Win32 module. Helper function for BUILTIN32_LoadModule.
114 static HMODULE32
BUILTIN32_DoLoadModule( BUILTIN32_DLL
*dll
, PDB32
*pdb
)
116 extern void RELAY_CallFrom32();
121 IMAGE_DATA_DIRECTORY
*dir
;
122 IMAGE_DOS_HEADER
*dos
;
123 IMAGE_NT_HEADERS
*nt
;
124 IMAGE_SECTION_HEADER
*sec
;
125 IMAGE_EXPORT_DIRECTORY
*exp
;
128 DEBUG_ENTRY_POINT
*debug
;
134 /* Allocate the module */
136 size
= (sizeof(IMAGE_DOS_HEADER
)
137 + sizeof(IMAGE_NT_HEADERS
)
138 + 2 * sizeof(IMAGE_SECTION_HEADER
)
139 + sizeof(IMAGE_EXPORT_DIRECTORY
)
140 + dll
->descr
->nb_funcs
* sizeof(LPVOID
)
141 + dll
->descr
->nb_names
* sizeof(LPSTR
));
144 size
+= dll
->descr
->nb_funcs
* sizeof(DEBUG_ENTRY_POINT
);
146 addr
= VirtualAlloc( NULL
, size
, MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
148 dos
= (IMAGE_DOS_HEADER
*)addr
;
149 nt
= (IMAGE_NT_HEADERS
*)(dos
+ 1);
150 sec
= (IMAGE_SECTION_HEADER
*)(nt
+ 1);
151 exp
= (IMAGE_EXPORT_DIRECTORY
*)(sec
+ 2);
152 funcs
= (LPVOID
*)(exp
+ 1);
153 names
= (LPSTR
*)(funcs
+ dll
->descr
->nb_funcs
);
154 debug
= (DEBUG_ENTRY_POINT
*)(names
+ dll
->descr
->nb_names
);
156 /* Build the DOS and NT headers */
158 dos
->e_magic
= IMAGE_DOS_SIGNATURE
;
159 dos
->e_lfanew
= sizeof(*dos
);
161 nt
->Signature
= IMAGE_NT_SIGNATURE
;
162 nt
->FileHeader
.Machine
= IMAGE_FILE_MACHINE_I386
;
163 nt
->FileHeader
.NumberOfSections
= 2; /* exports + code */
164 nt
->FileHeader
.SizeOfOptionalHeader
= sizeof(nt
->OptionalHeader
);
165 nt
->FileHeader
.Characteristics
= IMAGE_FILE_DLL
;
167 nt
->OptionalHeader
.Magic
= IMAGE_NT_OPTIONAL_HDR_MAGIC
;
168 nt
->OptionalHeader
.SizeOfCode
= 0x1000;
169 nt
->OptionalHeader
.SizeOfInitializedData
= 0;
170 nt
->OptionalHeader
.SizeOfUninitializedData
= 0;
171 nt
->OptionalHeader
.ImageBase
= (DWORD
)addr
;
172 nt
->OptionalHeader
.SectionAlignment
= 0x1000;
173 nt
->OptionalHeader
.FileAlignment
= 0x1000;
174 nt
->OptionalHeader
.MajorOperatingSystemVersion
= 1;
175 nt
->OptionalHeader
.MinorOperatingSystemVersion
= 0;
176 nt
->OptionalHeader
.MajorSubsystemVersion
= 4;
177 nt
->OptionalHeader
.MinorSubsystemVersion
= 0;
178 nt
->OptionalHeader
.SizeOfImage
= size
;
179 nt
->OptionalHeader
.SizeOfHeaders
= (BYTE
*)exp
- addr
;
180 nt
->OptionalHeader
.NumberOfRvaAndSizes
= IMAGE_NUMBEROF_DIRECTORY_ENTRIES
;
181 if (dll
->descr
->dllentrypoint
)
182 nt
->OptionalHeader
.AddressOfEntryPoint
= (DWORD
)dll
->descr
->dllentrypoint
- (DWORD
)addr
;
184 /* Build the export directory */
186 dir
= &nt
->OptionalHeader
.DataDirectory
[IMAGE_FILE_EXPORT_DIRECTORY
];
187 dir
->VirtualAddress
= (BYTE
*)exp
- addr
;
188 dir
->Size
= sizeof(*exp
)
189 + dll
->descr
->nb_funcs
* sizeof(LPVOID
)
190 + dll
->descr
->nb_names
* sizeof(LPSTR
);
192 /* Build the exports section */
194 strcpy( sec
->Name
, ".edata" );
195 sec
->Misc
.VirtualSize
= dir
->Size
;
196 sec
->VirtualAddress
= (BYTE
*)exp
- addr
;
197 sec
->SizeOfRawData
= dir
->Size
;
198 sec
->PointerToRawData
= (BYTE
*)exp
- addr
;
199 sec
->Characteristics
= (IMAGE_SCN_CNT_INITIALIZED_DATA
|
200 IMAGE_SCN_MEM_EXECUTE
| IMAGE_SCN_MEM_READ
|
201 IMAGE_SCN_MEM_WRITE
);
203 /* Build the code section */
206 strcpy( sec
->Name
, ".code" );
207 sec
->SizeOfRawData
= 0;
210 sec
->SizeOfRawData
+= dll
->descr
->nb_funcs
* sizeof(DEBUG_ENTRY_POINT
);
212 sec
->Misc
.VirtualSize
= sec
->SizeOfRawData
;
213 sec
->VirtualAddress
= (BYTE
*)debug
- addr
;
214 sec
->PointerToRawData
= (BYTE
*)debug
- addr
;
215 sec
->Characteristics
= (IMAGE_SCN_CNT_INITIALIZED_DATA
|
216 IMAGE_SCN_MEM_EXECUTE
| IMAGE_SCN_MEM_READ
);
218 /* Build the exports section data */
220 exp
->Name
= ((BYTE
*)dll
->descr
->name
) - addr
; /*??*/
221 exp
->Base
= dll
->descr
->base
;
222 exp
->NumberOfFunctions
= dll
->descr
->nb_funcs
;
223 exp
->NumberOfNames
= dll
->descr
->nb_names
;
224 exp
->AddressOfFunctions
= (LPDWORD
*)((BYTE
*)funcs
- addr
);
225 exp
->AddressOfNames
= (LPDWORD
*)((BYTE
*)names
- addr
);
226 exp
->AddressOfNameOrdinals
= (LPWORD
*)((BYTE
*)dll
->descr
->ordinals
- addr
);
228 /* Build the funcs table */
230 for (i
= 0; i
< dll
->descr
->nb_funcs
; i
++, funcs
++, debug
++)
232 BYTE args
= dll
->descr
->args
[i
];
233 if (!dll
->descr
->functions
[i
]) continue;
234 *funcs
= (LPVOID
)((BYTE
*)dll
->descr
->functions
[i
] - addr
);
236 if (!TRACE_ON(relay
)) continue;
239 case 0xfe: /* register func */
241 debug
->callfrom32
= (DWORD
)dll
->descr
->functions
[i
] -
243 debug
->ret
= 0x90; /* nop */
245 *funcs
= (LPVOID
)((BYTE
*)debug
- addr
);
247 case 0xff: /* stub or extern */
249 default: /* normal function (stdcall or cdecl) */
251 debug
->callfrom32
= (DWORD
)RELAY_CallFrom32
-
253 debug
->ret
= (args
& 0x80) ? 0xc3 : 0xc2; /*ret/ret $n*/
254 debug
->args
= (args
& 0x7f) * sizeof(int);
255 *funcs
= (LPVOID
)((BYTE
*)debug
- addr
);
258 #endif /* __i386__ */
261 /* Build the names table */
263 for (i
= 0; i
< exp
->NumberOfNames
; i
++, names
++)
264 if (dll
->descr
->names
[i
])
265 *names
= (LPSTR
)((BYTE
*)dll
->descr
->names
[i
] - addr
);
267 /* Create a modref */
268 wm
= (WINE_MODREF
*)HeapAlloc( pdb
->heap
, HEAP_ZERO_MEMORY
, sizeof(*wm
) );
269 wm
->type
= MODULE32_PE
;
270 pem
= &(wm
->binfmt
.pe
);
271 wm
->module
= (HMODULE32
)addr
;
272 wm
->next
= pdb
->modref_list
;
273 pdb
->modref_list
= wm
;
274 wm
->modname
= HEAP_strdupA(pdb
->heap
,0,dll
->descr
->name
);
275 /* FIXME: hmm ... probably add windows directory? don't know ... -MM */
276 wm
->shortname
= HEAP_strdupA(pdb
->heap
,0,wm
->modname
);
277 wm
->longname
= HEAP_strdupA(pdb
->heap
,0,wm
->modname
);
279 pem
->pe_export
= exp
;
280 pem
->flags
= PE_MODREF_INTERNAL
;
282 /* Create a Win16 dummy module */
284 sprintf( ofs
.szPathName
, "%s.DLL", dll
->descr
->name
);
285 hModule
= MODULE_CreateDummyModule( &ofs
);
286 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
287 pModule
->flags
= NE_FFLAGS_SINGLEDATA
| NE_FFLAGS_BUILTIN
|
288 NE_FFLAGS_LIBMODULE
| NE_FFLAGS_WIN32
;
289 pModule
->module32
= (HMODULE32
)addr
;
290 return pModule
->module32
;
294 /***********************************************************************
295 * BUILTIN32_LoadModule
297 * Load a built-in module. If the 'force' parameter is FALSE, we only
298 * load the module if it has not been disabled via the -dll option.
300 HMODULE32
BUILTIN32_LoadModule( LPCSTR name
, BOOL32 force
, PDB32
*process
)
302 BUILTIN32_DLL
*table
;
303 char dllname
[16], *p
;
305 /* Fix the name in case we have a full path and extension */
307 if ((p
= strrchr( name
, '\\' ))) name
= p
+ 1;
308 lstrcpyn32A( dllname
, name
, sizeof(dllname
) );
309 if ((p
= strrchr( dllname
, '.' ))) *p
= '\0';
311 for (table
= BuiltinDLLs
; table
->descr
; table
++)
312 if (!lstrcmpi32A( table
->descr
->name
, dllname
)) break;
313 if (!table
->descr
) return 0;
316 if (!force
) return 0;
317 table
->used
= TRUE
; /* So next time we use it at once */
319 return BUILTIN32_DoLoadModule( table
, process
);
323 /***********************************************************************
324 * BUILTIN32_GetEntryPoint
326 * Return the name of the DLL entry point corresponding
327 * to a relay entry point address. This is used only by relay debugging.
329 * This function _must_ return the real entry point to call
330 * after the debug info is printed.
332 ENTRYPOINT32
BUILTIN32_GetEntryPoint( char *buffer
, void *relay
,
333 unsigned int *typemask
)
339 /* First find the module */
341 for (dll
= BuiltinDLLs
; dll
->descr
; dll
++)
343 && ((hModule
= GetModuleHandle32A(dll
->descr
->name
)) != 0))
345 IMAGE_SECTION_HEADER
*sec
= PE_SECTIONS(hModule
);
346 DEBUG_ENTRY_POINT
*debug
=
347 (DEBUG_ENTRY_POINT
*)((DWORD
)hModule
+ sec
[1].VirtualAddress
);
348 DEBUG_ENTRY_POINT
*func
= (DEBUG_ENTRY_POINT
*)relay
;
350 if (debug
<= func
&& func
< debug
+ dll
->descr
->nb_funcs
)
352 ordinal
= func
- debug
;
358 return (ENTRYPOINT32
)NULL
;
360 /* Now find the function */
362 for (i
= 0; i
< dll
->descr
->nb_names
; i
++)
363 if (dll
->descr
->ordinals
[i
] == ordinal
) break;
364 assert( i
< dll
->descr
->nb_names
);
366 sprintf( buffer
, "%s.%d: %s", dll
->descr
->name
, ordinal
+ dll
->descr
->base
,
367 dll
->descr
->names
[i
] );
368 *typemask
= dll
->descr
->argtypes
[ordinal
];
369 return dll
->descr
->functions
[ordinal
];
373 /***********************************************************************
374 * BUILTIN32_Unimplemented
376 * This function is called for unimplemented 32-bit entry points (declared
377 * as 'stub' in the spec file).
379 void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR
*descr
, int ordinal
)
381 const char *func_name
= "???";
384 __RESTORE_ES
; /* Just in case */
386 for (i
= 0; i
< descr
->nb_names
; i
++)
387 if (descr
->ordinals
[i
] + descr
->base
== ordinal
) break;
388 if (i
< descr
->nb_names
) func_name
= descr
->names
[i
];
390 MSG( "No handler for Win32 routine %s.%d: %s",
391 descr
->name
, ordinal
, func_name
);
393 MSG( " (called from %p)", __builtin_return_address(1) );
400 /***********************************************************************
401 * BUILTIN32_EnableDLL
403 * Enable or disable a built-in DLL.
405 int BUILTIN32_EnableDLL( const char *name
, int len
, int enable
)
410 for (i
= 0, dll
= BuiltinDLLs
; dll
->descr
; dll
++)
412 if (!lstrncmpi32A( name
, dll
->descr
->name
, len
))
422 /***********************************************************************
423 * BUILTIN32_PrintDLLs
425 * Print the list of built-in DLLs that can be disabled.
427 void BUILTIN32_PrintDLLs(void)
432 MSG("Available Win32 DLLs:\n");
433 for (i
= 0, dll
= BuiltinDLLs
; dll
->descr
; dll
++)
434 MSG("%-9s%c", dll
->descr
->name
,
435 ((++i
) % 8) ? ' ' : '\n' );