:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / kernel32 / misc / ldr.c
1 /* $Id$
2  *
3  * COPYRIGHT: See COPYING in the top level directory
4  * PROJECT  : ReactOS user mode libraries
5  * MODULE   : kernel32.dll
6  * FILE     : reactos/lib/kernel32/misc/ldr.c
7  * AUTHOR   : Boudewijn Dekker
8  */
9
10 #include <ddk/ntddk.h>
11 #include <ntdll/ldr.h>
12 #include <windows.h>
13
14 #define NDEBUG
15 #include <kernel32/kernel32.h>
16 #include <kernel32/error.h>
17
18
19 /* FUNCTIONS ****************************************************************/
20
21 WINBOOL
22 STDCALL
23 DisableThreadLibraryCalls (
24         HMODULE hLibModule
25         )
26 {
27         NTSTATUS Status;
28
29         Status = LdrDisableThreadCalloutsForDll ((PVOID)hLibModule);
30         if (!NT_SUCCESS (Status))
31         {
32                 SetLastErrorByStatus (Status);
33                 return FALSE;
34         }
35         return TRUE;
36 }
37
38
39 HINSTANCE
40 STDCALL
41 LoadLibraryA (
42         LPCSTR  lpLibFileName
43         )
44 {
45         return LoadLibraryExA (lpLibFileName, 0, 0);
46 }
47
48
49 HINSTANCE
50 STDCALL
51 LoadLibraryExA (
52         LPCSTR  lpLibFileName,
53         HANDLE  hFile,
54         DWORD   dwFlags
55         )
56 {
57         UNICODE_STRING LibFileNameU;
58         ANSI_STRING LibFileName;
59         HINSTANCE hInst;
60         NTSTATUS Status;
61
62         RtlInitAnsiString (&LibFileName,
63                            (LPSTR)lpLibFileName);
64
65         /* convert ansi (or oem) string to unicode */
66         if (bIsFileApiAnsi)
67                 RtlAnsiStringToUnicodeString (&LibFileNameU,
68                                               &LibFileName,
69                                               TRUE);
70         else
71                 RtlOemStringToUnicodeString (&LibFileNameU,
72                                              &LibFileName,
73                                              TRUE);
74
75         Status = LdrLoadDll(NULL,
76                             dwFlags,
77                             &LibFileNameU,
78                             (PVOID*)&hInst);
79
80         RtlFreeUnicodeString (&LibFileNameU);
81
82         if ( !NT_SUCCESS(Status))
83         {
84                 SetLastErrorByStatus (Status);
85                 return NULL;
86         }
87
88         return hInst;
89 }
90
91
92 HINSTANCE
93 STDCALL
94 LoadLibraryW (
95         LPCWSTR lpLibFileName
96         )
97 {
98         return LoadLibraryExW (lpLibFileName, 0, 0);
99 }
100
101
102 HINSTANCE
103 STDCALL
104 LoadLibraryExW (
105         LPCWSTR lpLibFileName,
106         HANDLE  hFile,
107         DWORD   dwFlags
108         )
109 {
110         UNICODE_STRING DllName;
111         HINSTANCE hInst;
112         NTSTATUS Status;
113
114         if ( lpLibFileName == NULL )
115                 return NULL;
116
117         RtlInitUnicodeString (&DllName, (LPWSTR)lpLibFileName);
118         Status = LdrLoadDll(NULL, dwFlags, &DllName, (PVOID*)&hInst);
119         if ( !NT_SUCCESS(Status))
120         {
121                 SetLastErrorByStatus (Status);
122                 return NULL;
123         }
124         
125         return hInst;
126 }
127
128
129 FARPROC
130 STDCALL
131 GetProcAddress( HMODULE hModule, LPCSTR lpProcName )
132 {
133         ANSI_STRING ProcedureName;
134         FARPROC fnExp = NULL;
135
136         if (HIWORD(lpProcName) != 0)
137         {
138                 RtlInitAnsiString (&ProcedureName,
139                                    (LPSTR)lpProcName);
140                 LdrGetProcedureAddress ((PVOID)hModule,
141                                         &ProcedureName,
142                                         0,
143                                         (PVOID*)&fnExp);
144         }
145         else
146         {
147                 LdrGetProcedureAddress ((PVOID)hModule,
148                                         NULL,
149                                         (ULONG)lpProcName,
150                                         (PVOID*)&fnExp);
151         }
152
153         return fnExp;
154 }
155
156
157 WINBOOL
158 STDCALL
159 FreeLibrary( HMODULE hLibModule )
160 {
161         LdrUnloadDll(hLibModule);
162         return TRUE;
163 }
164
165
166 VOID
167 STDCALL
168 FreeLibraryAndExitThread (
169         HMODULE hLibModule,
170         DWORD   dwExitCode
171         )
172 {
173         if ( FreeLibrary(hLibModule) )
174                 ExitThread(dwExitCode);
175         return;
176 }
177
178
179 DWORD
180 STDCALL
181 GetModuleFileNameA (
182         HINSTANCE       hModule,
183         LPSTR           lpFilename,
184         DWORD           nSize
185         )
186 {
187         ANSI_STRING FileName;
188         PLIST_ENTRY ModuleListHead;
189         PLIST_ENTRY Entry;
190         PLDR_MODULE Module;
191         PPEB Peb;
192         ULONG Length = 0;
193
194         Peb = NtCurrentPeb ();
195         RtlEnterCriticalSection (Peb->LoaderLock);
196
197         if (hModule == NULL)
198                 hModule = Peb->ImageBaseAddress;
199
200         ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
201         Entry = ModuleListHead->Flink;
202
203         while (Entry != ModuleListHead)
204         {
205                 Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
206                 if (Module->BaseAddress == (PVOID)hModule)
207                 {
208                         if (nSize * sizeof(WCHAR) < Module->FullDllName.Length)
209                         {
210                                 SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
211                         }
212                         else
213                         {
214                                 FileName.Length = 0;
215                                 FileName.MaximumLength = nSize * sizeof(WCHAR);
216                                 FileName.Buffer = lpFilename;
217
218                                 /* convert unicode string to ansi (or oem) */
219                                 if (bIsFileApiAnsi)
220                                         RtlUnicodeStringToAnsiString (&FileName,
221                                                                       &Module->FullDllName,
222                                                                       FALSE);
223                                 else
224                                         RtlUnicodeStringToOemString (&FileName,
225                                                                      &Module->FullDllName,
226                                                                      FALSE);
227                                 Length = Module->FullDllName.Length / sizeof(WCHAR);
228                         }
229
230                         RtlLeaveCriticalSection (Peb->LoaderLock);
231                         return Length;
232                 }
233
234                 Entry = Entry->Flink;
235         }
236
237         SetLastErrorByStatus (STATUS_DLL_NOT_FOUND);
238         RtlLeaveCriticalSection (Peb->LoaderLock);
239
240         return 0;
241 }
242
243
244 DWORD
245 STDCALL
246 GetModuleFileNameW (
247         HINSTANCE       hModule,
248         LPWSTR          lpFilename,
249         DWORD           nSize
250         )
251 {
252         UNICODE_STRING FileName;
253         PLIST_ENTRY ModuleListHead;
254         PLIST_ENTRY Entry;
255         PLDR_MODULE Module;
256         PPEB Peb;
257         ULONG Length = 0;
258
259         Peb = NtCurrentPeb ();
260         RtlEnterCriticalSection (Peb->LoaderLock);
261
262         if (hModule == NULL)
263                 hModule = Peb->ImageBaseAddress;
264
265         ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
266         Entry = ModuleListHead->Flink;
267         while (Entry != ModuleListHead)
268         {
269                 Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
270
271                 if (Module->BaseAddress == (PVOID)hModule)
272                 {
273                         if (nSize * sizeof(WCHAR) < Module->FullDllName.Length)
274                         {
275                                 SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
276                         }
277                         else
278                         {
279                                 FileName.Length = 0;
280                                 FileName.MaximumLength = nSize * sizeof(WCHAR);
281                                 FileName.Buffer = lpFilename;
282
283                                 RtlCopyUnicodeString (&FileName,
284                                                       &Module->FullDllName);
285                                 Length = Module->FullDllName.Length / sizeof(WCHAR);
286                         }
287
288                         RtlLeaveCriticalSection (Peb->LoaderLock);
289                         return Length;
290                 }
291
292                 Entry = Entry->Flink;
293         }
294
295         SetLastErrorByStatus (STATUS_DLL_NOT_FOUND);
296         RtlLeaveCriticalSection (Peb->LoaderLock);
297
298         return 0;
299 }
300
301
302 HMODULE
303 STDCALL
304 GetModuleHandleA ( LPCSTR lpModuleName )
305 {
306         UNICODE_STRING UnicodeName;
307         ANSI_STRING ModuleName;
308         PVOID BaseAddress;
309         NTSTATUS Status;
310
311         if (lpModuleName == NULL)
312                 return ((HMODULE)NtCurrentPeb()->ImageBaseAddress);
313         RtlInitAnsiString (&ModuleName,
314                            (LPSTR)lpModuleName);
315
316         /* convert ansi (or oem) string to unicode */
317         if (bIsFileApiAnsi)
318                 RtlAnsiStringToUnicodeString (&UnicodeName,
319                                               &ModuleName,
320                                               TRUE);
321         else
322                 RtlOemStringToUnicodeString (&UnicodeName,
323                                              &ModuleName,
324                                              TRUE);
325
326         Status = LdrGetDllHandle (0,
327                                   0,
328                                   &UnicodeName,
329                                   &BaseAddress);
330
331         RtlFreeUnicodeString (&UnicodeName);
332
333         if (!NT_SUCCESS(Status))
334         {
335                 SetLastErrorByStatus (Status);
336                 return NULL;
337         }
338
339         return ((HMODULE)BaseAddress);
340 }
341
342
343 HMODULE
344 STDCALL
345 GetModuleHandleW (LPCWSTR lpModuleName)
346 {
347         UNICODE_STRING ModuleName;
348         PVOID BaseAddress;
349         NTSTATUS Status;
350
351         if (lpModuleName == NULL)
352                 return ((HMODULE)NtCurrentPeb()->ImageBaseAddress);
353
354         RtlInitUnicodeString (&ModuleName,
355                               (LPWSTR)lpModuleName);
356
357         Status = LdrGetDllHandle (0,
358                                   0,
359                                   &ModuleName,
360                                   &BaseAddress);
361         if (!NT_SUCCESS(Status))
362         {
363                 SetLastErrorByStatus (Status);
364                 return NULL;
365         }
366
367         return ((HMODULE)BaseAddress);
368 }
369
370 /* EOF */