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