ReactOS 0.4.15-dev-7788-g1ad9096
ldrutils.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT User-Mode Library
4 * FILE: dll/ntdll/ldr/ldrutils.c
5 * PURPOSE: Internal Loader Utility Functions
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Aleksey Bragin (aleksey@reactos.org)
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include <ntdll.h>
13
14#define NDEBUG
15#include <debug.h>
16
17/* GLOBALS *******************************************************************/
18
20
28
29/* FUNCTIONS *****************************************************************/
30
35{
36 /* Sanity checks */
39
40 /* Assume failure */
41 StringOut->Length = 0;
42
43 /* Make sure it's not mis-aligned */
44 if (Length & 1)
45 {
46 /* Fail */
47 StringOut->Buffer = NULL;
48 StringOut->MaximumLength = 0;
50 }
51
52 /* Allocate the string*/
54 0,
55 Length + sizeof(WCHAR));
56 if (!StringOut->Buffer)
57 {
58 /* Fail */
59 StringOut->MaximumLength = 0;
60 return STATUS_NO_MEMORY;
61 }
62
63 /* Null-terminate it */
64 StringOut->Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
65
66 /* Check if this is a maximum-sized string */
68 {
69 /* It's not, so set the maximum length to be one char more */
70 StringOut->MaximumLength = (USHORT)Length + sizeof(UNICODE_NULL);
71 }
72 else
73 {
74 /* The length is already the maximum possible */
75 StringOut->MaximumLength = UNICODE_STRING_MAX_BYTES;
76 }
77
78 /* Return success */
79 return STATUS_SUCCESS;
80}
81
82VOID
85{
86 ASSERT(StringIn != NULL);
87
88 /* If Buffer is not NULL - free it */
89 if (StringIn->Buffer)
90 {
91 RtlFreeHeap(LdrpHeap, 0, StringIn->Buffer);
92 }
93
94 /* Zero it out */
95 RtlInitEmptyUnicodeString(StringIn, NULL, 0);
96}
97
104{
105 /* Call the entry */
106 return EntryPoint(BaseAddress, Reason, Context);
107}
108
109/* NOTE: This function is broken */
110VOID
111NTAPI
113 IN ULONG Flags,
114 OUT PUNICODE_STRING UpdateString)
115{
116 PIMAGE_BOUND_FORWARDER_REF NewImportForwarder;
119 PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
120 PIMAGE_THUNK_DATA FirstThunk;
122 PUNICODE_STRING ImportNameUnic, RedirectedImportName;
123 ANSI_STRING ImportNameAnsi;
124 LPSTR ImportName;
125 ULONG ImportSize;
127 ULONG i;
128 BOOLEAN RedirectedDll;
129 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
130
131 /* Set up the Act Ctx */
132 ActCtx.Size = sizeof(ActCtx);
135
136 /* Activate the ActCtx */
138 LdrEntry->EntryPointActivationContext);
139
140 /* Check the action we need to perform */
142 {
143 /* Make sure entry is not being loaded already */
144 if (LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS)
145 goto done;
146
147 LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
148 }
149 else if (Flags == LDRP_UPDATE_DEREFCOUNT)
150 {
151 /* Make sure the entry is not being unloaded already */
152 if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS)
153 goto done;
154
155 LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
156 }
157
158 /* Go through all bound DLLs and dereference them */
159 ImportNameUnic = &NtCurrentTeb()->StaticUnicodeString;
160
161 /* Try to get the new import entry */
162 FirstEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
163 TRUE,
165 &ImportSize);
166
167 if (FirstEntry)
168 {
169 /* Set entry flags if refing/derefing */
171 LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
172 else if (Flags == LDRP_UPDATE_DEREFCOUNT)
173 LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
174
175 BoundEntry = FirstEntry;
176 while (BoundEntry->OffsetModuleName)
177 {
178 /* Get pointer to the current import name */
179 ImportName = (LPSTR)FirstEntry + BoundEntry->OffsetModuleName;
180
181 RtlInitAnsiString(&ImportNameAnsi, ImportName);
182 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
183
184 if (NT_SUCCESS(Status))
185 {
186 RedirectedDll = FALSE;
187 RedirectedImportName = ImportNameUnic;
188
189 /* Check if the SxS Assemblies specify another file */
191 ImportNameUnic,
193 UpdateString,
194 NULL,
195 &RedirectedImportName,
196 NULL,
197 NULL,
198 NULL);
199
200 /* Check success */
201 if (NT_SUCCESS(Status))
202 {
203 /* Let Ldrp know */
204 if (ShowSnaps)
205 {
206 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
207 }
208
209 RedirectedDll = TRUE;
210 }
211
212 if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
213 {
215 RedirectedImportName,
216 TRUE,
217 RedirectedDll,
218 &Entry))
219 {
220 if (Entry->LoadCount != 0xFFFF)
221 {
222 /* Perform the required action */
223 switch (Flags)
224 {
226 Entry->LoadCount++;
227 break;
229 Entry->LoadCount--;
230 break;
231 case LDRP_UPDATE_PIN:
232 Entry->LoadCount = 0xFFFF;
233 break;
234 }
235
236 /* Show snaps */
237 if (ShowSnaps)
238 {
239 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
240 }
241 }
242
243 /* Recurse into this entry */
244 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
245 }
246 else if (RedirectedDll)
247 {
248 DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
249 }
250 }
251 else
252 {
253 /* Unrecoverable SxS failure */
254 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic);
255 }
256
257 }
258
259 /* Go through forwarders */
260 NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1);
261 for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++)
262 {
263 ImportName = (LPSTR)FirstEntry + NewImportForwarder->OffsetModuleName;
264
265 RtlInitAnsiString(&ImportNameAnsi, ImportName);
266 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
267 if (NT_SUCCESS(Status))
268 {
269 RedirectedDll = FALSE;
270 RedirectedImportName = ImportNameUnic;
271
272 /* Check if the SxS Assemblies specify another file */
274 ImportNameUnic,
276 UpdateString,
277 NULL,
278 &RedirectedImportName,
279 NULL,
280 NULL,
281 NULL);
282 /* Check success */
283 if (NT_SUCCESS(Status))
284 {
285 if (ShowSnaps)
286 {
287 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
288 }
289 /* Let Ldrp know */
290 RedirectedDll = TRUE;
291 }
292
293 if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
294 {
296 RedirectedImportName,
297 TRUE,
298 RedirectedDll,
299 &Entry))
300 {
301 if (Entry->LoadCount != 0xFFFF)
302 {
303 /* Perform the required action */
304 switch (Flags)
305 {
307 Entry->LoadCount++;
308 break;
310 Entry->LoadCount--;
311 break;
312 case LDRP_UPDATE_PIN:
313 Entry->LoadCount = 0xFFFF;
314 break;
315 }
316
317 /* Show snaps */
318 if (ShowSnaps)
319 {
320 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
321 }
322 }
323
324 /* Recurse into this entry */
325 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
326 }
327 else if (RedirectedDll)
328 {
329 DPRINT1("LDR: LdrpCheckForLoadedDll failed with status %x for redirected dll %wZ\n", Status, RedirectedImportName);
330 }
331 }
332 else
333 {
334 /* Unrecoverable SxS failure */
335 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic);
336 }
337
338 }
339
340 NewImportForwarder++;
341 }
342
343 BoundEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder;
344 }
345
346 /* We're done */
347 goto done;
348 }
349
350 /* Check oldstyle import descriptor */
351 ImportEntry = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(LdrEntry->DllBase,
352 TRUE,
354 &ImportSize);
355 if (ImportEntry)
356 {
357 /* There is old one, so go through its entries */
358 while (ImportEntry->Name && ImportEntry->FirstThunk)
359 {
360 FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->FirstThunk);
361
362 /* Skip this entry if needed */
363 if (!FirstThunk->u1.Function)
364 {
365 ImportEntry++;
366 continue;
367 }
368
369 ImportName = (PSZ)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name);
370
371 RtlInitAnsiString(&ImportNameAnsi, ImportName);
372 Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
373 if (NT_SUCCESS(Status))
374 {
375 RedirectedDll = FALSE;
376 RedirectedImportName = ImportNameUnic;
377
378 /* Check if the SxS Assemblies specify another file */
380 ImportNameUnic,
382 UpdateString,
383 NULL,
384 &RedirectedImportName,
385 NULL,
386 NULL,
387 NULL);
388 /* Check success */
389 if (NT_SUCCESS(Status))
390 {
391 if (ShowSnaps)
392 {
393 DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
394 }
395
396 /* Let Ldrp know */
397 RedirectedDll = TRUE;
398 }
399
400 if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
401 {
403 RedirectedImportName,
404 TRUE,
405 RedirectedDll,
406 &Entry))
407 {
408 if (Entry->LoadCount != 0xFFFF)
409 {
410 /* Perform the required action */
411 switch (Flags)
412 {
414 Entry->LoadCount++;
415 break;
417 Entry->LoadCount--;
418 break;
419 case LDRP_UPDATE_PIN:
420 Entry->LoadCount = 0xFFFF;
421 break;
422 }
423
424 /* Show snaps */
425 if (ShowSnaps)
426 {
427 DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
428 }
429 }
430
431 /* Recurse */
432 LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
433 }
434 else if (RedirectedDll)
435 {
436 DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
437 }
438
439 }
440 else
441 {
442 /* Unrecoverable SxS failure */
443 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed for dll %wZ\n", ImportNameUnic);
444 }
445
446 }
447
448 /* Go to the next entry */
449 ImportEntry++;
450 }
451 }
452
453done:
454 /* Release the context */
456}
457
458VOID
459NTAPI
461 IN ULONG Flags)
462{
464 UNICODE_STRING UpdateString;
465
466 /* Setup the string and call the extended API */
467 RtlInitEmptyUnicodeString(&UpdateString, Buffer, sizeof(Buffer));
468 LdrpUpdateLoadCount3(LdrEntry, Flags, &UpdateString);
469}
470
471VOID
472NTAPI
475{
476 PIMAGE_TLS_DIRECTORY TlsDirectory;
478 ULONG Size;
479
480 /* Get the TLS Directory */
481 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
482 TRUE,
484 &Size);
485
486 /* Protect against invalid pointers */
488 {
489 /* Make sure it's valid */
490 if (TlsDirectory)
491 {
492 /* Get the array */
493 Array = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks;
494 if (Array)
495 {
496 /* Display debug */
497 if (ShowSnaps)
498 {
499 DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n",
500 LdrEntry->DllBase, TlsDirectory, Array);
501 }
502
503 /* Loop the array */
504 while (*Array)
505 {
506 /* Get the TLS Entrypoint */
507 Callback = *Array++;
508
509 /* Display debug */
510 if (ShowSnaps)
511 {
512 DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n",
513 LdrEntry->DllBase, Callback);
514 }
515
516 /* Call it */
518 LdrEntry->DllBase,
519 Reason,
520 NULL);
521 }
522 }
523 }
524 }
526 {
527 DPRINT1("LDR: Exception 0x%x during Tls Callback(%u) for %wZ\n",
528 _SEH2_GetExceptionCode(), Reason, &LdrEntry->BaseDllName);
529 }
530 _SEH2_END;
531}
532
534NTAPI
536 IN HANDLE DllHandle)
537{
538 /* Not implemented */
539 return STATUS_SUCCESS;
540}
541
543NTAPI
545 IN HANDLE DllHandle,
546 IN PULONG DllCharacteristics OPTIONAL,
547 OUT PHANDLE SectionHandle)
548{
553 ULONG_PTR HardErrorParameters[1];
555 SECTION_IMAGE_INFORMATION SectionImageInfo;
556
557 /* Check if we don't already have a handle */
558 if (!DllHandle)
559 {
560 /* Create the object attributes */
562 FullName,
564 NULL,
565 NULL);
566
567 /* Open the DLL */
574
575 /* Check if we failed */
576 if (!NT_SUCCESS(Status))
577 {
578 /* Attempt to open for execute only */
585
586 /* Check if this failed too */
587 if (!NT_SUCCESS(Status))
588 {
589 /* Show debug message */
590 if (ShowSnaps)
591 {
592 DPRINT1("LDR: LdrpCreateDllSection - NtOpenFile failed; status = %x\n",
593 Status);
594 }
595
596 /* Make sure to return an expected status code */
598 {
599 /* Callers expect this instead */
601 }
602
603 /* Return an empty section handle */
604 *SectionHandle = NULL;
605 return Status;
606 }
607 }
608 }
609 else
610 {
611 /* Use the handle we already have */
612 FileHandle = DllHandle;
613 }
614
615 /* Create a section for the DLL */
616 Status = NtCreateSection(SectionHandle,
619 NULL,
620 NULL,
622 SEC_IMAGE,
623 FileHandle);
624
625 /* If mapping failed, raise a hard error */
626 if (!NT_SUCCESS(Status))
627 {
628 /* Forget the handle */
629 *SectionHandle = NULL;
630
631 /* Give the DLL name */
632 HardErrorParameters[0] = (ULONG_PTR)FullName;
633
634 /* Raise the error */
636 1,
637 1,
638 HardErrorParameters,
639 OptionOk,
640 &Response);
641
642 /* Increment the error count */
644
645 goto Exit;
646 }
647
648 /* Check for Safer restrictions */
649 if (!DllCharacteristics ||
650 !(*DllCharacteristics & IMAGE_FILE_SYSTEM))
651 {
652 /* Make sure it's executable */
653 Status = ZwQuerySection(*SectionHandle,
655 &SectionImageInfo,
657 NULL);
658 if (NT_SUCCESS(Status))
659 {
660 /* Bypass the check for .NET images */
661 if (!(SectionImageInfo.LoaderFlags & IMAGE_LOADER_FLAGS_COMPLUS))
662 {
663 /* Check with Safer */
666 {
667 /* Show debug message */
668 if (ShowSnaps)
669 {
670 DPRINT1("LDR: Loading of (%wZ) blocked by Winsafer\n",
671 &FullName);
672 }
673
674 /* Failure case, close section handle */
675 NtClose(*SectionHandle);
676 *SectionHandle = NULL;
677 }
678 }
679 }
680 else
681 {
682 /* Failure case, close section handle */
683 NtClose(*SectionHandle);
684 *SectionHandle = NULL;
685 }
686 }
687
688Exit:
689 /* Close the file handle, we don't need it */
691
692 /* Return status */
693 return Status;
694}
695
696/* NOTE: This function is totally b0rked and doesn't handle the parameters/functionality it should */
698NTAPI
700 PWSTR DllName,
702 PUNICODE_STRING BaseDllName)
703{
704 PWCHAR NameBuffer, p1, p2 = 0;
706 ULONG BufSize = 500;
707
708 /* Allocate space for full DLL name */
710 if (!FullDllName->Buffer) return FALSE;
711
713 DllName,
714 NULL,
715 BufSize,
716 FullDllName->Buffer,
717 &BaseDllName->Buffer);
718
719 if (!Length || Length > BufSize)
720 {
721 if (ShowSnaps)
722 {
723 DPRINT1("LDR: LdrResolveDllName - Unable to find ");
724 DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
725 }
726
728 return FALSE;
729 }
730
731 /* Construct full DLL name */
732 FullDllName->Length = Length;
733 FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
734
735 /* Allocate a new buffer */
736 NameBuffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
737 if (!NameBuffer)
738 {
739 RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
740 return FALSE;
741 }
742
743 /* Copy over the contents from the previous one and free it */
744 RtlCopyMemory(NameBuffer, FullDllName->Buffer, FullDllName->MaximumLength);
745 RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
746 FullDllName->Buffer = NameBuffer;
747
748 /* Find last backslash */
749 p1 = FullDllName->Buffer;
750 while (*p1)
751 {
752 if (*p1++ == L'\\')
753 {
754 p2 = p1;
755 }
756 }
757
758 /* If found, set p1 to it, otherwise p1 points to the beginning of DllName */
759 if (p2)
760 p1 = p2;
761 else
762 p1 = DllName;
763
764 p2 = p1;
765
766 /* Calculate remaining length */
767 while (*p1) ++p1;
768
769 /* Construct base DLL name */
770 BaseDllName->Length = (ULONG_PTR)p1 - (ULONG_PTR)p2;
771 BaseDllName->MaximumLength = BaseDllName->Length + sizeof(UNICODE_NULL);
772 BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BaseDllName->MaximumLength);
773
774 if (!BaseDllName->Buffer)
775 {
776 RtlFreeHeap(LdrpHeap, 0, NameBuffer);
777 return FALSE;
778 }
779
780 /* Copy base dll name to the new buffer */
781 RtlMoveMemory(BaseDllName->Buffer,
782 p2,
783 BaseDllName->Length);
784
785 /* Null-terminate the string */
786 BaseDllName->Buffer[BaseDllName->Length / sizeof(WCHAR)] = 0;
787
788 return TRUE;
789}
790
791PVOID
792NTAPI
794{
795 PIMAGE_NT_HEADERS NtHeaders;
796 ULONG_PTR EntryPoint = 0;
797
798 /* Get entry point offset from NT headers */
799 NtHeaders = RtlImageNtHeader(ImageBase);
800 if (NtHeaders)
801 {
802 /* Add image base */
803 EntryPoint = NtHeaders->OptionalHeader.AddressOfEntryPoint;
804 if (EntryPoint) EntryPoint += (ULONG_PTR)ImageBase;
805 }
806
807 /* Return calculated pointer (or zero in case of failure) */
808 return (PVOID)EntryPoint;
809}
810
811/* NOTE: This function is partially missing SxS */
813NTAPI
816 PUNICODE_STRING BaseDllName,
817 HANDLE *SectionHandle)
818{
820 HANDLE Section = NULL;
821 UNICODE_STRING DllNameUnic;
823 PCHAR p1;
824 PWCHAR p2;
825
826 /* Zero initialize provided parameters */
827 if (SectionHandle) *SectionHandle = 0;
828
829 if (FullDllName)
830 {
831 FullDllName->Length = 0;
832 FullDllName->MaximumLength = 0;
833 FullDllName->Buffer = NULL;
834 }
835
836 if (BaseDllName)
837 {
838 BaseDllName->Length = 0;
839 BaseDllName->MaximumLength = 0;
840 BaseDllName->Buffer = NULL;
841 }
842
843 /* If any of these three params are missing then fail */
844 if (!SectionHandle || !FullDllName || !BaseDllName)
846
847 /* Check the Loader Lock */
849
850 /* Upgrade DllName to a unicode string */
851 RtlInitUnicodeString(&DllNameUnic, DllName);
852
853 /* FIXME: Missing RtlComputePrivatizedDllName_U related functionality */
854
855 /* Get the activation context */
857 NULL,
858 ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
859 &DllNameUnic,
860 NULL);
861
862 /* Check if it's a SxS or not */
865 {
866 /* NOTE: Here it's beneficial to allocate one big unicode string
867 using LdrpAllocateUnicodeString instead of fragmenting the heap
868 with two allocations as it's done now. */
869
870 /* Set up BaseDllName */
871 BaseDllName->Length = DllNameUnic.Length;
872 BaseDllName->MaximumLength = DllNameUnic.MaximumLength;
873 BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap,
874 0,
875 DllNameUnic.MaximumLength);
876 if (!BaseDllName->Buffer)
877 {
879 goto Failure;
880 }
881
882 /* Copy the contents there */
883 RtlMoveMemory(BaseDllName->Buffer, DllNameUnic.Buffer, DllNameUnic.MaximumLength);
884
885 /* Set up FullDllName */
886 FullDllName->Length = LdrpKnownDllPath.Length + BaseDllName->Length + sizeof(WCHAR);
887 FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
888 FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
889 if (!FullDllName->Buffer)
890 {
892 goto Failure;
893 }
894
896
897 /* Put a slash there */
899 p2 = (PWCHAR)p1;
900 *p2++ = (WCHAR)'\\';
901 p1 = (PCHAR)p2;
902
903 /* Set up DllNameUnic for a relative path */
904 DllNameUnic.Buffer = (PWSTR)p1;
905 DllNameUnic.Length = BaseDllName->Length;
906 DllNameUnic.MaximumLength = DllNameUnic.Length + sizeof(UNICODE_NULL);
907
908 /* Copy the contents */
909 RtlMoveMemory(p1, BaseDllName->Buffer, BaseDllName->MaximumLength);
910
911 /* There are all names, init attributes and open the section */
913 &DllNameUnic,
916 NULL);
917
918 Status = NtOpenSection(&Section,
921 if (!NT_SUCCESS(Status))
922 {
923 /* Clear status in case it was just not found */
925 goto Failure;
926 }
927
928 /* Pass section handle to the caller and return success */
929 *SectionHandle = Section;
930 return STATUS_SUCCESS;
931 }
932
933Failure:
934 /* Close section object if it was opened */
935 if (Section) NtClose(Section);
936
937 /* Free string resources */
938 if (BaseDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, BaseDllName->Buffer);
939 if (FullDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
940
941 /* Return status */
942 return Status;
943}
944
946NTAPI
948 BOOLEAN Restore)
949{
950 PIMAGE_NT_HEADERS NtHeaders;
951 PIMAGE_SECTION_HEADER Section;
953 PVOID SectionBase;
954 SIZE_T SectionSize;
955 ULONG NewProtection, OldProtection, i;
956
957 /* Get the NT headers */
958 NtHeaders = RtlImageNtHeader(ViewBase);
959 if (!NtHeaders) return STATUS_INVALID_IMAGE_FORMAT;
960
961 /* Compute address of the first section header */
962 Section = IMAGE_FIRST_SECTION(NtHeaders);
963
964 /* Go through all sections */
965 for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
966 {
967 /* Check for read-only non-zero section */
968 if ((Section->SizeOfRawData) &&
970 {
971 /* Check if we are setting or restoring protection */
972 if (Restore)
973 {
974 /* Set it to either EXECUTE or READONLY */
976 {
977 NewProtection = PAGE_EXECUTE;
978 }
979 else
980 {
981 NewProtection = PAGE_READONLY;
982 }
983
984 /* Add PAGE_NOCACHE if needed */
986 {
987 NewProtection |= PAGE_NOCACHE;
988 }
989 }
990 else
991 {
992 /* Enable write access */
993 NewProtection = PAGE_READWRITE;
994 }
995
996 /* Get the section VA */
997 SectionBase = (PVOID)((ULONG_PTR)ViewBase + Section->VirtualAddress);
998 SectionSize = Section->SizeOfRawData;
999 if (SectionSize)
1000 {
1001 /* Set protection */
1003 &SectionBase,
1004 &SectionSize,
1005 NewProtection,
1006 &OldProtection);
1007 if (!NT_SUCCESS(Status)) return Status;
1008 }
1009 }
1010
1011 /* Move to the next section */
1012 Section++;
1013 }
1014
1015 /* Flush instruction cache if necessary */
1016 if (Restore) ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
1017 return STATUS_SUCCESS;
1018}
1019
1020/* NOTE: Not yet reviewed */
1022NTAPI
1024 IN PWSTR DllPath2,
1025 IN PWSTR DllName OPTIONAL,
1026 IN PULONG DllCharacteristics,
1028 IN BOOLEAN Redirect,
1029 OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
1030{
1031 PTEB Teb = NtCurrentTeb();
1032 PPEB Peb = NtCurrentPeb();
1033 PWCHAR p1 = DllName;
1034 WCHAR TempChar;
1035 BOOLEAN KnownDll = FALSE;
1036 UNICODE_STRING FullDllName, BaseDllName;
1037 HANDLE SectionHandle = NULL, DllHandle = 0;
1038 UNICODE_STRING NtPathDllName;
1039 ULONG_PTR HardErrorParameters[2];
1040 UNICODE_STRING HardErrorDllName, HardErrorDllPath;
1042 SIZE_T ViewSize = 0;
1043 PVOID ViewBase = NULL;
1044 PVOID ArbitraryUserPointer;
1045 PIMAGE_NT_HEADERS NtHeaders;
1046 NTSTATUS HardErrorStatus, Status;
1047 BOOLEAN OverlapDllFound = FALSE;
1048 ULONG_PTR ImageBase, ImageEnd;
1049 PLIST_ENTRY ListHead, NextEntry;
1050 PLDR_DATA_TABLE_ENTRY CandidateEntry, LdrEntry;
1051 ULONG_PTR CandidateBase, CandidateEnd;
1052 UNICODE_STRING OverlapDll;
1053 BOOLEAN RelocatableDll = TRUE;
1054 UNICODE_STRING IllegalDll;
1055 PVOID RelocData;
1056 ULONG RelocDataSize = 0;
1057
1058 // FIXME: AppCompat stuff is missing
1059
1060 if (ShowSnaps)
1061 {
1062 DPRINT1("LDR: LdrpMapDll: Image Name %ws, Search Path %ws\n",
1063 DllName,
1064 SearchPath ? SearchPath : L"");
1065 }
1066
1067 /* Check if we have a known dll directory */
1068 if (LdrpKnownDllObjectDirectory && Redirect == FALSE)
1069 {
1070 /* Check if the path is full */
1071 while (*p1)
1072 {
1073 TempChar = *p1++;
1074 if (TempChar == '\\' || TempChar == '/' )
1075 {
1076 /* Complete path, don't do Known Dll lookup */
1077 goto SkipCheck;
1078 }
1079 }
1080
1081 /* Try to find a Known DLL */
1082 Status = LdrpCheckForKnownDll(DllName,
1083 &FullDllName,
1084 &BaseDllName,
1085 &SectionHandle);
1086
1088 {
1089 /* Failure */
1092 "LDR: %s - call to LdrpCheckForKnownDll(\"%ws\", ...) failed with status %x\n",
1094 DllName,
1095 Status);
1096
1097 return Status;
1098 }
1099 }
1100
1101SkipCheck:
1102
1103 /* Check if the Known DLL Check returned something */
1104 if (!SectionHandle)
1105 {
1106 /* It didn't, so try to resolve the name now */
1108 DllName,
1109 &FullDllName,
1110 &BaseDllName))
1111 {
1112 /* Got a name, display a message */
1113 if (ShowSnaps)
1114 {
1115 DPRINT1("LDR: Loading (%s) %wZ\n",
1116 Static ? "STATIC" : "DYNAMIC",
1117 &FullDllName);
1118 }
1119
1120 /* Convert to NT Name */
1122 &NtPathDllName,
1123 NULL,
1124 NULL))
1125 {
1126 /* Path was invalid */
1128 }
1129
1130 /* Create a section for this dLL */
1131 Status = LdrpCreateDllSection(&NtPathDllName,
1132 DllHandle,
1133 DllCharacteristics,
1134 &SectionHandle);
1135
1136 /* Free the NT Name */
1137 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
1138
1139 /* If we failed */
1140 if (!NT_SUCCESS(Status))
1141 {
1142 /* Free the name strings and return */
1144 LdrpFreeUnicodeString(&BaseDllName);
1145 return Status;
1146 }
1147 }
1148 else
1149 {
1150 /* We couldn't resolve the name, is this a static load? */
1151 if (Static)
1152 {
1153 /*
1154 * This is BAD! Static loads are CRITICAL. Bugcheck!
1155 * Initialize the strings for the error
1156 */
1157 RtlInitUnicodeString(&HardErrorDllName, DllName);
1158 RtlInitUnicodeString(&HardErrorDllPath,
1159 DllPath2 ? DllPath2 : LdrpDefaultPath.Buffer);
1160
1161 /* Set them as error parameters */
1162 HardErrorParameters[0] = (ULONG_PTR)&HardErrorDllName;
1163 HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllPath;
1164
1165 /* Raise the hard error */
1167 2,
1168 0x00000003,
1169 HardErrorParameters,
1170 OptionOk,
1171 &Response);
1172
1173 /* We're back, where we initializing? */
1175 }
1176
1177 /* Return failure */
1178 return STATUS_DLL_NOT_FOUND;
1179 }
1180 }
1181 else
1182 {
1183 /* We have a section handle, so this is a known dll */
1184 KnownDll = TRUE;
1185 }
1186
1187 /* Stuff the image name in the TIB, for the debugger */
1188 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1190
1191 /* Map the DLL */
1192 ViewBase = NULL;
1193 ViewSize = 0;
1194 Status = NtMapViewOfSection(SectionHandle,
1196 &ViewBase,
1197 0,
1198 0,
1199 NULL,
1200 &ViewSize,
1201 ViewShare,
1202 0,
1204
1205 /* Restore */
1206 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1207
1208 /* Fail if we couldn't map it */
1209 if (!NT_SUCCESS(Status))
1210 {
1211 /* Close and return */
1212 NtClose(SectionHandle);
1213 return Status;
1214 }
1215
1216 /* Get the NT Header */
1217 if (!(NtHeaders = RtlImageNtHeader(ViewBase)))
1218 {
1219 /* Invalid image, unmap, close handle and fail */
1221 NtClose(SectionHandle);
1223 }
1224
1225 // FIXME: .NET support is missing
1226
1227 /* Allocate an entry */
1228 if (!(LdrEntry = LdrpAllocateDataTableEntry(ViewBase)))
1229 {
1230 /* Invalid image, unmap, close handle and fail */
1232 NtClose(SectionHandle);
1233 return STATUS_NO_MEMORY;
1234 }
1235
1236 /* Setup the entry */
1237 LdrEntry->Flags = Static ? LDRP_STATIC_LINK : 0;
1238 if (Redirect) LdrEntry->Flags |= LDRP_REDIRECTED;
1239 LdrEntry->LoadCount = 0;
1240 LdrEntry->FullDllName = FullDllName;
1241 LdrEntry->BaseDllName = BaseDllName;
1242 LdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrEntry->DllBase);
1243
1244 /* Show debug message */
1245 if (ShowSnaps)
1246 {
1247 DPRINT1("LDR: LdrpMapDll: Full Name %wZ, Base Name %wZ\n",
1248 &FullDllName,
1249 &BaseDllName);
1250 }
1251
1252 /* Insert this entry */
1254
1255 // LdrpSendDllNotifications(LdrEntry, TRUE, Status == STATUS_IMAGE_NOT_AT_BASE)
1256
1257 /* Check for invalid CPU Image */
1259 {
1260 /* Load our header */
1262
1263 /* Assume defaults if we don't have to run the Hard Error path */
1264 HardErrorStatus = STATUS_SUCCESS;
1266
1267 /* Are we an NT 3.0 image? [Do these still exist? LOL -- IAI] */
1269 {
1270 /* Reset the entrypoint, save our Dll Name */
1271 LdrEntry->EntryPoint = 0;
1272 HardErrorParameters[0] = (ULONG_PTR)&FullDllName;
1273
1274 /* Raise the error */
1276 1,
1277 1,
1278 HardErrorParameters,
1280 &Response);
1281 }
1282
1283 /* Check if the user pressed cancel */
1284 if (NT_SUCCESS(HardErrorStatus) && Response == ResponseCancel)
1285 {
1286 /* Remove the DLL from the lists */
1289 RemoveEntryList(&LdrEntry->HashLinks);
1290
1291 /* Remove the LDR Entry */
1292 RtlFreeHeap(LdrpHeap, 0, LdrEntry );
1293
1294 /* Unmap and close section */
1296 NtClose(SectionHandle);
1297
1298 /* Did we do a hard error? */
1300 {
1301 /* Yup, so increase fatal error count if we are initializing */
1303 }
1304
1305 /* Return failure */
1307 }
1308 }
1309 else
1310 {
1311 /* The image was valid. Is it a DLL? */
1312 if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
1313 {
1314 /* Set the DLL Flag */
1315 LdrEntry->Flags |= LDRP_IMAGE_DLL;
1316 }
1317
1318 /* If we're not a DLL, clear the entrypoint */
1319 if (!(LdrEntry->Flags & LDRP_IMAGE_DLL))
1320 {
1321 LdrEntry->EntryPoint = 0;
1322 }
1323 }
1324
1325 /* Return it for the caller */
1326 *DataTableEntry = LdrEntry;
1327
1328 /* Check if we loaded somewhere else */
1330 {
1331 /* Write the flag */
1332 LdrEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
1333
1334 /* Find our region */
1335 ImageBase = (ULONG_PTR)NtHeaders->OptionalHeader.ImageBase;
1336 ImageEnd = ImageBase + ViewSize;
1337
1338 DPRINT("LDR: LdrpMapDll Relocating Image Name %ws (%p-%p -> %p)\n", DllName, (PVOID)ImageBase, (PVOID)ImageEnd, ViewBase);
1339
1340 /* Scan all the modules */
1341 ListHead = &Peb->Ldr->InLoadOrderModuleList;
1342 NextEntry = ListHead->Flink;
1343 while (NextEntry != ListHead)
1344 {
1345 /* Get the entry */
1346 CandidateEntry = CONTAINING_RECORD(NextEntry,
1348 InLoadOrderLinks);
1349 NextEntry = NextEntry->Flink;
1350
1351 /* Get the entry's bounds */
1352 CandidateBase = (ULONG_PTR)CandidateEntry->DllBase;
1353 CandidateEnd = CandidateBase + CandidateEntry->SizeOfImage;
1354
1355 /* Make sure this entry isn't unloading */
1356 if (!CandidateEntry->InMemoryOrderLinks.Flink) continue;
1357
1358 /* Check if our regions are colliding */
1359 if ((ImageBase >= CandidateBase && ImageBase <= CandidateEnd) ||
1360 (ImageEnd >= CandidateBase && ImageEnd <= CandidateEnd) ||
1361 (CandidateBase >= ImageBase && CandidateBase <= ImageEnd))
1362 {
1363 /* Found who is overlapping */
1364 OverlapDllFound = TRUE;
1365 OverlapDll = CandidateEntry->FullDllName;
1366 break;
1367 }
1368 }
1369
1370 /* Check if we found the DLL overlapping with us */
1371 if (!OverlapDllFound)
1372 {
1373 /* It's not another DLL, it's memory already here */
1374 RtlInitUnicodeString(&OverlapDll, L"Dynamically Allocated Memory");
1375 }
1376
1377 DPRINT("Overlapping DLL: %wZ\n", &OverlapDll);
1378
1379 /* Are we dealing with a DLL? */
1380 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
1381 {
1382 /* Check if relocs were stripped */
1384 {
1385 /* Get the relocation data */
1386 RelocData = RtlImageDirectoryEntryToData(ViewBase,
1387 TRUE,
1389 &RelocDataSize);
1390
1391 /* Does the DLL not have any? */
1392 if (!RelocData && !RelocDataSize)
1393 {
1394 /* We'll allow this and simply continue */
1395 goto NoRelocNeeded;
1396 }
1397 }
1398
1399 /* See if this is an Illegal DLL - IE: user32 and kernel32 */
1400 RtlInitUnicodeString(&IllegalDll,L"user32.dll");
1401 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1402 {
1403 /* Can't relocate user32 */
1404 RelocatableDll = FALSE;
1405 }
1406 else
1407 {
1408 RtlInitUnicodeString(&IllegalDll, L"kernel32.dll");
1409 if (RtlEqualUnicodeString(&BaseDllName, &IllegalDll, TRUE))
1410 {
1411 /* Can't relocate kernel32 */
1412 RelocatableDll = FALSE;
1413 }
1414 }
1415
1416 /* Known DLLs are not allowed to be relocated */
1417 if (KnownDll && !RelocatableDll)
1418 {
1419 /* Setup for hard error */
1420 HardErrorParameters[0] = (ULONG_PTR)&IllegalDll;
1421 HardErrorParameters[1] = (ULONG_PTR)&OverlapDll;
1422
1423 DPRINT1("Illegal DLL relocation! %wZ overlaps %wZ\n", &OverlapDll, &IllegalDll);
1424
1425 /* Raise the error */
1427 2,
1428 3,
1429 HardErrorParameters,
1430 OptionOk,
1431 &Response);
1432
1433 /* If initializing, increase the error count */
1435
1436 /* Don't do relocation */
1438 goto FailRelocate;
1439 }
1440
1441 /* Change the protection to prepare for relocation */
1442 Status = LdrpSetProtection(ViewBase, FALSE);
1443
1444 /* Make sure we changed the protection */
1445 if (NT_SUCCESS(Status))
1446 {
1447 /* Do the relocation */
1450
1451 if (NT_SUCCESS(Status))
1452 {
1453 /* Stuff the image name in the TIB, for the debugger */
1454 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1456#if 0
1457 /* Map the DLL */
1458 Status = NtMapViewOfSection(SectionHandle,
1460 &ViewBase,
1461 0,
1462 0,
1463 NULL,
1464 &ViewSize,
1465 ViewShare,
1466 0,
1468#endif
1469 /* Restore */
1470 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1471
1472 /* Return the protection */
1473 Status = LdrpSetProtection(ViewBase, TRUE);
1474 }
1475 }
1476FailRelocate:
1477 /* Handle any kind of failure */
1478 if (!NT_SUCCESS(Status))
1479 {
1480 /* Remove it from the lists */
1483 RemoveEntryList(&LdrEntry->HashLinks);
1484
1485 /* Unmap it, clear the entry */
1487 LdrEntry = NULL;
1488 }
1489
1490 /* Show debug message */
1491 if (ShowSnaps)
1492 {
1493 DPRINT1("LDR: Fixups %successfully re-applied @ %p\n",
1494 NT_SUCCESS(Status) ? "s" : "uns", ViewBase);
1495 }
1496 }
1497 else
1498 {
1499NoRelocNeeded:
1500 /* Not a DLL, or no relocation needed */
1502
1503 /* Stuff the image name in the TIB, for the debugger */
1504 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
1506#if 0
1507 /* Map the DLL */
1508 Status = NtMapViewOfSection(SectionHandle,
1510 &ViewBase,
1511 0,
1512 0,
1513 NULL,
1514 &ViewSize,
1515 ViewShare,
1516 0,
1518#endif
1519 /* Restore */
1520 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
1521
1522 /* Show debug message */
1523 if (ShowSnaps)
1524 {
1525 DPRINT1("LDR: Fixups won't be re-applied to non-Dll @ %p\n", ViewBase);
1526 }
1527 }
1528 }
1529
1530 // FIXME: LdrpCheckCorImage() is missing
1531
1532 /* Check if this is an SMP Machine and a DLL */
1533 if ((LdrpNumberOfProcessors > 1) &&
1534 (LdrEntry && (LdrEntry->Flags & LDRP_IMAGE_DLL)))
1535 {
1536 /* Validate the image for MP */
1537 LdrpValidateImageForMp(LdrEntry);
1538 }
1539
1540 // FIXME: LdrpCorUnloadImage() is missing
1541
1542 /* Close section and return status */
1543 NtClose(SectionHandle);
1544 return Status;
1545}
1546
1548NTAPI
1550{
1551 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
1552 PIMAGE_NT_HEADERS NtHeader;
1553
1554 /* Make sure the header is valid */
1555 NtHeader = RtlImageNtHeader(BaseAddress);
1556 DPRINT("LdrpAllocateDataTableEntry(%p), NtHeader %p\n", BaseAddress, NtHeader);
1557
1558 if (NtHeader)
1559 {
1560 /* Allocate an entry */
1561 LdrEntry = RtlAllocateHeap(LdrpHeap,
1563 sizeof(LDR_DATA_TABLE_ENTRY));
1564
1565 /* Make sure we got one */
1566 if (LdrEntry)
1567 {
1568 /* Set it up */
1569 LdrEntry->DllBase = BaseAddress;
1570 LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
1571 LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
1572 LdrEntry->PatchInformation = NULL;
1573 }
1574 }
1575
1576 /* Return the entry */
1577 return LdrEntry;
1578}
1579
1580VOID
1581NTAPI
1583{
1584 PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
1585 ULONG i;
1586
1587 /* Insert into hash table */
1588 i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]);
1589 InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks);
1590
1591 /* Insert into other lists */
1592 InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
1593 InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderLinks);
1594}
1595
1596VOID
1597NTAPI
1599{
1600 /* Sanity check */
1601 ASSERT(Entry != NULL);
1602
1603 /* Release the activation context if it exists and wasn't already released */
1604 if ((Entry->EntryPointActivationContext) &&
1605 (Entry->EntryPointActivationContext != INVALID_HANDLE_VALUE))
1606 {
1607 /* Mark it as invalid */
1608 RtlReleaseActivationContext(Entry->EntryPointActivationContext);
1609 Entry->EntryPointActivationContext = INVALID_HANDLE_VALUE;
1610 }
1611
1612 /* Release the full dll name string */
1613 if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
1614
1615 /* Finally free the entry's memory */
1617}
1618
1619BOOLEAN
1620NTAPI
1622 OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
1623{
1624 PLDR_DATA_TABLE_ENTRY Current;
1625 PLIST_ENTRY ListHead, Next;
1626
1627 /* Check the cache first */
1630 {
1631 /* We got lucky, return the cached entry */
1632 *LdrEntry = LdrpLoadedDllHandleCache;
1633 return TRUE;
1634 }
1635
1636 /* Time for a lookup */
1637 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1638 Next = ListHead->Flink;
1639 while (Next != ListHead)
1640 {
1641 /* Get the current entry */
1642 Current = CONTAINING_RECORD(Next,
1644 InLoadOrderLinks);
1645
1646 /* Make sure it's not unloading and check for a match */
1647 if ((Current->InMemoryOrderLinks.Flink) && (Base == Current->DllBase))
1648 {
1649 /* Save in cache */
1650 LdrpLoadedDllHandleCache = Current;
1651
1652 /* Return it */
1653 *LdrEntry = Current;
1654 return TRUE;
1655 }
1656
1657 /* Move to the next one */
1658 Next = Next->Flink;
1659 }
1660
1661 /* Nothing found */
1662 return FALSE;
1663}
1664
1666NTAPI
1668 IN PUNICODE_STRING PathName,
1669 IN PUNICODE_STRING FullPathName,
1670 IN PUNICODE_STRING *ExpandedName)
1671{
1673// RTL_PATH_TYPE PathType;
1674// BOOLEAN InvalidName;
1675 ULONG Length;
1676
1677 /* Display debug output if snaps are on */
1678 if (ShowSnaps)
1679 {
1682 "LDR: %s - Expanding full name of %wZ\n",
1684 OriginalName);
1685 }
1686
1687 /* FIXME: Lock the PEB */
1688 //RtlEnterCriticalSection(&FastPebLock);
1689#if 0
1690 /* Get the path name */
1691 Length = RtlGetFullPathName_Ustr(OriginalName,
1692 PathName->Length,
1693 PathName->Buffer,
1694 NULL,
1695 &InvalidName,
1696 &PathType);
1697#else
1698 Length = 0;
1699#endif
1701 {
1702 /* Fail */
1704 goto Quickie;
1705 }
1706
1707 /* Check if the length hasn't changed */
1708 if (Length <= PathName->Length)
1709 {
1710 /* Return the same thing */
1711 *ExpandedName = PathName;
1712 PathName->Length = (USHORT)Length;
1713 goto Quickie;
1714 }
1715
1716 /* Sanity check */
1717 ASSERT(Length >= sizeof(WCHAR));
1718
1719 /* Allocate a string */
1720 Status = LdrpAllocateUnicodeString(FullPathName, Length - sizeof(WCHAR));
1721 if (!NT_SUCCESS(Status)) goto Quickie;
1722
1723 /* Now get the full path again */
1724#if 0
1725 Length = RtlGetFullPathName_Ustr(OriginalName,
1726 FullPathName->Length,
1727 FullPathName->Buffer,
1728 NULL,
1729 &InvalidName,
1730 &PathType);
1731#else
1732 Length = 0;
1733#endif
1734 if (!(Length) || (Length > FullPathName->Length))
1735 {
1736 /* Fail */
1737 LdrpFreeUnicodeString(FullPathName);
1739 }
1740 else
1741 {
1742 /* Return the expanded name */
1743 *ExpandedName = FullPathName;
1744 FullPathName->Length = (USHORT)Length;
1745 }
1746
1747Quickie:
1748 /* FIXME: Unlock the PEB */
1749 //RtlLeaveCriticalSection(&FastPebLock);
1750
1751 /* Display debug output if snaps are on */
1752 if (ShowSnaps)
1753 {
1754 /* Check which output to use -- failure or success */
1755 if (NT_SUCCESS(Status))
1756 {
1759 "LDR: %s - Expanded to %wZ\n",
1761 *ExpandedName);
1762 }
1763 else
1764 {
1767 "LDR: %s - Failed to expand %wZ; 0x%08x\n",
1769 OriginalName,
1770 Status);
1771 }
1772 }
1773
1774 /* If we failed, return NULL */
1775 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1776
1777 /* Return status */
1778 return Status;
1779}
1780
1782NTAPI
1784 IN PWCHAR DllName,
1785 IN PUNICODE_STRING PathName,
1786 IN PUNICODE_STRING FullPathName,
1787 IN PUNICODE_STRING *ExpandedName)
1788{
1790 PWCHAR ActualSearchPath = *SearchPath;
1791 UNICODE_STRING TestName;
1793 PWCHAR Buffer, BufEnd = NULL;
1794 ULONG Length = 0;
1795 WCHAR p;
1796 //PWCHAR pp;
1797
1798 /* Check if we don't have a search path */
1799 if (!ActualSearchPath) *SearchPath = LdrpDefaultPath.Buffer;
1800
1801 /* Display debug output if snaps are on */
1802 if (ShowSnaps)
1803 {
1806 "LDR: %s - Looking for %ws in %ws\n",
1808 DllName,
1809 *SearchPath);
1810 }
1811
1812 /* Check if we're dealing with a relative path */
1814 {
1815 /* Good, we're not. Create the name string */
1816 Status = RtlInitUnicodeStringEx(&TestName, DllName);
1817 if (!NT_SUCCESS(Status)) goto Quickie;
1818
1819 /* Make sure it exists */
1820 #if 0
1821 if (!RtlDoesFileExists_UstrEx(&TestName, TRUE))
1822 {
1823 /* It doesn't, fail */
1825 goto Quickie;
1826 }
1827 #endif
1828
1829 /* Resolve the full name */
1830 Status = LdrpResolveFullName(&TestName,
1831 PathName,
1832 FullPathName,
1833 ExpandedName);
1834 goto Quickie;
1835 }
1836
1837 /* FIXME: Handle relative case semicolon-lookup here */
1838
1839 /* Calculate length */
1840 Length += (ULONG)wcslen(DllName) + 1;
1842 {
1843 /* Too long, fail */
1845 goto Quickie;
1846 }
1847
1848 /* Allocate buffer */
1849 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
1850 if (!Buffer)
1851 {
1852 /* Fail */
1854 goto Quickie;
1855 }
1856
1857 /* FIXME: Setup TestName here */
1859 BufEnd = Buffer;
1860
1861 /* Start loop */
1862 do
1863 {
1864 /* Get character */
1865 p = *ActualSearchPath;
1866 if (!(p) || (p == ';'))
1867 {
1868 /* FIXME: We don't have a character, or is a semicolon.*/
1869
1870 /* Display debug output if snaps are on */
1871 if (ShowSnaps)
1872 {
1875 "LDR: %s - Looking for %ws\n",
1877 Buffer);
1878 }
1879
1880 /* Sanity check */
1881 TestName.Length = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR);
1882#if 0
1883 ASSERT(TestName.Length < TestName.MaximumLength);
1884#endif
1885
1886 /* Check if the file exists */
1887 #if 0
1888 if (RtlDoesFileExists_UstrEx(&TestName, FALSE))
1889 #endif
1890 {
1891 /* It does. Reallocate the buffer */
1892 TestName.MaximumLength = (USHORT)ALIGN_DOWN((BufEnd - Buffer), WCHAR) + sizeof(WCHAR);
1893 TestName.Buffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1894 0,
1895 Buffer,
1896 TestName.MaximumLength);
1897 if (!TestName.Buffer)
1898 {
1899 /* Keep the old one */
1900 TestName.Buffer = Buffer;
1901 }
1902 else
1903 {
1904 /* Update buffer */
1905 Buffer = TestName.Buffer;
1906 }
1907
1908 /* Make sure we have a buffer at least */
1909 ASSERT(TestName.Buffer);
1910
1911 /* Resolve the name */
1912 *SearchPath = ActualSearchPath++;
1913 Status = LdrpResolveFullName(&TestName,
1914 PathName,
1915 FullPathName,
1916 ExpandedName);
1917 break;
1918 }
1919
1920 /* Update buffer end */
1921 BufEnd = Buffer;
1922
1923 /* Update string position */
1924 //pp = ActualSearchPath++;
1925 }
1926 else
1927 {
1928 /* Otherwise, write the character */
1929 *BufEnd = p;
1930 BufEnd++;
1931 }
1932
1933 /* Check if the string is empty, meaning we're done */
1934 if (!(*ActualSearchPath)) TryAgain = TRUE;
1935
1936 /* Advance in the string */
1937 ActualSearchPath++;
1938 } while (!TryAgain);
1939
1940 /* Check if we had a buffer and free it */
1941 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1942
1943Quickie:
1944 /* Check if we got here through failure */
1945 if (!NT_SUCCESS(Status)) *ExpandedName = NULL;
1946
1947 /* Display debug output if snaps are on */
1948 if (ShowSnaps)
1949 {
1950 /* Check which output to use -- failure or success */
1951 if (NT_SUCCESS(Status))
1952 {
1955 "LDR: %s - Returning %wZ\n",
1957 *ExpandedName);
1958 }
1959 else
1960 {
1963 "LDR: %s - Unable to locate %ws in %ws: 0x%08x\n",
1965 DllName,
1966 ActualSearchPath,
1967 Status);
1968 }
1969 }
1970
1971 /* Return status */
1972 return Status;
1973}
1974
1975
1976/* NOTE: This function is b0rked and in the process of being slowly unf*cked */
1977BOOLEAN
1978NTAPI
1980 IN PUNICODE_STRING DllName,
1981 IN BOOLEAN Flag,
1982 IN BOOLEAN RedirectedDll,
1983 OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
1984{
1985 ULONG HashIndex;
1986 PLIST_ENTRY ListHead, ListEntry;
1987 PLDR_DATA_TABLE_ENTRY CurEntry;
1988 BOOLEAN FullPath = FALSE;
1989 PWCHAR wc;
1990 WCHAR NameBuf[266];
1991 UNICODE_STRING FullDllName, NtPathName;
1992 ULONG Length;
1995 HANDLE FileHandle, SectionHandle;
1997 PVOID ViewBase = NULL;
1998 SIZE_T ViewSize = 0;
1999 PIMAGE_NT_HEADERS NtHeader, NtHeader2;
2000 DPRINT("LdrpCheckForLoadedDll('%S' '%wZ' %u %u %p)\n", DllPath ? ((ULONG_PTR)DllPath == 1 ? L"" : DllPath) : L"", DllName, Flag, RedirectedDll, LdrEntry);
2001
2002 /* Check if a dll name was provided */
2003 if (!(DllName->Buffer) || !(DllName->Buffer[0])) return FALSE;
2004
2005 /* FIXME: Warning, "Flag" is used as magic instead of "Static" */
2006 /* FIXME: Warning, code does not support redirection at all */
2007
2008 /* Look in the hash table if flag was set */
2009lookinhash:
2010 if (Flag /* the second check is a hack */ && !RedirectedDll)
2011 {
2012 /* FIXME: if we get redirected dll it means that we also get a full path so we need to find its filename for the hash lookup */
2013
2014 /* Get hash index */
2015 HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
2016
2017 /* Traverse that list */
2018 ListHead = &LdrpHashTable[HashIndex];
2019 ListEntry = ListHead->Flink;
2020 while (ListEntry != ListHead)
2021 {
2022 /* Get the current entry */
2023 CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
2024
2025 /* Check base name of that module */
2026 if (RtlEqualUnicodeString(DllName, &CurEntry->BaseDllName, TRUE))
2027 {
2028 /* It matches, return it */
2029 *LdrEntry = CurEntry;
2030 return TRUE;
2031 }
2032
2033 /* Advance to the next entry */
2034 ListEntry = ListEntry->Flink;
2035 }
2036
2037 /* Module was not found, return failure */
2038 return FALSE;
2039 }
2040
2041 /* Check if this is a redirected DLL */
2042 if (RedirectedDll)
2043 {
2044 /* Redirected dlls already have a full path */
2045 FullPath = TRUE;
2046 FullDllName = *DllName;
2047 }
2048 else
2049 {
2050 /* Check if there is a full path in this DLL */
2051 wc = DllName->Buffer;
2052 while (*wc)
2053 {
2054 /* Check for a slash in the current position*/
2055 if ((*wc == L'\\') || (*wc == L'/'))
2056 {
2057 /* Found the slash, so dll name contains path */
2058 FullPath = TRUE;
2059
2060 /* Setup full dll name string */
2061 FullDllName.Buffer = NameBuf;
2062
2063 /* FIXME: This is from the Windows 2000 loader, not XP/2003, we should call LdrpSearchPath */
2065 DllName->Buffer,
2066 NULL,
2067 sizeof(NameBuf) - sizeof(UNICODE_NULL),
2068 FullDllName.Buffer,
2069 NULL);
2070
2071 /* Check if that was successful */
2072 if (!(Length) || (Length > (sizeof(NameBuf) - sizeof(UNICODE_NULL))))
2073 {
2074 if (ShowSnaps)
2075 {
2076 DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
2077 &DllName, Length);
2078 }
2079 }
2080
2081 /* Full dll name is found */
2082 FullDllName.Length = Length;
2083 FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
2084 break;
2085 }
2086
2087 wc++;
2088 }
2089 }
2090
2091 /* Go check the hash table */
2092 if (!FullPath)
2093 {
2094 Flag = TRUE;
2095 goto lookinhash;
2096 }
2097
2098 /* FIXME: Warning, activation context missing */
2099 DPRINT("Warning, activation context missing\n");
2100
2101 /* NOTE: From here on down, everything looks good */
2102
2103 /* Loop the module list */
2104 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2105 ListEntry = ListHead->Flink;
2106 while (ListEntry != ListHead)
2107 {
2108 /* Get the current entry and advance to the next one */
2109 CurEntry = CONTAINING_RECORD(ListEntry,
2111 InLoadOrderLinks);
2112 ListEntry = ListEntry->Flink;
2113
2114 /* Check if it's being unloaded */
2115 if (!CurEntry->InMemoryOrderLinks.Flink) continue;
2116
2117 /* Check if name matches */
2119 &CurEntry->FullDllName,
2120 TRUE))
2121 {
2122 /* Found it */
2123 *LdrEntry = CurEntry;
2124 return TRUE;
2125 }
2126 }
2127
2128 /* Convert given path to NT path */
2130 &NtPathName,
2131 NULL,
2132 NULL))
2133 {
2134 /* Fail if conversion failed */
2135 return FALSE;
2136 }
2137
2138 /* Initialize object attributes and open it */
2140 &NtPathName,
2142 NULL,
2143 NULL);
2147 &Iosb,
2150
2151 /* Free NT path name */
2152 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
2153
2154 /* If opening the file failed - return failure */
2155 if (!NT_SUCCESS(Status)) return FALSE;
2156
2157 /* Create a section for this file */
2158 Status = NtCreateSection(&SectionHandle,
2162 NULL,
2163 NULL,
2165 SEC_COMMIT,
2166 FileHandle);
2167
2168 /* Close file handle */
2170
2171 /* If creating section failed - return failure */
2172 if (!NT_SUCCESS(Status)) return FALSE;
2173
2174 /* Map view of this section */
2175 Status = ZwMapViewOfSection(SectionHandle,
2177 &ViewBase,
2178 0,
2179 0,
2180 NULL,
2181 &ViewSize,
2182 ViewShare,
2183 0,
2184 PAGE_EXECUTE);
2185
2186 /* Close section handle */
2187 NtClose(SectionHandle);
2188
2189 /* If section mapping failed - return failure */
2190 if (!NT_SUCCESS(Status)) return FALSE;
2191
2192 /* Get pointer to the NT header of this section */
2193 Status = RtlImageNtHeaderEx(0, ViewBase, ViewSize, &NtHeader);
2194 if (!(NT_SUCCESS(Status)) || !(NtHeader))
2195 {
2196 /* Unmap the section and fail */
2198 return FALSE;
2199 }
2200
2201 /* Go through the list of modules again */
2202 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2203 ListEntry = ListHead->Flink;
2204 while (ListEntry != ListHead)
2205 {
2206 /* Get the current entry and advance to the next one */
2207 CurEntry = CONTAINING_RECORD(ListEntry,
2209 InLoadOrderLinks);
2210 ListEntry = ListEntry->Flink;
2211
2212 /* Check if it's in the process of being unloaded */
2213 if (!CurEntry->InMemoryOrderLinks.Flink) continue;
2214
2215 /* The header is untrusted, use SEH */
2216 _SEH2_TRY
2217 {
2218 /* Check if timedate stamp and sizes match */
2219 if ((CurEntry->TimeDateStamp == NtHeader->FileHeader.TimeDateStamp) &&
2220 (CurEntry->SizeOfImage == NtHeader->OptionalHeader.SizeOfImage))
2221 {
2222 /* Time, date and size match. Let's compare their headers */
2223 NtHeader2 = RtlImageNtHeader(CurEntry->DllBase);
2224 if (RtlCompareMemory(NtHeader2, NtHeader, sizeof(IMAGE_NT_HEADERS)))
2225 {
2226 /* Headers match too! Finally ask the kernel to compare mapped files */
2227 Status = ZwAreMappedFilesTheSame(CurEntry->DllBase, ViewBase);
2228 if (NT_SUCCESS(Status))
2229 {
2230 /* This is our entry!, unmap and return success */
2231 *LdrEntry = CurEntry;
2233 _SEH2_YIELD(return TRUE;)
2234 }
2235 }
2236 }
2237 }
2239 {
2240 _SEH2_YIELD(break;)
2241 }
2242 _SEH2_END;
2243 }
2244
2245 /* Unmap the section and fail */
2247 return FALSE;
2248}
2249
2251NTAPI
2254 _In_opt_ _When_(Ordinal == 0, _Notnull_) PANSI_STRING Name,
2255 _In_opt_ _When_(Name == NULL, _In_range_(>, 0)) ULONG Ordinal,
2256 _Out_ PVOID *ProcedureAddress,
2257 _In_ BOOLEAN ExecuteInit)
2258{
2260 UCHAR ImportBuffer[64]; // 128 since NT6.2
2261 PLDR_DATA_TABLE_ENTRY LdrEntry;
2262 IMAGE_THUNK_DATA Thunk;
2263 PVOID ImageBase;
2264 PIMAGE_IMPORT_BY_NAME ImportName = NULL;
2265 PIMAGE_EXPORT_DIRECTORY ExportDir;
2266 ULONG ExportDirSize, Length;
2268
2269 /* Show debug message */
2270 if (ShowSnaps) DPRINT1("LDR: LdrGetProcedureAddress by ");
2271
2272 /* Check if we got a name */
2273 if (Name)
2274 {
2275 /* Show debug message */
2276 if (ShowSnaps) DbgPrint("NAME - %s\n", Name->Buffer);
2277
2278 /* Make sure it's not too long */
2279 Length = Name->Length +
2280 sizeof(CHAR) +
2283 {
2284 /* Won't have enough space to add the hint */
2285 return STATUS_NAME_TOO_LONG;
2286 }
2287
2288 /* Check if our buffer is large enough */
2289 if (Length > sizeof(ImportBuffer))
2290 {
2291 /* Allocate from heap, plus 2 bytes for the Hint */
2292 ImportName = RtlAllocateHeap(RtlGetProcessHeap(),
2293 0,
2294 Length);
2295 if (!ImportName)
2296 {
2297 /* Return STATUS_INSUFFICIENT_RESOURCES since NT6.2 */
2299 }
2300 }
2301 else
2302 {
2303 /* Use our internal buffer */
2304 ImportName = (PIMAGE_IMPORT_BY_NAME)ImportBuffer;
2305 }
2306
2307 /* Clear the hint */
2308 ImportName->Hint = 0;
2309
2310 /* Copy the name and null-terminate it */
2311 RtlCopyMemory(ImportName->Name, Name->Buffer, Name->Length);
2312 ImportName->Name[Name->Length] = ANSI_NULL;
2313
2314 /* Clear the high bit */
2315 ImageBase = ImportName;
2316 Thunk.u1.AddressOfData = 0;
2317 }
2318 else
2319 {
2320 /* Do it by ordinal */
2321 ImageBase = NULL;
2322
2323 /* Show debug message */
2324 if (ShowSnaps) DbgPrint("ORDINAL - %lx\n", Ordinal);
2325
2326 /* Make sure an ordinal was given */
2327 if (!Ordinal)
2328 {
2329 /* No ordinal */
2330 DPRINT1("No ordinal and no name\n");
2332 }
2333
2334 /* Set the original flag in the thunk */
2335 Thunk.u1.Ordinal = Ordinal | IMAGE_ORDINAL_FLAG;
2336 }
2337
2338 /* Acquire lock unless we are initting */
2340
2341 _SEH2_TRY
2342 {
2343 /* Try to find the loaded DLL */
2345 {
2346 /* Invalid base */
2347 DPRINT1("Invalid base address %p\n", BaseAddress);
2349 _SEH2_YIELD(goto Quickie;)
2350 }
2351
2352 /* Get the pointer to the export directory */
2353 ExportDir = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
2354 TRUE,
2356 &ExportDirSize);
2357
2358 if (!ExportDir)
2359 {
2360 DPRINT1("Image %wZ has no exports, but were trying to get procedure %Z. BaseAddress asked 0x%p, got entry BA 0x%p\n",
2361 &LdrEntry->BaseDllName, Name, BaseAddress, LdrEntry->DllBase);
2363 _SEH2_YIELD(goto Quickie;)
2364 }
2365
2366 /* Now get the thunk */
2367 Status = LdrpSnapThunk(LdrEntry->DllBase,
2368 ImageBase,
2369 &Thunk,
2370 &Thunk,
2371 ExportDir,
2372 ExportDirSize,
2373 FALSE,
2374 NULL);
2375
2376 /* Finally, see if we're supposed to run the init routines */
2377 if ((NT_SUCCESS(Status)) && (ExecuteInit))
2378 {
2379 /*
2380 * It's possible a forwarded entry had us load the DLL. In that case,
2381 * then we will call its DllMain. Use the last loaded DLL for this.
2382 */
2383 Entry = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink;
2384 LdrEntry = CONTAINING_RECORD(Entry,
2386 InInitializationOrderLinks);
2387
2388 /* Make sure we didn't process it yet*/
2389 if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
2390 {
2391 /* Call the init routine */
2392 _SEH2_TRY
2393 {
2395 }
2397 {
2398 /* Get the exception code */
2400 }
2401 _SEH2_END;
2402 }
2403 }
2404
2405 /* Make sure we're OK till here */
2406 if (NT_SUCCESS(Status))
2407 {
2408 /* Return the address */
2409 *ProcedureAddress = (PVOID)Thunk.u1.Function;
2410 }
2411 }
2413 {
2414 /* Just ignore exceptions */
2415 }
2416 _SEH2_END;
2417
2418Quickie:
2419 /* Cleanup */
2420 if (ImportName && (ImportName != (PIMAGE_IMPORT_BY_NAME)ImportBuffer))
2421 {
2422 /* We allocated from heap, free it */
2423 RtlFreeHeap(RtlGetProcessHeap(), 0, ImportName);
2424 }
2425
2426 /* Release the CS if we entered it */
2428
2429 /* We're done */
2430 return Status;
2431}
2432
2434NTAPI
2437 IN PULONG DllCharacteristics OPTIONAL,
2438 IN PUNICODE_STRING DllName,
2440 IN BOOLEAN CallInit)
2441{
2442 PPEB Peb = NtCurrentPeb();
2444 const WCHAR *p;
2445 BOOLEAN GotExtension;
2446 WCHAR c;
2447 WCHAR NameBuffer[MAX_PATH + 6];
2448 UNICODE_STRING RawDllName;
2449 PLDR_DATA_TABLE_ENTRY LdrEntry;
2450 BOOLEAN InInit = LdrpInLdrInit;
2451
2452 /* Save the Raw DLL Name */
2453 if (DllName->Length >= sizeof(NameBuffer)) return STATUS_NAME_TOO_LONG;
2454 RtlInitEmptyUnicodeString(&RawDllName, NameBuffer, sizeof(NameBuffer));
2455 RtlCopyUnicodeString(&RawDllName, DllName);
2456
2457 /* Find the extension, if present */
2458 /* NOTE: Access violation is expected here in some cases (Buffer[-1]) */
2459 p = DllName->Buffer + DllName->Length / sizeof(WCHAR) - 1;
2460 GotExtension = FALSE;
2461 while (p >= DllName->Buffer)
2462 {
2463 c = *p--;
2464 if (c == L'.')
2465 {
2466 GotExtension = TRUE;
2467 break;
2468 }
2469 else if (c == L'\\')
2470 {
2471 break;
2472 }
2473 }
2474
2475 /* If no extension was found, add the default extension */
2476 if (!GotExtension)
2477 {
2478 /* Check that we have space to add one */
2479 if ((DllName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
2480 sizeof(NameBuffer))
2481 {
2482 /* No space to add the extension */
2485 "LDR: %s - Dll name missing extension; with extension "
2486 "added the name is too long\n"
2487 " DllName: (@ %p) \"%wZ\"\n"
2488 " DllName->Length: %u\n",
2490 DllName,
2491 DllName,
2492 DllName->Length);
2493 return STATUS_NAME_TOO_LONG;
2494 }
2495
2496 /* Add it. Needs to be null terminated, thus the length check above */
2499 }
2500
2501 /* Check for init flag and acquire lock */
2503
2504 _SEH2_TRY
2505 {
2506 /* Show debug message */
2507 if (ShowSnaps)
2508 {
2509 DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n",
2510 &RawDllName,
2511 DllPath ? DllPath : L"");
2512 }
2513
2514 /* Check if the DLL is already loaded */
2516 &RawDllName,
2517 FALSE,
2518 Redirected,
2519 &LdrEntry))
2520 {
2521 /* Map it */
2523 DllPath,
2524 NameBuffer,
2525 DllCharacteristics,
2526 FALSE,
2527 Redirected,
2528 &LdrEntry);
2529 if (!NT_SUCCESS(Status))
2531
2532 /* FIXME: Need to mark the DLL range for the stack DB */
2533 //RtlpStkMarkDllRange(LdrEntry);
2534
2535 /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */
2536 if ((DllCharacteristics) &&
2537 (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
2538 {
2539 /* This is not a DLL, so remove such data */
2540 LdrEntry->EntryPoint = NULL;
2541 LdrEntry->Flags &= ~LDRP_IMAGE_DLL;
2542 }
2543
2544 /* Make sure it's a DLL */
2545 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
2546 {
2547 /* Check if this is a .NET Image */
2548 if (!(LdrEntry->Flags & LDRP_COR_IMAGE))
2549 {
2550 /* Walk the Import Descriptor */
2552 }
2553
2554 /* Update load count, unless it's locked */
2555 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2557
2558 /* Check if we failed */
2559 if (!NT_SUCCESS(Status))
2560 {
2561 /* Clear entrypoint, and insert into list */
2562 LdrEntry->EntryPoint = NULL;
2564 &LdrEntry->InInitializationOrderLinks);
2565
2566 /* Cancel the load */
2568
2569 /* Unload the DLL */
2570 if (ShowSnaps)
2571 {
2572 DbgPrint("LDR: Unloading %wZ due to error %x walking "
2573 "import descriptors\n",
2574 DllName,
2575 Status);
2576 }
2577 LdrUnloadDll(LdrEntry->DllBase);
2578
2579 /* Return the error */
2581 }
2582 }
2583 else if (LdrEntry->LoadCount != 0xFFFF)
2584 {
2585 /* Increase load count */
2586 LdrEntry->LoadCount++;
2587 }
2588
2589 /* Insert it into the list */
2591 &LdrEntry->InInitializationOrderLinks);
2592
2593 /* If we have to run the entrypoint, make sure the DB is ready */
2594 if (CallInit && LdrpLdrDatabaseIsSetup)
2595 {
2596 /* Notify Shim Engine */
2597 if (g_ShimsEnabled)
2598 {
2600 SE_DllLoaded(LdrEntry);
2601 }
2602
2603 /* Run the init routine */
2605 if (!NT_SUCCESS(Status))
2606 {
2607 /* Failed, unload the DLL */
2608 if (ShowSnaps)
2609 {
2610 DbgPrint("LDR: Unloading %wZ because either its init "
2611 "routine or one of its static imports failed; "
2612 "status = 0x%08lx\n",
2613 DllName,
2614 Status);
2615 }
2616 LdrUnloadDll(LdrEntry->DllBase);
2617 }
2618 }
2619 else
2620 {
2621 /* The DB isn't ready, which means we were loaded because of a forwarder */
2623 }
2624 }
2625 else
2626 {
2627 /* We were already loaded. Are we a DLL? */
2628 if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
2629 {
2630 /* Increase load count */
2631 LdrEntry->LoadCount++;
2633
2634 /* Clear the load in progress */
2636 }
2637 else
2638 {
2639 /* Not a DLL, just increase the load count */
2640 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
2641 }
2642 }
2643
2644 }
2646 {
2647 /* Release the lock */
2649 }
2650 _SEH2_END;
2651
2652 /* Check for success */
2653 if (NT_SUCCESS(Status))
2654 {
2655 /* Return the base address */
2656 *BaseAddress = LdrEntry->DllBase;
2657 }
2658 else
2659 {
2660 /* Nothing found */
2661 *BaseAddress = NULL;
2662 }
2663
2664 /* Return status */
2665 return Status;
2666}
2667
2668ULONG
2669NTAPI
2671{
2672 PLIST_ENTRY ListHead, Entry;
2673 PLDR_DATA_TABLE_ENTRY LdrEntry;
2674 ULONG ModulesCount = 0;
2675
2676 /* Traverse the init list */
2677 ListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
2678 Entry = ListHead->Flink;
2679 while (Entry != ListHead)
2680 {
2681 /* Get the loader entry */
2682 LdrEntry = CONTAINING_RECORD(Entry,
2684 InInitializationOrderLinks);
2685
2686 /* Clear load in progress flag */
2687 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
2688
2689 /* Check for modules with entry point count but not processed yet */
2690 if ((LdrEntry->EntryPoint) &&
2691 !(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
2692 {
2693 /* Increase counter */
2694 ModulesCount++;
2695 }
2696
2697 /* Advance to the next entry */
2698 Entry = Entry->Flink;
2699 }
2700
2701 /* Return final count */
2702 return ModulesCount;
2703}
2704
2706{
2709 PVOID Address;
2711 /* Skip Dll init */
2713 return NT_SUCCESS(Status) ? Address : NULL;
2714}
2715
2716VOID
2717NTAPI
2719{
2722 PVOID SE_InstallBeforeInit = LdrpGetShimEngineFunction("SE_InstallBeforeInit");
2723 PVOID SE_InstallAfterInit = LdrpGetShimEngineFunction("SE_InstallAfterInit");
2724 PVOID SE_ProcessDying = LdrpGetShimEngineFunction("SE_ProcessDying");
2725
2727 {
2734 }
2735 else
2736 {
2738 }
2739}
2740
2741VOID
2742NTAPI
2744{
2745 PLIST_ENTRY ListHead, Next;
2746 PLDR_DATA_TABLE_ENTRY LdrEntry;
2747
2748 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
2749 Next = ListHead->Flink;
2750 while (Next != ListHead)
2751 {
2752 LdrEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2753
2754 if (g_pShimEngineModule == LdrEntry->DllBase)
2755 {
2756 if (LdrEntry->EntryPoint)
2757 {
2758 _SEH2_TRY
2759 {
2760 LdrpCallInitRoutine(LdrEntry->EntryPoint, LdrEntry->DllBase, Reason, NULL);
2761 }
2763 {
2764 DPRINT1("WARNING: Exception 0x%x during LdrpRunShimEngineInitRoutine(%u)\n",
2766 }
2767 _SEH2_END;
2768 }
2769 return;
2770 }
2771
2772 Next = Next->Flink;
2773 }
2774}
2775
2776VOID
2777NTAPI
2779{
2780 UNICODE_STRING ShimLibraryName;
2781 PVOID ShimLibrary;
2783 RtlInitUnicodeString(&ShimLibraryName, ImageName);
2784 /* We should NOT pass CallInit = TRUE!
2785 If we do this, other init routines will be called before we get a chance to shim stuff.. */
2786 Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, FALSE);
2787 if (NT_SUCCESS(Status))
2788 {
2789 g_pShimEngineModule = ShimLibrary;
2792 if (g_ShimsEnabled)
2793 {
2796 SE_InstallBeforeInit(ProcessImage, pShimData);
2797 }
2798 }
2799}
2800
2801VOID
2802NTAPI
2804{
2805 /* Make sure we do not call into the shim engine anymore */
2810}
2811
2812/* EOF */
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3848
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3441
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3569
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3622
#define NtCurrentPeb()
Definition: FLS.c:22
#define BufSize
Definition: FsRtlTunnel.c:28
unsigned char BOOLEAN
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN OUT PATH_TYPE_AND_UNKNOWN * PathType
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN InvalidName
#define VOID
Definition: acefi.h:82
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char * FunctionName
Definition: acpixf.h:1279
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
#define CHAR(Char)
@ TryAgain
Definition: bl.h:896
NTSTATUS NTAPI RtlImageNtHeaderEx(_In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size, _Out_ PIMAGE_NT_HEADERS *OutHeaders)
Definition: libsupp.c:32
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
struct _LDR_DATA_TABLE_ENTRY * PLDR_DATA_TABLE_ENTRY
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
PIMAGE_NT_HEADERS WINAPI ImageNtHeader(_In_ PVOID)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS NTAPI RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING Extension, IN OUT PUNICODE_STRING StaticString, IN OUT PUNICODE_STRING DynamicString, IN OUT PUNICODE_STRING *NewName, IN PULONG NewFlags, IN PSIZE_T FileNameSize, IN PSIZE_T RequiredLength)
Definition: libsupp.c:818
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define RtlImageNtHeader
Definition: compat.h:806
#define MAX_PATH
Definition: compat.h:34
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
PPEB Peb
Definition: dllmain.c:27
@ DPFLTR_LDR_ID
Definition: dpfilter.h:113
#define __FUNCTION__
Definition: types.h:116
return Iosb
Definition: create.c:4402
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define DbgPrint
Definition: hal.h:12
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlFindActivationContextSectionString(ULONG, const GUID *, ULONG, const UNICODE_STRING *, PVOID)
Definition: actctx.c:5815
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2667
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5344
#define NtCurrentTeb
#define c
Definition: ke_i.h:80
NTSTATUS NTAPI LdrUnloadDll(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1331
#define LDRP_UNLOAD_IN_PROGRESS
Definition: ldrtypes.h:43
#define LDRP_REDIRECTED
Definition: ldrtypes.h:58
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
BOOLEAN(NTAPI * PDLL_INIT_ROUTINE)(_In_ PVOID DllHandle, _In_ ULONG Reason, _In_opt_ PCONTEXT Context)
Definition: ldrtypes.h:254
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
#define LDRP_IMAGE_NOT_AT_BASE
Definition: ldrtypes.h:51
#define LDRP_STATIC_LINK
Definition: ldrtypes.h:38
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:52
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:247
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:42
VOID NTAPI LdrpCallTlsInitializers(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason)
Definition: ldrutils.c:473
BOOLEAN NTAPI LdrpResolveDllName(PWSTR DllPath, PWSTR DllName, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName)
Definition: ldrutils.c:699
VOID NTAPI LdrpUnloadShimEngine()
Definition: ldrutils.c:2803
PVOID g_pfnSE_InstallBeforeInit
Definition: ldrutils.c:25
NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL, IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics, IN BOOLEAN Static, IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: ldrutils.c:1023
NTSTATUS NTAPI LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut, IN ULONG Length)
Definition: ldrutils.c:33
PVOID g_pfnSE_InstallAfterInit
Definition: ldrutils.c:26
VOID NTAPI LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
Definition: ldrutils.c:2778
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1621
NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress, IN BOOLEAN CallInit)
Definition: ldrutils.c:2435
PVOID g_pShimEngineModule
Definition: ldrutils.c:22
PVOID g_pfnSE_ProcessDying
Definition: ldrutils.c:27
NTSTATUS NTAPI LdrpSearchPath(IN PWCHAR *SearchPath, IN PWCHAR DllName, IN PUNICODE_STRING PathName, IN PUNICODE_STRING FullPathName, IN PUNICODE_STRING *ExpandedName)
Definition: ldrutils.c:1783
PVOID NTAPI LdrpFetchAddressOfEntryPoint(IN PVOID ImageBase)
Definition: ldrutils.c:793
VOID NTAPI LdrpUpdateLoadCount2(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags)
Definition: ldrutils.c:460
VOID NTAPI LdrpRunShimEngineInitRoutine(IN ULONG Reason)
Definition: ldrutils.c:2743
VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry(IN PLDR_DATA_TABLE_ENTRY Entry)
Definition: ldrutils.c:1598
NTSTATUS NTAPI LdrpCheckForKnownDll(PWSTR DllName, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName, HANDLE *SectionHandle)
Definition: ldrutils.c:814
PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
Definition: ldrutils.c:19
NTSTATUS NTAPI LdrpGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress, _In_ BOOLEAN ExecuteInit)
Definition: ldrutils.c:2252
VOID NTAPI LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Flags, OUT PUNICODE_STRING UpdateString)
Definition: ldrutils.c:112
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1582
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:947
BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1979
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
NTSTATUS NTAPI LdrpCodeAuthzCheckDllAllowed(IN PUNICODE_STRING FullName, IN HANDLE DllHandle)
Definition: ldrutils.c:535
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1549
NTSTATUS NTAPI LdrpCreateDllSection(IN PUNICODE_STRING FullName, IN HANDLE DllHandle, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle)
Definition: ldrutils.c:544
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
NTSTATUS NTAPI LdrpResolveFullName(IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING PathName, IN PUNICODE_STRING FullPathName, IN PUNICODE_STRING *ExpandedName)
Definition: ldrutils.c:1667
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2670
PVOID LdrpGetShimEngineFunction(PCSZ FunctionName)
Definition: ldrutils.c:2705
PVOID g_pfnSE_DllUnloaded
Definition: ldrutils.c:24
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
Definition: ldrutils.c:19
PVOID g_pfnSE_DllLoaded
Definition: ldrutils.c:23
VOID NTAPI LdrpFreeUnicodeString(IN PUNICODE_STRING StringIn)
Definition: ldrutils.c:84
VOID NTAPI LdrpGetShimEngineInterface()
Definition: ldrutils.c:2718
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
PVOID PVOID PWCHAR PVOID USHORT PULONG Reason
Definition: env.c:47
string StringOut(const string &String, bool forcePrint=true)
Definition: tools.cpp:96
static const char const char * DllPath
Definition: image.c:34
static const char * ImageName
Definition: image.c:34
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Notnull_
Definition: ms_sal.h:658
#define _Out_
Definition: ms_sal.h:345
#define _When_(expr, annos)
Definition: ms_sal.h:254
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define _In_range_(lb, ub)
Definition: ms_sal.h:571
NTSYSAPI NTSTATUS NTAPI ZwRaiseHardError(_In_ NTSTATUS ErrorStatus, _In_ ULONG NumberOfParameters, _In_ ULONG UnicodeStringParameterMask, _In_ PULONG_PTR Parameters, _In_ ULONG ValidResponseOptions, _Out_ PULONG Response)
@ OptionOkCancel
Definition: extypes.h:188
@ OptionOk
Definition: extypes.h:187
@ ResponseCancel
Definition: extypes.h:202
NTSYSAPI NTSTATUS NTAPI ZwFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ ULONG NumberOfBytesToFlush)
NTSYSAPI NTSTATUS NTAPI ZwQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T Length, _Out_opt_ PSIZE_T ResultLength)
NTSYSAPI NTSTATUS NTAPI ZwAreMappedFilesTheSame(_In_ PVOID File1MappedAsAnImage, _In_ PVOID File2MappedAsFile)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
NTSYSAPI NTSTATUS NTAPI ZwProtectVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID *BaseAddress, _In_ SIZE_T *NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection)
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_IMAGE
Definition: mmtypes.h:97
@ SectionImageInformation
Definition: mmtypes.h:196
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
NTSYSAPI ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID BaseAddress, _In_ LONGLONG AdditionalBias, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
Definition: image.c:474
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI ULONG NTAPI RtlDosSearchPath_U(_In_ PCWSTR Path, _In_ PCWSTR FileName, _In_ PCWSTR Extension, _In_ ULONG BufferSize, _Out_ PWSTR Buffer, _Out_ PWSTR *PartName)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
@ RtlPathTypeRelative
Definition: rtltypes.h:476
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
#define FILE_READ_DATA
Definition: nt_native.h:628
#define PAGE_NOCACHE
Definition: nt_native.h:1311
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_QUERY
Definition: nt_native.h:1287
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define PAGE_EXECUTE
Definition: nt_native.h:1306
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
@ ViewShare
Definition: nt_native.h:1278
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define UNICODE_NULL
#define UNICODE_STRING_MAX_CHARS
#define UNICODE_STRING_MAX_BYTES
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:65
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
ULONG LdrpNumberOfProcessors
Definition: ldrinit.c:55
PVOID LdrpHeap
Definition: ldrinit.c:59
#define LDRP_UPDATE_DEREFCOUNT
Definition: ntdllp.h:16
UNICODE_STRING LdrApiDefaultExtension
Definition: ldrapi.c:22
#define LDR_GET_HASH_ENTRY(x)
Definition: ntdllp.h:12
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:83
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1539
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:60
UNICODE_STRING LdrpKnownDllPath
Definition: ldrinit.c:63
#define IMAGE_LOADER_FLAGS_COMPLUS
Definition: ntdllp.h:20
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:641
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:62
#define LDRP_UPDATE_PIN
Definition: ntdllp.h:17
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
#define LDRP_UPDATE_REFCOUNT
Definition: ntdllp.h:15
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:409
NTSTATUS NTAPI LdrpSnapThunk(IN PVOID ExportBase, IN PVOID ImportBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportEntry, IN ULONG ExportSize, IN BOOLEAN Static, IN LPSTR DllName)
Definition: ldrpe.c:950
#define IMAGE_SCN_MEM_NOT_CACHED
Definition: ntimage.h:236
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
struct _IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
VOID(NTAPI * PIMAGE_TLS_CALLBACK)(PVOID DllHandle, ULONG Reason, PVOID Reserved)
Definition: ntimage.h:531
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:128
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:545
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_ILLEGAL_DLL_RELOCATION
Definition: ntstatus.h:742
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:358
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define STATUS_SXS_SECTION_NOT_FOUND
Definition: ntstatus.h:1382
#define STATUS_SXS_KEY_NOT_FOUND
Definition: ntstatus.h:1389
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:117
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define L(x)
Definition: ntvdm.h:50
#define IMAGE_FILE_EXECUTABLE_IMAGE
Definition: pedump.c:160
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define IMAGE_ORDINAL_FLAG
Definition: pedump.c:336
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
Definition: pedump.c:270
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_DLL
Definition: pedump.c:169
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
#define IMAGE_FILE_SYSTEM
Definition: pedump.c:168
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
static WCHAR Address[46]
Definition: ping.c:68
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5934
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:6011
BOOLEAN NTAPI RtlDoesFileExists_UstrEx(IN PCUNICODE_STRING FileName, IN BOOLEAN SucceedIfBusy)
Definition: path.c:1430
ULONG NTAPI RtlGetFullPathName_Ustr(_In_ PUNICODE_STRING FileName, _In_ ULONG Size, _Out_z_bytecap_(Size) PWSTR Buffer, _Out_opt_ PCWSTR *ShortName, _Out_opt_ PBOOLEAN InvalidName, _Out_ RTL_PATH_TYPE *PathType)
Definition: path.c:734
PVOID NTAPI RtlEncodeSystemPointer(IN PVOID Pointer)
Definition: process.c:429
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1436
VOID NTAPI SE_InstallBeforeInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1417
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1441
VOID WINAPI SE_DllLoaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1447
VOID WINAPI SE_DllUnloaded(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: shimeng.c:1465
#define DPRINT
Definition: sndvol32.h:71
static void Exit(void)
Definition: sock.c:1330
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base of all file and directory entries
Definition: entries.h:83
Definition: xml2sdb.h:80
Definition: ncftp.h:89
Definition: window.h:585
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
union _IMAGE_THUNK_DATA32::@2129 u1
Definition: btrfs_drv.h:1876
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID EntryPoint
Definition: ntddk_ex.h:203
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
ULONG SizeOfImage
Definition: ldrtypes.h:143
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:140
PVOID DllBase
Definition: btrfs_drv.h:1880
LIST_ENTRY InMemoryOrderLinks
Definition: btrfs_drv.h:1878
ULONG Flags
Definition: ntddk_ex.h:207
ULONG TimeDateStamp
Definition: btrfs_drv.h:1889
LIST_ENTRY HashLinks
Definition: ldrtypes.h:151
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
PVOID PatchInformation
Definition: ldrtypes.h:164
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID ArbitraryUserPointer
Definition: compat.h:719
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:122
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
Definition: compat.h:836
NT_TIB NtTib
Definition: ntddk_ex.h:332
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define LL
Definition: tui.h:167
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
CONST char * PCSZ
Definition: umtypes.h:125
#define ALIGN_DOWN(size, type)
Definition: umtypes.h:88
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
#define SearchPath
Definition: winbase.h:3835
char * PSZ
Definition: windef.h:57
struct _IMAGE_BOUND_FORWARDER_REF * PIMAGE_BOUND_FORWARDER_REF
struct _IMAGE_BOUND_IMPORT_DESCRIPTOR * PIMAGE_BOUND_IMPORT_DESCRIPTOR
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ PSTRING FullName
Definition: rtlfuncs.h:1648
char * LPSTR
Definition: xmlstorage.h:182
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180