ReactOS 0.4.16-dev-2354-g16de117
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 /* Cleanup trace logging data (Etw) */
987 if (SharedUserData->TraceLogging)
988 {
989 /* FIXME */
990 DPRINT1("We don't support Etw yet.\n");
991 }
992
993 /* Start at the end */
995 NextEntry = ListHead->Blink;
996 while (NextEntry != ListHead)
997 {
998 /* Get the current entry */
999 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1000 NextEntry = NextEntry->Blink;
1001
1002 /* Make sure it's not ourselves */
1003 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1004 {
1005 /* Get the entrypoint */
1006 EntryPoint = LdrEntry->EntryPoint;
1007
1008 /* Check if we are ready to call it */
1009 if (EntryPoint &&
1010 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1011 LdrEntry->Flags)
1012 {
1013 /* Set up the Act Ctx */
1014 ActCtx.Size = sizeof(ActCtx);
1015 ActCtx.Format = 1;
1017
1018 /* Activate the ActCtx */
1019 RtlActivateActivationContextUnsafeFast(&ActCtx,
1020 LdrEntry->EntryPointActivationContext);
1021
1022 _SEH2_TRY
1023 {
1024 /* Check if it has TLS */
1025 if (LdrEntry->TlsIndex)
1026 {
1027 /* Call TLS */
1029 }
1030
1031 /* Call the Entrypoint */
1032 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1033 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1034 LdrpCallInitRoutine(EntryPoint,
1035 LdrEntry->DllBase,
1037 (PVOID)1);
1038 }
1040 {
1041 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
1042 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1043 }
1044 _SEH2_END;
1045
1046 /* Deactivate the ActCtx */
1047 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1048 }
1049 }
1050 }
1051
1052 /* Check for TLS */
1053 if (LdrpImageHasTls)
1054 {
1055 /* Set up the Act Ctx */
1056 ActCtx.Size = sizeof(ActCtx);
1057 ActCtx.Format = 1;
1059
1060 /* Activate the ActCtx */
1061 RtlActivateActivationContextUnsafeFast(&ActCtx,
1063
1064 _SEH2_TRY
1065 {
1066 /* Do TLS callbacks */
1068 }
1070 {
1071 /* Do nothing */
1072 }
1073 _SEH2_END;
1074
1075 /* Deactivate the ActCtx */
1076 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1077 }
1078
1079 /* FIXME: Do Heap detection and Etw final shutdown */
1080
1081 /* Release the lock */
1083 DPRINT("LdrpShutdownProcess() done\n");
1084
1085 return STATUS_SUCCESS;
1086}
1087
1088/*
1089 * @implemented
1090 */
1092NTAPI
1094{
1095 PPEB Peb = NtCurrentPeb();
1096 PTEB Teb = NtCurrentTeb();
1097 PLDR_DATA_TABLE_ENTRY LdrEntry;
1098 PLIST_ENTRY NextEntry, ListHead;
1099 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
1100 PVOID EntryPoint;
1101
1102 DPRINT("LdrShutdownThread() called for %wZ\n",
1104
1105 /* Cleanup trace logging data (Etw) */
1106 if (SharedUserData->TraceLogging)
1107 {
1108 /* FIXME */
1109 DPRINT1("We don't support Etw yet.\n");
1110 }
1111
1112 /* Get the Ldr Lock */
1114
1115 /* Start at the end */
1117 NextEntry = ListHead->Blink;
1118 while (NextEntry != ListHead)
1119 {
1120 /* Get the current entry */
1121 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1122 NextEntry = NextEntry->Blink;
1123
1124 /* Make sure it's not ourselves */
1125 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1126 {
1127 /* Check if we should call */
1128 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
1129 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1130 (LdrEntry->Flags & LDRP_IMAGE_DLL))
1131 {
1132 /* Get the entrypoint */
1133 EntryPoint = LdrEntry->EntryPoint;
1134
1135 /* Check if we are ready to call it */
1136 if (EntryPoint)
1137 {
1138 /* Set up the Act Ctx */
1139 ActCtx.Size = sizeof(ActCtx);
1140 ActCtx.Format = 1;
1142
1143 /* Activate the ActCtx */
1144 RtlActivateActivationContextUnsafeFast(&ActCtx,
1145 LdrEntry->EntryPointActivationContext);
1146
1147 _SEH2_TRY
1148 {
1149 /* Check if it has TLS */
1150 if (LdrEntry->TlsIndex)
1151 {
1152 /* Make sure we're not shutting down */
1154 {
1155 /* Call TLS */
1157 }
1158 }
1159
1160 /* Make sure we're not shutting down */
1162 {
1163 /* Call the Entrypoint */
1164 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1165 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1166 LdrpCallInitRoutine(EntryPoint,
1167 LdrEntry->DllBase,
1169 NULL);
1170 }
1171 }
1173 {
1174 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_DETACH) for %wZ\n",
1175 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1176 }
1177 _SEH2_END;
1178
1179 /* Deactivate the ActCtx */
1180 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1181 }
1182 }
1183 }
1184 }
1185
1186 /* Check for TLS */
1187 if (LdrpImageHasTls)
1188 {
1189 /* Set up the Act Ctx */
1190 ActCtx.Size = sizeof(ActCtx);
1191 ActCtx.Format = 1;
1193
1194 /* Activate the ActCtx */
1195 RtlActivateActivationContextUnsafeFast(&ActCtx,
1197
1198 _SEH2_TRY
1199 {
1200 /* Do TLS callbacks */
1202 }
1204 {
1205 /* Do nothing */
1206 }
1207 _SEH2_END;
1208
1209 /* Deactivate the ActCtx */
1210 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1211 }
1212
1213 /* Free TLS */
1214 LdrpFreeTls();
1216
1217 /* Check for expansion slots */
1218 if (Teb->TlsExpansionSlots)
1219 {
1220 /* Free expansion slots */
1221 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->TlsExpansionSlots);
1222 }
1223
1224 /* Check for FLS Data */
1225 if (Teb->FlsData)
1226 {
1227 /* Mimic BaseRundownFls */
1228 ULONG n, FlsHighIndex;
1229 PRTL_FLS_DATA pFlsData;
1230 PFLS_CALLBACK_FUNCTION lpCallback;
1231
1232 pFlsData = Teb->FlsData;
1233
1235 FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
1236 RemoveEntryList(&pFlsData->ListEntry);
1238
1239 for (n = 1; n <= FlsHighIndex; ++n)
1240 {
1241 lpCallback = NtCurrentPeb()->FlsCallback[n];
1242 if (lpCallback && pFlsData->Data[n])
1243 {
1244 lpCallback(pFlsData->Data[n]);
1245 }
1246 }
1247
1248 RtlFreeHeap(RtlGetProcessHeap(), 0, pFlsData);
1249 Teb->FlsData = NULL;
1250 }
1251
1252 /* Check for Fiber data */
1253 if (Teb->HasFiberData)
1254 {
1255 /* Free Fiber data*/
1256 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->NtTib.FiberData);
1257 Teb->NtTib.FiberData = NULL;
1258 }
1259
1260 /* Free the activation context stack */
1262 DPRINT("LdrShutdownThread() done\n");
1263
1264 return STATUS_SUCCESS;
1265}
1266
1268NTAPI
1270{
1271 PLIST_ENTRY NextEntry, ListHead;
1272 PLDR_DATA_TABLE_ENTRY LdrEntry;
1273 PIMAGE_TLS_DIRECTORY TlsDirectory;
1274 PLDRP_TLS_DATA TlsData;
1275 ULONG Size;
1276
1277 /* Initialize the TLS List */
1279
1280 /* Loop all the modules */
1281 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1282 NextEntry = ListHead->Flink;
1283 while (ListHead != NextEntry)
1284 {
1285 /* Get the entry */
1286 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1287 NextEntry = NextEntry->Flink;
1288
1289 /* Get the TLS directory */
1290 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1291 TRUE,
1293 &Size);
1294
1295 /* Check if we have a directory */
1296 if (!TlsDirectory) continue;
1297
1298 /* Check if the image has TLS */
1300
1301 /* Show debug message */
1302 if (ShowSnaps)
1303 {
1304 DPRINT1("LDR: Tls Found in %wZ at %p\n",
1305 &LdrEntry->BaseDllName,
1306 TlsDirectory);
1307 }
1308
1309 /* Allocate an entry */
1310 TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA));
1311 if (!TlsData) return STATUS_NO_MEMORY;
1312
1313 /* Lock the DLL and mark it for TLS Usage */
1314 LdrEntry->LoadCount = -1;
1315 LdrEntry->TlsIndex = -1;
1316
1317 /* Save the cached TLS data */
1318 TlsData->TlsDirectory = *TlsDirectory;
1319 InsertTailList(&LdrpTlsList, &TlsData->TlsLinks);
1320
1321 /* Update the index */
1324 }
1325
1326 /* Done setting up TLS, allocate entries */
1327 return LdrpAllocateTls();
1328}
1329
1331NTAPI
1333{
1334 PTEB Teb = NtCurrentTeb();
1335 PLIST_ENTRY NextEntry, ListHead;
1336 PLDRP_TLS_DATA TlsData;
1337 SIZE_T TlsDataSize;
1338 PVOID *TlsVector;
1339
1340 /* Check if we have any entries */
1342 return STATUS_SUCCESS;
1343
1344 /* Allocate the vector array */
1345 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1346 0,
1347 LdrpNumberOfTlsEntries * sizeof(PVOID));
1348 if (!TlsVector) return STATUS_NO_MEMORY;
1349 Teb->ThreadLocalStoragePointer = TlsVector;
1350
1351 /* Loop the TLS Array */
1352 ListHead = &LdrpTlsList;
1353 NextEntry = ListHead->Flink;
1354 while (NextEntry != ListHead)
1355 {
1356 /* Get the entry */
1357 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1358 NextEntry = NextEntry->Flink;
1359
1360 /* Allocate this vector */
1361 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1363 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1364 0,
1365 TlsDataSize);
1366 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1367 {
1368 /* Out of memory */
1369 return STATUS_NO_MEMORY;
1370 }
1371
1372 /* Show debug message */
1373 if (ShowSnaps)
1374 {
1375 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1376 TlsVector,
1378 &TlsVector[TlsData->TlsDirectory.Characteristics],
1380 TlsVector[TlsData->TlsDirectory.Characteristics]);
1381 }
1382
1383 /* Copy the data */
1384 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1386 TlsDataSize);
1387 }
1388
1389 /* Done */
1390 return STATUS_SUCCESS;
1391}
1392
1393VOID
1394NTAPI
1396{
1397 PLIST_ENTRY ListHead, NextEntry;
1398 PLDRP_TLS_DATA TlsData;
1399 PVOID *TlsVector;
1400 PTEB Teb = NtCurrentTeb();
1401
1402 /* Get a pointer to the vector array */
1403 TlsVector = Teb->ThreadLocalStoragePointer;
1404 if (!TlsVector) return;
1405
1406 /* Loop through it */
1407 ListHead = &LdrpTlsList;
1408 NextEntry = ListHead->Flink;
1409 while (NextEntry != ListHead)
1410 {
1411 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1412 NextEntry = NextEntry->Flink;
1413
1414 /* Free each entry */
1415 if (TlsVector[TlsData->TlsDirectory.Characteristics])
1416 {
1417 RtlFreeHeap(RtlGetProcessHeap(),
1418 0,
1419 TlsVector[TlsData->TlsDirectory.Characteristics]);
1420 }
1421 }
1422
1423 /* Free the array itself */
1424 RtlFreeHeap(RtlGetProcessHeap(),
1425 0,
1426 TlsVector);
1427}
1428
1430NTAPI
1432{
1435 ULONG ExecuteOptions, MinimumStackCommit = 0, GlobalFlag;
1436
1437 /* Return error if we were not provided a pointer where to save the options key handle */
1438 if (!OptionsKey) return STATUS_INVALID_HANDLE;
1439
1440 /* Zero initialize the options key pointer */
1441 *OptionsKey = NULL;
1442
1443 /* Open the options key */
1444 Status = LdrOpenImageFileOptionsKey(ImagePathName, 0, &KeyHandle);
1445
1446 /* Save it if it was opened successfully */
1447 if (NT_SUCCESS(Status))
1448 *OptionsKey = KeyHandle;
1449
1450 if (KeyHandle)
1451 {
1452 /* There are image specific options, read them starting with NXCOMPAT */
1454 L"ExecuteOptions",
1455 4,
1456 &ExecuteOptions,
1457 sizeof(ExecuteOptions),
1458 0);
1459
1460 if (NT_SUCCESS(Status))
1461 {
1462 /* TODO: Set execution options for the process */
1463 /*
1464 if (ExecuteOptions == 0)
1465 ExecuteOptions = 1;
1466 else
1467 ExecuteOptions = 2;
1468 ZwSetInformationProcess(NtCurrentProcess(),
1469 ProcessExecuteFlags,
1470 &ExecuteOptions,
1471 sizeof(ULONG));*/
1472
1473 }
1474
1475 /* Check if this image uses large pages */
1476 if (Peb->ImageUsesLargePages)
1477 {
1478 /* TODO: If it does, open large page key */
1480 }
1481
1482 /* Get various option values */
1484 L"DisableHeapLookaside",
1485 REG_DWORD,
1488 NULL);
1489
1491 L"ShutdownFlags",
1492 REG_DWORD,
1495 NULL);
1496
1498 L"MinimumStackCommitInBytes",
1499 REG_DWORD,
1500 &MinimumStackCommit,
1501 sizeof(MinimumStackCommit),
1502 NULL);
1503
1504 /* Update PEB's minimum stack commit if it's lower */
1505 if (Peb->MinimumStackCommit < MinimumStackCommit)
1506 Peb->MinimumStackCommit = MinimumStackCommit;
1507
1508 /* Set the global flag */
1510 L"GlobalFlag",
1511 REG_DWORD,
1512 &GlobalFlag,
1513 sizeof(GlobalFlag),
1514 NULL);
1515
1516 if (NT_SUCCESS(Status))
1517 Peb->NtGlobalFlag = GlobalFlag;
1518 else
1519 GlobalFlag = 0;
1520
1521 /* Call AVRF if necessary */
1523 {
1525 if (!NT_SUCCESS(Status))
1526 {
1527 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1528 }
1529 }
1530 }
1531 else
1532 {
1533 /* There are no image-specific options, so perform global initialization */
1535 {
1536 /* Initialize app verifier package */
1538 if (!NT_SUCCESS(Status))
1539 {
1540 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1541 }
1542 }
1543 }
1544
1545 return STATUS_SUCCESS;
1546}
1547
1548VOID
1549NTAPI
1551{
1552 DPRINT("LdrpValidateImageForMp is unimplemented\n");
1553 // TODO:
1554 // Scan the LockPrefixTable in the load config directory
1555}
1556
1557BOOLEAN
1558NTAPI
1560{
1561 UNICODE_STRING PolicyKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\Software\\Policies\\Microsoft\\Windows\\AppCompat");
1562 UNICODE_STRING DisableDetection = RTL_CONSTANT_STRING(L"DisableCompatGuidDetection");
1568
1569 Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &PolicyKeyAttributes);
1570 if (NT_SUCCESS(Status))
1571 {
1573 &DisableDetection,
1575 &KeyInfo,
1576 sizeof(KeyInfo),
1577 &ResultLength);
1579 if ((NT_SUCCESS(Status)) &&
1580 (KeyInfo.Type == REG_DWORD) &&
1581 (KeyInfo.DataLength == sizeof(ULONG)) &&
1582 (KeyInfo.Data[0] == TRUE))
1583 {
1584 return TRUE;
1585 }
1586 }
1587 return FALSE;
1588}
1589
1590
1591VOID
1592NTAPI
1593LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData)
1594{
1595 static const struct
1596 {
1597 const GUID* Guid;
1598 const DWORD Version;
1599 } KnownCompatGuids[] = {
1600 { &COMPAT_GUID_WIN10, _WIN32_WINNT_WIN10 },
1601 { &COMPAT_GUID_WIN81, _WIN32_WINNT_WINBLUE },
1602 { &COMPAT_GUID_WIN8, _WIN32_WINNT_WIN8 },
1603 { &COMPAT_GUID_WIN7, _WIN32_WINNT_WIN7 },
1604 { &COMPAT_GUID_VISTA, _WIN32_WINNT_VISTA },
1605 };
1606
1607 ULONG Buffer[(sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 10 + sizeof(ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION)) / sizeof(ULONG)];
1608 ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION* ContextCompatInfo;
1609 SIZE_T SizeRequired;
1611 DWORD n, cur;
1612 ReactOS_ShimData* pShimData = *pOldShimData;
1613
1614 if (pShimData)
1615 {
1616 if (pShimData->dwMagic != REACTOS_SHIMDATA_MAGIC ||
1617 pShimData->dwSize != sizeof(ReactOS_ShimData))
1618 {
1619 DPRINT1("LdrpInitializeProcessCompat: Corrupt pShimData (0x%x, %u)\n", pShimData->dwMagic, pShimData->dwSize);
1620 return;
1621 }
1622#ifdef _M_AMD64
1623 pShimData->RtlGetCurrentDirectory_U_RtlpMsysDecoy = &RtlGetCurrentDirectory_U_RtlpMsysDecoy; /* We need this private symbol for a MSYS shim */
1624#endif
1625 if (pShimData->dwRosProcessCompatVersion)
1626 {
1628 {
1629 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion set to ignore manifest\n");
1630 }
1631 else
1632 {
1633 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion already set to 0x%x\n", pShimData->dwRosProcessCompatVersion);
1634 }
1635 return;
1636 }
1637 }
1638
1639 SizeRequired = sizeof(Buffer);
1641 pProcessActctx,
1642 NULL,
1643 CompatibilityInformationInActivationContext,
1644 Buffer,
1645 sizeof(Buffer),
1646 &SizeRequired);
1647
1648 if (!NT_SUCCESS(Status))
1649 {
1650 DPRINT1("LdrpInitializeProcessCompat: Unable to query process actctx with status %x\n", Status);
1651 return;
1652 }
1653
1654 ContextCompatInfo = (ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*)Buffer;
1655 /* No Compatibility elements present, bail out */
1656 if (ContextCompatInfo->ElementCount == 0)
1657 return;
1658
1659 /* Search for known GUIDs, starting from oldest to newest.
1660 Note that on Windows it is somewhat reversed, starting from the latest known
1661 version, going down. But we are not Windows, trying to allow a lower version,
1662 we are ReactOS trying to fake a higher version. So we interpret what Windows
1663 does as "try the closest version to the actual version", so we start with the
1664 lowest version, which is closest to Windows 2003, which we mostly are. */
1665 for (cur = RTL_NUMBER_OF(KnownCompatGuids) - 1; cur != -1; --cur)
1666 {
1667 for (n = 0; n < ContextCompatInfo->ElementCount; ++n)
1668 {
1669 if (ContextCompatInfo->Elements[n].Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS &&
1670 RtlCompareMemory(&ContextCompatInfo->Elements[n].Id, KnownCompatGuids[cur].Guid, sizeof(GUID)) == sizeof(GUID))
1671 {
1673 {
1674 DPRINT1("LdrpInitializeProcessCompat: Not applying automatic fix for winver 0x%x due to policy\n", KnownCompatGuids[cur].Version);
1675 return;
1676 }
1677
1678 /* If this process did not need shim data before, allocate and store it */
1679 if (pShimData == NULL)
1680 {
1681 PPEB Peb = NtCurrentPeb();
1682
1683 ASSERT(Peb->pShimData == NULL);
1684 pShimData = RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*pShimData));
1685
1686 if (!pShimData)
1687 {
1688 DPRINT1("LdrpInitializeProcessCompat: Unable to allocated %u bytes\n", sizeof(*pShimData));
1689 return;
1690 }
1691
1692 pShimData->dwSize = sizeof(*pShimData);
1693 pShimData->dwMagic = REACTOS_SHIMDATA_MAGIC;
1694#ifdef _M_AMD64
1695 /* 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 */
1696 pShimData->RtlGetCurrentDirectory_U_RtlpMsysDecoy = &RtlGetCurrentDirectory_U_RtlpMsysDecoy;
1697#endif
1698
1699 Peb->pShimData = pShimData;
1700 *pOldShimData = pShimData;
1701 }
1702
1703 /* Store the lowest found version, and bail out. */
1704 pShimData->dwRosProcessCompatVersion = KnownCompatGuids[cur].Version;
1705 DPRINT1("LdrpInitializeProcessCompat: Found guid for winver 0x%x in manifest from %wZ\n",
1706 KnownCompatGuids[cur].Version,
1707 &(NtCurrentPeb()->ProcessParameters->ImagePathName));
1708 return;
1709 }
1710 }
1711 }
1712}
1713
1714VOID
1715NTAPI
1717{
1718 UNICODE_STRING ImagePathName = ProcessParameters->ImagePathName;
1719 WCHAR LocalBuffer[MAX_PATH];
1720 UNICODE_STRING DotLocal;
1723
1724 RequiredSize = ImagePathName.Length + LdrpDotLocal.Length + sizeof(UNICODE_NULL);
1725 if (RequiredSize <= sizeof(LocalBuffer))
1726 {
1727 RtlInitEmptyUnicodeString(&DotLocal, LocalBuffer, sizeof(LocalBuffer));
1728 }
1730 {
1731 DotLocal.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RequiredSize);
1732 DotLocal.Length = 0;
1733 DotLocal.MaximumLength = RequiredSize;
1734 if (!DotLocal.Buffer)
1735 DPRINT1("LDR: Failed to allocate memory for .local check\n");
1736 }
1737 else
1738 {
1739 DotLocal.Buffer = NULL;
1740 DotLocal.Length = 0;
1741 DotLocal.MaximumLength = 0;
1742 DPRINT1("LDR: String too big for .local check\n");
1743 }
1744
1745 if (DotLocal.Buffer)
1746 {
1747 Status = RtlAppendUnicodeStringToString(&DotLocal, &ImagePathName);
1749 if (NT_SUCCESS(Status))
1750 {
1753 }
1754
1755 if (NT_SUCCESS(Status))
1756 {
1757 if (RtlDoesFileExists_UStr(&DotLocal))
1758 {
1760 }
1761 }
1762 else
1763 {
1764 DPRINT1("LDR: Failed to append: 0x%lx\n", Status);
1765 }
1766
1767 if (DotLocal.Buffer != LocalBuffer)
1768 {
1769 RtlFreeHeap(RtlGetProcessHeap(), 0, DotLocal.Buffer);
1770 }
1771 }
1772}
1773
1774
1776NTAPI
1779{
1780 RTL_HEAP_PARAMETERS HeapParameters;
1781 ULONG ComSectionSize;
1782 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1783 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1784 PVOID OldShimData;
1786 //UNICODE_STRING LocalFileName, FullImageName;
1787 HANDLE SymLinkHandle;
1788 //ULONG DebugHeapOnly;
1789 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1790 PPEB Peb = NtCurrentPeb();
1791 BOOLEAN IsDotNetImage = FALSE;
1792 BOOLEAN FreeCurDir = FALSE;
1793 //HANDLE CompatKey;
1794 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1795 //LPWSTR ImagePathBuffer;
1796 ULONG ConfigSize;
1798 HANDLE OptionsKey;
1799 ULONG HeapFlags;
1800 PIMAGE_NT_HEADERS NtHeader;
1801 LPWSTR NtDllName = NULL;
1802 NTSTATUS Status, ImportStatus;
1803 NLSTABLEINFO NlsTable;
1805 PTEB Teb = NtCurrentTeb();
1806 PLIST_ENTRY ListHead;
1807 PLIST_ENTRY NextEntry;
1808 ULONG i;
1809 PWSTR ImagePath;
1810 ULONG DebugProcessHeapOnly = 0;
1811 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1812 PWCHAR Current;
1813 ULONG ExecuteOptions = 0;
1814 PVOID ViewBase;
1815
1816 /* Set a NULL SEH Filter */
1818
1819 /* Get the image path */
1821
1822 /* Check if it's not normalized */
1824 {
1825 /* Normalize it*/
1826 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1827 }
1828
1829 /* Create a unicode string for the Image Path */
1831 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1832 ImagePathName.Buffer = ImagePath;
1833
1834 /* Get the NT Headers */
1836
1837 /* Get the execution options */
1838 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1839
1840 /* Check if this is a .NET executable */
1842 TRUE,
1844 &ComSectionSize))
1845 {
1846 /* Remember this for later */
1847 IsDotNetImage = TRUE;
1848 }
1849
1850 /* Save the NTDLL Base address */
1852
1853 /* If this is a Native Image */
1855 {
1856 /* Then do DLL Validation */
1858 }
1859
1860 /* Save the old Shim Data */
1861 OldShimData = Peb->pShimData;
1862
1863 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1864 //Peb->pShimData = NULL;
1865
1866 /* Save the number of processors and CS timeout */
1869
1870 /* Normalize the parameters */
1871 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1872 if (ProcessParameters)
1873 {
1874 /* Save the Image and Command Line Names */
1875 ImageFileName = ProcessParameters->ImagePathName;
1876 CommandLine = ProcessParameters->CommandLine;
1877 }
1878 else
1879 {
1880 /* It failed, initialize empty strings */
1881 RtlInitUnicodeString(&ImageFileName, NULL);
1882 RtlInitUnicodeString(&CommandLine, NULL);
1883 }
1884
1885 /* Initialize NLS data */
1889 &NlsTable);
1890
1891 /* Reset NLS Translations */
1892 RtlResetRtlTranslations(&NlsTable);
1893
1894 /* Get the Image Config Directory */
1896 TRUE,
1898 &ConfigSize);
1899
1900 /* Setup the Heap Parameters */
1901 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1902 HeapFlags = HEAP_GROWABLE;
1903 HeapParameters.Length = sizeof(HeapParameters);
1904
1905 /* Check if we have Configuration Data */
1906#define VALID_CONFIG_FIELD(Name) (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
1907 /* The 'original' load config ends after SecurityCookie */
1908 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1909 {
1910 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1911 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1912 else
1913 DPRINT1("Applying LOAD_CONFIG\n");
1914
1915 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1916 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1917
1918 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1919 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1920
1921 /* Convert the default CS timeout from milliseconds to 100ns units */
1922 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1923 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000);
1924
1925 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1926 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1927
1928 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1929 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1930
1931 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1932 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1933
1934 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1935 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1936
1937 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1938 HeapFlags = LoadConfig->ProcessHeapFlags;
1939 }
1940#undef VALID_CONFIG_FIELD
1941
1942 /* Check for custom affinity mask */
1944 {
1945 /* Set it */
1949 sizeof(Peb->ImageProcessAffinityMask));
1950 }
1951
1952 /* Check if verbose debugging (ShowSnaps) was requested */
1954
1955 /* Start verbose debugging messages right now if they were requested */
1956 if (ShowSnaps)
1957 {
1958 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1960 &CommandLine);
1961 }
1962
1963 /* If the CS timeout is longer than 1 hour, disable it */
1964 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1966
1967 /* Initialize Critical Section Data */
1969
1970 /* Initialize VEH Call lists */
1972
1973 /* Set TLS/FLS Bitmap data */
1977
1978 /* Initialize FLS Bitmap */
1982 RtlSetBit(&FlsBitMap, 0);
1984
1985 /* Initialize TLS Bitmap */
1989 RtlSetBit(&TlsBitMap, 0);
1994
1995 /* Initialize the Hash Table */
1996 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1997 {
1999 }
2000
2001 /* Initialize the Loader Lock */
2002 // FIXME: What's the point of initing it manually, if two lines lower
2003 // a call to RtlInitializeCriticalSection() is being made anyway?
2004 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
2005 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
2008
2009 /* Check if User Stack Trace Database support was requested */
2011 {
2012 DPRINT1("We don't support user stack trace databases yet\n");
2013 }
2014
2015 /* Setup Fast PEB Lock */
2018 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
2019 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
2020
2021 /* Setup Callout Lock */
2022 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2023
2024 /* For old executables, use 16-byte aligned heap */
2025 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2026 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2027 {
2028 HeapFlags |= HEAP_CREATE_ALIGN_16;
2029 }
2030
2031 /* Setup the Heap */
2033 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2034 NULL,
2037 NULL,
2038 &HeapParameters);
2039
2040 if (!Peb->ProcessHeap)
2041 {
2042 DPRINT1("Failed to create process heap\n");
2043 return STATUS_NO_MEMORY;
2044 }
2045
2047 if (!NT_SUCCESS(Status))
2048 {
2049 DPRINT1("Failed to initialize locale table\n");
2050 return Status;
2051 }
2052
2053 /* Allocate an Activation Context Stack */
2054 Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
2055 if (!NT_SUCCESS(Status)) return Status;
2056
2057 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2058 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2059 HeapParameters.Length = sizeof(HeapParameters);
2060 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2061 if (!LdrpHeap)
2062 {
2063 DPRINT1("Failed to create loader private heap\n");
2064 return STATUS_NO_MEMORY;
2065 }
2066
2067 /* Check for Debug Heap */
2068 if (OptionsKey)
2069 {
2070 /* Query the setting */
2072 L"DebugProcessHeapOnly",
2073 REG_DWORD,
2074 &DebugProcessHeapOnly,
2075 sizeof(ULONG),
2076 NULL);
2077
2078 if (NT_SUCCESS(Status))
2079 {
2080 /* Reset DPH if requested */
2081 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2082 {
2083 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2085 }
2086 }
2087 }
2088
2089 /* Build the NTDLL Path */
2090 FullPath.Buffer = StringBuffer;
2091 FullPath.Length = 0;
2092 FullPath.MaximumLength = sizeof(StringBuffer);
2095 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2096
2097 /* Open the Known DLLs directory */
2098 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2100 &KnownDllString,
2102 NULL,
2103 NULL);
2107
2108 /* Check if it exists */
2109 if (NT_SUCCESS(Status))
2110 {
2111 /* Open the Known DLLs Path */
2112 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2114 &KnownDllString,
2117 NULL);
2118 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2121 if (NT_SUCCESS(Status))
2122 {
2123 /* Query the path */
2127 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2128 NtClose(SymLinkHandle);
2129 if (!NT_SUCCESS(Status))
2130 {
2131 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2132 return Status;
2133 }
2134 }
2135 }
2136
2137 /* Check if we failed */
2138 if (!NT_SUCCESS(Status))
2139 {
2140 /* Assume System32 */
2143 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2144 }
2145
2146 /* If we have process parameters, get the default path and current path */
2147 if (ProcessParameters)
2148 {
2149 /* Check if we have a Dll Path */
2150 if (ProcessParameters->DllPath.Length)
2151 {
2152 /* Get the path */
2153 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2154 }
2155 else
2156 {
2157 /* We need a valid path */
2158 DPRINT1("No valid DllPath was given!\n");
2160 }
2161
2162 /* Set the current directory */
2163 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2164
2165 /* Check if it's empty or invalid */
2166 if ((!CurrentDirectory.Buffer) ||
2167 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2168 (!CurrentDirectory.Length))
2169 {
2170 /* Allocate space for the buffer */
2172 0,
2173 3 * sizeof(WCHAR) +
2174 sizeof(UNICODE_NULL));
2175 if (!CurrentDirectory.Buffer)
2176 {
2177 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2178 // FIXME: And what?
2179 }
2180
2181 /* Copy the drive of the system root */
2183 SharedUserData->NtSystemRoot,
2184 3 * sizeof(WCHAR));
2185 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2186 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2187 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2188
2189 FreeCurDir = TRUE;
2190 DPRINT("Using dynamically allocd curdir\n");
2191 }
2192 else
2193 {
2194 /* Use the local buffer */
2195 DPRINT("Using local system root\n");
2196 }
2197 }
2198
2199 /* Setup Loader Data */
2200 Peb->Ldr = &PebLdr;
2204 PebLdr.Length = sizeof(PEB_LDR_DATA);
2206
2207 /* Allocate a data entry for the Image */
2209
2210 /* Set it up */
2214 LdrpImageEntry->FullDllName = ImageFileName;
2215
2216 if (IsDotNetImage)
2218 else
2219 LdrpImageEntry->Flags = 0;
2220
2221 /* Check if the name is empty */
2222 if (!ImageFileName.Buffer[0])
2223 {
2224 /* Use the same Base name */
2226 }
2227 else
2228 {
2229 /* Find the last slash */
2230 Current = ImageFileName.Buffer;
2231 while (*Current)
2232 {
2233 if (*Current++ == '\\')
2234 {
2235 /* Set this path */
2236 NtDllName = Current;
2237 }
2238 }
2239
2240 /* Did we find anything? */
2241 if (!NtDllName)
2242 {
2243 /* Use the same Base name */
2245 }
2246 else
2247 {
2248 /* Setup the name */
2249 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2252 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2253 }
2254 }
2255
2256 /* Processing done, insert it */
2259
2260 /* Now add an entry for NTDLL */
2262 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2263 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2264 NtLdrEntry->LoadCount = -1;
2265 NtLdrEntry->EntryPointActivationContext = 0;
2266
2267 NtLdrEntry->FullDllName.Length = FullPath.Length;
2268 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2269 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2271
2272 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2274 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2275
2276 /* Processing done, insert it */
2277 LdrpNtDllDataTableEntry = NtLdrEntry;
2278 LdrpInsertMemoryTableEntry(NtLdrEntry);
2279
2280 /* Let the world know */
2281 if (ShowSnaps)
2282 {
2283 DPRINT1("LDR: NEW PROCESS\n");
2284 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2285 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2286 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2287 }
2288
2289 /* Link the Init Order List */
2292
2293 /* Initialize Wine's active context implementation for the current process */
2294 RtlpInitializeActCtx(&OldShimData);
2295
2296 /* Set the current directory */
2298 if (!NT_SUCCESS(Status))
2299 {
2300 /* We failed, check if we should free it */
2301 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2302
2303 /* Set it to the NT Root */
2306 }
2307 else
2308 {
2309 /* We're done with it, free it */
2310 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2311 }
2312
2313 /* Check if we should look for a .local file */
2314 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2315 {
2316 LdrpInitializeDotLocalSupport(ProcessParameters);
2317 }
2318
2319 /* Check if the Application Verifier was enabled */
2321 {
2323 if (!NT_SUCCESS(Status))
2324 {
2325 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2326 return Status;
2327 }
2328
2329 }
2330
2331 if (IsDotNetImage)
2332 {
2333 /* FIXME */
2334 DPRINT1("We don't support .NET applications yet\n");
2335 }
2336
2339 {
2340 PVOID Kernel32BaseAddress;
2341 PVOID FunctionAddress;
2342
2343 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2344
2345 if (!NT_SUCCESS(Status))
2346 {
2347 if (ShowSnaps)
2348 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2349 return Status;
2350 }
2351
2352 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2353 &BaseProcessInitPostImportName,
2354 0,
2355 &FunctionAddress);
2356
2357 if (!NT_SUCCESS(Status))
2358 {
2359 if (ShowSnaps)
2360 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", Status);
2361 return Status;
2362 }
2363 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2364
2365 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2366 &BaseQueryModuleDataName,
2367 0,
2368 &FunctionAddress);
2369
2370 if (!NT_SUCCESS(Status))
2371 {
2372 if (ShowSnaps)
2373 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", Status);
2374 return Status;
2375 }
2376 Kernel32BaseQueryModuleData = FunctionAddress;
2377 }
2378
2379 /* Walk the IAT and load all the DLLs */
2381
2382 /* Check if relocation is needed */
2384 {
2385 DPRINT1("LDR: Performing EXE relocation\n");
2386
2387 /* Change the protection to prepare for relocation */
2388 ViewBase = Peb->ImageBaseAddress;
2389 Status = LdrpSetProtection(ViewBase, FALSE);
2390 if (!NT_SUCCESS(Status)) return Status;
2391
2392 /* Do the relocation */
2394 0LL,
2395 NULL,
2399 if (!NT_SUCCESS(Status))
2400 {
2401 DPRINT1("LdrRelocateImageWithBias() failed\n");
2402 return Status;
2403 }
2404
2405 /* Check if a start context was provided */
2406 if (Context)
2407 {
2408 DPRINT1("WARNING: Relocated EXE Context");
2409 UNIMPLEMENTED; // We should support this
2411 }
2412
2413 /* Restore the protection */
2414 Status = LdrpSetProtection(ViewBase, TRUE);
2415 if (!NT_SUCCESS(Status)) return Status;
2416 }
2417
2418 /* Lock the DLLs */
2419 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2420 NextEntry = ListHead->Flink;
2421 while (ListHead != NextEntry)
2422 {
2423 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2424 NtLdrEntry->LoadCount = -1;
2425 NextEntry = NextEntry->Flink;
2426 }
2427
2428 /* Phase 0 is done */
2430
2431 /* Check whether all static imports were properly loaded and return here */
2432 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2433
2434 /* Following two calls are for Vista+ support, required for winesync */
2435 /* Initialize the keyed event for condition variables */
2438
2439 /* Initialize TLS */
2441 if (!NT_SUCCESS(Status))
2442 {
2443 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2444 Status);
2445 return Status;
2446 }
2447
2448 /* FIXME Mark the DLL Ranges for Stack Traces later */
2449
2450 /* Notify the debugger now */
2451 if (Peb->BeingDebugged)
2452 {
2453 /* Break */
2454 DbgBreakPoint();
2455
2456 /* Update show snaps again */
2458 }
2459
2460 /* Validate the Image for MP Usage */
2462
2463 /* Check NX options and set them */
2464 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2465 {
2466 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2469 }
2470 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2471 {
2473 }
2476 &ExecuteOptions,
2477 sizeof(ExecuteOptions));
2478 if (!NT_SUCCESS(Status))
2479 {
2480 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2481 ExecuteOptions, Status);
2482 }
2483
2484 // FIXME: Should be done by Application Compatibility features,
2485 // by reading the registry, etc...
2486 // For now, this is the old code from ntdll!RtlGetVersion().
2487 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2488 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2489 {
2490 WCHAR szCSDVersion[128];
2491 LONG i;
2492 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2493 i = _snwprintf(szCSDVersion, Length,
2494 L"Service Pack %d",
2495 ((Peb->OSCSDVersion >> 8) & 0xFF));
2496 if (i < 0)
2497 {
2498 /* Null-terminate if it was overflowed */
2499 szCSDVersion[Length] = UNICODE_NULL;
2500 }
2501
2502 Length *= sizeof(WCHAR);
2503 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2504 0,
2505 Length + sizeof(UNICODE_NULL));
2506 if (Peb->CSDVersion.Buffer)
2507 {
2510
2512 szCSDVersion,
2515 }
2516 }
2517
2518 /* Check if we had Shim Data */
2519 if (OldShimData)
2520 {
2521 /* Load the Shim Engine */
2523 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2524 }
2525 else
2526 {
2527 /* Check for Application Compatibility Goo */
2528 //LdrQueryApplicationCompatibilityGoo(hKey);
2529 DPRINT("Querying app compat hacks is missing!\n");
2530 }
2531
2532 /*
2533 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2534 * incompatible images.
2535 */
2536
2537 /* Now call the Init Routines */
2539 if (!NT_SUCCESS(Status))
2540 {
2541 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2542 Status);
2543 return Status;
2544 }
2545
2546 /* Notify Shim Engine */
2547 if (g_ShimsEnabled)
2548 {
2551 SE_InstallAfterInit(&ImagePathName, OldShimData);
2552 }
2553
2554 /* Check if we have a user-defined Post Process Routine */
2556 {
2557 /* Call it */
2559 }
2560
2561 /* Close the key if we have one opened */
2562 if (OptionsKey) NtClose(OptionsKey);
2563
2564 /* Return status */
2565 return Status;
2566}
2567
2568VOID
2569NTAPI
2571{
2573 PPEB Peb = NtCurrentPeb();
2574
2575 /* Print a debug message */
2576 DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2578
2579 /* Raise a hard error */
2581 {
2583 }
2584}
2585
2586VOID
2587NTAPI
2591{
2593 PTEB Teb = NtCurrentTeb();
2594 NTSTATUS Status, LoaderStatus = STATUS_SUCCESS;
2595 MEMORY_BASIC_INFORMATION MemoryBasicInfo;
2596 PPEB Peb = NtCurrentPeb();
2597
2598 DPRINT("LdrpInit() %p/%p\n",
2599 NtCurrentTeb()->RealClientId.UniqueProcess,
2600 NtCurrentTeb()->RealClientId.UniqueThread);
2601
2602#ifdef _WIN64
2603 /* Set the SList header usage */
2605#endif /* _WIN64 */
2606
2607 /* Check if we have a deallocation stack */
2608 if (!Teb->DeallocationStack)
2609 {
2610 /* We don't, set one */
2612 Teb->NtTib.StackLimit,
2614 &MemoryBasicInfo,
2616 NULL);
2617 if (!NT_SUCCESS(Status))
2618 {
2619 /* Fail */
2622 return;
2623 }
2624
2625 /* Set the stack */
2626 Teb->DeallocationStack = MemoryBasicInfo.AllocationBase;
2627 }
2628
2629 /* Now check if the process is already being initialized */
2631 1,
2632 0) == 1)
2633 {
2634 /* Set the timeout to 30 milliseconds */
2635 Timeout.QuadPart = Int32x32To64(30, -10000);
2636
2637 /* Make sure the status hasn't changed */
2638 while (LdrpProcessInitialized == 1)
2639 {
2640 /* Do the wait */
2642 }
2643 }
2644
2645 /* Check if we have already setup LDR data */
2646 if (!Peb->Ldr)
2647 {
2648 /* Setup the Loader Lock */
2650
2651 /* Let other code know we're initializing */
2653
2654 /* Protect with SEH */
2655 _SEH2_TRY
2656 {
2657 /* Initialize the Process */
2658 LoaderStatus = LdrpInitializeProcess(Context,
2660
2661 /* Check for success and if MinimumStackCommit was requested */
2662 if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit)
2663 {
2664 /* Enforce the limit */
2665 //LdrpTouchThreadStack(Peb->MinimumStackCommit);
2667 }
2668 }
2670 {
2671 /* Fail with the SEH error */
2672 LoaderStatus = _SEH2_GetExceptionCode();
2673 }
2674 _SEH2_END;
2675
2676 /* We're not initializing anymore */
2678
2679 /* Check if init worked */
2680 if (NT_SUCCESS(LoaderStatus))
2681 {
2682 /* Set the process as Initialized */
2684 }
2685 }
2686 else
2687 {
2688 /* Loader data is there... is this a fork() ? */
2690 {
2691 /* Handle the fork() */
2692 //LoaderStatus = LdrpForkProcess();
2693 LoaderStatus = STATUS_NOT_IMPLEMENTED;
2695 }
2696 else
2697 {
2698 /* This is a new thread initializing */
2700 }
2701 }
2702
2703 /* All done, test alert the thread */
2704 NtTestAlert();
2705
2706 /* Return */
2707 if (!NT_SUCCESS(LoaderStatus))
2708 {
2709 /* Fail */
2710 LdrpInitFailure(LoaderStatus);
2711 RtlRaiseStatus(LoaderStatus);
2712 }
2713}
2714
2715/* 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
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
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_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlSetBit
Definition: dbgbitmap.h:344
#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 ARRAYSIZE(array)
Definition: filtermapper.c:47
#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:1493
#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:25
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:67
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:57
#define FLG_HEAP_PAGE_ALLOCS
Definition: pstypes.h:84
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:311
#define FLG_APPLICATION_VERIFIER
Definition: pstypes.h:64
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
#define NtCurrentTeb
#define REG_SZ
Definition: layer.c:22
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:1716
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:2588
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:1395
static IN LPSTR IN PVOID IN PVOID Unk3
Definition: ldrinit.c:47
VOID NTAPI RtlpInitDeferredCriticalSection(VOID)
Definition: critical.c:272
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
NTSTATUS NTAPI LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
Definition: ldrinit.c:1431
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:25
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)
Definition: locale.c:529
#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:1550
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:1777
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:1559
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:2570
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:1593
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1269
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:26
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:1332
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:106
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:187
NTSYSAPI NTSTATUS NTAPI ZwDelayExecution(_In_ BOOLEAN Alertable, _In_ LARGE_INTEGER *Interval)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#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:119
#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:336
#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:3402
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:2757
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:2649
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:76
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:1389
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
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:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#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
_In_ PVOID Context
Definition: storport.h:2269
Definition: ncftp.h:89
HANDLE UniqueProcess
Definition: compat.h:825
UNICODE_STRING DosPath
Definition: rtltypes.h:1362
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:1217
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE]
Definition: rtltypes.h:1218
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:166
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
#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
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
#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_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782
_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
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_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:1202
#define WINAPI
Definition: msvc.h:6
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:84
NTSYSAPI void WINAPI RtlSetUnhandledExceptionFilter(PRTL_EXCEPTION_FILTER)
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:74
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:1093
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:1137
_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:740
#define NX_SUPPORT_POLICY_ALWAYSON
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:741
#define PF_COMPARE_EXCHANGE128
Definition: ketypes.h:190
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182