ReactOS 0.4.17-dev-1196-gb6224c3
ldrinit.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/ldrinit.c
5 * PURPOSE: User-Mode Process/Thread Startup
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Aleksey Bragin (aleksey@reactos.org)
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include <ntdll.h>
13#include <compat_undoc.h>
14#include <compatguid_undoc.h>
15
16#define NDEBUG
17#include <debug.h>
18
19
20/* GLOBALS *******************************************************************/
21
24UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options");
29
36
38
42extern PTEB LdrpTopLevelDllBeingLoadedTeb; // defined in rtlsupp.c!
45
46static NTSTATUS (WINAPI *Kernel32ProcessInitPostImportFunction)(VOID);
47static BOOL (WINAPI *Kernel32BaseQueryModuleData)(IN LPSTR ModuleName, IN LPSTR Unk1, IN PVOID Unk2, IN PVOID Unk3, IN PVOID Unk4);
48
64
66
69{
71 -1,
72 0,
73 0,
74 0,
75 0
76};
78
80
83
84//extern LIST_ENTRY RtlCriticalSectionList;
85
90
91ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c
93
97
98#ifdef _M_AMD64
100#endif
101
102#ifdef _WIN64
103#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
104#else
105#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
106#endif
107
108/* FUNCTIONS *****************************************************************/
109
110/*
111 * @implemented
112 */
114NTAPI
116 _In_ PUNICODE_STRING SubKey,
117 _In_ BOOLEAN Wow64,
118 _Out_ PHANDLE NewKeyHandle)
119{
120 PHANDLE RootKeyLocation;
122 UNICODE_STRING SubKeyString;
125 PWCHAR p1;
126
127 /* Check which root key to open */
128 if (Wow64)
129 RootKeyLocation = &Wow64ExecOptionsKey;
130 else
131 RootKeyLocation = &ImageExecOptionsKey;
132
133 /* Get the current key */
134 RootKey = *RootKeyLocation;
135
136 /* Setup the object attributes */
138 Wow64 ?
141 NULL,
142 NULL);
143
144 /* Open the root key */
146 if (NT_SUCCESS(Status))
147 {
148 /* Write the key handle */
149 if (InterlockedCompareExchangePointer(RootKeyLocation, RootKey, NULL) != NULL)
150 {
151 /* Someone already opened it, use it instead */
153 RootKey = *RootKeyLocation;
154 }
155
156 /* Extract the name */
157 SubKeyString = *SubKey;
158 p1 = (PWCHAR)((ULONG_PTR)SubKeyString.Buffer + SubKeyString.Length);
159 while (SubKeyString.Length)
160 {
161 if (p1[-1] == L'\\') break;
162 p1--;
163 SubKeyString.Length -= sizeof(*p1);
164 }
165 SubKeyString.Buffer = p1;
166 SubKeyString.Length = SubKey->Length - SubKeyString.Length;
167
168 /* Setup the object attributes */
170 &SubKeyString,
172 RootKey,
173 NULL);
174
175 /* Open the setting key */
176 Status = ZwOpenKey((PHANDLE)NewKeyHandle, GENERIC_READ, &ObjectAttributes);
177 }
178
179 /* Return to caller */
180 return Status;
181}
182
183/*
184 * @implemented
185 */
187NTAPI
195{
196 ULONG KeyInfo[256];
197 UNICODE_STRING ValueNameString, IntegerString;
198 ULONG KeyInfoSize, ResultSize;
200 BOOLEAN FreeHeap = FALSE;
202
203 /* Build a string for the value name */
204 Status = RtlInitUnicodeStringEx(&ValueNameString, ValueName);
205 if (!NT_SUCCESS(Status)) return Status;
206
207 /* Query the value */
208 Status = ZwQueryValueKey(KeyHandle,
209 &ValueNameString,
211 KeyValueInformation,
212 sizeof(KeyInfo),
213 &ResultSize);
215 {
216 /* Our local buffer wasn't enough, allocate one */
217 KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
218 KeyValueInformation->DataLength;
219 KeyValueInformation = RtlAllocateHeap(RtlGetProcessHeap(),
220 0,
221 KeyInfoSize);
222 if (KeyValueInformation != NULL)
223 {
224 /* Try again */
225 Status = ZwQueryValueKey(KeyHandle,
226 &ValueNameString,
228 KeyValueInformation,
229 KeyInfoSize,
230 &ResultSize);
231 FreeHeap = TRUE;
232 }
233 else
234 {
235 /* Give up this time */
237 }
238 }
239
240 /* Check for success */
241 if (NT_SUCCESS(Status))
242 {
243 /* Handle binary data */
244 if (KeyValueInformation->Type == REG_BINARY)
245 {
246 /* Check validity */
247 if ((Buffer) && (KeyValueInformation->DataLength <= BufferSize))
248 {
249 /* Copy into buffer */
251 &KeyValueInformation->Data,
252 KeyValueInformation->DataLength);
253 }
254 else
255 {
257 }
258
259 /* Copy the result length */
260 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
261 }
262 else if (KeyValueInformation->Type == REG_DWORD)
263 {
264 /* Check for valid type */
265 if (KeyValueInformation->Type != Type)
266 {
267 /* Error */
269 }
270 else
271 {
272 /* Check validity */
273 if ((Buffer) &&
274 (BufferSize == sizeof(ULONG)) &&
275 (KeyValueInformation->DataLength <= BufferSize))
276 {
277 /* Copy into buffer */
279 &KeyValueInformation->Data,
280 KeyValueInformation->DataLength);
281 }
282 else
283 {
285 }
286
287 /* Copy the result length */
288 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
289 }
290 }
291 else if (KeyValueInformation->Type != REG_SZ)
292 {
293 /* We got something weird */
295 }
296 else
297 {
298 /* String, check what you requested */
299 if (Type == REG_DWORD)
300 {
301 /* Validate */
302 if (BufferSize != sizeof(ULONG))
303 {
304 /* Invalid size */
305 BufferSize = 0;
307 }
308 else
309 {
310 /* OK, we know what you want... */
311 IntegerString.Buffer = (PWSTR)KeyValueInformation->Data;
312 IntegerString.Length = (USHORT)KeyValueInformation->DataLength -
313 sizeof(WCHAR);
314 IntegerString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
315 Status = RtlUnicodeStringToInteger(&IntegerString, 0, (PULONG)Buffer);
316 }
317 }
318 else
319 {
320 /* Validate */
321 if (KeyValueInformation->DataLength > BufferSize)
322 {
323 /* Invalid */
325 }
326 else
327 {
328 /* Set the size */
329 BufferSize = KeyValueInformation->DataLength;
330 }
331
332 /* Copy the string */
333 RtlMoveMemory(Buffer, &KeyValueInformation->Data, BufferSize);
334 }
335
336 /* Copy the result length */
337 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
338 }
339 }
340
341 /* Check if buffer was in heap */
342 if (FreeHeap) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
343
344 /* Return status */
345 return Status;
346}
347
348/*
349 * @implemented
350 */
352NTAPI
354 _In_ PUNICODE_STRING SubKey,
360 _In_ BOOLEAN Wow64)
361{
364
365 /* Open a handle to the key */
367
368 /* Check for success */
369 if (NT_SUCCESS(Status))
370 {
371 /* Query the data */
373 ValueName,
374 Type,
375 Buffer,
378
379 /* Close the key */
381 }
382
383 /* Return to caller */
384 return Status;
385}
386
387/*
388 * @implemented
389 */
391NTAPI
393 _In_ PUNICODE_STRING SubKey,
399{
400 /* Call the newer function */
402 ValueName,
403 Type,
404 Buffer,
407 FALSE);
408}
409
410VOID
411NTAPI
413{
414 // Ignored atm
415}
416
417PVOID
418NTAPI
420{
422 ULONG DirSize;
423 PVOID Cookie = NULL;
424
425 /* Check NT header first */
426 if (!RtlImageNtHeader(BaseAddress)) return NULL;
427
428 /* Get the pointer to the config directory */
430 TRUE,
432 &DirSize);
433
434 /* Check for sanity */
435 if (!ConfigDir ||
436 (DirSize != 64 && ConfigDir->Size != DirSize) ||
437 (ConfigDir->Size < 0x48))
438 return NULL;
439
440 /* Now get the cookie */
441 Cookie = (PVOID)ConfigDir->SecurityCookie;
442
443 /* Check this cookie */
445 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
446 {
447 Cookie = NULL;
448 }
449
450 /* Return validated security cookie */
451 return Cookie;
452}
453
454PVOID
455NTAPI
457{
460 ULONG_PTR NewCookie;
461
462 /* Fetch address of the cookie */
464
465 if (Cookie)
466 {
467 /* Check if it's a default one */
469 (*Cookie == 0xBB40))
470 {
471 /* Make up a cookie from a bunch of values which may uniquely represent
472 current moment of time, environment, etc */
474
475 NewCookie = Counter.LowPart ^ Counter.HighPart;
476 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueProcess;
477 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueThread;
478
479 /* Loop like it's done in KeQueryTickCount(). We don't want to call it directly. */
480 while (SharedUserData->SystemTime.High1Time != SharedUserData->SystemTime.High2Time)
481 {
483 };
484
485 /* Calculate the milliseconds value and xor it to the cookie */
486 NewCookie ^= Int64ShrlMod32(UInt32x32To64(SharedUserData->TickCountMultiplier, SharedUserData->TickCount.LowPart), 24) +
487 (SharedUserData->TickCountMultiplier * (SharedUserData->TickCount.High1Time << 8));
488
489 /* Make the cookie 16bit if necessary */
490 if (*Cookie == 0xBB40) NewCookie &= 0xFFFF;
491
492 /* If the result is 0 or the same as we got, just subtract one from the existing value
493 and that's it */
494 if ((NewCookie == 0) || (NewCookie == *Cookie))
495 {
496 NewCookie = *Cookie - 1;
497 }
498
499 /* Set the new cookie value */
500 *Cookie = NewCookie;
501 }
502 }
503
504 return Cookie;
505}
506
507VOID
508NTAPI
510{
512 PLDR_DATA_TABLE_ENTRY LdrEntry;
513 PLIST_ENTRY NextEntry, ListHead;
514 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
516 PVOID EntryPoint;
517
518 DPRINT("LdrpInitializeThread() called for %wZ (%p/%p)\n",
520 NtCurrentTeb()->RealClientId.UniqueProcess,
521 NtCurrentTeb()->RealClientId.UniqueThread);
522
523 /* Acquire the loader Lock */
525
526 /* Allocate an Activation Context Stack */
527 DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
528 Status = RtlAllocateActivationContextStack(&NtCurrentTeb()->ActivationContextStackPointer);
529 if (!NT_SUCCESS(Status))
530 {
531 DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
532 }
533
534 /* Make sure we are not shutting down */
536
537 /* Allocate TLS */
539
540 /* Start at the beginning */
541 ListHead = &Peb->Ldr->InMemoryOrderModuleList;
542 NextEntry = ListHead->Flink;
543 while (NextEntry != ListHead)
544 {
545 /* Get the current entry */
546 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
547
548 /* Make sure it's not ourselves */
549 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
550 {
551 /* Check if we should call */
552 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS))
553 {
554 /* Get the entrypoint */
555 EntryPoint = LdrEntry->EntryPoint;
556
557 /* Check if we are ready to call it */
558 if ((EntryPoint) &&
559 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
560 (LdrEntry->Flags & LDRP_IMAGE_DLL))
561 {
562 /* Set up the Act Ctx */
563 ActCtx.Size = sizeof(ActCtx);
564 ActCtx.Format = 1;
566
567 /* Activate the ActCtx */
568 RtlActivateActivationContextUnsafeFast(&ActCtx,
570
572 {
573 /* Check if it has TLS */
574 if (LdrEntry->TlsIndex)
575 {
576 /* Make sure we're not shutting down */
578 {
579 /* Call TLS */
581 }
582 }
583
584 /* Make sure we're not shutting down */
586 {
587 /* Call the Entrypoint */
588 DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
589 &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
590 NtCurrentTeb()->RealClientId.UniqueProcess,
591 NtCurrentTeb()->RealClientId.UniqueThread);
593 LdrEntry->DllBase,
595 NULL);
596 }
597 }
599 {
600 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_ATTACH) for %wZ\n",
601 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
602 }
603 _SEH2_END;
604
605 /* Deactivate the ActCtx */
606 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
607 }
608 }
609 }
610
611 /* Next entry */
612 NextEntry = NextEntry->Flink;
613 }
614
615 /* Check for TLS */
617 {
618 /* Set up the Act Ctx */
619 ActCtx.Size = sizeof(ActCtx);
620 ActCtx.Format = 1;
622
623 /* Activate the ActCtx */
624 RtlActivateActivationContextUnsafeFast(&ActCtx,
626
628 {
629 /* Do TLS callbacks */
631 }
633 {
634 /* Do nothing */
635 }
636 _SEH2_END;
637
638 /* Deactivate the ActCtx */
639 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
640 }
641
642Exit:
643
644 /* Release the loader lock */
646
647 DPRINT("LdrpInitializeThread() done\n");
648}
649
651NTAPI
653{
654 PLDR_DATA_TABLE_ENTRY LocalArray[16];
655 PLIST_ENTRY ListHead;
656 PLIST_ENTRY NextEntry;
657 PLDR_DATA_TABLE_ENTRY LdrEntry, *LdrRootEntry, OldInitializer;
658 PVOID EntryPoint;
659 ULONG Count, i;
660 //ULONG BreakOnInit;
663 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
664 ULONG BreakOnDllLoad;
665 PTEB OldTldTeb;
666 BOOLEAN DllStatus;
667
668 DPRINT("LdrpRunInitializeRoutines() called for %wZ (%p/%p)\n",
670 NtCurrentTeb()->RealClientId.UniqueProcess,
671 NtCurrentTeb()->RealClientId.UniqueThread);
672
673 /* Check the Loader Lock */
675
676 /* Get the number of entries to call */
678 {
679 /* Check if we can use our local buffer */
680 if (Count > 16)
681 {
682 /* Allocate space for all the entries */
683 LdrRootEntry = RtlAllocateHeap(LdrpHeap,
684 0,
685 Count * sizeof(*LdrRootEntry));
686 if (!LdrRootEntry) return STATUS_NO_MEMORY;
687 }
688 else
689 {
690 /* Use our local array */
691 LdrRootEntry = LocalArray;
692 }
693 }
694 else
695 {
696 /* Don't need one */
697 LdrRootEntry = NULL;
698 }
699
700 /* Show debug message */
701 if (ShowSnaps)
702 {
703 DPRINT1("[%p,%p] LDR: Real INIT LIST for Process %wZ\n",
704 NtCurrentTeb()->RealClientId.UniqueThread,
705 NtCurrentTeb()->RealClientId.UniqueProcess,
707 }
708
709 /* Loop in order */
711 NextEntry = ListHead->Flink;
712 i = 0;
713 while (NextEntry != ListHead)
714 {
715 /* Get the Data Entry */
716 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
717
718 /* Check if we have a Root Entry */
719 if (LdrRootEntry)
720 {
721 /* Check flags */
722 if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
723 {
724 /* Setup the Cookie for the DLL */
725 LdrpInitSecurityCookie(LdrEntry);
726
727 /* Check for valid entrypoint */
728 if (LdrEntry->EntryPoint)
729 {
730 /* Write in array */
731 ASSERT(i < Count);
732 LdrRootEntry[i] = LdrEntry;
733
734 /* Display debug message */
735 if (ShowSnaps)
736 {
737 DPRINT1("[%p,%p] LDR: %wZ init routine %p\n",
738 NtCurrentTeb()->RealClientId.UniqueThread,
739 NtCurrentTeb()->RealClientId.UniqueProcess,
740 &LdrEntry->FullDllName,
741 LdrEntry->EntryPoint);
742 }
743 i++;
744 }
745 }
746 }
747
748 /* Set the flag */
749 LdrEntry->Flags |= LDRP_ENTRY_PROCESSED;
750 NextEntry = NextEntry->Flink;
751 }
752
754
755 /* If we got a context, then we have to call Kernel32 for TS support */
756 if (Context)
757 {
758 /* Check if we have one */
759 if (Kernel32ProcessInitPostImportFunction)
760 {
761 /* Call it */
762 Status = Kernel32ProcessInitPostImportFunction();
763 if (!NT_SUCCESS(Status))
764 {
765 DPRINT1("LDR: LdrpRunInitializeRoutines - Failed running kernel32 post-import function, Status=0x%08lx\n", Status);
766 }
767 }
768 /* Clear it */
769 Kernel32ProcessInitPostImportFunction = NULL;
770 }
771
772 /* No root entry? return */
773 if (!LdrRootEntry)
774 return Status;
775
776 /* Set the TLD TEB */
779
780 /* Loop */
781 i = 0;
782 while (i < Count)
783 {
784 /* Get an entry */
785 LdrEntry = LdrRootEntry[i];
786
787 /* FIXME: Verify NX Compat */
788
789 /* Move to next entry */
790 i++;
791
792 /* Get its entrypoint */
793 EntryPoint = LdrEntry->EntryPoint;
794
795 /* Are we being debugged? */
796 BreakOnDllLoad = 0;
798 {
799 /* Check if we should break on load */
801 L"BreakOnDllLoad",
802 REG_DWORD,
803 &BreakOnDllLoad,
804 sizeof(ULONG),
805 NULL);
806 if (!NT_SUCCESS(Status)) BreakOnDllLoad = 0;
807
808 /* Reset status back to STATUS_SUCCESS */
810 }
811
812 /* Break if aksed */
813 if (BreakOnDllLoad)
814 {
815 /* Check if we should show a message */
816 if (ShowSnaps)
817 {
818 DPRINT1("LDR: %wZ loaded.", &LdrEntry->BaseDllName);
819 DPRINT1(" - About to call init routine at %p\n", EntryPoint);
820 }
821
822 /* Break in debugger */
824 }
825
826 /* Make sure we have an entrypoint */
827 if (EntryPoint)
828 {
829 /* Save the old Dll Initializer and write the current one */
830 OldInitializer = LdrpCurrentDllInitializer;
831 LdrpCurrentDllInitializer = LdrEntry;
832
833 /* Set up the Act Ctx */
834 ActCtx.Size = sizeof(ActCtx);
835 ActCtx.Format = 1;
837
838 /* Activate the ActCtx */
839 RtlActivateActivationContextUnsafeFast(&ActCtx,
841
843 {
844 /* Check if it has TLS */
845 if (LdrEntry->TlsIndex && Context)
846 {
847 /* Call TLS */
849 }
850
851 /* Call the Entrypoint */
852 if (ShowSnaps)
853 {
854 DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n",
855 &LdrEntry->BaseDllName, EntryPoint);
856 }
857 DllStatus = LdrpCallInitRoutine(EntryPoint,
858 LdrEntry->DllBase,
860 Context);
861 }
863 {
864 DllStatus = FALSE;
865 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_ATTACH) for %wZ\n",
866 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
867 }
868 _SEH2_END;
869
870 /* Deactivate the ActCtx */
871 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
872
873 /* Save the Current DLL Initializer */
874 LdrpCurrentDllInitializer = OldInitializer;
875
876 /* Mark the entry as processed */
878
879 /* Fail if DLL init failed */
880 if (!DllStatus)
881 {
882 DPRINT1("LDR: DLL_PROCESS_ATTACH for dll \"%wZ\" (InitRoutine: %p) failed\n",
883 &LdrEntry->BaseDllName, EntryPoint);
884
886 goto Quickie;
887 }
888 }
889 }
890
891 /* Loop in order */
893 NextEntry = NextEntry->Flink;
894 while (NextEntry != ListHead)
895 {
896 /* Get the Data Entry */
897 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
898
899 /* FIXME: Verify NX Compat */
900 // LdrpCheckNXCompatibility()
901
902 /* Next entry */
903 NextEntry = NextEntry->Flink;
904 }
905
906 /* Check for TLS */
908 {
909 /* Set up the Act Ctx */
910 ActCtx.Size = sizeof(ActCtx);
911 ActCtx.Format = 1;
913
914 /* Activate the ActCtx */
915 RtlActivateActivationContextUnsafeFast(&ActCtx,
917
919 {
920 /* Do TLS callbacks */
922 }
924 {
925 /* Do nothing */
926 }
927 _SEH2_END;
928
929 /* Deactivate the ActCtx */
930 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
931 }
932
933Quickie:
934 /* Restore old TEB */
936
937 /* Check if the array is in the heap */
938 if (LdrRootEntry != LocalArray)
939 {
940 /* Free the array */
941 RtlFreeHeap(LdrpHeap, 0, LdrRootEntry);
942 }
943
944 /* Return to caller */
945 DPRINT("LdrpRunInitializeRoutines() done\n");
946 return Status;
947}
948
949/*
950 * @implemented
951 */
953NTAPI
955{
957 PLDR_DATA_TABLE_ENTRY LdrEntry;
958 PLIST_ENTRY NextEntry, ListHead;
959 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
960 PVOID EntryPoint;
961
962 DPRINT("LdrShutdownProcess() called for %wZ\n", &LdrpImageEntry->BaseDllName);
964
965 /* Tell the Shim Engine */
966 if (g_ShimsEnabled)
967 {
971 }
972
973 /* Tell the world */
974 if (ShowSnaps)
975 {
976 DPRINT1("\n");
977 }
978
979 /* Set the shutdown variables */
980 LdrpShutdownThreadId = NtCurrentTeb()->RealClientId.UniqueThread;
982
983 /* Enter the Loader Lock */
985
986#if (NTDDI_VERSION < NTDDI_VISTA)
987 /* Cleanup trace logging data (Etw) */
988 if (SharedUserData->TraceLogging)
989 {
990 /* FIXME */
991 DPRINT1("We don't support Etw yet.\n");
992 }
993#endif
994
995 /* Start at the end */
997 NextEntry = ListHead->Blink;
998 while (NextEntry != ListHead)
999 {
1000 /* Get the current entry */
1001 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1002 NextEntry = NextEntry->Blink;
1003
1004 /* Make sure it's not ourselves */
1005 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1006 {
1007 /* Get the entrypoint */
1008 EntryPoint = LdrEntry->EntryPoint;
1009
1010 /* Check if we are ready to call it */
1011 if (EntryPoint &&
1012 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1013 LdrEntry->Flags)
1014 {
1015 /* Set up the Act Ctx */
1016 ActCtx.Size = sizeof(ActCtx);
1017 ActCtx.Format = 1;
1019
1020 /* Activate the ActCtx */
1021 RtlActivateActivationContextUnsafeFast(&ActCtx,
1022 LdrEntry->EntryPointActivationContext);
1023
1024 _SEH2_TRY
1025 {
1026 /* Check if it has TLS */
1027 if (LdrEntry->TlsIndex)
1028 {
1029 /* Call TLS */
1031 }
1032
1033 /* Call the Entrypoint */
1034 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1035 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1036 LdrpCallInitRoutine(EntryPoint,
1037 LdrEntry->DllBase,
1039 (PVOID)1);
1040 }
1042 {
1043 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
1044 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1045 }
1046 _SEH2_END;
1047
1048 /* Deactivate the ActCtx */
1049 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1050 }
1051 }
1052 }
1053
1054 /* Check for TLS */
1055 if (LdrpImageHasTls)
1056 {
1057 /* Set up the Act Ctx */
1058 ActCtx.Size = sizeof(ActCtx);
1059 ActCtx.Format = 1;
1061
1062 /* Activate the ActCtx */
1063 RtlActivateActivationContextUnsafeFast(&ActCtx,
1065
1066 _SEH2_TRY
1067 {
1068 /* Do TLS callbacks */
1070 }
1072 {
1073 /* Do nothing */
1074 }
1075 _SEH2_END;
1076
1077 /* Deactivate the ActCtx */
1078 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1079 }
1080
1081 /* FIXME: Do Heap detection and Etw final shutdown */
1082
1083 /* Release the lock */
1085 DPRINT("LdrpShutdownProcess() done\n");
1086
1087 return STATUS_SUCCESS;
1088}
1089
1090/*
1091 * @implemented
1092 */
1094NTAPI
1096{
1097 PPEB Peb = NtCurrentPeb();
1098 PTEB Teb = NtCurrentTeb();
1099 PLDR_DATA_TABLE_ENTRY LdrEntry;
1100 PLIST_ENTRY NextEntry, ListHead;
1101 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
1102 PVOID EntryPoint;
1103
1104 DPRINT("LdrShutdownThread() called for %wZ\n",
1106
1107#if (NTDDI_VERSION < NTDDI_VISTA)
1108 /* Cleanup trace logging data (Etw) */
1109 if (SharedUserData->TraceLogging)
1110 {
1111 /* FIXME */
1112 DPRINT1("We don't support Etw yet.\n");
1113 }
1114#endif
1115
1116 /* Get the Ldr Lock */
1118
1119 /* Start at the end */
1121 NextEntry = ListHead->Blink;
1122 while (NextEntry != ListHead)
1123 {
1124 /* Get the current entry */
1125 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1126 NextEntry = NextEntry->Blink;
1127
1128 /* Make sure it's not ourselves */
1129 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1130 {
1131 /* Check if we should call */
1132 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
1133 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1134 (LdrEntry->Flags & LDRP_IMAGE_DLL))
1135 {
1136 /* Get the entrypoint */
1137 EntryPoint = LdrEntry->EntryPoint;
1138
1139 /* Check if we are ready to call it */
1140 if (EntryPoint)
1141 {
1142 /* Set up the Act Ctx */
1143 ActCtx.Size = sizeof(ActCtx);
1144 ActCtx.Format = 1;
1146
1147 /* Activate the ActCtx */
1148 RtlActivateActivationContextUnsafeFast(&ActCtx,
1149 LdrEntry->EntryPointActivationContext);
1150
1151 _SEH2_TRY
1152 {
1153 /* Check if it has TLS */
1154 if (LdrEntry->TlsIndex)
1155 {
1156 /* Make sure we're not shutting down */
1158 {
1159 /* Call TLS */
1161 }
1162 }
1163
1164 /* Make sure we're not shutting down */
1166 {
1167 /* Call the Entrypoint */
1168 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1169 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1170 LdrpCallInitRoutine(EntryPoint,
1171 LdrEntry->DllBase,
1173 NULL);
1174 }
1175 }
1177 {
1178 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_DETACH) for %wZ\n",
1179 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1180 }
1181 _SEH2_END;
1182
1183 /* Deactivate the ActCtx */
1184 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1185 }
1186 }
1187 }
1188 }
1189
1190 /* Check for TLS */
1191 if (LdrpImageHasTls)
1192 {
1193 /* Set up the Act Ctx */
1194 ActCtx.Size = sizeof(ActCtx);
1195 ActCtx.Format = 1;
1197
1198 /* Activate the ActCtx */
1199 RtlActivateActivationContextUnsafeFast(&ActCtx,
1201
1202 _SEH2_TRY
1203 {
1204 /* Do TLS callbacks */
1206 }
1208 {
1209 /* Do nothing */
1210 }
1211 _SEH2_END;
1212
1213 /* Deactivate the ActCtx */
1214 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1215 }
1216
1217 /* Free TLS */
1218 LdrpFreeTls();
1220
1221 /* Check for expansion slots */
1222 if (Teb->TlsExpansionSlots)
1223 {
1224 /* Free expansion slots */
1225 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->TlsExpansionSlots);
1226 }
1227
1228 /* Check for FLS Data */
1229 if (Teb->FlsData)
1230 {
1231 /* Mimic BaseRundownFls */
1232 ULONG n, FlsHighIndex;
1233 PRTL_FLS_DATA pFlsData;
1234 PFLS_CALLBACK_FUNCTION lpCallback;
1235
1236 pFlsData = Teb->FlsData;
1237
1239 FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
1240 RemoveEntryList(&pFlsData->ListEntry);
1242
1243 for (n = 1; n <= FlsHighIndex; ++n)
1244 {
1245 lpCallback = NtCurrentPeb()->FlsCallback[n];
1246 if (lpCallback && pFlsData->Data[n])
1247 {
1248 lpCallback(pFlsData->Data[n]);
1249 }
1250 }
1251
1252 RtlFreeHeap(RtlGetProcessHeap(), 0, pFlsData);
1253 Teb->FlsData = NULL;
1254 }
1255
1256 /* Check for Fiber data */
1257#if (NTDDI_VERSION < NTDDI_LONGHORN)
1258 if (Teb->HasFiberData)
1259#else
1260 if (Teb->DbgHasFiberData)
1261#endif
1262 {
1263 /* Free Fiber data*/
1264 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->NtTib.FiberData);
1265 Teb->NtTib.FiberData = NULL;
1266 }
1267
1268 /* Free the activation context stack */
1270 DPRINT("LdrShutdownThread() done\n");
1271
1272 return STATUS_SUCCESS;
1273}
1274
1276NTAPI
1278{
1279 PLIST_ENTRY NextEntry, ListHead;
1280 PLDR_DATA_TABLE_ENTRY LdrEntry;
1281 PIMAGE_TLS_DIRECTORY TlsDirectory;
1282 PLDRP_TLS_DATA TlsData;
1283 ULONG Size;
1284
1285 /* Initialize the TLS List */
1287
1288 /* Loop all the modules */
1289 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1290 NextEntry = ListHead->Flink;
1291 while (ListHead != NextEntry)
1292 {
1293 /* Get the entry */
1294 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1295 NextEntry = NextEntry->Flink;
1296
1297 /* Get the TLS directory */
1298 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1299 TRUE,
1301 &Size);
1302
1303 /* Check if we have a directory */
1304 if (!TlsDirectory) continue;
1305
1306 /* Check if the image has TLS */
1308
1309 /* Show debug message */
1310 if (ShowSnaps)
1311 {
1312 DPRINT1("LDR: Tls Found in %wZ at %p\n",
1313 &LdrEntry->BaseDllName,
1314 TlsDirectory);
1315 }
1316
1317 /* Allocate an entry */
1318 TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA));
1319 if (!TlsData) return STATUS_NO_MEMORY;
1320
1321 /* Lock the DLL and mark it for TLS Usage */
1322 LdrEntry->LoadCount = -1;
1323 LdrEntry->TlsIndex = -1;
1324
1325 /* Save the cached TLS data */
1326 TlsData->TlsDirectory = *TlsDirectory;
1327 InsertTailList(&LdrpTlsList, &TlsData->TlsLinks);
1328
1329 /* Update the index */
1332 }
1333
1334 /* Done setting up TLS, allocate entries */
1335 return LdrpAllocateTls();
1336}
1337
1339NTAPI
1341{
1342 PTEB Teb = NtCurrentTeb();
1343 PLIST_ENTRY NextEntry, ListHead;
1344 PLDRP_TLS_DATA TlsData;
1345 SIZE_T TlsDataSize;
1346 PVOID *TlsVector;
1347
1348 /* Check if we have any entries */
1350 return STATUS_SUCCESS;
1351
1352 /* Allocate the vector array */
1353 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1354 0,
1355 LdrpNumberOfTlsEntries * sizeof(PVOID));
1356 if (!TlsVector) return STATUS_NO_MEMORY;
1357 Teb->ThreadLocalStoragePointer = TlsVector;
1358
1359 /* Loop the TLS Array */
1360 ListHead = &LdrpTlsList;
1361 NextEntry = ListHead->Flink;
1362 while (NextEntry != ListHead)
1363 {
1364 /* Get the entry */
1365 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1366 NextEntry = NextEntry->Flink;
1367
1368 /* Allocate this vector */
1369 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1371 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1372 0,
1373 TlsDataSize);
1374 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1375 {
1376 /* Out of memory */
1377 return STATUS_NO_MEMORY;
1378 }
1379
1380 /* Show debug message */
1381 if (ShowSnaps)
1382 {
1383 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1384 TlsVector,
1386 &TlsVector[TlsData->TlsDirectory.Characteristics],
1388 TlsVector[TlsData->TlsDirectory.Characteristics]);
1389 }
1390
1391 /* Copy the data */
1392 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1394 TlsDataSize);
1395 }
1396
1397 /* Done */
1398 return STATUS_SUCCESS;
1399}
1400
1401VOID
1402NTAPI
1404{
1405 PLIST_ENTRY ListHead, NextEntry;
1406 PLDRP_TLS_DATA TlsData;
1407 PVOID *TlsVector;
1408 PTEB Teb = NtCurrentTeb();
1409
1410 /* Get a pointer to the vector array */
1411 TlsVector = Teb->ThreadLocalStoragePointer;
1412 if (!TlsVector) return;
1413
1414 /* Loop through it */
1415 ListHead = &LdrpTlsList;
1416 NextEntry = ListHead->Flink;
1417 while (NextEntry != ListHead)
1418 {
1419 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1420 NextEntry = NextEntry->Flink;
1421
1422 /* Free each entry */
1423 if (TlsVector[TlsData->TlsDirectory.Characteristics])
1424 {
1425 RtlFreeHeap(RtlGetProcessHeap(),
1426 0,
1427 TlsVector[TlsData->TlsDirectory.Characteristics]);
1428 }
1429 }
1430
1431 /* Free the array itself */
1432 RtlFreeHeap(RtlGetProcessHeap(),
1433 0,
1434 TlsVector);
1435}
1436
1438NTAPI
1440{
1443 ULONG ExecuteOptions, MinimumStackCommit = 0, GlobalFlag;
1444
1445 /* Return error if we were not provided a pointer where to save the options key handle */
1446 if (!OptionsKey) return STATUS_INVALID_HANDLE;
1447
1448 /* Zero initialize the options key pointer */
1449 *OptionsKey = NULL;
1450
1451 /* Open the options key */
1452 Status = LdrOpenImageFileOptionsKey(ImagePathName, 0, &KeyHandle);
1453
1454 /* Save it if it was opened successfully */
1455 if (NT_SUCCESS(Status))
1456 *OptionsKey = KeyHandle;
1457
1458 if (KeyHandle)
1459 {
1460 /* There are image specific options, read them starting with NXCOMPAT */
1462 L"ExecuteOptions",
1463 4,
1464 &ExecuteOptions,
1465 sizeof(ExecuteOptions),
1466 0);
1467
1468 if (NT_SUCCESS(Status))
1469 {
1470 /* TODO: Set execution options for the process */
1471 /*
1472 if (ExecuteOptions == 0)
1473 ExecuteOptions = 1;
1474 else
1475 ExecuteOptions = 2;
1476 ZwSetInformationProcess(NtCurrentProcess(),
1477 ProcessExecuteFlags,
1478 &ExecuteOptions,
1479 sizeof(ULONG));*/
1480
1481 }
1482
1483 /* Check if this image uses large pages */
1484 if (Peb->ImageUsesLargePages)
1485 {
1486 /* TODO: If it does, open large page key */
1488 }
1489
1490 /* Get various option values */
1492 L"DisableHeapLookaside",
1493 REG_DWORD,
1496 NULL);
1497
1499 L"ShutdownFlags",
1500 REG_DWORD,
1503 NULL);
1504
1506 L"MinimumStackCommitInBytes",
1507 REG_DWORD,
1508 &MinimumStackCommit,
1509 sizeof(MinimumStackCommit),
1510 NULL);
1511
1512 /* Update PEB's minimum stack commit if it's lower */
1513 if (Peb->MinimumStackCommit < MinimumStackCommit)
1514 Peb->MinimumStackCommit = MinimumStackCommit;
1515
1516 /* Set the global flag */
1518 L"GlobalFlag",
1519 REG_DWORD,
1520 &GlobalFlag,
1521 sizeof(GlobalFlag),
1522 NULL);
1523
1524 if (NT_SUCCESS(Status))
1525 Peb->NtGlobalFlag = GlobalFlag;
1526 else
1527 GlobalFlag = 0;
1528
1529 /* Call AVRF if necessary */
1531 {
1533 if (!NT_SUCCESS(Status))
1534 {
1535 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1536 }
1537 }
1538 }
1539 else
1540 {
1541 /* There are no image-specific options, so perform global initialization */
1543 {
1544 /* Initialize app verifier package */
1546 if (!NT_SUCCESS(Status))
1547 {
1548 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1549 }
1550 }
1551 }
1552
1553 return STATUS_SUCCESS;
1554}
1555
1556VOID
1557NTAPI
1559{
1560 DPRINT("LdrpValidateImageForMp is unimplemented\n");
1561 // TODO:
1562 // Scan the LockPrefixTable in the load config directory
1563}
1564
1565BOOLEAN
1566NTAPI
1568{
1569 UNICODE_STRING PolicyKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\Software\\Policies\\Microsoft\\Windows\\AppCompat");
1570 UNICODE_STRING DisableDetection = RTL_CONSTANT_STRING(L"DisableCompatGuidDetection");
1576
1577 Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &PolicyKeyAttributes);
1578 if (NT_SUCCESS(Status))
1579 {
1581 &DisableDetection,
1583 &KeyInfo,
1584 sizeof(KeyInfo),
1585 &ResultLength);
1587 if ((NT_SUCCESS(Status)) &&
1588 (KeyInfo.Type == REG_DWORD) &&
1589 (KeyInfo.DataLength == sizeof(ULONG)) &&
1590 (KeyInfo.Data[0] == TRUE))
1591 {
1592 return TRUE;
1593 }
1594 }
1595 return FALSE;
1596}
1597
1598
1599VOID
1600NTAPI
1601LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData)
1602{
1603 static const struct
1604 {
1605 const GUID* Guid;
1606 const DWORD Version;
1607 } KnownCompatGuids[] = {
1608 { &COMPAT_GUID_WIN10, _WIN32_WINNT_WIN10 },
1609 { &COMPAT_GUID_WIN81, _WIN32_WINNT_WINBLUE },
1610 { &COMPAT_GUID_WIN8, _WIN32_WINNT_WIN8 },
1611 { &COMPAT_GUID_WIN7, _WIN32_WINNT_WIN7 },
1612 { &COMPAT_GUID_VISTA, _WIN32_WINNT_VISTA },
1613 };
1614
1615 ULONG Buffer[(sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 10 + sizeof(ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION)) / sizeof(ULONG)];
1616 ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION* ContextCompatInfo;
1617 SIZE_T SizeRequired;
1619 DWORD n, cur;
1620 ReactOS_ShimData* pShimData = *pOldShimData;
1621
1622 if (pShimData)
1623 {
1624 if (pShimData->dwMagic != REACTOS_SHIMDATA_MAGIC ||
1625 pShimData->dwSize != sizeof(ReactOS_ShimData))
1626 {
1627 DPRINT1("LdrpInitializeProcessCompat: Corrupt pShimData (0x%x, %u)\n", pShimData->dwMagic, pShimData->dwSize);
1628 return;
1629 }
1630#ifdef _M_AMD64
1631 pShimData->RtlGetCurrentDirectory_U_RtlpMsysDecoy = &RtlGetCurrentDirectory_U_RtlpMsysDecoy; /* We need this private symbol for a MSYS shim */
1632#endif
1633 if (pShimData->dwRosProcessCompatVersion)
1634 {
1636 {
1637 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion set to ignore manifest\n");
1638 }
1639 else
1640 {
1641 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion already set to 0x%x\n", pShimData->dwRosProcessCompatVersion);
1642 }
1643 return;
1644 }
1645 }
1646
1647 SizeRequired = sizeof(Buffer);
1649 pProcessActctx,
1650 NULL,
1651 CompatibilityInformationInActivationContext,
1652 Buffer,
1653 sizeof(Buffer),
1654 &SizeRequired);
1655
1656 if (!NT_SUCCESS(Status))
1657 {
1658 DPRINT1("LdrpInitializeProcessCompat: Unable to query process actctx with status %x\n", Status);
1659 return;
1660 }
1661
1662 ContextCompatInfo = (ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*)Buffer;
1663 /* No Compatibility elements present, bail out */
1664 if (ContextCompatInfo->ElementCount == 0)
1665 return;
1666
1667 /* Search for known GUIDs, starting from oldest to newest.
1668 Note that on Windows it is somewhat reversed, starting from the latest known
1669 version, going down. But we are not Windows, trying to allow a lower version,
1670 we are ReactOS trying to fake a higher version. So we interpret what Windows
1671 does as "try the closest version to the actual version", so we start with the
1672 lowest version, which is closest to Windows 2003, which we mostly are. */
1673 for (cur = RTL_NUMBER_OF(KnownCompatGuids) - 1; cur != -1; --cur)
1674 {
1675 for (n = 0; n < ContextCompatInfo->ElementCount; ++n)
1676 {
1677 if (ContextCompatInfo->Elements[n].Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS &&
1678 RtlCompareMemory(&ContextCompatInfo->Elements[n].Id, KnownCompatGuids[cur].Guid, sizeof(GUID)) == sizeof(GUID))
1679 {
1681 {
1682 DPRINT1("LdrpInitializeProcessCompat: Not applying automatic fix for winver 0x%x due to policy\n", KnownCompatGuids[cur].Version);
1683 return;
1684 }
1685
1686 /* If this process did not need shim data before, allocate and store it */
1687 if (pShimData == NULL)
1688 {
1689 PPEB Peb = NtCurrentPeb();
1690
1691 ASSERT(Peb->pShimData == NULL);
1692 pShimData = RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*pShimData));
1693
1694 if (!pShimData)
1695 {
1696 DPRINT1("LdrpInitializeProcessCompat: Unable to allocated %u bytes\n", sizeof(*pShimData));
1697 return;
1698 }
1699
1700 pShimData->dwSize = sizeof(*pShimData);
1701 pShimData->dwMagic = REACTOS_SHIMDATA_MAGIC;
1702#ifdef _M_AMD64
1703 /* The process did not ask for shims, but we want to make sure that if the Peb->pShimData is available, the data in it is complete */
1704 pShimData->RtlGetCurrentDirectory_U_RtlpMsysDecoy = &RtlGetCurrentDirectory_U_RtlpMsysDecoy;
1705#endif
1706
1707 Peb->pShimData = pShimData;
1708 *pOldShimData = pShimData;
1709 }
1710
1711 /* Store the lowest found version, and bail out. */
1712 pShimData->dwRosProcessCompatVersion = KnownCompatGuids[cur].Version;
1713 DPRINT1("LdrpInitializeProcessCompat: Found guid for winver 0x%x in manifest from %wZ\n",
1714 KnownCompatGuids[cur].Version,
1715 &(NtCurrentPeb()->ProcessParameters->ImagePathName));
1716 return;
1717 }
1718 }
1719 }
1720}
1721
1722VOID
1723NTAPI
1725{
1726 UNICODE_STRING ImagePathName = ProcessParameters->ImagePathName;
1727 WCHAR LocalBuffer[MAX_PATH];
1728 UNICODE_STRING DotLocal;
1731
1732 RequiredSize = ImagePathName.Length + LdrpDotLocal.Length + sizeof(UNICODE_NULL);
1733 if (RequiredSize <= sizeof(LocalBuffer))
1734 {
1735 RtlInitEmptyUnicodeString(&DotLocal, LocalBuffer, sizeof(LocalBuffer));
1736 }
1738 {
1739 DotLocal.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RequiredSize);
1740 DotLocal.Length = 0;
1741 DotLocal.MaximumLength = RequiredSize;
1742 if (!DotLocal.Buffer)
1743 DPRINT1("LDR: Failed to allocate memory for .local check\n");
1744 }
1745 else
1746 {
1747 DotLocal.Buffer = NULL;
1748 DotLocal.Length = 0;
1749 DotLocal.MaximumLength = 0;
1750 DPRINT1("LDR: String too big for .local check\n");
1751 }
1752
1753 if (DotLocal.Buffer)
1754 {
1755 Status = RtlAppendUnicodeStringToString(&DotLocal, &ImagePathName);
1757 if (NT_SUCCESS(Status))
1758 {
1761 }
1762
1763 if (NT_SUCCESS(Status))
1764 {
1765 if (RtlDoesFileExists_UStr(&DotLocal))
1766 {
1768 }
1769 }
1770 else
1771 {
1772 DPRINT1("LDR: Failed to append: 0x%lx\n", Status);
1773 }
1774
1775 if (DotLocal.Buffer != LocalBuffer)
1776 {
1777 RtlFreeHeap(RtlGetProcessHeap(), 0, DotLocal.Buffer);
1778 }
1779 }
1780}
1781
1782
1784NTAPI
1787{
1788 RTL_HEAP_PARAMETERS HeapParameters;
1789 ULONG ComSectionSize;
1790 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1791 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1792 PVOID OldShimData;
1794 //UNICODE_STRING LocalFileName, FullImageName;
1795 HANDLE SymLinkHandle;
1796 //ULONG DebugHeapOnly;
1797 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1798 PPEB Peb = NtCurrentPeb();
1799 BOOLEAN IsDotNetImage = FALSE;
1800 BOOLEAN FreeCurDir = FALSE;
1801 //HANDLE CompatKey;
1802 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1803 //LPWSTR ImagePathBuffer;
1804 ULONG ConfigSize;
1806 HANDLE OptionsKey;
1807 ULONG HeapFlags;
1808 PIMAGE_NT_HEADERS NtHeader;
1809 LPWSTR NtDllName = NULL;
1810 NTSTATUS Status, ImportStatus;
1811 NLSTABLEINFO NlsTable;
1813 PTEB Teb = NtCurrentTeb();
1814 PLIST_ENTRY ListHead;
1815 PLIST_ENTRY NextEntry;
1816 ULONG i;
1817 PWSTR ImagePath;
1818 ULONG DebugProcessHeapOnly = 0;
1819 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1820 PWCHAR Current;
1821 ULONG ExecuteOptions = 0;
1822 PVOID ViewBase;
1823
1824 /* Set a NULL SEH Filter */
1826
1827 /* Get the image path */
1829
1830 /* Check if it's not normalized */
1832 {
1833 /* Normalize it*/
1834 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1835 }
1836
1837 /* Create a unicode string for the Image Path */
1839 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1840 ImagePathName.Buffer = ImagePath;
1841
1842 /* Get the NT Headers */
1844
1845 /* Get the execution options */
1846 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1847
1848 /* Check if this is a .NET executable */
1850 TRUE,
1852 &ComSectionSize))
1853 {
1854 /* Remember this for later */
1855 IsDotNetImage = TRUE;
1856 }
1857
1858 /* Save the NTDLL Base address */
1860
1861 /* If this is a Native Image */
1863 {
1864 /* Then do DLL Validation */
1866 }
1867
1868 /* Save the old Shim Data */
1869 OldShimData = Peb->pShimData;
1870
1871 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1872 //Peb->pShimData = NULL;
1873
1874 /* Save the number of processors and CS timeout */
1877
1878 /* Normalize the parameters */
1879 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1880 if (ProcessParameters)
1881 {
1882 /* Save the Image and Command Line Names */
1883 ImageFileName = ProcessParameters->ImagePathName;
1884 CommandLine = ProcessParameters->CommandLine;
1885 }
1886 else
1887 {
1888 /* It failed, initialize empty strings */
1889 RtlInitUnicodeString(&ImageFileName, NULL);
1890 RtlInitUnicodeString(&CommandLine, NULL);
1891 }
1892
1893 /* Initialize NLS data */
1897 &NlsTable);
1898
1899 /* Reset NLS Translations */
1900 RtlResetRtlTranslations(&NlsTable);
1901
1902 /* Get the Image Config Directory */
1904 TRUE,
1906 &ConfigSize);
1907
1908 /* Setup the Heap Parameters */
1909 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1910 HeapFlags = HEAP_GROWABLE;
1911 HeapParameters.Length = sizeof(HeapParameters);
1912
1913 /* Check if we have Configuration Data */
1914#define VALID_CONFIG_FIELD(Name) (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
1915 /* The 'original' load config ends after SecurityCookie */
1916 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1917 {
1918 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1919 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1920 else
1921 DPRINT1("Applying LOAD_CONFIG\n");
1922
1923 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1924 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1925
1926 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1927 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1928
1929 /* Convert the default CS timeout from milliseconds to 100ns units */
1930 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1931 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000);
1932
1933 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1934 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1935
1936 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1937 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1938
1939 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1940 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1941
1942 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1943 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1944
1945 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1946 HeapFlags = LoadConfig->ProcessHeapFlags;
1947 }
1948#undef VALID_CONFIG_FIELD
1949
1950 /* Check for custom affinity mask */
1952 {
1953 /* Set it */
1957 sizeof(Peb->ImageProcessAffinityMask));
1958 }
1959
1960 /* Check if verbose debugging (ShowSnaps) was requested */
1962
1963 /* Start verbose debugging messages right now if they were requested */
1964 if (ShowSnaps)
1965 {
1966 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1968 &CommandLine);
1969 }
1970
1971 /* If the CS timeout is longer than 1 hour, disable it */
1972 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1974
1975 /* Initialize Critical Section Data */
1977
1978 /* Initialize VEH Call lists */
1980
1981 /* Set TLS/FLS Bitmap data */
1985
1986 /* Initialize FLS Bitmap */
1990 RtlSetBit(&FlsBitMap, 0);
1992
1993 /* Initialize TLS Bitmap */
1997 RtlSetBit(&TlsBitMap, 0);
2002
2003 /* Initialize the Hash Table */
2004 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
2005 {
2007 }
2008
2009 /* Initialize the Loader Lock */
2010 // FIXME: What's the point of initing it manually, if two lines lower
2011 // a call to RtlInitializeCriticalSection() is being made anyway?
2012 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
2013 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
2016
2017 /* Check if User Stack Trace Database support was requested */
2019 {
2020 DPRINT1("We don't support user stack trace databases yet\n");
2021 }
2022
2023 /* Setup Fast PEB Lock */
2026 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
2027 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
2028
2029 /* Setup Callout Lock */
2030 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2031
2032 /* For old executables, use 16-byte aligned heap */
2033 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2034 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2035 {
2036 HeapFlags |= HEAP_CREATE_ALIGN_16;
2037 }
2038
2039 /* Setup the Heap */
2041 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2042 NULL,
2045 NULL,
2046 &HeapParameters);
2047
2048 if (!Peb->ProcessHeap)
2049 {
2050 DPRINT1("Failed to create process heap\n");
2051 return STATUS_NO_MEMORY;
2052 }
2053
2055 if (!NT_SUCCESS(Status))
2056 {
2057 DPRINT1("Failed to initialize locale table\n");
2058 return Status;
2059 }
2060
2061 /* Allocate an Activation Context Stack */
2062 Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
2063 if (!NT_SUCCESS(Status)) return Status;
2064
2065 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2066 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2067 HeapParameters.Length = sizeof(HeapParameters);
2068 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2069 if (!LdrpHeap)
2070 {
2071 DPRINT1("Failed to create loader private heap\n");
2072 return STATUS_NO_MEMORY;
2073 }
2074
2075 /* Check for Debug Heap */
2076 if (OptionsKey)
2077 {
2078 /* Query the setting */
2080 L"DebugProcessHeapOnly",
2081 REG_DWORD,
2082 &DebugProcessHeapOnly,
2083 sizeof(ULONG),
2084 NULL);
2085
2086 if (NT_SUCCESS(Status))
2087 {
2088 /* Reset DPH if requested */
2089 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2090 {
2091 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2093 }
2094 }
2095 }
2096
2097 /* Build the NTDLL Path */
2098 FullPath.Buffer = StringBuffer;
2099 FullPath.Length = 0;
2100 FullPath.MaximumLength = sizeof(StringBuffer);
2103 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2104
2105 /* Open the Known DLLs directory */
2106 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2108 &KnownDllString,
2110 NULL,
2111 NULL);
2115
2116 /* Check if it exists */
2117 if (NT_SUCCESS(Status))
2118 {
2119 /* Open the Known DLLs Path */
2120 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2122 &KnownDllString,
2125 NULL);
2126 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2129 if (NT_SUCCESS(Status))
2130 {
2131 /* Query the path */
2135 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2136 NtClose(SymLinkHandle);
2137 if (!NT_SUCCESS(Status))
2138 {
2139 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2140 return Status;
2141 }
2142 }
2143 }
2144
2145 /* Check if we failed */
2146 if (!NT_SUCCESS(Status))
2147 {
2148 /* Assume System32 */
2151 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2152 }
2153
2154 /* If we have process parameters, get the default path and current path */
2155 if (ProcessParameters)
2156 {
2157 /* Check if we have a Dll Path */
2158 if (ProcessParameters->DllPath.Length)
2159 {
2160 /* Get the path */
2161 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2162 }
2163 else
2164 {
2165 /* We need a valid path */
2166 DPRINT1("No valid DllPath was given!\n");
2168 }
2169
2170 /* Set the current directory */
2171 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2172
2173 /* Check if it's empty or invalid */
2174 if ((!CurrentDirectory.Buffer) ||
2175 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2176 (!CurrentDirectory.Length))
2177 {
2178 /* Allocate space for the buffer */
2180 0,
2181 3 * sizeof(WCHAR) +
2182 sizeof(UNICODE_NULL));
2183 if (!CurrentDirectory.Buffer)
2184 {
2185 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2186 // FIXME: And what?
2187 }
2188
2189 /* Copy the drive of the system root */
2191 SharedUserData->NtSystemRoot,
2192 3 * sizeof(WCHAR));
2193 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2194 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2195 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2196
2197 FreeCurDir = TRUE;
2198 DPRINT("Using dynamically allocd curdir\n");
2199 }
2200 else
2201 {
2202 /* Use the local buffer */
2203 DPRINT("Using local system root\n");
2204 }
2205 }
2206
2207 /* Setup Loader Data */
2208 Peb->Ldr = &PebLdr;
2212 PebLdr.Length = sizeof(PEB_LDR_DATA);
2214
2215 /* Allocate a data entry for the Image */
2217
2218 /* Set it up */
2222 LdrpImageEntry->FullDllName = ImageFileName;
2223
2224 if (IsDotNetImage)
2226 else
2227 LdrpImageEntry->Flags = 0;
2228
2229 /* Check if the name is empty */
2230 if (!ImageFileName.Buffer[0])
2231 {
2232 /* Use the same Base name */
2234 }
2235 else
2236 {
2237 /* Find the last slash */
2238 Current = ImageFileName.Buffer;
2239 while (*Current)
2240 {
2241 if (*Current++ == '\\')
2242 {
2243 /* Set this path */
2244 NtDllName = Current;
2245 }
2246 }
2247
2248 /* Did we find anything? */
2249 if (!NtDllName)
2250 {
2251 /* Use the same Base name */
2253 }
2254 else
2255 {
2256 /* Setup the name */
2257 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2260 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2261 }
2262 }
2263
2264 /* Processing done, insert it */
2267
2268 /* Now add an entry for NTDLL */
2270 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2271 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2272 NtLdrEntry->LoadCount = -1;
2273 NtLdrEntry->EntryPointActivationContext = 0;
2274
2275 NtLdrEntry->FullDllName.Length = FullPath.Length;
2276 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2277 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2279
2280 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2282 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2283
2284 /* Processing done, insert it */
2285 LdrpNtDllDataTableEntry = NtLdrEntry;
2286 LdrpInsertMemoryTableEntry(NtLdrEntry);
2287
2288 /* Let the world know */
2289 if (ShowSnaps)
2290 {
2291 DPRINT1("LDR: NEW PROCESS\n");
2292 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2293 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2294 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2295 }
2296
2297 /* Link the Init Order List */
2300
2301 /* Initialize Wine's active context implementation for the current process */
2302 RtlpInitializeActCtx(&OldShimData);
2303
2304 /* Set the current directory */
2306 if (!NT_SUCCESS(Status))
2307 {
2308 /* We failed, check if we should free it */
2309 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2310
2311 /* Set it to the NT Root */
2314 }
2315 else
2316 {
2317 /* We're done with it, free it */
2318 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2319 }
2320
2321 /* Check if we should look for a .local file */
2322 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2323 {
2324 LdrpInitializeDotLocalSupport(ProcessParameters);
2325 }
2326
2327 /* Check if the Application Verifier was enabled */
2329 {
2331 if (!NT_SUCCESS(Status))
2332 {
2333 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2334 return Status;
2335 }
2336
2337 }
2338
2339 if (IsDotNetImage)
2340 {
2341 /* FIXME */
2342 DPRINT1("We don't support .NET applications yet\n");
2343 }
2344
2347 {
2348 PVOID Kernel32BaseAddress;
2349 PVOID FunctionAddress;
2350
2351 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2352
2353 if (!NT_SUCCESS(Status))
2354 {
2355 if (ShowSnaps)
2356 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2357 return Status;
2358 }
2359
2360 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2361 &BaseProcessInitPostImportName,
2362 0,
2363 &FunctionAddress);
2364
2365 if (!NT_SUCCESS(Status))
2366 {
2367 if (ShowSnaps)
2368 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", Status);
2369 return Status;
2370 }
2371 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2372
2373 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2374 &BaseQueryModuleDataName,
2375 0,
2376 &FunctionAddress);
2377
2378 if (!NT_SUCCESS(Status))
2379 {
2380 if (ShowSnaps)
2381 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", Status);
2382 return Status;
2383 }
2384 Kernel32BaseQueryModuleData = FunctionAddress;
2385 }
2386
2387 /* Walk the IAT and load all the DLLs */
2389
2390 /* Check if relocation is needed */
2392 {
2393 DPRINT1("LDR: Performing EXE relocation\n");
2394
2395 /* Change the protection to prepare for relocation */
2396 ViewBase = Peb->ImageBaseAddress;
2397 Status = LdrpSetProtection(ViewBase, FALSE);
2398 if (!NT_SUCCESS(Status)) return Status;
2399
2400 /* Do the relocation */
2402 0LL,
2403 NULL,
2407 if (!NT_SUCCESS(Status))
2408 {
2409 DPRINT1("LdrRelocateImageWithBias() failed\n");
2410 return Status;
2411 }
2412
2413 /* Check if a start context was provided */
2414 if (Context)
2415 {
2416 DPRINT1("WARNING: Relocated EXE Context");
2417 UNIMPLEMENTED; // We should support this
2419 }
2420
2421 /* Restore the protection */
2422 Status = LdrpSetProtection(ViewBase, TRUE);
2423 if (!NT_SUCCESS(Status)) return Status;
2424 }
2425
2426 /* Lock the DLLs */
2427 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2428 NextEntry = ListHead->Flink;
2429 while (ListHead != NextEntry)
2430 {
2431 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2432 NtLdrEntry->LoadCount = -1;
2433 NextEntry = NextEntry->Flink;
2434 }
2435
2436 /* Phase 0 is done */
2438
2439 /* Check whether all static imports were properly loaded and return here */
2440 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2441
2442 /* Following two calls are for Vista+ support, required for winesync */
2443 /* Initialize the keyed event for condition variables */
2446
2447 /* Initialize TLS */
2449 if (!NT_SUCCESS(Status))
2450 {
2451 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2452 Status);
2453 return Status;
2454 }
2455
2456 /* FIXME Mark the DLL Ranges for Stack Traces later */
2457
2458 /* Notify the debugger now */
2459 if (Peb->BeingDebugged)
2460 {
2461 /* Break */
2462 DbgBreakPoint();
2463
2464 /* Update show snaps again */
2466 }
2467
2468 /* Validate the Image for MP Usage */
2470
2471 /* Check NX options and set them */
2472 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2473 {
2474 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2477 }
2478 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2479 {
2481 }
2484 &ExecuteOptions,
2485 sizeof(ExecuteOptions));
2486 if (!NT_SUCCESS(Status))
2487 {
2488 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2489 ExecuteOptions, Status);
2490 }
2491
2492 // FIXME: Should be done by Application Compatibility features,
2493 // by reading the registry, etc...
2494 // For now, this is the old code from ntdll!RtlGetVersion().
2495 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2496 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2497 {
2498 WCHAR szCSDVersion[128];
2499 LONG i;
2500 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2501 i = _snwprintf(szCSDVersion, Length,
2502 L"Service Pack %d",
2503 ((Peb->OSCSDVersion >> 8) & 0xFF));
2504 if (i < 0)
2505 {
2506 /* Null-terminate if it was overflowed */
2507 szCSDVersion[Length] = UNICODE_NULL;
2508 }
2509
2510 Length *= sizeof(WCHAR);
2511 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2512 0,
2513 Length + sizeof(UNICODE_NULL));
2514 if (Peb->CSDVersion.Buffer)
2515 {
2518
2520 szCSDVersion,
2523 }
2524 }
2525
2526 /* Check if we had Shim Data */
2527 if (OldShimData)
2528 {
2529 /* Load the Shim Engine */
2531 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2532 }
2533 else
2534 {
2535 /* Check for Application Compatibility Goo */
2536 //LdrQueryApplicationCompatibilityGoo(hKey);
2537 DPRINT("Querying app compat hacks is missing!\n");
2538 }
2539
2540 /*
2541 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2542 * incompatible images.
2543 */
2544
2545 /* Now call the Init Routines */
2547 if (!NT_SUCCESS(Status))
2548 {
2549 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2550 Status);
2551 return Status;
2552 }
2553
2554 /* Notify Shim Engine */
2555 if (g_ShimsEnabled)
2556 {
2559 SE_InstallAfterInit(&ImagePathName, OldShimData);
2560 }
2561
2562 /* Check if we have a user-defined Post Process Routine */
2564 {
2565 /* Call it */
2567 }
2568
2569 /* Close the key if we have one opened */
2570 if (OptionsKey) NtClose(OptionsKey);
2571
2572 /* Return status */
2573 return Status;
2574}
2575
2576VOID
2577NTAPI
2579{
2581 PPEB Peb = NtCurrentPeb();
2582
2583 /* Print a debug message */
2584 DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2586
2587 /* Raise a hard error */
2589 {
2591 }
2592}
2593
2594VOID
2595NTAPI
2599{
2601 PTEB Teb = NtCurrentTeb();
2602 NTSTATUS Status, LoaderStatus = STATUS_SUCCESS;
2603 MEMORY_BASIC_INFORMATION MemoryBasicInfo;
2604 PPEB Peb = NtCurrentPeb();
2605
2606 DPRINT("LdrpInit() %p/%p\n",
2607 NtCurrentTeb()->RealClientId.UniqueProcess,
2608 NtCurrentTeb()->RealClientId.UniqueThread);
2609
2610#ifdef _WIN64
2611 /* Set the SList header usage */
2613#endif /* _WIN64 */
2614
2615 /* Check if we have a deallocation stack */
2616 if (!Teb->DeallocationStack)
2617 {
2618 /* We don't, set one */
2620 Teb->NtTib.StackLimit,
2622 &MemoryBasicInfo,
2624 NULL);
2625 if (!NT_SUCCESS(Status))
2626 {
2627 /* Fail */
2630 return;
2631 }
2632
2633 /* Set the stack */
2634 Teb->DeallocationStack = MemoryBasicInfo.AllocationBase;
2635 }
2636
2637 /* Now check if the process is already being initialized */
2639 1,
2640 0) == 1)
2641 {
2642 /* Set the timeout to 30 milliseconds */
2643 Timeout.QuadPart = Int32x32To64(30, -10000);
2644
2645 /* Make sure the status hasn't changed */
2646 while (LdrpProcessInitialized == 1)
2647 {
2648 /* Do the wait */
2650 }
2651 }
2652
2653 /* Check if we have already setup LDR data */
2654 if (!Peb->Ldr)
2655 {
2656 /* Setup the Loader Lock */
2658
2659 /* Let other code know we're initializing */
2661
2662 /* Protect with SEH */
2663 _SEH2_TRY
2664 {
2665 /* Initialize the Process */
2666 LoaderStatus = LdrpInitializeProcess(Context,
2668
2669 /* Check for success and if MinimumStackCommit was requested */
2670 if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit)
2671 {
2672 /* Enforce the limit */
2673 //LdrpTouchThreadStack(Peb->MinimumStackCommit);
2675 }
2676 }
2678 {
2679 /* Fail with the SEH error */
2680 LoaderStatus = _SEH2_GetExceptionCode();
2681 }
2682 _SEH2_END;
2683
2684 /* We're not initializing anymore */
2686
2687 /* Check if init worked */
2688 if (NT_SUCCESS(LoaderStatus))
2689 {
2690 /* Set the process as Initialized */
2692 }
2693 }
2694 else
2695 {
2696 /* Loader data is there... is this a fork() ? */
2698 {
2699 /* Handle the fork() */
2700 //LoaderStatus = LdrpForkProcess();
2701 LoaderStatus = STATUS_NOT_IMPLEMENTED;
2703 }
2704 else
2705 {
2706 /* This is a new thread initializing */
2708 }
2709 }
2710
2711 /* All done, test alert the thread */
2712 NtTestAlert();
2713
2714 /* Return */
2715 if (!NT_SUCCESS(LoaderStatus))
2716 {
2717 /* Fail */
2718 LdrpInitFailure(LoaderStatus);
2719 RtlRaiseStatus(LoaderStatus);
2720 }
2721}
2722
2723/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Type
Definition: Type.h:7
#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 const char * ModuleName
Definition: acpixf.h:1280
unsigned char BOOLEAN
Definition: actypes.h:127
#define REG_SZ
Definition: layer.c:22
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
struct _PEB_LDR_DATA PEB_LDR_DATA
#define ARRAYSIZE(a)
Definition: cat.c:25
Definition: bufpool.h:45
#define REACTOS_SHIMDATA_MAGIC
Definition: compat_undoc.h:19
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlSetBit
Definition: dbgbitmap.h:344
_In_ ULONG BufferSize
Definition: dispmprt.h:490
#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:33
#define NTSTATUS
Definition: precomp.h:19
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define DLL_THREAD_DETACH
Definition: compat.h:133
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define GENERIC_READ
Definition: compat.h:135
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
#define RtlImageNtHeader
Definition: compat.h:806
#define MAX_PATH
Definition: compat.h:34
#define DLL_THREAD_ATTACH
Definition: compat.h:132
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
PPEB Peb
Definition: dllmain.c:27
#define SYMBOLIC_LINK_QUERY
Definition: volume.c:47
_ACRTIMP int __cdecl _snwprintf(wchar_t *, size_t, const wchar_t *,...)
Definition: wcs.c:1498
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned long DWORD
Definition: ntddk_ex.h:95
FxCollectionEntry * cur
Status
Definition: gdiplustypes.h:24
GLdouble n
Definition: glext.h:7729
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 REACTOS_COMPATVERSION_IGNOREMANIFEST
Definition: hsdb.c:36
#define FLG_USER_STACK_TRACE_DB
Definition: pstypes.h:62
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:52
#define FLG_HEAP_PAGE_ALLOCS
Definition: pstypes.h:79
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:336
#define FLG_APPLICATION_VERIFIER
Definition: pstypes.h:59
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
#define NtCurrentTeb
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
ULONG RtlpDisableHeapLookaside
Definition: ldrinit.c:91
PVOID NtDllBase
Definition: ldrinit.c:56
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
PLDR_DATA_TABLE_ENTRY LdrpImageEntry
Definition: ldrinit.c:39
VOID NTAPI LdrpInitializeDotLocalSupport(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
Definition: ldrinit.c:1724
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
WCHAR LdrpKnownDllPathBuffer[128]
Definition: ldrinit.c:62
VOID NTAPI LdrpInit(PCONTEXT Context, PVOID SystemArgument1, PVOID SystemArgument2)
Definition: ldrinit.c:2596
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:63
NTSTATUS NTAPI LdrQueryImageFileExecutionOptionsEx(_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength, _In_ BOOLEAN Wow64)
Definition: ldrinit.c:353
ULONG RtlpShutdownProcessFlags
Definition: ldrinit.c:92
VOID NTAPI LdrpFreeTls(VOID)
Definition: ldrinit.c:1403
static IN LPSTR IN PVOID IN PVOID Unk3
Definition: ldrinit.c:47
VOID NTAPI RtlpInitDeferredCriticalSection(VOID)
Definition: critical.c:274
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
NTSTATUS NTAPI LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
Definition: ldrinit.c:1439
RTL_CRITICAL_SECTION FastPebLock
Definition: ldrinit.c:77
LONG LdrpProcessInitialized
Definition: ldrinit.c:31
ULONG LdrpNumberOfTlsEntries
Definition: ldrinit.c:54
ULONG LdrpNumberOfProcessors
Definition: ldrinit.c:55
LIST_ENTRY LdrpTlsList
Definition: ldrinit.c:53
RTL_BITMAP FlsBitMap
Definition: ldrinit.c:51
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
Definition: ldrinit.c:43
ULONG LdrpActiveUnloadCount
Definition: ldrinit.c:82
NTSTATUS NTAPI LdrQueryImageFileExecutionOptions(_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:392
RTL_BITMAP TlsBitMap
Definition: ldrinit.c:49
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrinit.c:456
BOOLEAN LdrpLoaderLockInit
Definition: ldrinit.c:32
const UNICODE_STRING LdrpDotLocal
Definition: ldrinit.c:28
HANDLE ImageExecOptionsKey
Definition: ldrinit.c:22
static IN LPSTR IN PVOID Unk2
Definition: ldrinit.c:47
LARGE_INTEGER RtlpTimeout
Definition: critical.c:26
NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase)
HANDLE Wow64ExecOptionsKey
Definition: ldrinit.c:23
static IN LPSTR Unk1
Definition: ldrinit.c:47
NTSTATUS NTAPI RtlpInitializeLocaleTable(VOID)
Initializes the locale index table, that maps the LCIDs to their indexes in the alphabetical table,...
Definition: locale.c:515
#define DEFAULT_SECURITY_COOKIE
Definition: ldrinit.c:105
NTSTATUS NTAPI LdrQueryImageFileKeyOption(_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:188
PTEB LdrpTopLevelDllBeingLoadedTeb
Definition: libsupp.c:20
VOID NTAPI RtlInitializeHeapManager(VOID)
Definition: libsupp.c:243
NTSTATUS NTAPI LdrOpenImageFileOptionsKey(_In_ PUNICODE_STRING SubKey, _In_ BOOLEAN Wow64, _Out_ PHANDLE NewKeyHandle)
Definition: ldrinit.c:115
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: ldrinit.c:419
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:81
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1558
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:59
UNICODE_STRING LdrpKnownDllPath
Definition: ldrinit.c:61
NTSTATUS NTAPI LdrpInitializeProcess(IN PCONTEXT Context, IN PVOID SystemArgument1)
Definition: ldrinit.c:1785
RTL_BITMAP TlsExpansionBitMap
Definition: ldrinit.c:50
BOOLEAN LdrpImageHasTls
Definition: ldrinit.c:52
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:652
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug
Definition: ldrinit.c:67
VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID)
Definition: vectoreh.c:30
BOOLEAN NTAPI LdrpDisableProcessCompatGuidDetection(VOID)
Definition: ldrinit.c:1567
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
BOOLEAN ShowSnaps
Definition: ldrinit.c:79
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:60
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:68
VOID NTAPI LdrpInitFailure(NTSTATUS Status)
Definition: ldrinit.c:2578
PUNICODE_STRING LdrpTopLevelDllBeingLoaded
Definition: ldrinit.c:40
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry
Definition: ldrinit.c:44
VOID NTAPI LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID *pOldShimData)
Definition: ldrinit.c:1601
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1277
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:412
#define VALID_CONFIG_FIELD(Name)
UNICODE_STRING ImageExecOptionsString
Definition: ldrinit.c:24
UNICODE_STRING Kernel32String
Definition: ldrinit.c:27
BOOLEAN RtlpTimeoutDisable
Definition: critical.c:27
UNICODE_STRING Wow64OptionsString
Definition: ldrinit.c:25
VOID NTAPI LdrpInitializeThread(IN PCONTEXT Context)
Definition: ldrinit.c:509
UNICODE_STRING NtDllString
Definition: ldrinit.c:26
NTSTATUS NTAPI RtlpInitializeActCtx(PVOID *pOldShimData)
NTSTATUS NTAPI LdrpAllocateTls(VOID)
Definition: ldrinit.c:1340
static IN LPSTR IN PVOID IN PVOID IN PVOID Unk4
Definition: ldrinit.c:47
BOOLEAN LdrpDllValidation
Definition: ldrinit.c:37
PEB_LDR_DATA PebLdr
Definition: ldrinit.c:65
BOOLEAN RtlpUse16ByteSLists
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(_In_opt_ PWSTR SearchPath, _In_opt_ PULONG DllCharacteristics, _In_ PUNICODE_STRING DllName, _Out_ PVOID *BaseAddress)
Definition: ldrapi.c:312
NTSTATUS NTAPI LdrGetProcedureAddress(_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)
Definition: ldrapi.c:789
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:48
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:264
#define LDRP_DONT_CALL_FOR_THREADS
Definition: ldrtypes.h:52
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:56
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
#define LDRP_PROCESS_ATTACH_CALLED
Definition: ldrtypes.h:53
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
static PVOID RtlGetCurrentDirectory_U_RtlpMsysDecoy
Definition: msys2.c:16
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwRaiseHardError(_In_ NTSTATUS ErrorStatus, _In_ ULONG NumberOfParameters, _In_ ULONG UnicodeStringParameterMask, _In_ PULONG_PTR Parameters, _In_ ULONG ValidResponseOptions, _Out_ PULONG Response)
@ OptionOk
Definition: extypes.h:192
NTSYSAPI NTSTATUS NTAPI ZwDelayExecution(_In_ BOOLEAN Alertable, _In_ LARGE_INTEGER *Interval)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID * BaseAddress
Definition: mmfuncs.h:408
#define MEM_EXECUTE_OPTION_DISABLE
Definition: mmtypes.h:73
@ MemoryBasicInformation
Definition: mmtypes.h:183
#define MEM_EXECUTE_OPTION_PERMANENT
Definition: mmtypes.h:76
#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
Definition: mmtypes.h:75
#define MEM_EXECUTE_OPTION_ENABLE
Definition: mmtypes.h:74
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI VOID NTAPI RtlInitNlsTables(_In_ PUSHORT AnsiTableBase, _In_ PUSHORT OemTableBase, _In_ PUSHORT CaseTableBase, _Out_ PNLSTABLEINFO NlsTable)
NTSYSAPI VOID NTAPI RtlResetRtlTranslations(_In_ PNLSTABLEINFO NlsTable)
NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U(_In_ PUNICODE_STRING name)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
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 NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS NTAPI RtlNormalizeProcessParams(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH
Definition: rtltypes.h:53
#define RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH
Definition: rtltypes.h:52
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_NO_ADDREF
Definition: rtltypes.h:127
#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED
Definition: rtltypes.h:41
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:335
#define REG_BINARY
Definition: nt_native.h:1499
@ KeyValuePartialInformation
Definition: nt_native.h:1185
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define DIRECTORY_QUERY
Definition: nt_native.h:1257
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1258
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define HEAP_CLASS_1
Definition: nt_native.h:1714
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define NtCurrentProcess()
Definition: nt_native.h:1660
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
#define HEAP_GROWABLE
Definition: nt_native.h:1696
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1022
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3434
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define BOOL
Definition: nt_native.h:43
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define HEAP_CREATE_ALIGN_16
Definition: nt_native.h:1704
#define Int32x32To64(a, b)
#define Int64ShrlMod32(a, b)
#define UNICODE_NULL
#define UNICODE_STRING_MAX_BYTES
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
VOID NTAPI LdrpCallTlsInitializers(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason)
Definition: ldrutils.c:447
NTSTATUS NTAPI LdrpInitializeApplicationVerifierPackage(IN HANDLE KeyHandle, IN PPEB Peb, IN BOOLEAN SystemWide, IN BOOLEAN ReadAdvancedOptions)
BOOLEAN NTAPI RtlDoesFileExists_UStr(IN PUNICODE_STRING FileName)
Definition: path.c:1503
PVOID g_pfnSE_InstallAfterInit
Definition: ldrutils.c:26
VOID NTAPI LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
Definition: ldrutils.c:2766
ULONG RtlpDphGlobalFlags
Definition: heappage.c:108
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
PVOID g_pfnSE_ProcessDying
Definition: ldrutils.c:27
NTSTATUS NTAPI AVrfInitializeVerifier(VOID)
Definition: verifier.c:672
PVOID LdrpHeap
Definition: ldrinit.c:3
#define LDR_HASH_TABLE_ENTRIES
Definition: ntdllp.h:11
VOID NTAPI RtlpInitializeThreadPooling(VOID)
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1561
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:921
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
PVOID NTAPI LdrpFetchAddressOfEntryPoint(PVOID ImageBase)
BOOLEAN RtlpPageHeapEnabled
Definition: heappage.c:107
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1528
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2658
VOID NTAPI RtlpInitializeKeyedEvent(VOID)
Definition: condvar.c:460
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
UNICODE_STRING NtSystemRoot
Definition: init.c:80
NTSTATUS NTAPI NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter, OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
Definition: profile.c:278
NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN MEMORY_INFORMATION_CLASS MemoryInformationClass, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
Definition: virtual.c:4374
NTSTATUS NTAPI NtSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
Definition: query.c:1422
NTSTATUS NTAPI NtTestAlert(VOID)
Definition: state.c:465
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:453
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:652
#define STATUS_APP_INIT_FAILURE
Definition: ntstatus.h:655
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
unsigned short USHORT
Definition: pedump.c:61
static ULONG Timeout
Definition: ping.c:61
static VOID LoadConfig(HWND hwndDlg, PPOWER_SCHEMES_PAGE_DATA pPageData, PPOWER_SCHEME pScheme)
Definition: powershemes.c:238
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define REG_DWORD
Definition: sdbapi.c:615
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
long __cdecl _InterlockedCompareExchange(_Interlocked_operand_ long volatile *_Destination, long _Exchange, long _Comparand)
#define YieldProcessor
Definition: ke.h:48
#define SharedUserData
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
static PMEMKEY RootKey
Definition: registry.c:55
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
#define _WIN32_WINNT_WINBLUE
Definition: sdkddkver.h:30
#define _WIN32_WINNT_WIN8
Definition: sdkddkver.h:29
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1469
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1474
#define DPRINT
Definition: sndvol32.h:73
static void Exit(void)
Definition: sock.c:1330
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
Definition: ncftp.h:89
HANDLE UniqueProcess
Definition: compat.h:825
UNICODE_STRING DosPath
Definition: rtltypes.h:1390
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
ULONG StartAddressOfRawData
Definition: ntimage.h:546
IMAGE_TLS_DIRECTORY TlsDirectory
Definition: ntdllp.h:29
LIST_ENTRY TlsLinks
Definition: ntdllp.h:28
Definition: btrfs_drv.h:1876
PACTIVATION_CONTEXT EntryPointActivationContext
Definition: ldrtypes.h:167
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:147
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:144
PVOID DllBase
Definition: btrfs_drv.h:1880
USHORT TlsIndex
Definition: ntddk_ex.h:209
ULONG Flags
Definition: ntddk_ex.h:207
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID FiberData
Definition: compat.h:716
PVOID StackLimit
Definition: compat.h:713
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:126
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
ULONG Length
Definition: ntddk_ex.h:221
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:124
BOOLEAN Initialized
Definition: ntddk_ex.h:222
UNICODE_STRING CSDVersion
Definition: winternl.h:545
PVOID LoaderLock
Definition: ntddk_ex.h:295
BOOLEAN ReadImageFileExecOptions
Definition: ntddk_ex.h:240
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
ULONG NumberOfProcessors
Definition: ntddk_ex.h:269
ULONG TlsBitmapBits[2]
Definition: ntddk_ex.h:260
ULONG ImageProcessAffinityMask
Definition: ntddk_ex.h:307
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
PVOID TlsBitmap
Definition: ntddk_ex.h:259
LARGE_INTEGER CriticalSectionTimeout
Definition: ntddk_ex.h:274
PVOID ProcessHeap
Definition: ntddk_ex.h:249
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
PVOID AnsiCodePageData
Definition: ntddk_ex.h:264
BYTE BeingDebugged
Definition: btrfs_drv.h:1909
SIZE_T MinimumStackCommit
Definition: winternl.h:550
ULONG TlsExpansionBitmapBits[32]
Definition: winternl.h:539
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine
Definition: btrfs_drv.h:1916
PVOID OemCodePageData
Definition: ntddk_ex.h:265
LIST_ENTRY FlsListHead
Definition: winternl.h:552
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
PRTL_BITMAP FlsBitmap
Definition: winternl.h:555
ULONG FlsBitmapBits[4]
Definition: winternl.h:560
PVOID AppCompatInfo
Definition: winternl.h:544
BOOLEAN InheritedAddressSpace
Definition: ntddk_ex.h:239
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:538
PVOID UnicodeCaseTableData
Definition: ntddk_ex.h:266
PVOID FastPebLock
Definition: ntddk_ex.h:250
LIST_ENTRY ListEntry
Definition: rtltypes.h:1228
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE]
Definition: rtltypes.h:1229
ULONG DeCommitFreeBlockThreshold
Definition: nt_native.h:1673
ULONG VirtualMemoryThreshold
Definition: nt_native.h:1676
ULONG DeCommitTotalFreeThreshold
Definition: nt_native.h:1674
UNICODE_STRING CommandLine
Definition: btrfs_drv.h:1902
UNICODE_STRING ImagePathName
Definition: btrfs_drv.h:1901
DWORD dwRosProcessCompatVersion
Definition: compat_undoc.h:11
Definition: compat.h:836
PVOID ActivationContextStackPointer
Definition: compat.h:854
PVOID * TlsExpansionSlots
Definition: compat.h:894
NT_TIB NtTib
Definition: ntddk_ex.h:332
PVOID ThreadLocalStoragePointer
Definition: compat.h:841
CLIENT_ID ClientId
Definition: compat.h:839
PVOID DeallocationStack
Definition: compat.h:878
USHORT MaximumLength
Definition: env_spec_w32.h:370
static LARGE_INTEGER Counter
Definition: clock.c:43
#define LL
Definition: tui.h:167
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
char * LPSTR
Definition: typedefs.h:51
#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
int32_t * PLONG
Definition: typedefs.h:58
#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
char * PCHAR
Definition: typedefs.h:51
_In_ PGUID _In_ ULONG _Out_ PULONG ResultLength
Definition: ucxcontroller.h:83
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4445
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1178
#define WINAPI
Definition: msvc.h:6
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:95
NTSYSAPI void WINAPI RtlSetUnhandledExceptionFilter(PRTL_EXCEPTION_FILTER)
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:85
NTSYSAPI void WINAPI DbgBreakPoint(void)
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
NTSYSAPI void WINAPI RtlFreeThreadActivationContextStack(void)
Definition: actctx.c:5762
NTSYSAPI void WINAPI LdrShutdownProcess(void)
Definition: ldrinit.c:954
@ ProcessAffinityMask
Definition: winternl.h:1903
@ ProcessExecuteFlags
Definition: winternl.h:1916
NTSYSAPI void WINAPI LdrShutdownThread(void)
Definition: ldrinit.c:1095
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5833
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1141
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
#define NX_SUPPORT_POLICY_ALWAYSOFF
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:756
#define NX_SUPPORT_POLICY_ALWAYSON
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:757
#define PF_COMPARE_EXCHANGE128
Definition: ketypes.h:190