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
25 #include "wine/exception.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
)
47 NTSTATUS ret
= STATUS_SUCCESS
;
49 RtlEnterCriticalSection( &loader_section
);
51 wm
= MODULE32_LookupHMODULE( hModule
);
53 ret
= STATUS_DLL_NOT_FOUND
;
55 wm
->flags
|= WINE_MODREF_NO_DLL_CALLS
;
57 RtlLeaveCriticalSection( &loader_section
);
62 /**********************************************************************
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
70 * the module handle if found
73 WINE_MODREF
*MODULE_FindModule(LPCSTR path
)
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
) )
87 if ( !FILE_strcasecmp( dllname
, wm
->filename
) )
89 if ( !FILE_strcasecmp( dllname
, wm
->short_modname
) )
91 if ( !FILE_strcasecmp( dllname
, wm
->short_filename
) )
98 /******************************************************************
99 * LdrGetDllHandle (NTDLL.@)
103 NTSTATUS WINAPI
LdrGetDllHandle(ULONG x
, ULONG y
, PUNICODE_STRING name
, HMODULE
*base
)
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 */
118 RtlUnicodeStringToAnsiString( &str
, name
, TRUE
);
120 wm
= MODULE_FindModule( str
.Buffer
);
121 RtlFreeAnsiString( &str
);
129 return STATUS_DLL_NOT_FOUND
;
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 */
148 if (HIWORD(function
))
149 TRACE("(%p,%s (%d))\n",hModule
,function
,hint
);
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
);
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)
186 MODULE_DllProcessDetach( TRUE
, (LPVOID
)1 );
187 return STATUS_SUCCESS
; /* FIXME */
190 /******************************************************************
191 * LdrShutdownThread (NTDLL.@)
194 NTSTATUS WINAPI
LdrShutdownThread(void)
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
) )
209 if ( wm
->flags
& WINE_MODREF_NO_DLL_CALLS
)
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
;
228 IMAGE_DOS_HEADER
*dos
= (IMAGE_DOS_HEADER
*)hModule
;
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
;
246 /***********************************************************************
247 * RtlImageDirectoryEntryToData (NTDLL.@)
249 PVOID WINAPI
RtlImageDirectoryEntryToData( HMODULE module
, BOOL image
, WORD dir
, ULONG
*size
)
251 const IMAGE_NT_HEADERS
*nt
;
254 if ((ULONG_PTR
)module
& 1) /* mapped as data file */
256 module
= (HMODULE
)((ULONG_PTR
)module
& ~1);
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
)
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
))
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 */
299 if ((sec
->VirtualAddress
<= rva
) && (sec
->VirtualAddress
+ sec
->SizeOfRawData
> rva
))
302 if (!(sec
= RtlImageRvaToSection( nt
, module
, rva
))) return NULL
;
304 if (section
) *section
= sec
;
305 return (char *)module
+ sec
->PointerToRawData
+ (rva
- sec
->VirtualAddress
);