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