1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT : ReactOS system libraries
4c2c66affSColin Finck * MODULE : kernel32.dll
5c2c66affSColin Finck * FILE : reactos/dll/win32/kernel32/misc/ldr.c
6c2c66affSColin Finck * AUTHOR : Aleksey Bragin <aleksey@reactos.org>
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck #include <k32.h>
10c2c66affSColin Finck
11c2c66affSColin Finck #define NDEBUG
12c2c66affSColin Finck #include <debug.h>
13c2c66affSColin Finck
14c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
15c2c66affSColin Finck
16c2c66affSColin Finck NTSTATUS
17c2c66affSColin Finck WINAPI
BasepInitializeTermsrvFpns(VOID)18c2c66affSColin Finck BasepInitializeTermsrvFpns(VOID)
19c2c66affSColin Finck {
20c2c66affSColin Finck UNIMPLEMENTED;
21c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED;
22c2c66affSColin Finck }
23c2c66affSColin Finck
24c2c66affSColin Finck DWORD
25c2c66affSColin Finck WINAPI
BasepGetModuleHandleExParameterValidation(DWORD dwFlags,LPCWSTR lpwModuleName,HMODULE * phModule)26c2c66affSColin Finck BasepGetModuleHandleExParameterValidation(DWORD dwFlags,
27c2c66affSColin Finck LPCWSTR lpwModuleName,
28c2c66affSColin Finck HMODULE *phModule)
29c2c66affSColin Finck {
30c2c66affSColin Finck /* Set phModule to 0 if it's not a NULL pointer */
31c2c66affSColin Finck if (phModule) *phModule = 0;
32c2c66affSColin Finck
33c2c66affSColin Finck /* Check for invalid flags combination */
34c2c66affSColin Finck if (dwFlags & ~(GET_MODULE_HANDLE_EX_FLAG_PIN |
35c2c66affSColin Finck GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
36c2c66affSColin Finck GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) ||
37c2c66affSColin Finck ((dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) &&
38c2c66affSColin Finck (dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) ||
39c2c66affSColin Finck (!lpwModuleName && (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
40c2c66affSColin Finck )
41c2c66affSColin Finck {
42c2c66affSColin Finck BaseSetLastNTError(STATUS_INVALID_PARAMETER_1);
43c2c66affSColin Finck return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR;
44c2c66affSColin Finck }
45c2c66affSColin Finck
46c2c66affSColin Finck /* Check 2nd parameter */
47c2c66affSColin Finck if (!phModule)
48c2c66affSColin Finck {
49c2c66affSColin Finck BaseSetLastNTError(STATUS_INVALID_PARAMETER_2);
50c2c66affSColin Finck return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR;
51c2c66affSColin Finck }
52c2c66affSColin Finck
53c2c66affSColin Finck /* Return what we have according to the module name */
54c2c66affSColin Finck if (lpwModuleName)
55c2c66affSColin Finck {
56c2c66affSColin Finck return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE;
57c2c66affSColin Finck }
58c2c66affSColin Finck
59c2c66affSColin Finck /* No name given, so put ImageBaseAddress there */
60c2c66affSColin Finck *phModule = (HMODULE)NtCurrentPeb()->ImageBaseAddress;
61c2c66affSColin Finck
62c2c66affSColin Finck return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS;
63c2c66affSColin Finck }
64c2c66affSColin Finck
65c2c66affSColin Finck PVOID
66c2c66affSColin Finck WINAPI
BasepMapModuleHandle(HMODULE hModule,BOOLEAN AsDataFile)67c2c66affSColin Finck BasepMapModuleHandle(HMODULE hModule, BOOLEAN AsDataFile)
68c2c66affSColin Finck {
69c2c66affSColin Finck /* If no handle is provided - use current image base address */
70c2c66affSColin Finck if (!hModule) return NtCurrentPeb()->ImageBaseAddress;
71c2c66affSColin Finck
72c2c66affSColin Finck /* Check if it's a normal or a datafile one */
73c2c66affSColin Finck if (LDR_IS_DATAFILE(hModule) && !AsDataFile)
74c2c66affSColin Finck return NULL;
75c2c66affSColin Finck
76c2c66affSColin Finck /* It's a normal DLL, just return its handle */
77c2c66affSColin Finck return hModule;
78c2c66affSColin Finck }
79c2c66affSColin Finck
80c2c66affSColin Finck /*
81c2c66affSColin Finck * @implemented
82c2c66affSColin Finck */
83c2c66affSColin Finck BOOL
84c2c66affSColin Finck WINAPI
DisableThreadLibraryCalls(IN HMODULE hLibModule)85c2c66affSColin Finck DisableThreadLibraryCalls(
86c2c66affSColin Finck IN HMODULE hLibModule)
87c2c66affSColin Finck {
88c2c66affSColin Finck NTSTATUS Status;
89c2c66affSColin Finck
90c2c66affSColin Finck /* Disable thread library calls */
91c2c66affSColin Finck Status = LdrDisableThreadCalloutsForDll((PVOID)hLibModule);
92c2c66affSColin Finck
93c2c66affSColin Finck /* If it wasn't success - set last error and return failure */
94c2c66affSColin Finck if (!NT_SUCCESS(Status))
95c2c66affSColin Finck {
96c2c66affSColin Finck BaseSetLastNTError(Status);
97c2c66affSColin Finck return FALSE;
98c2c66affSColin Finck }
99c2c66affSColin Finck
100c2c66affSColin Finck /* Return success */
101c2c66affSColin Finck return TRUE;
102c2c66affSColin Finck }
103c2c66affSColin Finck
104c2c66affSColin Finck
105c2c66affSColin Finck /*
106c2c66affSColin Finck * @implemented
107c2c66affSColin Finck */
108c2c66affSColin Finck HINSTANCE
109c2c66affSColin Finck WINAPI
110c2c66affSColin Finck DECLSPEC_HOTPATCH
LoadLibraryA(LPCSTR lpLibFileName)111c2c66affSColin Finck LoadLibraryA(LPCSTR lpLibFileName)
112c2c66affSColin Finck {
1131b70ddd8STimo Kreuzer static const CHAR TwainDllName[] = "twain_32.dll";
114c2c66affSColin Finck LPSTR PathBuffer;
115c2c66affSColin Finck UINT Len;
116c2c66affSColin Finck HINSTANCE Result;
117c2c66affSColin Finck
118c2c66affSColin Finck /* Treat twain_32.dll in a special way (what a surprise...) */
1191b70ddd8STimo Kreuzer if (lpLibFileName && !_strcmpi(lpLibFileName, TwainDllName))
120c2c66affSColin Finck {
121c2c66affSColin Finck /* Allocate space for the buffer */
1221b70ddd8STimo Kreuzer PathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, MAX_PATH + sizeof(ANSI_NULL));
123c2c66affSColin Finck if (PathBuffer)
124c2c66affSColin Finck {
125c2c66affSColin Finck /* Get windows dir in this buffer */
1261b70ddd8STimo Kreuzer Len = GetWindowsDirectoryA(PathBuffer, MAX_PATH);
1271b70ddd8STimo Kreuzer if ((Len != 0) && (Len < (MAX_PATH - sizeof(TwainDllName) - sizeof('\\'))))
128c2c66affSColin Finck {
129c2c66affSColin Finck /* We successfully got windows directory. Concatenate twain_32.dll to it */
1301b70ddd8STimo Kreuzer PathBuffer[Len] = '\\';
1311b70ddd8STimo Kreuzer strcpy(&PathBuffer[Len + 1], TwainDllName);
132c2c66affSColin Finck
133c2c66affSColin Finck /* And recursively call ourselves with a new string */
134c2c66affSColin Finck Result = LoadLibraryA(PathBuffer);
135c2c66affSColin Finck
136c2c66affSColin Finck /* If it was successful - free memory and return result */
137c2c66affSColin Finck if (Result)
138c2c66affSColin Finck {
139c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
140c2c66affSColin Finck return Result;
141c2c66affSColin Finck }
142c2c66affSColin Finck }
143c2c66affSColin Finck
144c2c66affSColin Finck /* Free allocated buffer */
145c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
146c2c66affSColin Finck }
147c2c66affSColin Finck }
148c2c66affSColin Finck
149c2c66affSColin Finck /* Call the Ex version of the API */
150c2c66affSColin Finck return LoadLibraryExA(lpLibFileName, 0, 0);
151c2c66affSColin Finck }
152c2c66affSColin Finck
153c2c66affSColin Finck /*
154c2c66affSColin Finck * @implemented
155c2c66affSColin Finck */
156c2c66affSColin Finck HINSTANCE
157c2c66affSColin Finck WINAPI
158c2c66affSColin Finck DECLSPEC_HOTPATCH
LoadLibraryExA(LPCSTR lpLibFileName,HANDLE hFile,DWORD dwFlags)159c2c66affSColin Finck LoadLibraryExA(LPCSTR lpLibFileName,
160c2c66affSColin Finck HANDLE hFile,
161c2c66affSColin Finck DWORD dwFlags)
162c2c66affSColin Finck {
163c2c66affSColin Finck PUNICODE_STRING FileNameW;
164c2c66affSColin Finck
165c2c66affSColin Finck /* Convert file name to unicode */
166c2c66affSColin Finck if (!(FileNameW = Basep8BitStringToStaticUnicodeString(lpLibFileName)))
167c2c66affSColin Finck return NULL;
168c2c66affSColin Finck
169c2c66affSColin Finck /* And call W version of the API */
170c2c66affSColin Finck return LoadLibraryExW(FileNameW->Buffer, hFile, dwFlags);
171c2c66affSColin Finck }
172c2c66affSColin Finck
173c2c66affSColin Finck /*
174c2c66affSColin Finck * @implemented
175c2c66affSColin Finck */
176c2c66affSColin Finck HINSTANCE
177c2c66affSColin Finck WINAPI
178c2c66affSColin Finck DECLSPEC_HOTPATCH
LoadLibraryW(LPCWSTR lpLibFileName)179c2c66affSColin Finck LoadLibraryW(LPCWSTR lpLibFileName)
180c2c66affSColin Finck {
181c2c66affSColin Finck /* Call Ex version of the API */
182c2c66affSColin Finck return LoadLibraryExW(lpLibFileName, 0, 0);
183c2c66affSColin Finck }
184c2c66affSColin Finck
185c2c66affSColin Finck
186c2c66affSColin Finck static
187c2c66affSColin Finck NTSTATUS
BasepLoadLibraryAsDatafile(PWSTR Path,LPCWSTR Name,HMODULE * hModule)188c2c66affSColin Finck BasepLoadLibraryAsDatafile(PWSTR Path, LPCWSTR Name, HMODULE *hModule)
189c2c66affSColin Finck {
190c2c66affSColin Finck WCHAR FilenameW[MAX_PATH];
191c2c66affSColin Finck HANDLE hFile = INVALID_HANDLE_VALUE;
192c2c66affSColin Finck HANDLE hMapping;
193c2c66affSColin Finck NTSTATUS Status;
194c2c66affSColin Finck PVOID lpBaseAddress = NULL;
195c2c66affSColin Finck SIZE_T ViewSize = 0;
196c2c66affSColin Finck //PUNICODE_STRING OriginalName;
197c2c66affSColin Finck //UNICODE_STRING dotDLL = RTL_CONSTANT_STRING(L".DLL");
198c2c66affSColin Finck
199c2c66affSColin Finck /* Zero out handle value */
200c2c66affSColin Finck *hModule = 0;
201c2c66affSColin Finck
202c2c66affSColin Finck DPRINT("BasepLoadLibraryAsDatafile(%S %S %p)\n", Path, Name, hModule);
203c2c66affSColin Finck
204c2c66affSColin Finck /*Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
205c2c66affSColin Finck Name,
206c2c66affSColin Finck &dotDLL,
207c2c66affSColin Finck RedirName,
208c2c66affSColin Finck RedirName2,
209c2c66affSColin Finck &OriginalName2,
210c2c66affSColin Finck NULL,
211c2c66affSColin Finck NULL,
212c2c66affSColin Finck NULL);*/
213c2c66affSColin Finck
214c2c66affSColin Finck /* Try to search for it */
215c2c66affSColin Finck if (!SearchPathW(Path,
216c2c66affSColin Finck Name,
217c2c66affSColin Finck L".DLL",
218c2c66affSColin Finck sizeof(FilenameW) / sizeof(FilenameW[0]),
219c2c66affSColin Finck FilenameW,
220c2c66affSColin Finck NULL))
221c2c66affSColin Finck {
222c2c66affSColin Finck /* Return last status value directly */
223c2c66affSColin Finck return NtCurrentTeb()->LastStatusValue;
224c2c66affSColin Finck }
225c2c66affSColin Finck
226c2c66affSColin Finck /* Open this file we found */
227c2c66affSColin Finck hFile = CreateFileW(FilenameW,
228c2c66affSColin Finck GENERIC_READ,
229c2c66affSColin Finck FILE_SHARE_READ | FILE_SHARE_DELETE,
230c2c66affSColin Finck NULL,
231c2c66affSColin Finck OPEN_EXISTING,
232c2c66affSColin Finck 0,
233c2c66affSColin Finck 0);
234c2c66affSColin Finck
235c2c66affSColin Finck /* If opening failed - return last status value */
236c2c66affSColin Finck if (hFile == INVALID_HANDLE_VALUE) return NtCurrentTeb()->LastStatusValue;
237c2c66affSColin Finck
238c2c66affSColin Finck /* Create file mapping */
239c2c66affSColin Finck hMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
240c2c66affSColin Finck
241c2c66affSColin Finck /* Close the file handle */
242c2c66affSColin Finck CloseHandle(hFile);
243c2c66affSColin Finck
244c2c66affSColin Finck /* If creating file mapping failed - return last status value */
245c2c66affSColin Finck if (!hMapping) return NtCurrentTeb()->LastStatusValue;
246c2c66affSColin Finck
247c2c66affSColin Finck /* Map view of section */
248c2c66affSColin Finck Status = NtMapViewOfSection(hMapping,
249c2c66affSColin Finck NtCurrentProcess(),
250c2c66affSColin Finck &lpBaseAddress,
251c2c66affSColin Finck 0,
252c2c66affSColin Finck 0,
253c2c66affSColin Finck 0,
254c2c66affSColin Finck &ViewSize,
255c2c66affSColin Finck ViewShare,
256c2c66affSColin Finck 0,
257c2c66affSColin Finck PAGE_READONLY);
258c2c66affSColin Finck
259c2c66affSColin Finck /* Close handle to the section */
260c2c66affSColin Finck CloseHandle(hMapping);
261c2c66affSColin Finck
262c2c66affSColin Finck /* If mapping view of section failed - return last status value */
263c2c66affSColin Finck if (!NT_SUCCESS(Status)) return NtCurrentTeb()->LastStatusValue;
264c2c66affSColin Finck
265c2c66affSColin Finck /* Make sure it's a valid PE file */
266c2c66affSColin Finck if (!RtlImageNtHeader(lpBaseAddress))
267c2c66affSColin Finck {
268c2c66affSColin Finck /* Unmap the view and return failure status */
269c2c66affSColin Finck UnmapViewOfFile(lpBaseAddress);
270c2c66affSColin Finck return STATUS_INVALID_IMAGE_FORMAT;
271c2c66affSColin Finck }
272c2c66affSColin Finck
273c2c66affSColin Finck /* Set low bit of handle to indicate datafile module */
274c2c66affSColin Finck *hModule = (HMODULE)((ULONG_PTR)lpBaseAddress | 1);
275c2c66affSColin Finck
276c2c66affSColin Finck /* Load alternate resource module */
277c2c66affSColin Finck //LdrLoadAlternateResourceModule(*hModule, FilenameW);
278c2c66affSColin Finck
279c2c66affSColin Finck return STATUS_SUCCESS;
280c2c66affSColin Finck }
281c2c66affSColin Finck
282c2c66affSColin Finck /*
283c2c66affSColin Finck * @implemented
284c2c66affSColin Finck */
285c2c66affSColin Finck HINSTANCE
286c2c66affSColin Finck WINAPI
287c2c66affSColin Finck DECLSPEC_HOTPATCH
LoadLibraryExW(LPCWSTR lpLibFileName,HANDLE hFile,DWORD dwFlags)288c2c66affSColin Finck LoadLibraryExW(LPCWSTR lpLibFileName,
289c2c66affSColin Finck HANDLE hFile,
290c2c66affSColin Finck DWORD dwFlags)
291c2c66affSColin Finck {
292c2c66affSColin Finck UNICODE_STRING DllName;
293c2c66affSColin Finck HINSTANCE hInst;
294c2c66affSColin Finck NTSTATUS Status;
295c2c66affSColin Finck PWSTR SearchPath;
296c2c66affSColin Finck ULONG DllCharacteristics = 0;
297c2c66affSColin Finck BOOL FreeString = FALSE;
298c2c66affSColin Finck
299c2c66affSColin Finck /* Check for any flags LdrLoadDll might be interested in */
300c2c66affSColin Finck if (dwFlags & DONT_RESOLVE_DLL_REFERENCES)
301c2c66affSColin Finck {
302c2c66affSColin Finck /* Tell LDR to treat it as an EXE */
303c2c66affSColin Finck DllCharacteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
304c2c66affSColin Finck }
305c2c66affSColin Finck
306c2c66affSColin Finck /* Build up a unicode dll name from null-terminated string */
307c2c66affSColin Finck RtlInitUnicodeString(&DllName, (LPWSTR)lpLibFileName);
308c2c66affSColin Finck
309c2c66affSColin Finck /* Lazy-initialize BasepExeLdrEntry */
310c2c66affSColin Finck if (!BasepExeLdrEntry)
311c2c66affSColin Finck LdrEnumerateLoadedModules(0, BasepLocateExeLdrEntry, NtCurrentPeb()->ImageBaseAddress);
312c2c66affSColin Finck
313c2c66affSColin Finck /* Check if that module is our exe*/
314c2c66affSColin Finck if (BasepExeLdrEntry && !(dwFlags & LOAD_LIBRARY_AS_DATAFILE) &&
315c2c66affSColin Finck DllName.Length == BasepExeLdrEntry->FullDllName.Length)
316c2c66affSColin Finck {
317c2c66affSColin Finck /* Lengths match and it's not a datafile, so perform name comparison */
318c2c66affSColin Finck if (RtlEqualUnicodeString(&DllName, &BasepExeLdrEntry->FullDllName, TRUE))
319c2c66affSColin Finck {
320c2c66affSColin Finck /* That's us! */
321c2c66affSColin Finck return BasepExeLdrEntry->DllBase;
322c2c66affSColin Finck }
323c2c66affSColin Finck }
324c2c66affSColin Finck
325c2c66affSColin Finck /* Check for trailing spaces and remove them if necessary */
326c2c66affSColin Finck if (DllName.Buffer[DllName.Length/sizeof(WCHAR) - 1] == L' ')
327c2c66affSColin Finck {
328c2c66affSColin Finck RtlCreateUnicodeString(&DllName, (LPWSTR)lpLibFileName);
329c2c66affSColin Finck while (DllName.Length > sizeof(WCHAR) &&
330c2c66affSColin Finck DllName.Buffer[DllName.Length/sizeof(WCHAR) - 1] == L' ')
331c2c66affSColin Finck {
332c2c66affSColin Finck DllName.Length -= sizeof(WCHAR);
333c2c66affSColin Finck }
334c2c66affSColin Finck DllName.Buffer[DllName.Length/sizeof(WCHAR)] = UNICODE_NULL;
335c2c66affSColin Finck FreeString = TRUE;
336c2c66affSColin Finck }
337c2c66affSColin Finck
338c2c66affSColin Finck /* Compute the load path */
339c2c66affSColin Finck SearchPath = BaseComputeProcessDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ?
340c2c66affSColin Finck DllName.Buffer : NULL,
341c2c66affSColin Finck NULL);
342c2c66affSColin Finck if (!SearchPath)
343c2c66affSColin Finck {
344c2c66affSColin Finck /* Getting DLL path failed, so set last error, free mem and return */
345c2c66affSColin Finck BaseSetLastNTError(STATUS_NO_MEMORY);
346c2c66affSColin Finck if (FreeString) RtlFreeUnicodeString(&DllName);
347c2c66affSColin Finck return NULL;
348c2c66affSColin Finck }
349c2c66affSColin Finck
350c2c66affSColin Finck _SEH2_TRY
351c2c66affSColin Finck {
352c2c66affSColin Finck if (dwFlags & LOAD_LIBRARY_AS_DATAFILE)
353c2c66affSColin Finck {
354c2c66affSColin Finck /* If the image is loaded as a datafile, try to get its handle */
355c2c66affSColin Finck Status = LdrGetDllHandleEx(0, SearchPath, NULL, &DllName, (PVOID*)&hInst);
356c2c66affSColin Finck if (!NT_SUCCESS(Status))
357c2c66affSColin Finck {
358c2c66affSColin Finck /* It's not loaded yet - so load it up */
359c2c66affSColin Finck Status = BasepLoadLibraryAsDatafile(SearchPath, DllName.Buffer, &hInst);
360c2c66affSColin Finck }
361c2c66affSColin Finck _SEH2_YIELD(goto done;)
362c2c66affSColin Finck }
363c2c66affSColin Finck
364c2c66affSColin Finck /* Call the API Properly */
365c2c66affSColin Finck Status = LdrLoadDll(SearchPath,
366c2c66affSColin Finck &DllCharacteristics,
367c2c66affSColin Finck &DllName,
368c2c66affSColin Finck (PVOID*)&hInst);
369c2c66affSColin Finck }
370c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
371c2c66affSColin Finck {
372c2c66affSColin Finck Status = _SEH2_GetExceptionCode();
373c2c66affSColin Finck } _SEH2_END;
374c2c66affSColin Finck
375c2c66affSColin Finck
376c2c66affSColin Finck done:
377c2c66affSColin Finck /* Free SearchPath buffer */
378c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
379c2c66affSColin Finck
380c2c66affSColin Finck /* Free DllName string if it was dynamically allocated */
381c2c66affSColin Finck if (FreeString) RtlFreeUnicodeString(&DllName);
382c2c66affSColin Finck
383c2c66affSColin Finck /* Set last error in failure case */
384c2c66affSColin Finck if (!NT_SUCCESS(Status))
385c2c66affSColin Finck {
386c2c66affSColin Finck DPRINT1("LoadLibraryExW(%ls) failing with status %lx\n", lpLibFileName, Status);
387c2c66affSColin Finck BaseSetLastNTError(Status);
388c2c66affSColin Finck return NULL;
389c2c66affSColin Finck }
390c2c66affSColin Finck
391c2c66affSColin Finck /* Return loaded module handle */
392c2c66affSColin Finck return hInst;
393c2c66affSColin Finck }
394c2c66affSColin Finck
395c2c66affSColin Finck
396c2c66affSColin Finck /*
397c2c66affSColin Finck * @implemented
398c2c66affSColin Finck */
399c2c66affSColin Finck FARPROC
400c2c66affSColin Finck WINAPI
GetProcAddress(HMODULE hModule,LPCSTR lpProcName)401c2c66affSColin Finck GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
402c2c66affSColin Finck {
403c2c66affSColin Finck ANSI_STRING ProcedureName, *ProcNamePtr = NULL;
404c2c66affSColin Finck FARPROC fnExp = NULL;
405c2c66affSColin Finck NTSTATUS Status;
406c2c66affSColin Finck PVOID hMapped;
407c2c66affSColin Finck ULONG Ordinal = 0;
408c2c66affSColin Finck
4094f0a158aSTimo Kreuzer if ((ULONG_PTR)lpProcName > MAXUSHORT)
410c2c66affSColin Finck {
411c2c66affSColin Finck /* Look up by name */
412c2c66affSColin Finck RtlInitAnsiString(&ProcedureName, (LPSTR)lpProcName);
413c2c66affSColin Finck ProcNamePtr = &ProcedureName;
414c2c66affSColin Finck }
415c2c66affSColin Finck else
416c2c66affSColin Finck {
417c2c66affSColin Finck /* Look up by ordinal */
4184f0a158aSTimo Kreuzer Ordinal = PtrToUlong(lpProcName);
419c2c66affSColin Finck }
420c2c66affSColin Finck
421c2c66affSColin Finck /* Map provided handle */
422c2c66affSColin Finck hMapped = BasepMapModuleHandle(hModule, FALSE);
423c2c66affSColin Finck
424c2c66affSColin Finck /* Get the proc address */
425c2c66affSColin Finck Status = LdrGetProcedureAddress(hMapped,
426c2c66affSColin Finck ProcNamePtr,
427c2c66affSColin Finck Ordinal,
428c2c66affSColin Finck (PVOID*)&fnExp);
429c2c66affSColin Finck
430c2c66affSColin Finck if (!NT_SUCCESS(Status))
431c2c66affSColin Finck {
432c2c66affSColin Finck BaseSetLastNTError(Status);
433c2c66affSColin Finck return NULL;
434c2c66affSColin Finck }
435c2c66affSColin Finck
436c2c66affSColin Finck /* Check for a special case when returned pointer is
437c2c66affSColin Finck the same as image's base address */
438c2c66affSColin Finck if (fnExp == hMapped)
439c2c66affSColin Finck {
440c2c66affSColin Finck /* Set correct error code */
441c2c66affSColin Finck if (HIWORD(lpProcName) != 0)
442c2c66affSColin Finck BaseSetLastNTError(STATUS_ENTRYPOINT_NOT_FOUND);
443c2c66affSColin Finck else
444c2c66affSColin Finck BaseSetLastNTError(STATUS_ORDINAL_NOT_FOUND);
445c2c66affSColin Finck
446c2c66affSColin Finck return NULL;
447c2c66affSColin Finck }
448c2c66affSColin Finck
449c2c66affSColin Finck /* All good, return procedure pointer */
450c2c66affSColin Finck return fnExp;
451c2c66affSColin Finck }
452c2c66affSColin Finck
453c2c66affSColin Finck
454c2c66affSColin Finck /*
455c2c66affSColin Finck * @implemented
456c2c66affSColin Finck */
457c2c66affSColin Finck BOOL
458c2c66affSColin Finck WINAPI
459c2c66affSColin Finck DECLSPEC_HOTPATCH
FreeLibrary(HINSTANCE hLibModule)460c2c66affSColin Finck FreeLibrary(HINSTANCE hLibModule)
461c2c66affSColin Finck {
462c2c66affSColin Finck NTSTATUS Status;
463c2c66affSColin Finck PIMAGE_NT_HEADERS NtHeaders;
464c2c66affSColin Finck
465c2c66affSColin Finck if (LDR_IS_DATAFILE(hLibModule))
466c2c66affSColin Finck {
467c2c66affSColin Finck /* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */
468c2c66affSColin Finck NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1));
469c2c66affSColin Finck
470c2c66affSColin Finck if (NtHeaders)
471c2c66affSColin Finck {
472c2c66affSColin Finck /* Unmap view */
473c2c66affSColin Finck Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1));
474c2c66affSColin Finck
475c2c66affSColin Finck /* Unload alternate resource module */
476c2c66affSColin Finck LdrUnloadAlternateResourceModule(hLibModule);
477c2c66affSColin Finck }
478c2c66affSColin Finck else
479c2c66affSColin Finck Status = STATUS_INVALID_IMAGE_FORMAT;
480c2c66affSColin Finck }
481c2c66affSColin Finck else
482c2c66affSColin Finck {
483c2c66affSColin Finck /* Just unload it */
484c2c66affSColin Finck Status = LdrUnloadDll((PVOID)hLibModule);
485c2c66affSColin Finck }
486c2c66affSColin Finck
487c2c66affSColin Finck /* Check what kind of status we got */
488c2c66affSColin Finck if (!NT_SUCCESS(Status))
489c2c66affSColin Finck {
490c2c66affSColin Finck /* Set last error */
491c2c66affSColin Finck BaseSetLastNTError(Status);
492c2c66affSColin Finck
493c2c66affSColin Finck /* Return failure */
494c2c66affSColin Finck return FALSE;
495c2c66affSColin Finck }
496c2c66affSColin Finck
497c2c66affSColin Finck /* Return success */
498c2c66affSColin Finck return TRUE;
499c2c66affSColin Finck }
500c2c66affSColin Finck
501c2c66affSColin Finck
502c2c66affSColin Finck /*
503c2c66affSColin Finck * @implemented
504c2c66affSColin Finck */
505c2c66affSColin Finck VOID
506c2c66affSColin Finck WINAPI
FreeLibraryAndExitThread(HMODULE hLibModule,DWORD dwExitCode)507c2c66affSColin Finck FreeLibraryAndExitThread(HMODULE hLibModule,
508c2c66affSColin Finck DWORD dwExitCode)
509c2c66affSColin Finck {
510c2c66affSColin Finck
511c2c66affSColin Finck if (LDR_IS_DATAFILE(hLibModule))
512c2c66affSColin Finck {
513c2c66affSColin Finck /* This is a LOAD_LIBRARY_AS_DATAFILE module */
514c2c66affSColin Finck if (RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1)))
515c2c66affSColin Finck {
516c2c66affSColin Finck /* Unmap view */
517c2c66affSColin Finck NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1));
518c2c66affSColin Finck
519c2c66affSColin Finck /* Unload alternate resource module */
520c2c66affSColin Finck LdrUnloadAlternateResourceModule(hLibModule);
521c2c66affSColin Finck }
522c2c66affSColin Finck }
523c2c66affSColin Finck else
524c2c66affSColin Finck {
525c2c66affSColin Finck /* Just unload it */
526c2c66affSColin Finck LdrUnloadDll((PVOID)hLibModule);
527c2c66affSColin Finck }
528c2c66affSColin Finck
529c2c66affSColin Finck /* Exit thread */
530c2c66affSColin Finck ExitThread(dwExitCode);
531c2c66affSColin Finck }
532c2c66affSColin Finck
533c2c66affSColin Finck
534c2c66affSColin Finck /*
535c2c66affSColin Finck * @implemented
536c2c66affSColin Finck */
537c2c66affSColin Finck DWORD
538c2c66affSColin Finck WINAPI
GetModuleFileNameA(HINSTANCE hModule,LPSTR lpFilename,DWORD nSize)539c2c66affSColin Finck GetModuleFileNameA(HINSTANCE hModule,
540c2c66affSColin Finck LPSTR lpFilename,
541c2c66affSColin Finck DWORD nSize)
542c2c66affSColin Finck {
543c2c66affSColin Finck UNICODE_STRING FilenameW;
544c2c66affSColin Finck ANSI_STRING FilenameA;
545c2c66affSColin Finck NTSTATUS Status;
546c2c66affSColin Finck DWORD Length = 0, LengthToCopy;
547c2c66affSColin Finck
548c2c66affSColin Finck /* Allocate a unicode buffer */
549c2c66affSColin Finck FilenameW.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nSize * sizeof(WCHAR));
550c2c66affSColin Finck if (!FilenameW.Buffer)
551c2c66affSColin Finck {
552c2c66affSColin Finck BaseSetLastNTError(STATUS_NO_MEMORY);
553c2c66affSColin Finck return 0;
554c2c66affSColin Finck }
555c2c66affSColin Finck
556c2c66affSColin Finck /* Call unicode API */
557c2c66affSColin Finck FilenameW.Length = (USHORT)GetModuleFileNameW(hModule, FilenameW.Buffer, nSize) * sizeof(WCHAR);
558c2c66affSColin Finck FilenameW.MaximumLength = FilenameW.Length + sizeof(WCHAR);
559c2c66affSColin Finck
560c2c66affSColin Finck if (FilenameW.Length)
561c2c66affSColin Finck {
562c2c66affSColin Finck /* Convert to ansi string */
563c2c66affSColin Finck Status = BasepUnicodeStringTo8BitString(&FilenameA, &FilenameW, TRUE);
564c2c66affSColin Finck if (!NT_SUCCESS(Status))
565c2c66affSColin Finck {
566c2c66affSColin Finck /* Set last error, free string and return failure */
567c2c66affSColin Finck BaseSetLastNTError(Status);
568c2c66affSColin Finck RtlFreeUnicodeString(&FilenameW);
569c2c66affSColin Finck return 0;
570c2c66affSColin Finck }
571c2c66affSColin Finck
572c2c66affSColin Finck /* Calculate size to copy */
573c2c66affSColin Finck Length = min(nSize, FilenameA.Length);
574c2c66affSColin Finck
575c2c66affSColin Finck /* Include terminating zero */
576c2c66affSColin Finck if (nSize > Length)
577c2c66affSColin Finck LengthToCopy = Length + 1;
578c2c66affSColin Finck else
579c2c66affSColin Finck LengthToCopy = nSize;
580c2c66affSColin Finck
581c2c66affSColin Finck /* Now copy back to the caller amount he asked */
582c2c66affSColin Finck RtlMoveMemory(lpFilename, FilenameA.Buffer, LengthToCopy);
583c2c66affSColin Finck
584c2c66affSColin Finck /* Free ansi filename */
585c2c66affSColin Finck RtlFreeAnsiString(&FilenameA);
586c2c66affSColin Finck }
587c2c66affSColin Finck
588c2c66affSColin Finck /* Free unicode filename */
589c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, FilenameW.Buffer);
590c2c66affSColin Finck
591c2c66affSColin Finck /* Return length copied */
592c2c66affSColin Finck return Length;
593c2c66affSColin Finck }
594c2c66affSColin Finck
595c2c66affSColin Finck /*
596c2c66affSColin Finck * @implemented
597c2c66affSColin Finck */
598c2c66affSColin Finck DWORD
599c2c66affSColin Finck WINAPI
GetModuleFileNameW(HINSTANCE hModule,LPWSTR lpFilename,DWORD nSize)600c2c66affSColin Finck GetModuleFileNameW(HINSTANCE hModule,
601c2c66affSColin Finck LPWSTR lpFilename,
602c2c66affSColin Finck DWORD nSize)
603c2c66affSColin Finck {
604c2c66affSColin Finck PLIST_ENTRY ModuleListHead, Entry;
605c2c66affSColin Finck PLDR_DATA_TABLE_ENTRY Module;
606c2c66affSColin Finck ULONG Length = 0;
607d6792047SIvan Labutin ULONG_PTR Cookie;
608c2c66affSColin Finck PPEB Peb;
609c2c66affSColin Finck
610c2c66affSColin Finck hModule = BasepMapModuleHandle(hModule, FALSE);
611c2c66affSColin Finck
612c2c66affSColin Finck /* Upscale nSize from chars to bytes */
613c2c66affSColin Finck nSize *= sizeof(WCHAR);
614c2c66affSColin Finck
615c2c66affSColin Finck _SEH2_TRY
616c2c66affSColin Finck {
617c2c66affSColin Finck /* We don't use per-thread cur dir now */
618c2c66affSColin Finck //PRTL_PERTHREAD_CURDIR PerThreadCurdir = (PRTL_PERTHREAD_CURDIR)teb->NtTib.SubSystemTib;
619c2c66affSColin Finck
620c2c66affSColin Finck Peb = NtCurrentPeb ();
621c2c66affSColin Finck
622c2c66affSColin Finck /* Acquire a loader lock */
623c2c66affSColin Finck LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);
624c2c66affSColin Finck
625c2c66affSColin Finck /* Traverse the module list */
626c2c66affSColin Finck ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
627c2c66affSColin Finck Entry = ModuleListHead->Flink;
628c2c66affSColin Finck while (Entry != ModuleListHead)
629c2c66affSColin Finck {
630c2c66affSColin Finck Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
631c2c66affSColin Finck
632c2c66affSColin Finck /* Check if this is the requested module */
633c2c66affSColin Finck if (Module->DllBase == (PVOID)hModule)
634c2c66affSColin Finck {
635c2c66affSColin Finck /* Calculate size to copy */
636c2c66affSColin Finck Length = min(nSize, Module->FullDllName.MaximumLength);
637c2c66affSColin Finck
638c2c66affSColin Finck /* Copy contents */
639c2c66affSColin Finck RtlMoveMemory(lpFilename, Module->FullDllName.Buffer, Length);
640c2c66affSColin Finck
641c2c66affSColin Finck /* Subtract a terminating zero */
642c2c66affSColin Finck if (Length == Module->FullDllName.MaximumLength)
643c2c66affSColin Finck Length -= sizeof(WCHAR);
644c2c66affSColin Finck
645c2c66affSColin Finck /* Break out of the loop */
646c2c66affSColin Finck break;
647c2c66affSColin Finck }
648c2c66affSColin Finck
649c2c66affSColin Finck /* Advance to the next entry */
650c2c66affSColin Finck Entry = Entry->Flink;
651c2c66affSColin Finck }
652c2c66affSColin Finck }
653c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
654c2c66affSColin Finck {
655c2c66affSColin Finck BaseSetLastNTError(_SEH2_GetExceptionCode());
656c2c66affSColin Finck Length = 0;
657c2c66affSColin Finck } _SEH2_END
658c2c66affSColin Finck
659c2c66affSColin Finck /* Release the loader lock */
660*bd0a5498SRatin Gao LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
661c2c66affSColin Finck
662c2c66affSColin Finck return Length / sizeof(WCHAR);
663c2c66affSColin Finck }
664c2c66affSColin Finck
665c2c66affSColin Finck HMODULE
666c2c66affSColin Finck WINAPI
GetModuleHandleForUnicodeString(PUNICODE_STRING ModuleName)667c2c66affSColin Finck GetModuleHandleForUnicodeString(PUNICODE_STRING ModuleName)
668c2c66affSColin Finck {
669c2c66affSColin Finck NTSTATUS Status;
670c2c66affSColin Finck PVOID Module;
671c2c66affSColin Finck LPWSTR DllPath;
672c2c66affSColin Finck
673c2c66affSColin Finck /* Try to get a handle with a magic value of 1 for DllPath */
674c2c66affSColin Finck Status = LdrGetDllHandle((LPWSTR)1, NULL, ModuleName, &Module);
675c2c66affSColin Finck
676c2c66affSColin Finck /* If that succeeded - we're done */
677c2c66affSColin Finck if (NT_SUCCESS(Status)) return Module;
678c2c66affSColin Finck
679c2c66affSColin Finck /* If not, then the path should be computed */
680d6d30f9eSHermès Bélusca-Maïto DllPath = BaseComputeProcessDllPath(NULL, NULL);
681c2c66affSColin Finck if (!DllPath)
682c2c66affSColin Finck {
683c2c66affSColin Finck Status = STATUS_NO_MEMORY;
684c2c66affSColin Finck }
685c2c66affSColin Finck else
686c2c66affSColin Finck {
687c2c66affSColin Finck _SEH2_TRY
688c2c66affSColin Finck {
689c2c66affSColin Finck Status = LdrGetDllHandle(DllPath, NULL, ModuleName, &Module);
690c2c66affSColin Finck }
691c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
692c2c66affSColin Finck {
693c2c66affSColin Finck /* Fail with the SEH error */
694c2c66affSColin Finck Status = _SEH2_GetExceptionCode();
695c2c66affSColin Finck }
696c2c66affSColin Finck _SEH2_END;
697c2c66affSColin Finck }
698c2c66affSColin Finck
699c2c66affSColin Finck /* Free the DllPath */
700c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath);
701c2c66affSColin Finck
702c2c66affSColin Finck /* In case of error set last win32 error and return NULL */
703c2c66affSColin Finck if (!NT_SUCCESS(Status))
704c2c66affSColin Finck {
705c2c66affSColin Finck DPRINT("Failure acquiring DLL module '%wZ' handle, Status 0x%08X\n", ModuleName, Status);
706c2c66affSColin Finck BaseSetLastNTError(Status);
707c2c66affSColin Finck Module = 0;
708c2c66affSColin Finck }
709c2c66affSColin Finck
710c2c66affSColin Finck /* Return module */
711c2c66affSColin Finck return (HMODULE)Module;
712c2c66affSColin Finck }
713c2c66affSColin Finck
714c2c66affSColin Finck BOOLEAN
715c2c66affSColin Finck WINAPI
BasepGetModuleHandleExW(BOOLEAN NoLock,DWORD dwPublicFlags,LPCWSTR lpwModuleName,HMODULE * phModule)716c2c66affSColin Finck BasepGetModuleHandleExW(BOOLEAN NoLock, DWORD dwPublicFlags, LPCWSTR lpwModuleName, HMODULE *phModule)
717c2c66affSColin Finck {
718d6792047SIvan Labutin ULONG_PTR Cookie;
719c2c66affSColin Finck NTSTATUS Status = STATUS_SUCCESS, Status2;
720c2c66affSColin Finck HANDLE hModule = NULL;
721c2c66affSColin Finck UNICODE_STRING ModuleNameU;
722c2c66affSColin Finck DWORD dwValid;
723c2c66affSColin Finck BOOLEAN Redirected = FALSE; // FIXME
724c2c66affSColin Finck
725c2c66affSColin Finck /* Validate parameters */
726c2c66affSColin Finck dwValid = BasepGetModuleHandleExParameterValidation(dwPublicFlags, lpwModuleName, phModule);
727c2c66affSColin Finck ASSERT(dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE);
728c2c66affSColin Finck
729c2c66affSColin Finck /* Acquire lock if necessary */
730c2c66affSColin Finck if (!NoLock)
731c2c66affSColin Finck {
732c2c66affSColin Finck Status = LdrLockLoaderLock(0, NULL, &Cookie);
733c2c66affSColin Finck if (!NT_SUCCESS(Status))
734c2c66affSColin Finck {
735c2c66affSColin Finck /* Fail */
736c2c66affSColin Finck BaseSetLastNTError(Status);
737c2c66affSColin Finck if (phModule) *phModule = NULL;
738c2c66affSColin Finck return NT_SUCCESS(Status);
739c2c66affSColin Finck }
740c2c66affSColin Finck }
741c2c66affSColin Finck
742c2c66affSColin Finck if (!(dwPublicFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
743c2c66affSColin Finck {
744c2c66affSColin Finck /* Create a unicode string out of module name */
745c2c66affSColin Finck RtlInitUnicodeString(&ModuleNameU, lpwModuleName);
746c2c66affSColin Finck
747c2c66affSColin Finck // FIXME: Do some redirected DLL stuff?
748c2c66affSColin Finck if (Redirected)
749c2c66affSColin Finck {
750c2c66affSColin Finck UNIMPLEMENTED;
751c2c66affSColin Finck }
752c2c66affSColin Finck
753c2c66affSColin Finck if (!hModule)
754c2c66affSColin Finck {
755c2c66affSColin Finck hModule = GetModuleHandleForUnicodeString(&ModuleNameU);
756c2c66affSColin Finck if (!hModule)
757c2c66affSColin Finck {
758c2c66affSColin Finck /* Last error is already set, so just return failure by setting status */
759c2c66affSColin Finck Status = STATUS_DLL_NOT_FOUND;
760c2c66affSColin Finck goto quickie;
761c2c66affSColin Finck }
762c2c66affSColin Finck }
763c2c66affSColin Finck }
764c2c66affSColin Finck else
765c2c66affSColin Finck {
766c2c66affSColin Finck /* Perform Pc to file header to get module instance */
767c2c66affSColin Finck hModule = (HMODULE)RtlPcToFileHeader((PVOID)lpwModuleName,
768c2c66affSColin Finck (PVOID*)&hModule);
769c2c66affSColin Finck
770c2c66affSColin Finck /* Check if it succeeded */
771c2c66affSColin Finck if (!hModule)
772c2c66affSColin Finck {
773c2c66affSColin Finck /* Set "dll not found" status and quit */
774c2c66affSColin Finck Status = STATUS_DLL_NOT_FOUND;
775c2c66affSColin Finck goto quickie;
776c2c66affSColin Finck }
777c2c66affSColin Finck }
778c2c66affSColin Finck
779c2c66affSColin Finck /* Check if changing reference is not forbidden */
780c2c66affSColin Finck if (!(dwPublicFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
781c2c66affSColin Finck {
782c2c66affSColin Finck /* Add reference to this DLL */
783c2c66affSColin Finck Status = LdrAddRefDll((dwPublicFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) ? LDR_ADDREF_DLL_PIN : 0,
784c2c66affSColin Finck hModule);
785c2c66affSColin Finck }
786c2c66affSColin Finck
787c2c66affSColin Finck quickie:
788c2c66affSColin Finck /* Set last error in case of failure */
789c2c66affSColin Finck if (!NT_SUCCESS(Status))
790c2c66affSColin Finck BaseSetLastNTError(Status);
791c2c66affSColin Finck
792c2c66affSColin Finck /* Unlock loader lock if it was acquired */
793c2c66affSColin Finck if (!NoLock)
794c2c66affSColin Finck {
795c2c66affSColin Finck Status2 = LdrUnlockLoaderLock(0, Cookie);
796c2c66affSColin Finck ASSERT(NT_SUCCESS(Status2));
797c2c66affSColin Finck }
798c2c66affSColin Finck
799c2c66affSColin Finck /* Set the module handle to the caller */
800c2c66affSColin Finck if (phModule) *phModule = hModule;
801c2c66affSColin Finck
802c2c66affSColin Finck /* Return TRUE on success and FALSE otherwise */
803c2c66affSColin Finck return NT_SUCCESS(Status);
804c2c66affSColin Finck }
805c2c66affSColin Finck
806c2c66affSColin Finck /*
807c2c66affSColin Finck * @implemented
808c2c66affSColin Finck */
809c2c66affSColin Finck HMODULE
810c2c66affSColin Finck WINAPI
811c2c66affSColin Finck DECLSPEC_HOTPATCH
GetModuleHandleA(LPCSTR lpModuleName)812c2c66affSColin Finck GetModuleHandleA(LPCSTR lpModuleName)
813c2c66affSColin Finck {
814c2c66affSColin Finck PUNICODE_STRING ModuleNameW;
815c2c66affSColin Finck PTEB pTeb = NtCurrentTeb();
816c2c66affSColin Finck
817c2c66affSColin Finck /* Check if we have no name to convert */
818c2c66affSColin Finck if (!lpModuleName)
819c2c66affSColin Finck return ((HMODULE)pTeb->ProcessEnvironmentBlock->ImageBaseAddress);
820c2c66affSColin Finck
821c2c66affSColin Finck /* Convert module name to unicode */
822c2c66affSColin Finck ModuleNameW = Basep8BitStringToStaticUnicodeString(lpModuleName);
823c2c66affSColin Finck
824c2c66affSColin Finck /* Call W version if conversion was successful */
825c2c66affSColin Finck if (ModuleNameW)
826c2c66affSColin Finck return GetModuleHandleW(ModuleNameW->Buffer);
827c2c66affSColin Finck
828c2c66affSColin Finck /* Return failure */
829c2c66affSColin Finck return 0;
830c2c66affSColin Finck }
831c2c66affSColin Finck
832c2c66affSColin Finck
833c2c66affSColin Finck /*
834c2c66affSColin Finck * @implemented
835c2c66affSColin Finck */
836c2c66affSColin Finck HMODULE
837c2c66affSColin Finck WINAPI
GetModuleHandleW(LPCWSTR lpModuleName)838c2c66affSColin Finck GetModuleHandleW(LPCWSTR lpModuleName)
839c2c66affSColin Finck {
840c2c66affSColin Finck HMODULE hModule;
841c2c66affSColin Finck BOOLEAN Success;
842c2c66affSColin Finck
843c2c66affSColin Finck /* If current module is requested - return it right away */
844c2c66affSColin Finck if (!lpModuleName)
845c2c66affSColin Finck return ((HMODULE)NtCurrentPeb()->ImageBaseAddress);
846c2c66affSColin Finck
847c2c66affSColin Finck /* Use common helper routine */
848c2c66affSColin Finck Success = BasepGetModuleHandleExW(TRUE,
849c2c66affSColin Finck GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
850c2c66affSColin Finck lpModuleName,
851c2c66affSColin Finck &hModule);
852c2c66affSColin Finck
853c2c66affSColin Finck /* If it wasn't successful - return NULL */
854c2c66affSColin Finck if (!Success) hModule = NULL;
855c2c66affSColin Finck
856c2c66affSColin Finck /* Return the handle */
857c2c66affSColin Finck return hModule;
858c2c66affSColin Finck }
859c2c66affSColin Finck
860c2c66affSColin Finck
861c2c66affSColin Finck /*
862c2c66affSColin Finck * @implemented
863c2c66affSColin Finck */
864c2c66affSColin Finck BOOL
865c2c66affSColin Finck WINAPI
GetModuleHandleExW(IN DWORD dwFlags,IN LPCWSTR lpwModuleName OPTIONAL,OUT HMODULE * phModule)866c2c66affSColin Finck GetModuleHandleExW(IN DWORD dwFlags,
867c2c66affSColin Finck IN LPCWSTR lpwModuleName OPTIONAL,
868c2c66affSColin Finck OUT HMODULE* phModule)
869c2c66affSColin Finck {
870c2c66affSColin Finck DWORD dwValid;
871c2c66affSColin Finck BOOL Ret;
872c2c66affSColin Finck
873c2c66affSColin Finck /* Validate parameters */
874c2c66affSColin Finck dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, lpwModuleName, phModule);
875c2c66affSColin Finck
876c2c66affSColin Finck /* If result is invalid parameter - return failure */
877c2c66affSColin Finck if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE;
878c2c66affSColin Finck
879c2c66affSColin Finck /* If result is 2, there is no need to do anything - return success. */
880c2c66affSColin Finck if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
881c2c66affSColin Finck
882c2c66affSColin Finck /* Use common helper routine */
883c2c66affSColin Finck Ret = BasepGetModuleHandleExW(FALSE,
884c2c66affSColin Finck dwFlags,
885c2c66affSColin Finck lpwModuleName,
886c2c66affSColin Finck phModule);
887c2c66affSColin Finck
888c2c66affSColin Finck return Ret;
889c2c66affSColin Finck }
890c2c66affSColin Finck
891c2c66affSColin Finck /*
892c2c66affSColin Finck * @implemented
893c2c66affSColin Finck */
894c2c66affSColin Finck BOOL
895c2c66affSColin Finck WINAPI
GetModuleHandleExA(IN DWORD dwFlags,IN LPCSTR lpModuleName OPTIONAL,OUT HMODULE * phModule)896c2c66affSColin Finck GetModuleHandleExA(IN DWORD dwFlags,
897c2c66affSColin Finck IN LPCSTR lpModuleName OPTIONAL,
898c2c66affSColin Finck OUT HMODULE* phModule)
899c2c66affSColin Finck {
900c2c66affSColin Finck PUNICODE_STRING lpModuleNameW;
901c2c66affSColin Finck DWORD dwValid;
902c2c66affSColin Finck BOOL Ret;
903c2c66affSColin Finck
904c2c66affSColin Finck /* Validate parameters */
905c2c66affSColin Finck dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, (LPCWSTR)lpModuleName, phModule);
906c2c66affSColin Finck
907c2c66affSColin Finck /* If result is invalid parameter - return failure */
908c2c66affSColin Finck if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE;
909c2c66affSColin Finck
910c2c66affSColin Finck /* If result is 2, there is no need to do anything - return success. */
911c2c66affSColin Finck if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
912c2c66affSColin Finck
913c2c66affSColin Finck /* Check if we don't need to convert the name */
914c2c66affSColin Finck if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
915c2c66affSColin Finck {
916c2c66affSColin Finck /* Call the extended version of the API without conversion */
917c2c66affSColin Finck Ret = BasepGetModuleHandleExW(FALSE,
918c2c66affSColin Finck dwFlags,
919c2c66affSColin Finck (LPCWSTR)lpModuleName,
920c2c66affSColin Finck phModule);
921c2c66affSColin Finck }
922c2c66affSColin Finck else
923c2c66affSColin Finck {
924c2c66affSColin Finck /* Convert module name to unicode */
925c2c66affSColin Finck lpModuleNameW = Basep8BitStringToStaticUnicodeString(lpModuleName);
926c2c66affSColin Finck
927c2c66affSColin Finck /* Return FALSE if conversion failed */
928c2c66affSColin Finck if (!lpModuleNameW) return FALSE;
929c2c66affSColin Finck
930c2c66affSColin Finck /* Call the extended version of the API */
931c2c66affSColin Finck Ret = BasepGetModuleHandleExW(FALSE,
932c2c66affSColin Finck dwFlags,
933c2c66affSColin Finck lpModuleNameW->Buffer,
934c2c66affSColin Finck phModule);
935c2c66affSColin Finck }
936c2c66affSColin Finck
937c2c66affSColin Finck /* Return result */
938c2c66affSColin Finck return Ret;
939c2c66affSColin Finck }
940c2c66affSColin Finck
941c2c66affSColin Finck
942c2c66affSColin Finck /*
943c2c66affSColin Finck * @implemented
944c2c66affSColin Finck */
945c2c66affSColin Finck DWORD
946c2c66affSColin Finck WINAPI
LoadModule(LPCSTR lpModuleName,LPVOID lpParameterBlock)947c2c66affSColin Finck LoadModule(LPCSTR lpModuleName,
948c2c66affSColin Finck LPVOID lpParameterBlock)
949c2c66affSColin Finck {
950c2c66affSColin Finck STARTUPINFOA StartupInfo;
951c2c66affSColin Finck PROCESS_INFORMATION ProcessInformation;
952c2c66affSColin Finck LOADPARMS32 *LoadParams;
953c2c66affSColin Finck char FileName[MAX_PATH];
954c2c66affSColin Finck LPSTR CommandLine;
955c2c66affSColin Finck DWORD Length, Error;
956c2c66affSColin Finck BOOL ProcessStatus;
957c2c66affSColin Finck ANSI_STRING AnsiStr;
958c2c66affSColin Finck UNICODE_STRING UnicStr;
959c2c66affSColin Finck RTL_PATH_TYPE PathType;
960c2c66affSColin Finck HANDLE Handle;
961c2c66affSColin Finck
962c2c66affSColin Finck LoadParams = (LOADPARMS32*)lpParameterBlock;
963c2c66affSColin Finck
964c2c66affSColin Finck /* Check load parameters */
965c2c66affSColin Finck if (LoadParams->dwReserved || LoadParams->wMagicValue != 2)
966c2c66affSColin Finck {
967c2c66affSColin Finck /* Fail with invalid param error */
968c2c66affSColin Finck BaseSetLastNTError(STATUS_INVALID_PARAMETER);
969c2c66affSColin Finck return 0;
970c2c66affSColin Finck }
971c2c66affSColin Finck
972c2c66affSColin Finck /* Search path */
973c2c66affSColin Finck Length = SearchPathA(NULL, lpModuleName, ".exe", MAX_PATH, FileName, NULL);
974c2c66affSColin Finck
975c2c66affSColin Finck /* Check if path was found */
976c2c66affSColin Finck if (Length && Length < MAX_PATH)
977c2c66affSColin Finck {
978c2c66affSColin Finck /* Build StartupInfo */
979c2c66affSColin Finck RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
980c2c66affSColin Finck
981c2c66affSColin Finck StartupInfo.cb = sizeof(STARTUPINFOA);
982c2c66affSColin Finck StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
983c2c66affSColin Finck StartupInfo.wShowWindow = LoadParams->wCmdShow;
984c2c66affSColin Finck
985c2c66affSColin Finck /* Allocate command line buffer */
986c2c66affSColin Finck CommandLine = RtlAllocateHeap(RtlGetProcessHeap(),
987c2c66affSColin Finck HEAP_ZERO_MEMORY,
988c2c66affSColin Finck (ULONG)LoadParams->lpCmdLine[0] + Length + 2);
989c2c66affSColin Finck
990c2c66affSColin Finck /* Put module name there, then a space, and then copy provided command line,
991c2c66affSColin Finck and null-terminate it */
992c2c66affSColin Finck RtlCopyMemory(CommandLine, FileName, Length);
993c2c66affSColin Finck CommandLine[Length] = ' ';
994c2c66affSColin Finck RtlCopyMemory(&CommandLine[Length + 1], &LoadParams->lpCmdLine[1], (ULONG)LoadParams->lpCmdLine[0]);
995c2c66affSColin Finck CommandLine[Length + 1 + (ULONG)LoadParams->lpCmdLine[0]] = 0;
996c2c66affSColin Finck
997c2c66affSColin Finck /* Create the process */
998c2c66affSColin Finck ProcessStatus = CreateProcessA(FileName,
999c2c66affSColin Finck CommandLine,
1000c2c66affSColin Finck NULL,
1001c2c66affSColin Finck NULL,
1002c2c66affSColin Finck FALSE,
1003c2c66affSColin Finck 0,
1004c2c66affSColin Finck LoadParams->lpEnvAddress,
1005c2c66affSColin Finck NULL,
1006c2c66affSColin Finck &StartupInfo,
1007c2c66affSColin Finck &ProcessInformation);
1008c2c66affSColin Finck
1009c2c66affSColin Finck /* Free the command line buffer */
1010c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, CommandLine);
1011c2c66affSColin Finck
1012c2c66affSColin Finck if (!ProcessStatus)
1013c2c66affSColin Finck {
1014c2c66affSColin Finck /* Creating process failed, return right error code */
1015c2c66affSColin Finck Error = GetLastError();
1016c2c66affSColin Finck switch(Error)
1017c2c66affSColin Finck {
1018c2c66affSColin Finck case ERROR_BAD_EXE_FORMAT:
1019c2c66affSColin Finck return ERROR_BAD_FORMAT;
1020c2c66affSColin Finck
1021c2c66affSColin Finck case ERROR_FILE_NOT_FOUND:
1022c2c66affSColin Finck case ERROR_PATH_NOT_FOUND:
1023c2c66affSColin Finck return Error;
1024c2c66affSColin Finck }
1025c2c66affSColin Finck
1026c2c66affSColin Finck /* Return 0 otherwise */
1027c2c66affSColin Finck return 0;
1028c2c66affSColin Finck }
1029c2c66affSColin Finck
1030c2c66affSColin Finck /* Wait up to 30 seconds for the process to become idle */
1031c2c66affSColin Finck if (UserWaitForInputIdleRoutine)
1032c2c66affSColin Finck {
1033c2c66affSColin Finck UserWaitForInputIdleRoutine(ProcessInformation.hProcess, 30000);
1034c2c66affSColin Finck }
1035c2c66affSColin Finck
1036c2c66affSColin Finck /* Close handles */
1037c2c66affSColin Finck NtClose(ProcessInformation.hThread);
1038c2c66affSColin Finck NtClose(ProcessInformation.hProcess);
1039c2c66affSColin Finck
1040c2c66affSColin Finck /* Return magic success value (33) */
1041c2c66affSColin Finck return 33;
1042c2c66affSColin Finck }
1043c2c66affSColin Finck
1044c2c66affSColin Finck /* The path was not found, create an ansi string from
1045c2c66affSColin Finck the module name and convert it to unicode */
1046c2c66affSColin Finck RtlInitAnsiString(&AnsiStr, lpModuleName);
1047c2c66affSColin Finck if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicStr,&AnsiStr,TRUE)))
1048c2c66affSColin Finck return ERROR_FILE_NOT_FOUND;
1049c2c66affSColin Finck
1050c2c66affSColin Finck /* Determine path type */
1051c2c66affSColin Finck PathType = RtlDetermineDosPathNameType_U(UnicStr.Buffer);
1052c2c66affSColin Finck
1053c2c66affSColin Finck /* Free the unicode module name */
1054c2c66affSColin Finck RtlFreeUnicodeString(&UnicStr);
1055c2c66affSColin Finck
1056c2c66affSColin Finck /* If it's a relative path, return file not found */
1057c2c66affSColin Finck if (PathType == RtlPathTypeRelative)
1058c2c66affSColin Finck return ERROR_FILE_NOT_FOUND;
1059c2c66affSColin Finck
1060c2c66affSColin Finck /* If not, try to open it */
1061c2c66affSColin Finck Handle = CreateFile(lpModuleName,
1062c2c66affSColin Finck GENERIC_READ,
1063c2c66affSColin Finck FILE_SHARE_READ | FILE_SHARE_WRITE,
1064c2c66affSColin Finck NULL,
1065c2c66affSColin Finck OPEN_EXISTING,
1066c2c66affSColin Finck FILE_ATTRIBUTE_NORMAL,
1067c2c66affSColin Finck NULL);
1068c2c66affSColin Finck
1069c2c66affSColin Finck if (Handle != INVALID_HANDLE_VALUE)
1070c2c66affSColin Finck {
1071c2c66affSColin Finck /* Opening file succeeded for some reason, close the handle and return file not found anyway */
1072c2c66affSColin Finck CloseHandle(Handle);
1073c2c66affSColin Finck return ERROR_FILE_NOT_FOUND;
1074c2c66affSColin Finck }
1075c2c66affSColin Finck
1076c2c66affSColin Finck /* Return last error which CreateFile set during an attempt to open it */
1077c2c66affSColin Finck return GetLastError();
1078c2c66affSColin Finck }
1079c2c66affSColin Finck
1080c2c66affSColin Finck /*
1081c2c66affSColin Finck * @unimplemented
1082c2c66affSColin Finck */
DelayLoadFailureHook(LPCSTR pszDllName,LPCSTR pszProcName)1083c2c66affSColin Finck FARPROC WINAPI DelayLoadFailureHook(LPCSTR pszDllName, LPCSTR pszProcName)
1084c2c66affSColin Finck {
1085c2c66affSColin Finck STUB;
1086c2c66affSColin Finck return NULL;
1087c2c66affSColin Finck }
1088c2c66affSColin Finck
1089c2c66affSColin Finck /*
1090c2c66affSColin Finck * @unimplemented
1091c2c66affSColin Finck */
UTRegister(HMODULE hModule,LPSTR lpsz16BITDLL,LPSTR lpszInitName,LPSTR lpszProcName,FARPROC * ppfn32Thunk,FARPROC pfnUT32CallBack,LPVOID lpBuff)1092c2c66affSColin Finck BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
1093c2c66affSColin Finck LPSTR lpszInitName, LPSTR lpszProcName,
1094c2c66affSColin Finck FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
1095c2c66affSColin Finck LPVOID lpBuff )
1096c2c66affSColin Finck {
1097c2c66affSColin Finck STUB;
1098c2c66affSColin Finck return 0;
1099c2c66affSColin Finck }
1100c2c66affSColin Finck
1101c2c66affSColin Finck /*
1102c2c66affSColin Finck * @unimplemented
1103c2c66affSColin Finck */
UTUnRegister(HMODULE hModule)1104c2c66affSColin Finck VOID WINAPI UTUnRegister( HMODULE hModule )
1105c2c66affSColin Finck {
1106c2c66affSColin Finck STUB;
1107c2c66affSColin Finck }
1108c2c66affSColin Finck
1109c2c66affSColin Finck /*
1110c2c66affSColin Finck * @unimplemented
1111c2c66affSColin Finck */
1112c2c66affSColin Finck BOOL
1113c2c66affSColin Finck WINAPI
BaseQueryModuleData(IN LPSTR ModuleName,IN LPSTR Unknown,IN PVOID Unknown2,IN PVOID Unknown3,IN PVOID Unknown4)1114c2c66affSColin Finck BaseQueryModuleData(IN LPSTR ModuleName,
1115c2c66affSColin Finck IN LPSTR Unknown,
1116c2c66affSColin Finck IN PVOID Unknown2,
1117c2c66affSColin Finck IN PVOID Unknown3,
1118c2c66affSColin Finck IN PVOID Unknown4)
1119c2c66affSColin Finck {
1120c2c66affSColin Finck DPRINT1("BaseQueryModuleData called: %s %s %p %p %p\n",
1121c2c66affSColin Finck ModuleName,
1122c2c66affSColin Finck Unknown,
1123c2c66affSColin Finck Unknown2,
1124c2c66affSColin Finck Unknown3,
1125c2c66affSColin Finck Unknown4);
1126c2c66affSColin Finck return FALSE;
1127c2c66affSColin Finck }
1128c2c66affSColin Finck
1129c2c66affSColin Finck /*
1130c2c66affSColin Finck * @implemented
1131c2c66affSColin Finck */
1132c2c66affSColin Finck NTSTATUS
1133c2c66affSColin Finck WINAPI
BaseProcessInitPostImport(VOID)1134c2c66affSColin Finck BaseProcessInitPostImport(VOID)
1135c2c66affSColin Finck {
11362bd33d58SPierre Schweitzer DPRINT("Post-init called\n");
11372bd33d58SPierre Schweitzer
1138c2c66affSColin Finck /* Check if this is a terminal server */
1139c2c66affSColin Finck if (SharedUserData->SuiteMask & VER_SUITE_TERMINAL)
1140c2c66affSColin Finck {
1141c2c66affSColin Finck /* Initialize TS pointers */
1142c2c66affSColin Finck return BasepInitializeTermsrvFpns();
1143c2c66affSColin Finck }
1144c2c66affSColin Finck
1145c2c66affSColin Finck /* FIXME: Initialize TS pointers */
1146c2c66affSColin Finck return STATUS_SUCCESS;
1147c2c66affSColin Finck }
1148c2c66affSColin Finck
1149c2c66affSColin Finck /* EOF */
1150