- implemented LdrGetProcedureAddress and made use of it for
[wine/wine-kai.git] / dlls / ntdll / loader.c
blobd72db1d0bf6c3c5ff6296f5218e1841e56fd76de
1 /*
2 * Copyright 2002 Dmitry Timoshkov for Codeweavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "winbase.h"
20 #include "winnt.h"
21 #include "winternl.h"
23 #include "module.h"
24 #include "file.h"
25 #include "wine/exception.h"
26 #include "excpt.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
31 /* filter for page-fault exceptions */
32 static WINE_EXCEPTION_FILTER(page_fault)
34 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
35 return EXCEPTION_EXECUTE_HANDLER;
36 return EXCEPTION_CONTINUE_SEARCH;
40 /******************************************************************
41 * LdrDisableThreadCalloutsForDll (NTDLL.@)
44 NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule)
46 WINE_MODREF *wm;
47 NTSTATUS ret = STATUS_SUCCESS;
49 RtlEnterCriticalSection( &loader_section );
51 wm = MODULE32_LookupHMODULE( hModule );
52 if ( !wm )
53 ret = STATUS_DLL_NOT_FOUND;
54 else
55 wm->flags |= WINE_MODREF_NO_DLL_CALLS;
57 RtlLeaveCriticalSection( &loader_section );
59 return ret;
62 /**********************************************************************
63 * MODULE_FindModule
65 * Find a (loaded) win32 module depending on path
66 * LPCSTR path: [in] pathname of module/library to be found
68 * The loader_section must be locked while calling this function
69 * RETURNS
70 * the module handle if found
71 * 0 if not
73 WINE_MODREF *MODULE_FindModule(LPCSTR path)
75 WINE_MODREF *wm;
76 char dllname[260], *p;
78 /* Append .DLL to name if no extension present */
79 strcpy( dllname, path );
80 if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
81 strcat( dllname, ".DLL" );
83 for ( wm = MODULE_modref_list; wm; wm = wm->next )
85 if ( !FILE_strcasecmp( dllname, wm->modname ) )
86 break;
87 if ( !FILE_strcasecmp( dllname, wm->filename ) )
88 break;
89 if ( !FILE_strcasecmp( dllname, wm->short_modname ) )
90 break;
91 if ( !FILE_strcasecmp( dllname, wm->short_filename ) )
92 break;
95 return wm;
98 /******************************************************************
99 * LdrGetDllHandle (NTDLL.@)
103 NTSTATUS WINAPI LdrGetDllHandle(ULONG x, ULONG y, PUNICODE_STRING name, HMODULE *base)
105 WINE_MODREF *wm;
107 TRACE("%08lx %08lx %s %p\n",
108 x, y, name ? debugstr_wn(name->Buffer, name->Length) : NULL, base);
110 if (x != 0 || y != 0)
111 FIXME("Unknown behavior, please report\n");
113 /* FIXME: we should store module name information as unicode */
114 if (name)
116 STRING str;
118 RtlUnicodeStringToAnsiString( &str, name, TRUE );
120 wm = MODULE_FindModule( str.Buffer );
121 RtlFreeAnsiString( &str );
123 else
124 wm = exe_modref;
126 if (!wm)
128 *base = 0;
129 return STATUS_DLL_NOT_FOUND;
132 *base = wm->module;
133 return STATUS_SUCCESS;
136 /***********************************************************************
137 * MODULE_GetProcAddress (internal)
139 FARPROC MODULE_GetProcAddress(
140 HMODULE hModule, /* [in] current module handle */
141 LPCSTR function, /* [in] function to be looked up */
142 int hint,
143 BOOL snoop )
145 WINE_MODREF *wm;
146 FARPROC retproc = 0;
148 if (HIWORD(function))
149 TRACE("(%p,%s (%d))\n",hModule,function,hint);
150 else
151 TRACE("(%p,%p)\n",hModule,function);
153 RtlEnterCriticalSection( &loader_section );
154 if ((wm = MODULE32_LookupHMODULE( hModule )))
156 retproc = wm->find_export( wm, function, hint, snoop );
157 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
159 RtlLeaveCriticalSection( &loader_section );
160 return retproc;
164 /******************************************************************
165 * LdrGetProcedureAddress (NTDLL.@)
169 NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE base, PANSI_STRING name, ULONG ord, PVOID *address)
171 WARN("%p %s %ld %p\n", base, name ? debugstr_an(name->Buffer, name->Length) : NULL, ord, address);
173 *address = MODULE_GetProcAddress( base, name ? name->Buffer : (LPSTR)ord, -1, TRUE );
175 return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND;
179 /******************************************************************
180 * LdrShutdownProcess (NTDLL.@)
183 NTSTATUS WINAPI LdrShutdownProcess(void)
185 TRACE("()\n");
186 MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
187 return STATUS_SUCCESS; /* FIXME */
190 /******************************************************************
191 * LdrShutdownThread (NTDLL.@)
194 NTSTATUS WINAPI LdrShutdownThread(void)
196 WINE_MODREF *wm;
197 TRACE("()\n");
199 /* don't do any detach calls if process is exiting */
200 if (process_detaching) return STATUS_SUCCESS;
201 /* FIXME: there is still a race here */
203 RtlEnterCriticalSection( &loader_section );
205 for ( wm = MODULE_modref_list; wm; wm = wm->next )
207 if ( !(wm->flags & WINE_MODREF_PROCESS_ATTACHED) )
208 continue;
209 if ( wm->flags & WINE_MODREF_NO_DLL_CALLS )
210 continue;
212 MODULE_InitDLL( wm, DLL_THREAD_DETACH, NULL );
215 RtlLeaveCriticalSection( &loader_section );
216 return STATUS_SUCCESS; /* FIXME */
219 /***********************************************************************
220 * RtlImageNtHeader (NTDLL.@)
222 PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
224 IMAGE_NT_HEADERS *ret;
226 __TRY
228 IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
230 ret = NULL;
231 if (dos->e_magic == IMAGE_DOS_SIGNATURE)
233 ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
234 if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
237 __EXCEPT(page_fault)
239 return NULL;
241 __ENDTRY
242 return ret;
246 /***********************************************************************
247 * RtlImageDirectoryEntryToData (NTDLL.@)
249 PVOID WINAPI RtlImageDirectoryEntryToData( HMODULE module, BOOL image, WORD dir, ULONG *size )
251 const IMAGE_NT_HEADERS *nt;
252 DWORD addr;
254 if ((ULONG_PTR)module & 1) /* mapped as data file */
256 module = (HMODULE)((ULONG_PTR)module & ~1);
257 image = FALSE;
259 if (!(nt = RtlImageNtHeader( module ))) return NULL;
260 if (dir >= nt->OptionalHeader.NumberOfRvaAndSizes) return NULL;
261 if (!(addr = nt->OptionalHeader.DataDirectory[dir].VirtualAddress)) return NULL;
262 *size = nt->OptionalHeader.DataDirectory[dir].Size;
263 if (image || addr < nt->OptionalHeader.SizeOfHeaders) return (char *)module + addr;
265 /* not mapped as image, need to find the section containing the virtual address */
266 return RtlImageRvaToVa( nt, module, addr, NULL );
270 /***********************************************************************
271 * RtlImageRvaToSection (NTDLL.@)
273 PIMAGE_SECTION_HEADER WINAPI RtlImageRvaToSection( const IMAGE_NT_HEADERS *nt,
274 HMODULE module, DWORD rva )
276 int i;
277 IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader +
278 nt->FileHeader.SizeOfOptionalHeader);
279 for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
281 if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva))
282 return sec;
284 return NULL;
288 /***********************************************************************
289 * RtlImageRvaToVa (NTDLL.@)
291 PVOID WINAPI RtlImageRvaToVa( const IMAGE_NT_HEADERS *nt, HMODULE module,
292 DWORD rva, IMAGE_SECTION_HEADER **section )
294 IMAGE_SECTION_HEADER *sec;
296 if (section && *section) /* try this section first */
298 sec = *section;
299 if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva))
300 goto found;
302 if (!(sec = RtlImageRvaToSection( nt, module, rva ))) return NULL;
303 found:
304 if (section) *section = sec;
305 return (char *)module + sec->PointerToRawData + (rva - sec->VirtualAddress);