ReactOS 0.4.15-dev-5666-gc548b97
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
66
68
71{
73 -1,
74 0,
75 0,
76 0,
77 0
78};
80
82
85
86//extern LIST_ENTRY RtlCriticalSectionList;
87
91
92ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c
94
96void actctx_init(PVOID* pOldShimData);
98
99#ifdef _WIN64
100#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
101#else
102#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
103#endif
104
105/* FUNCTIONS *****************************************************************/
106
107/*
108 * @implemented
109 */
111NTAPI
113 IN BOOLEAN Wow64,
114 OUT PHANDLE NewKeyHandle)
115{
116 PHANDLE RootKeyLocation;
118 UNICODE_STRING SubKeyString;
121 PWCHAR p1;
122
123 /* Check which root key to open */
124 if (Wow64)
125 RootKeyLocation = &Wow64ExecOptionsKey;
126 else
127 RootKeyLocation = &ImageExecOptionsKey;
128
129 /* Get the current key */
130 RootKey = *RootKeyLocation;
131
132 /* Setup the object attributes */
134 Wow64 ?
137 NULL,
138 NULL);
139
140 /* Open the root key */
142 if (NT_SUCCESS(Status))
143 {
144 /* Write the key handle */
145 if (InterlockedCompareExchangePointer(RootKeyLocation, RootKey, NULL) != NULL)
146 {
147 /* Someone already opened it, use it instead */
149 RootKey = *RootKeyLocation;
150 }
151
152 /* Extract the name */
153 SubKeyString = *SubKey;
154 p1 = (PWCHAR)((ULONG_PTR)SubKeyString.Buffer + SubKeyString.Length);
155 while (SubKeyString.Length)
156 {
157 if (p1[-1] == L'\\') break;
158 p1--;
159 SubKeyString.Length -= sizeof(*p1);
160 }
161 SubKeyString.Buffer = p1;
162 SubKeyString.Length = SubKey->Length - SubKeyString.Length;
163
164 /* Setup the object attributes */
166 &SubKeyString,
168 RootKey,
169 NULL);
170
171 /* Open the setting key */
172 Status = ZwOpenKey((PHANDLE)NewKeyHandle, GENERIC_READ, &ObjectAttributes);
173 }
174
175 /* Return to caller */
176 return Status;
177}
178
179/*
180 * @implemented
181 */
183NTAPI
186 IN ULONG Type,
190{
191 ULONG KeyInfo[256];
192 UNICODE_STRING ValueNameString, IntegerString;
193 ULONG KeyInfoSize, ResultSize;
195 BOOLEAN FreeHeap = FALSE;
197
198 /* Build a string for the value name */
199 Status = RtlInitUnicodeStringEx(&ValueNameString, ValueName);
200 if (!NT_SUCCESS(Status)) return Status;
201
202 /* Query the value */
203 Status = ZwQueryValueKey(KeyHandle,
204 &ValueNameString,
206 KeyValueInformation,
207 sizeof(KeyInfo),
208 &ResultSize);
210 {
211 /* Our local buffer wasn't enough, allocate one */
212 KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
213 KeyValueInformation->DataLength;
214 KeyValueInformation = RtlAllocateHeap(RtlGetProcessHeap(),
215 0,
216 KeyInfoSize);
217 if (KeyValueInformation != NULL)
218 {
219 /* Try again */
220 Status = ZwQueryValueKey(KeyHandle,
221 &ValueNameString,
223 KeyValueInformation,
224 KeyInfoSize,
225 &ResultSize);
226 FreeHeap = TRUE;
227 }
228 else
229 {
230 /* Give up this time */
232 }
233 }
234
235 /* Check for success */
236 if (NT_SUCCESS(Status))
237 {
238 /* Handle binary data */
239 if (KeyValueInformation->Type == REG_BINARY)
240 {
241 /* Check validity */
242 if ((Buffer) && (KeyValueInformation->DataLength <= BufferSize))
243 {
244 /* Copy into buffer */
246 &KeyValueInformation->Data,
247 KeyValueInformation->DataLength);
248 }
249 else
250 {
252 }
253
254 /* Copy the result length */
255 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
256 }
257 else if (KeyValueInformation->Type == REG_DWORD)
258 {
259 /* Check for valid type */
260 if (KeyValueInformation->Type != Type)
261 {
262 /* Error */
264 }
265 else
266 {
267 /* Check validity */
268 if ((Buffer) &&
269 (BufferSize == sizeof(ULONG)) &&
270 (KeyValueInformation->DataLength <= BufferSize))
271 {
272 /* Copy into buffer */
274 &KeyValueInformation->Data,
275 KeyValueInformation->DataLength);
276 }
277 else
278 {
280 }
281
282 /* Copy the result length */
283 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
284 }
285 }
286 else if (KeyValueInformation->Type != REG_SZ)
287 {
288 /* We got something weird */
290 }
291 else
292 {
293 /* String, check what you requested */
294 if (Type == REG_DWORD)
295 {
296 /* Validate */
297 if (BufferSize != sizeof(ULONG))
298 {
299 /* Invalid size */
300 BufferSize = 0;
302 }
303 else
304 {
305 /* OK, we know what you want... */
306 IntegerString.Buffer = (PWSTR)KeyValueInformation->Data;
307 IntegerString.Length = (USHORT)KeyValueInformation->DataLength -
308 sizeof(WCHAR);
309 IntegerString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
310 Status = RtlUnicodeStringToInteger(&IntegerString, 0, (PULONG)Buffer);
311 }
312 }
313 else
314 {
315 /* Validate */
316 if (KeyValueInformation->DataLength > BufferSize)
317 {
318 /* Invalid */
320 }
321 else
322 {
323 /* Set the size */
324 BufferSize = KeyValueInformation->DataLength;
325 }
326
327 /* Copy the string */
328 RtlMoveMemory(Buffer, &KeyValueInformation->Data, BufferSize);
329 }
330
331 /* Copy the result length */
332 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
333 }
334 }
335
336 /* Check if buffer was in heap */
337 if (FreeHeap) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
338
339 /* Return status */
340 return Status;
341}
342
343/*
344 * @implemented
345 */
347NTAPI
350 IN ULONG Type,
354 IN BOOLEAN Wow64)
355{
358
359 /* Open a handle to the key */
361
362 /* Check for success */
363 if (NT_SUCCESS(Status))
364 {
365 /* Query the data */
367 ValueName,
368 Type,
369 Buffer,
372
373 /* Close the key */
375 }
376
377 /* Return to caller */
378 return Status;
379}
380
381/*
382 * @implemented
383 */
385NTAPI
388 IN ULONG Type,
392{
393 /* Call the newer function */
395 ValueName,
396 Type,
397 Buffer,
400 FALSE);
401}
402
403VOID
404NTAPI
406{
407 // Ignored atm
408}
409
410PVOID
411NTAPI
413{
415 ULONG DirSize;
416 PVOID Cookie = NULL;
417
418 /* Check NT header first */
419 if (!RtlImageNtHeader(BaseAddress)) return NULL;
420
421 /* Get the pointer to the config directory */
423 TRUE,
425 &DirSize);
426
427 /* Check for sanity */
428 if (!ConfigDir ||
429 (DirSize != 64 && ConfigDir->Size != DirSize) ||
430 (ConfigDir->Size < 0x48))
431 return NULL;
432
433 /* Now get the cookie */
434 Cookie = (PVOID)ConfigDir->SecurityCookie;
435
436 /* Check this cookie */
438 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
439 {
440 Cookie = NULL;
441 }
442
443 /* Return validated security cookie */
444 return Cookie;
445}
446
447PVOID
448NTAPI
450{
453 ULONG_PTR NewCookie;
454
455 /* Fetch address of the cookie */
457
458 if (Cookie)
459 {
460 /* Check if it's a default one */
462 (*Cookie == 0xBB40))
463 {
464 /* Make up a cookie from a bunch of values which may uniquely represent
465 current moment of time, environment, etc */
467
468 NewCookie = Counter.LowPart ^ Counter.HighPart;
469 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueProcess;
470 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueThread;
471
472 /* Loop like it's done in KeQueryTickCount(). We don't want to call it directly. */
473 while (SharedUserData->SystemTime.High1Time != SharedUserData->SystemTime.High2Time)
474 {
476 };
477
478 /* Calculate the milliseconds value and xor it to the cookie */
479 NewCookie ^= Int64ShrlMod32(UInt32x32To64(SharedUserData->TickCountMultiplier, SharedUserData->TickCount.LowPart), 24) +
480 (SharedUserData->TickCountMultiplier * (SharedUserData->TickCount.High1Time << 8));
481
482 /* Make the cookie 16bit if necessary */
483 if (*Cookie == 0xBB40) NewCookie &= 0xFFFF;
484
485 /* If the result is 0 or the same as we got, just subtract one from the existing value
486 and that's it */
487 if ((NewCookie == 0) || (NewCookie == *Cookie))
488 {
489 NewCookie = *Cookie - 1;
490 }
491
492 /* Set the new cookie value */
493 *Cookie = NewCookie;
494 }
495 }
496
497 return Cookie;
498}
499
500VOID
501NTAPI
503{
505 PLDR_DATA_TABLE_ENTRY LdrEntry;
506 PLIST_ENTRY NextEntry, ListHead;
507 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
509 PVOID EntryPoint;
510
511 DPRINT("LdrpInitializeThread() called for %wZ (%p/%p)\n",
513 NtCurrentTeb()->RealClientId.UniqueProcess,
514 NtCurrentTeb()->RealClientId.UniqueThread);
515
516 /* Allocate an Activation Context Stack */
517 DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
518 Status = RtlAllocateActivationContextStack(&NtCurrentTeb()->ActivationContextStackPointer);
519 if (!NT_SUCCESS(Status))
520 {
521 DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
522 }
523
524 /* Make sure we are not shutting down */
525 if (LdrpShutdownInProgress) return;
526
527 /* Allocate TLS */
529
530 /* Start at the beginning */
531 ListHead = &Peb->Ldr->InMemoryOrderModuleList;
532 NextEntry = ListHead->Flink;
533 while (NextEntry != ListHead)
534 {
535 /* Get the current entry */
536 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
537
538 /* Make sure it's not ourselves */
539 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
540 {
541 /* Check if we should call */
542 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS))
543 {
544 /* Get the entrypoint */
545 EntryPoint = LdrEntry->EntryPoint;
546
547 /* Check if we are ready to call it */
548 if ((EntryPoint) &&
549 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
550 (LdrEntry->Flags & LDRP_IMAGE_DLL))
551 {
552 /* Set up the Act Ctx */
553 ActCtx.Size = sizeof(ActCtx);
554 ActCtx.Format = 1;
556
557 /* Activate the ActCtx */
560
562 {
563 /* Check if it has TLS */
564 if (LdrEntry->TlsIndex)
565 {
566 /* Make sure we're not shutting down */
568 {
569 /* Call TLS */
571 }
572 }
573
574 /* Make sure we're not shutting down */
576 {
577 /* Call the Entrypoint */
578 DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
579 &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
580 NtCurrentTeb()->RealClientId.UniqueProcess,
581 NtCurrentTeb()->RealClientId.UniqueThread);
583 LdrEntry->DllBase,
585 NULL);
586 }
587 }
589 {
590 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_ATTACH) for %wZ\n",
591 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
592 }
593 _SEH2_END;
594
595 /* Deactivate the ActCtx */
597 }
598 }
599 }
600
601 /* Next entry */
602 NextEntry = NextEntry->Flink;
603 }
604
605 /* Check for TLS */
607 {
608 /* Set up the Act Ctx */
609 ActCtx.Size = sizeof(ActCtx);
610 ActCtx.Format = 1;
612
613 /* Activate the ActCtx */
616
618 {
619 /* Do TLS callbacks */
621 }
623 {
624 /* Do nothing */
625 }
626 _SEH2_END;
627
628 /* Deactivate the ActCtx */
630 }
631
632 DPRINT("LdrpInitializeThread() done\n");
633}
634
636NTAPI
638{
639 PLDR_DATA_TABLE_ENTRY LocalArray[16];
640 PLIST_ENTRY ListHead;
641 PLIST_ENTRY NextEntry;
642 PLDR_DATA_TABLE_ENTRY LdrEntry, *LdrRootEntry, OldInitializer;
643 PVOID EntryPoint;
644 ULONG Count, i;
645 //ULONG BreakOnInit;
648 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
649 ULONG BreakOnDllLoad;
650 PTEB OldTldTeb;
651 BOOLEAN DllStatus;
652
653 DPRINT("LdrpRunInitializeRoutines() called for %wZ (%p/%p)\n",
655 NtCurrentTeb()->RealClientId.UniqueProcess,
656 NtCurrentTeb()->RealClientId.UniqueThread);
657
658 /* Check the Loader Lock */
660
661 /* Get the number of entries to call */
663 {
664 /* Check if we can use our local buffer */
665 if (Count > 16)
666 {
667 /* Allocate space for all the entries */
668 LdrRootEntry = RtlAllocateHeap(LdrpHeap,
669 0,
670 Count * sizeof(*LdrRootEntry));
671 if (!LdrRootEntry) return STATUS_NO_MEMORY;
672 }
673 else
674 {
675 /* Use our local array */
676 LdrRootEntry = LocalArray;
677 }
678 }
679 else
680 {
681 /* Don't need one */
682 LdrRootEntry = NULL;
683 }
684
685 /* Show debug message */
686 if (ShowSnaps)
687 {
688 DPRINT1("[%p,%p] LDR: Real INIT LIST for Process %wZ\n",
689 NtCurrentTeb()->RealClientId.UniqueThread,
690 NtCurrentTeb()->RealClientId.UniqueProcess,
692 }
693
694 /* Loop in order */
696 NextEntry = ListHead->Flink;
697 i = 0;
698 while (NextEntry != ListHead)
699 {
700 /* Get the Data Entry */
701 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
702
703 /* Check if we have a Root Entry */
704 if (LdrRootEntry)
705 {
706 /* Check flags */
707 if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
708 {
709 /* Setup the Cookie for the DLL */
710 LdrpInitSecurityCookie(LdrEntry);
711
712 /* Check for valid entrypoint */
713 if (LdrEntry->EntryPoint)
714 {
715 /* Write in array */
716 ASSERT(i < Count);
717 LdrRootEntry[i] = LdrEntry;
718
719 /* Display debug message */
720 if (ShowSnaps)
721 {
722 DPRINT1("[%p,%p] LDR: %wZ init routine %p\n",
723 NtCurrentTeb()->RealClientId.UniqueThread,
724 NtCurrentTeb()->RealClientId.UniqueProcess,
725 &LdrEntry->FullDllName,
726 LdrEntry->EntryPoint);
727 }
728 i++;
729 }
730 }
731 }
732
733 /* Set the flag */
734 LdrEntry->Flags |= LDRP_ENTRY_PROCESSED;
735 NextEntry = NextEntry->Flink;
736 }
737
739
740 /* If we got a context, then we have to call Kernel32 for TS support */
741 if (Context)
742 {
743 /* Check if we have one */
744 if (Kernel32ProcessInitPostImportFunction)
745 {
746 /* Call it */
747 Status = Kernel32ProcessInitPostImportFunction();
748 if (!NT_SUCCESS(Status))
749 {
750 DPRINT1("LDR: LdrpRunInitializeRoutines - Failed running kernel32 post-import function, Status=0x%08lx\n", Status);
751 }
752 }
753 /* Clear it */
754 Kernel32ProcessInitPostImportFunction = NULL;
755 }
756
757 /* No root entry? return */
758 if (!LdrRootEntry)
759 return Status;
760
761 /* Set the TLD TEB */
764
765 /* Loop */
766 i = 0;
767 while (i < Count)
768 {
769 /* Get an entry */
770 LdrEntry = LdrRootEntry[i];
771
772 /* FIXME: Verify NX Compat */
773
774 /* Move to next entry */
775 i++;
776
777 /* Get its entrypoint */
778 EntryPoint = LdrEntry->EntryPoint;
779
780 /* Are we being debugged? */
781 BreakOnDllLoad = 0;
783 {
784 /* Check if we should break on load */
786 L"BreakOnDllLoad",
787 REG_DWORD,
788 &BreakOnDllLoad,
789 sizeof(ULONG),
790 NULL);
791 if (!NT_SUCCESS(Status)) BreakOnDllLoad = 0;
792
793 /* Reset status back to STATUS_SUCCESS */
795 }
796
797 /* Break if aksed */
798 if (BreakOnDllLoad)
799 {
800 /* Check if we should show a message */
801 if (ShowSnaps)
802 {
803 DPRINT1("LDR: %wZ loaded.", &LdrEntry->BaseDllName);
804 DPRINT1(" - About to call init routine at %p\n", EntryPoint);
805 }
806
807 /* Break in debugger */
809 }
810
811 /* Make sure we have an entrypoint */
812 if (EntryPoint)
813 {
814 /* Save the old Dll Initializer and write the current one */
815 OldInitializer = LdrpCurrentDllInitializer;
816 LdrpCurrentDllInitializer = LdrEntry;
817
818 /* Set up the Act Ctx */
819 ActCtx.Size = sizeof(ActCtx);
820 ActCtx.Format = 1;
822
823 /* Activate the ActCtx */
826
828 {
829 /* Check if it has TLS */
830 if (LdrEntry->TlsIndex && Context)
831 {
832 /* Call TLS */
834 }
835
836 /* Call the Entrypoint */
837 if (ShowSnaps)
838 {
839 DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n",
840 &LdrEntry->BaseDllName, EntryPoint);
841 }
842 DllStatus = LdrpCallInitRoutine(EntryPoint,
843 LdrEntry->DllBase,
845 Context);
846 }
848 {
849 DllStatus = FALSE;
850 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_ATTACH) for %wZ\n",
851 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
852 }
853 _SEH2_END;
854
855 /* Deactivate the ActCtx */
857
858 /* Save the Current DLL Initializer */
859 LdrpCurrentDllInitializer = OldInitializer;
860
861 /* Mark the entry as processed */
863
864 /* Fail if DLL init failed */
865 if (!DllStatus)
866 {
867 DPRINT1("LDR: DLL_PROCESS_ATTACH for dll \"%wZ\" (InitRoutine: %p) failed\n",
868 &LdrEntry->BaseDllName, EntryPoint);
869
871 goto Quickie;
872 }
873 }
874 }
875
876 /* Loop in order */
878 NextEntry = NextEntry->Flink;
879 while (NextEntry != ListHead)
880 {
881 /* Get the Data Entry */
882 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
883
884 /* FIXME: Verify NX Compat */
885 // LdrpCheckNXCompatibility()
886
887 /* Next entry */
888 NextEntry = NextEntry->Flink;
889 }
890
891 /* Check for TLS */
893 {
894 /* Set up the Act Ctx */
895 ActCtx.Size = sizeof(ActCtx);
896 ActCtx.Format = 1;
898
899 /* Activate the ActCtx */
902
904 {
905 /* Do TLS callbacks */
907 }
909 {
910 /* Do nothing */
911 }
912 _SEH2_END;
913
914 /* Deactivate the ActCtx */
916 }
917
918Quickie:
919 /* Restore old TEB */
921
922 /* Check if the array is in the heap */
923 if (LdrRootEntry != LocalArray)
924 {
925 /* Free the array */
926 RtlFreeHeap(LdrpHeap, 0, LdrRootEntry);
927 }
928
929 /* Return to caller */
930 DPRINT("LdrpRunInitializeRoutines() done\n");
931 return Status;
932}
933
934/*
935 * @implemented
936 */
938NTAPI
940{
942 PLDR_DATA_TABLE_ENTRY LdrEntry;
943 PLIST_ENTRY NextEntry, ListHead;
944 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
945 PVOID EntryPoint;
946
947 DPRINT("LdrShutdownProcess() called for %wZ\n", &LdrpImageEntry->BaseDllName);
949
950 /* Tell the Shim Engine */
951 if (g_ShimsEnabled)
952 {
956 }
957
958 /* Tell the world */
959 if (ShowSnaps)
960 {
961 DPRINT1("\n");
962 }
963
964 /* Set the shutdown variables */
965 LdrpShutdownThreadId = NtCurrentTeb()->RealClientId.UniqueThread;
967
968 /* Enter the Loader Lock */
970
971 /* Cleanup trace logging data (Etw) */
972 if (SharedUserData->TraceLogging)
973 {
974 /* FIXME */
975 DPRINT1("We don't support Etw yet.\n");
976 }
977
978 /* Start at the end */
980 NextEntry = ListHead->Blink;
981 while (NextEntry != ListHead)
982 {
983 /* Get the current entry */
984 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
985 NextEntry = NextEntry->Blink;
986
987 /* Make sure it's not ourselves */
988 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
989 {
990 /* Get the entrypoint */
991 EntryPoint = LdrEntry->EntryPoint;
992
993 /* Check if we are ready to call it */
994 if (EntryPoint &&
995 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
996 LdrEntry->Flags)
997 {
998 /* Set up the Act Ctx */
999 ActCtx.Size = sizeof(ActCtx);
1000 ActCtx.Format = 1;
1002
1003 /* Activate the ActCtx */
1005 LdrEntry->EntryPointActivationContext);
1006
1007 _SEH2_TRY
1008 {
1009 /* Check if it has TLS */
1010 if (LdrEntry->TlsIndex)
1011 {
1012 /* Call TLS */
1014 }
1015
1016 /* Call the Entrypoint */
1017 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1018 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1019 LdrpCallInitRoutine(EntryPoint,
1020 LdrEntry->DllBase,
1022 (PVOID)1);
1023 }
1025 {
1026 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
1027 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1028 }
1029 _SEH2_END;
1030
1031 /* Deactivate the ActCtx */
1033 }
1034 }
1035 }
1036
1037 /* Check for TLS */
1038 if (LdrpImageHasTls)
1039 {
1040 /* Set up the Act Ctx */
1041 ActCtx.Size = sizeof(ActCtx);
1042 ActCtx.Format = 1;
1044
1045 /* Activate the ActCtx */
1048
1049 _SEH2_TRY
1050 {
1051 /* Do TLS callbacks */
1053 }
1055 {
1056 /* Do nothing */
1057 }
1058 _SEH2_END;
1059
1060 /* Deactivate the ActCtx */
1062 }
1063
1064 /* FIXME: Do Heap detection and Etw final shutdown */
1065
1066 /* Release the lock */
1068 DPRINT("LdrpShutdownProcess() done\n");
1069
1070 return STATUS_SUCCESS;
1071}
1072
1073/*
1074 * @implemented
1075 */
1077NTAPI
1079{
1080 PPEB Peb = NtCurrentPeb();
1081 PTEB Teb = NtCurrentTeb();
1082 PLDR_DATA_TABLE_ENTRY LdrEntry;
1083 PLIST_ENTRY NextEntry, ListHead;
1084 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
1085 PVOID EntryPoint;
1086
1087 DPRINT("LdrShutdownThread() called for %wZ\n",
1089
1090 /* Cleanup trace logging data (Etw) */
1091 if (SharedUserData->TraceLogging)
1092 {
1093 /* FIXME */
1094 DPRINT1("We don't support Etw yet.\n");
1095 }
1096
1097 /* Get the Ldr Lock */
1099
1100 /* Start at the end */
1102 NextEntry = ListHead->Blink;
1103 while (NextEntry != ListHead)
1104 {
1105 /* Get the current entry */
1106 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1107 NextEntry = NextEntry->Blink;
1108
1109 /* Make sure it's not ourselves */
1110 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1111 {
1112 /* Check if we should call */
1113 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
1114 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1115 (LdrEntry->Flags & LDRP_IMAGE_DLL))
1116 {
1117 /* Get the entrypoint */
1118 EntryPoint = LdrEntry->EntryPoint;
1119
1120 /* Check if we are ready to call it */
1121 if (EntryPoint)
1122 {
1123 /* Set up the Act Ctx */
1124 ActCtx.Size = sizeof(ActCtx);
1125 ActCtx.Format = 1;
1127
1128 /* Activate the ActCtx */
1130 LdrEntry->EntryPointActivationContext);
1131
1132 _SEH2_TRY
1133 {
1134 /* Check if it has TLS */
1135 if (LdrEntry->TlsIndex)
1136 {
1137 /* Make sure we're not shutting down */
1139 {
1140 /* Call TLS */
1142 }
1143 }
1144
1145 /* Make sure we're not shutting down */
1147 {
1148 /* Call the Entrypoint */
1149 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1150 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1151 LdrpCallInitRoutine(EntryPoint,
1152 LdrEntry->DllBase,
1154 NULL);
1155 }
1156 }
1158 {
1159 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_DETACH) for %wZ\n",
1160 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1161 }
1162 _SEH2_END;
1163
1164 /* Deactivate the ActCtx */
1166 }
1167 }
1168 }
1169 }
1170
1171 /* Check for TLS */
1172 if (LdrpImageHasTls)
1173 {
1174 /* Set up the Act Ctx */
1175 ActCtx.Size = sizeof(ActCtx);
1176 ActCtx.Format = 1;
1178
1179 /* Activate the ActCtx */
1182
1183 _SEH2_TRY
1184 {
1185 /* Do TLS callbacks */
1187 }
1189 {
1190 /* Do nothing */
1191 }
1192 _SEH2_END;
1193
1194 /* Deactivate the ActCtx */
1196 }
1197
1198 /* Free TLS */
1199 LdrpFreeTls();
1201
1202 /* Check for expansion slots */
1203 if (Teb->TlsExpansionSlots)
1204 {
1205 /* Free expansion slots */
1206 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->TlsExpansionSlots);
1207 }
1208
1209 /* Check for FLS Data */
1210 if (Teb->FlsData)
1211 {
1212 /* Mimic BaseRundownFls */
1213 ULONG n, FlsHighIndex;
1214 PRTL_FLS_DATA pFlsData;
1215 PFLS_CALLBACK_FUNCTION lpCallback;
1216
1217 pFlsData = Teb->FlsData;
1218
1220 FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
1221 RemoveEntryList(&pFlsData->ListEntry);
1223
1224 for (n = 1; n <= FlsHighIndex; ++n)
1225 {
1226 lpCallback = NtCurrentPeb()->FlsCallback[n];
1227 if (lpCallback && pFlsData->Data[n])
1228 {
1229 lpCallback(pFlsData->Data[n]);
1230 }
1231 }
1232
1233 RtlFreeHeap(RtlGetProcessHeap(), 0, pFlsData);
1234 Teb->FlsData = NULL;
1235 }
1236
1237 /* Check for Fiber data */
1238 if (Teb->HasFiberData)
1239 {
1240 /* Free Fiber data*/
1241 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->NtTib.FiberData);
1242 Teb->NtTib.FiberData = NULL;
1243 }
1244
1245 /* Free the activation context stack */
1247 DPRINT("LdrShutdownThread() done\n");
1248
1249 return STATUS_SUCCESS;
1250}
1251
1253NTAPI
1255{
1256 PLIST_ENTRY NextEntry, ListHead;
1257 PLDR_DATA_TABLE_ENTRY LdrEntry;
1258 PIMAGE_TLS_DIRECTORY TlsDirectory;
1259 PLDRP_TLS_DATA TlsData;
1260 ULONG Size;
1261
1262 /* Initialize the TLS List */
1264
1265 /* Loop all the modules */
1266 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1267 NextEntry = ListHead->Flink;
1268 while (ListHead != NextEntry)
1269 {
1270 /* Get the entry */
1271 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1272 NextEntry = NextEntry->Flink;
1273
1274 /* Get the TLS directory */
1275 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1276 TRUE,
1278 &Size);
1279
1280 /* Check if we have a directory */
1281 if (!TlsDirectory) continue;
1282
1283 /* Check if the image has TLS */
1285
1286 /* Show debug message */
1287 if (ShowSnaps)
1288 {
1289 DPRINT1("LDR: Tls Found in %wZ at %p\n",
1290 &LdrEntry->BaseDllName,
1291 TlsDirectory);
1292 }
1293
1294 /* Allocate an entry */
1295 TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA));
1296 if (!TlsData) return STATUS_NO_MEMORY;
1297
1298 /* Lock the DLL and mark it for TLS Usage */
1299 LdrEntry->LoadCount = -1;
1300 LdrEntry->TlsIndex = -1;
1301
1302 /* Save the cached TLS data */
1303 TlsData->TlsDirectory = *TlsDirectory;
1304 InsertTailList(&LdrpTlsList, &TlsData->TlsLinks);
1305
1306 /* Update the index */
1309 }
1310
1311 /* Done setting up TLS, allocate entries */
1312 return LdrpAllocateTls();
1313}
1314
1316NTAPI
1318{
1319 PTEB Teb = NtCurrentTeb();
1320 PLIST_ENTRY NextEntry, ListHead;
1321 PLDRP_TLS_DATA TlsData;
1322 SIZE_T TlsDataSize;
1323 PVOID *TlsVector;
1324
1325 /* Check if we have any entries */
1327 return STATUS_SUCCESS;
1328
1329 /* Allocate the vector array */
1330 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1331 0,
1332 LdrpNumberOfTlsEntries * sizeof(PVOID));
1333 if (!TlsVector) return STATUS_NO_MEMORY;
1334 Teb->ThreadLocalStoragePointer = TlsVector;
1335
1336 /* Loop the TLS Array */
1337 ListHead = &LdrpTlsList;
1338 NextEntry = ListHead->Flink;
1339 while (NextEntry != ListHead)
1340 {
1341 /* Get the entry */
1342 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1343 NextEntry = NextEntry->Flink;
1344
1345 /* Allocate this vector */
1346 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1348 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1349 0,
1350 TlsDataSize);
1351 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1352 {
1353 /* Out of memory */
1354 return STATUS_NO_MEMORY;
1355 }
1356
1357 /* Show debug message */
1358 if (ShowSnaps)
1359 {
1360 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1361 TlsVector,
1363 &TlsVector[TlsData->TlsDirectory.Characteristics],
1365 TlsVector[TlsData->TlsDirectory.Characteristics]);
1366 }
1367
1368 /* Copy the data */
1369 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1371 TlsDataSize);
1372 }
1373
1374 /* Done */
1375 return STATUS_SUCCESS;
1376}
1377
1378VOID
1379NTAPI
1381{
1382 PLIST_ENTRY ListHead, NextEntry;
1383 PLDRP_TLS_DATA TlsData;
1384 PVOID *TlsVector;
1385 PTEB Teb = NtCurrentTeb();
1386
1387 /* Get a pointer to the vector array */
1388 TlsVector = Teb->ThreadLocalStoragePointer;
1389 if (!TlsVector) return;
1390
1391 /* Loop through it */
1392 ListHead = &LdrpTlsList;
1393 NextEntry = ListHead->Flink;
1394 while (NextEntry != ListHead)
1395 {
1396 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1397 NextEntry = NextEntry->Flink;
1398
1399 /* Free each entry */
1400 if (TlsVector[TlsData->TlsDirectory.Characteristics])
1401 {
1402 RtlFreeHeap(RtlGetProcessHeap(),
1403 0,
1404 TlsVector[TlsData->TlsDirectory.Characteristics]);
1405 }
1406 }
1407
1408 /* Free the array itself */
1409 RtlFreeHeap(RtlGetProcessHeap(),
1410 0,
1411 TlsVector);
1412}
1413
1415NTAPI
1417{
1420 ULONG ExecuteOptions, MinimumStackCommit = 0, GlobalFlag;
1421
1422 /* Return error if we were not provided a pointer where to save the options key handle */
1423 if (!OptionsKey) return STATUS_INVALID_HANDLE;
1424
1425 /* Zero initialize the options key pointer */
1426 *OptionsKey = NULL;
1427
1428 /* Open the options key */
1429 Status = LdrOpenImageFileOptionsKey(ImagePathName, 0, &KeyHandle);
1430
1431 /* Save it if it was opened successfully */
1432 if (NT_SUCCESS(Status))
1433 *OptionsKey = KeyHandle;
1434
1435 if (KeyHandle)
1436 {
1437 /* There are image specific options, read them starting with NXCOMPAT */
1439 L"ExecuteOptions",
1440 4,
1441 &ExecuteOptions,
1442 sizeof(ExecuteOptions),
1443 0);
1444
1445 if (NT_SUCCESS(Status))
1446 {
1447 /* TODO: Set execution options for the process */
1448 /*
1449 if (ExecuteOptions == 0)
1450 ExecuteOptions = 1;
1451 else
1452 ExecuteOptions = 2;
1453 ZwSetInformationProcess(NtCurrentProcess(),
1454 ProcessExecuteFlags,
1455 &ExecuteOptions,
1456 sizeof(ULONG));*/
1457
1458 }
1459
1460 /* Check if this image uses large pages */
1461 if (Peb->ImageUsesLargePages)
1462 {
1463 /* TODO: If it does, open large page key */
1465 }
1466
1467 /* Get various option values */
1469 L"DisableHeapLookaside",
1470 REG_DWORD,
1473 NULL);
1474
1476 L"ShutdownFlags",
1477 REG_DWORD,
1480 NULL);
1481
1483 L"MinimumStackCommitInBytes",
1484 REG_DWORD,
1485 &MinimumStackCommit,
1486 sizeof(MinimumStackCommit),
1487 NULL);
1488
1489 /* Update PEB's minimum stack commit if it's lower */
1490 if (Peb->MinimumStackCommit < MinimumStackCommit)
1491 Peb->MinimumStackCommit = MinimumStackCommit;
1492
1493 /* Set the global flag */
1495 L"GlobalFlag",
1496 REG_DWORD,
1497 &GlobalFlag,
1498 sizeof(GlobalFlag),
1499 NULL);
1500
1501 if (NT_SUCCESS(Status))
1502 Peb->NtGlobalFlag = GlobalFlag;
1503 else
1504 GlobalFlag = 0;
1505
1506 /* Call AVRF if necessary */
1508 {
1510 if (!NT_SUCCESS(Status))
1511 {
1512 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1513 }
1514 }
1515 }
1516 else
1517 {
1518 /* There are no image-specific options, so perform global initialization */
1520 {
1521 /* Initialize app verifier package */
1523 if (!NT_SUCCESS(Status))
1524 {
1525 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1526 }
1527 }
1528 }
1529
1530 return STATUS_SUCCESS;
1531}
1532
1533VOID
1534NTAPI
1536{
1538}
1539
1540BOOLEAN
1541NTAPI
1543{
1544 UNICODE_STRING PolicyKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\Software\\Policies\\Microsoft\\Windows\\AppCompat");
1545 UNICODE_STRING DisableDetection = RTL_CONSTANT_STRING(L"DisableCompatGuidDetection");
1551
1552 Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &PolicyKeyAttributes);
1553 if (NT_SUCCESS(Status))
1554 {
1556 &DisableDetection,
1558 &KeyInfo,
1559 sizeof(KeyInfo),
1560 &ResultLength);
1562 if ((NT_SUCCESS(Status)) &&
1563 (KeyInfo.Type == REG_DWORD) &&
1564 (KeyInfo.DataLength == sizeof(ULONG)) &&
1565 (KeyInfo.Data[0] == TRUE))
1566 {
1567 return TRUE;
1568 }
1569 }
1570 return FALSE;
1571}
1572
1573
1574VOID
1575NTAPI
1576LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData)
1577{
1578 static const struct
1579 {
1580 const GUID* Guid;
1581 const DWORD Version;
1582 } KnownCompatGuids[] = {
1583 { &COMPAT_GUID_WIN10, _WIN32_WINNT_WIN10 },
1584 { &COMPAT_GUID_WIN81, _WIN32_WINNT_WINBLUE },
1585 { &COMPAT_GUID_WIN8, _WIN32_WINNT_WIN8 },
1586 { &COMPAT_GUID_WIN7, _WIN32_WINNT_WIN7 },
1587 { &COMPAT_GUID_VISTA, _WIN32_WINNT_VISTA },
1588 };
1589
1590 ULONG Buffer[(sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 10 + sizeof(ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION)) / sizeof(ULONG)];
1591 ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION* ContextCompatInfo;
1592 SIZE_T SizeRequired;
1594 DWORD n, cur;
1595 ReactOS_ShimData* pShimData = *pOldShimData;
1596
1597 if (pShimData)
1598 {
1599 if (pShimData->dwMagic != REACTOS_SHIMDATA_MAGIC ||
1600 pShimData->dwSize != sizeof(ReactOS_ShimData))
1601 {
1602 DPRINT1("LdrpInitializeProcessCompat: Corrupt pShimData (0x%x, %u)\n", pShimData->dwMagic, pShimData->dwSize);
1603 return;
1604 }
1605 if (pShimData->dwRosProcessCompatVersion)
1606 {
1608 {
1609 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion set to ignore manifest\n");
1610 }
1611 else
1612 {
1613 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion already set to 0x%x\n", pShimData->dwRosProcessCompatVersion);
1614 }
1615 return;
1616 }
1617 }
1618
1619 SizeRequired = sizeof(Buffer);
1621 pProcessActctx,
1622 NULL,
1623 CompatibilityInformationInActivationContext,
1624 Buffer,
1625 sizeof(Buffer),
1626 &SizeRequired);
1627
1628 if (!NT_SUCCESS(Status))
1629 {
1630 DPRINT1("LdrpInitializeProcessCompat: Unable to query process actctx with status %x\n", Status);
1631 return;
1632 }
1633
1634 ContextCompatInfo = (ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*)Buffer;
1635 /* No Compatibility elements present, bail out */
1636 if (ContextCompatInfo->ElementCount == 0)
1637 return;
1638
1639 /* Search for known GUIDs, starting from oldest to newest.
1640 Note that on Windows it is somewhat reversed, starting from the latest known
1641 version, going down. But we are not Windows, trying to allow a lower version,
1642 we are ReactOS trying to fake a higher version. So we interpret what Windows
1643 does as "try the closest version to the actual version", so we start with the
1644 lowest version, which is closest to Windows 2003, which we mostly are. */
1645 for (cur = RTL_NUMBER_OF(KnownCompatGuids) - 1; cur != -1; --cur)
1646 {
1647 for (n = 0; n < ContextCompatInfo->ElementCount; ++n)
1648 {
1649 if (ContextCompatInfo->Elements[n].Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS &&
1650 RtlCompareMemory(&ContextCompatInfo->Elements[n].Id, KnownCompatGuids[cur].Guid, sizeof(GUID)) == sizeof(GUID))
1651 {
1653 {
1654 DPRINT1("LdrpInitializeProcessCompat: Not applying automatic fix for winver 0x%x due to policy\n", KnownCompatGuids[cur].Version);
1655 return;
1656 }
1657
1658 /* If this process did not need shim data before, allocate and store it */
1659 if (pShimData == NULL)
1660 {
1661 PPEB Peb = NtCurrentPeb();
1662
1663 ASSERT(Peb->pShimData == NULL);
1664 pShimData = RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*pShimData));
1665
1666 if (!pShimData)
1667 {
1668 DPRINT1("LdrpInitializeProcessCompat: Unable to allocated %u bytes\n", sizeof(*pShimData));
1669 return;
1670 }
1671
1672 pShimData->dwSize = sizeof(*pShimData);
1673 pShimData->dwMagic = REACTOS_SHIMDATA_MAGIC;
1674
1675 Peb->pShimData = pShimData;
1676 *pOldShimData = pShimData;
1677 }
1678
1679 /* Store the lowest found version, and bail out. */
1680 pShimData->dwRosProcessCompatVersion = KnownCompatGuids[cur].Version;
1681 DPRINT1("LdrpInitializeProcessCompat: Found guid for winver 0x%x in manifest from %wZ\n",
1682 KnownCompatGuids[cur].Version,
1683 &(NtCurrentPeb()->ProcessParameters->ImagePathName));
1684 return;
1685 }
1686 }
1687 }
1688}
1689
1690VOID
1691NTAPI
1693{
1694 UNICODE_STRING ImagePathName = ProcessParameters->ImagePathName;
1695 WCHAR LocalBuffer[MAX_PATH];
1696 UNICODE_STRING DotLocal;
1699
1700 RequiredSize = ImagePathName.Length + LdrpDotLocal.Length + sizeof(UNICODE_NULL);
1701 if (RequiredSize <= sizeof(LocalBuffer))
1702 {
1703 RtlInitEmptyUnicodeString(&DotLocal, LocalBuffer, sizeof(LocalBuffer));
1704 }
1706 {
1707 DotLocal.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RequiredSize);
1708 DotLocal.Length = 0;
1709 DotLocal.MaximumLength = RequiredSize;
1710 if (!DotLocal.Buffer)
1711 DPRINT1("LDR: Failed to allocate memory for .local check\n");
1712 }
1713 else
1714 {
1715 DotLocal.Buffer = NULL;
1716 DotLocal.Length = 0;
1717 DotLocal.MaximumLength = 0;
1718 DPRINT1("LDR: String too big for .local check\n");
1719 }
1720
1721 if (DotLocal.Buffer)
1722 {
1723 Status = RtlAppendUnicodeStringToString(&DotLocal, &ImagePathName);
1725 if (NT_SUCCESS(Status))
1726 {
1729 }
1730
1731 if (NT_SUCCESS(Status))
1732 {
1733 if (RtlDoesFileExists_UStr(&DotLocal))
1734 {
1736 }
1737 }
1738 else
1739 {
1740 DPRINT1("LDR: Failed to append: 0x%lx\n", Status);
1741 }
1742
1743 if (DotLocal.Buffer != LocalBuffer)
1744 {
1745 RtlFreeHeap(RtlGetProcessHeap(), 0, DotLocal.Buffer);
1746 }
1747 }
1748}
1749
1750
1752NTAPI
1755{
1756 RTL_HEAP_PARAMETERS HeapParameters;
1757 ULONG ComSectionSize;
1758 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1759 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1760 PVOID OldShimData;
1762 //UNICODE_STRING LocalFileName, FullImageName;
1763 HANDLE SymLinkHandle;
1764 //ULONG DebugHeapOnly;
1765 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1766 PPEB Peb = NtCurrentPeb();
1767 BOOLEAN IsDotNetImage = FALSE;
1768 BOOLEAN FreeCurDir = FALSE;
1769 //HANDLE CompatKey;
1770 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1771 //LPWSTR ImagePathBuffer;
1772 ULONG ConfigSize;
1774 HANDLE OptionsKey;
1775 ULONG HeapFlags;
1776 PIMAGE_NT_HEADERS NtHeader;
1777 LPWSTR NtDllName = NULL;
1778 NTSTATUS Status, ImportStatus;
1779 NLSTABLEINFO NlsTable;
1781 PTEB Teb = NtCurrentTeb();
1782 PLIST_ENTRY ListHead;
1783 PLIST_ENTRY NextEntry;
1784 ULONG i;
1785 PWSTR ImagePath;
1786 ULONG DebugProcessHeapOnly = 0;
1787 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1788 PWCHAR Current;
1789 ULONG ExecuteOptions = 0;
1790 PVOID ViewBase;
1791
1792 /* Set a NULL SEH Filter */
1794
1795 /* Get the image path */
1797
1798 /* Check if it's not normalized */
1800 {
1801 /* Normalize it*/
1802 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1803 }
1804
1805 /* Create a unicode string for the Image Path */
1807 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1808 ImagePathName.Buffer = ImagePath;
1809
1810 /* Get the NT Headers */
1812
1813 /* Get the execution options */
1814 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1815
1816 /* Check if this is a .NET executable */
1818 TRUE,
1820 &ComSectionSize))
1821 {
1822 /* Remember this for later */
1823 IsDotNetImage = TRUE;
1824 }
1825
1826 /* Save the NTDLL Base address */
1828
1829 /* If this is a Native Image */
1831 {
1832 /* Then do DLL Validation */
1834 }
1835
1836 /* Save the old Shim Data */
1837 OldShimData = Peb->pShimData;
1838
1839 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1840 //Peb->pShimData = NULL;
1841
1842 /* Save the number of processors and CS Timeout */
1845
1846 /* Normalize the parameters */
1847 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1848 if (ProcessParameters)
1849 {
1850 /* Save the Image and Command Line Names */
1851 ImageFileName = ProcessParameters->ImagePathName;
1852 CommandLine = ProcessParameters->CommandLine;
1853 }
1854 else
1855 {
1856 /* It failed, initialize empty strings */
1857 RtlInitUnicodeString(&ImageFileName, NULL);
1858 RtlInitUnicodeString(&CommandLine, NULL);
1859 }
1860
1861 /* Initialize NLS data */
1865 &NlsTable);
1866
1867 /* Reset NLS Translations */
1868 RtlResetRtlTranslations(&NlsTable);
1869
1870 /* Get the Image Config Directory */
1872 TRUE,
1874 &ConfigSize);
1875
1876 /* Setup the Heap Parameters */
1877 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1878 HeapFlags = HEAP_GROWABLE;
1879 HeapParameters.Length = sizeof(HeapParameters);
1880
1881 /* Check if we have Configuration Data */
1882#define VALID_CONFIG_FIELD(Name) (ConfigSize >= (FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, Name) + sizeof(LoadConfig->Name)))
1883 /* The 'original' load config ends after SecurityCookie */
1884 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1885 {
1886 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1887 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1888 else
1889 DPRINT1("Applying LOAD_CONFIG\n");
1890
1891 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1892 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1893
1894 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1895 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1896
1897 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1898 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000000);
1899
1900 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1901 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1902
1903 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1904 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1905
1906 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1907 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1908
1909 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1910 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1911
1912 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1913 HeapFlags = LoadConfig->ProcessHeapFlags;
1914 }
1915#undef VALID_CONFIG_FIELD
1916
1917 /* Check for custom affinity mask */
1919 {
1920 /* Set it */
1924 sizeof(Peb->ImageProcessAffinityMask));
1925 }
1926
1927 /* Check if verbose debugging (ShowSnaps) was requested */
1929
1930 /* Start verbose debugging messages right now if they were requested */
1931 if (ShowSnaps)
1932 {
1933 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1935 &CommandLine);
1936 }
1937
1938 /* If the timeout is too long */
1939 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1940 {
1941 /* Then disable CS Timeout */
1943 }
1944
1945 /* Initialize Critical Section Data */
1947
1948 /* Initialize VEH Call lists */
1950
1951 /* Set TLS/FLS Bitmap data */
1955
1956 /* Initialize FLS Bitmap */
1960 RtlSetBit(&FlsBitMap, 0);
1962
1963 /* Initialize TLS Bitmap */
1967 RtlSetBit(&TlsBitMap, 0);
1972
1973 /* Initialize the Hash Table */
1974 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1975 {
1977 }
1978
1979 /* Initialize the Loader Lock */
1980 // FIXME: What's the point of initing it manually, if two lines lower
1981 // a call to RtlInitializeCriticalSection() is being made anyway?
1982 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
1983 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
1986
1987 /* Check if User Stack Trace Database support was requested */
1989 {
1990 DPRINT1("We don't support user stack trace databases yet\n");
1991 }
1992
1993 /* Setup Fast PEB Lock */
1996 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
1997 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
1998
1999 /* Setup Callout Lock and Notification list */
2000 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2002
2003 /* For old executables, use 16-byte aligned heap */
2004 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2005 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2006 {
2007 HeapFlags |= HEAP_CREATE_ALIGN_16;
2008 }
2009
2010 /* Setup the Heap */
2012 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2013 NULL,
2016 NULL,
2017 &HeapParameters);
2018
2019 if (!Peb->ProcessHeap)
2020 {
2021 DPRINT1("Failed to create process heap\n");
2022 return STATUS_NO_MEMORY;
2023 }
2024
2025 /* Allocate an Activation Context Stack */
2027 if (!NT_SUCCESS(Status)) return Status;
2028
2029 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2030 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2031 HeapParameters.Length = sizeof(HeapParameters);
2032 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2033 if (!LdrpHeap)
2034 {
2035 DPRINT1("Failed to create loader private heap\n");
2036 return STATUS_NO_MEMORY;
2037 }
2038
2039 /* Check for Debug Heap */
2040 if (OptionsKey)
2041 {
2042 /* Query the setting */
2044 L"DebugProcessHeapOnly",
2045 REG_DWORD,
2046 &DebugProcessHeapOnly,
2047 sizeof(ULONG),
2048 NULL);
2049
2050 if (NT_SUCCESS(Status))
2051 {
2052 /* Reset DPH if requested */
2053 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2054 {
2055 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2057 }
2058 }
2059 }
2060
2061 /* Build the NTDLL Path */
2062 FullPath.Buffer = StringBuffer;
2063 FullPath.Length = 0;
2064 FullPath.MaximumLength = sizeof(StringBuffer);
2067 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2068
2069 /* Open the Known DLLs directory */
2070 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2072 &KnownDllString,
2074 NULL,
2075 NULL);
2079
2080 /* Check if it exists */
2081 if (NT_SUCCESS(Status))
2082 {
2083 /* Open the Known DLLs Path */
2084 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2086 &KnownDllString,
2089 NULL);
2090 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2093 if (NT_SUCCESS(Status))
2094 {
2095 /* Query the path */
2099 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2100 NtClose(SymLinkHandle);
2101 if (!NT_SUCCESS(Status))
2102 {
2103 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2104 return Status;
2105 }
2106 }
2107 }
2108
2109 /* Check if we failed */
2110 if (!NT_SUCCESS(Status))
2111 {
2112 /* Assume System32 */
2115 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2116 }
2117
2118 /* If we have process parameters, get the default path and current path */
2119 if (ProcessParameters)
2120 {
2121 /* Check if we have a Dll Path */
2122 if (ProcessParameters->DllPath.Length)
2123 {
2124 /* Get the path */
2125 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2126 }
2127 else
2128 {
2129 /* We need a valid path */
2130 DPRINT1("No valid DllPath was given!\n");
2132 }
2133
2134 /* Set the current directory */
2135 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2136
2137 /* Check if it's empty or invalid */
2138 if ((!CurrentDirectory.Buffer) ||
2139 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2140 (!CurrentDirectory.Length))
2141 {
2142 /* Allocate space for the buffer */
2144 0,
2145 3 * sizeof(WCHAR) +
2146 sizeof(UNICODE_NULL));
2147 if (!CurrentDirectory.Buffer)
2148 {
2149 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2150 // FIXME: And what?
2151 }
2152
2153 /* Copy the drive of the system root */
2155 SharedUserData->NtSystemRoot,
2156 3 * sizeof(WCHAR));
2157 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2158 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2159 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2160
2161 FreeCurDir = TRUE;
2162 DPRINT("Using dynamically allocd curdir\n");
2163 }
2164 else
2165 {
2166 /* Use the local buffer */
2167 DPRINT("Using local system root\n");
2168 }
2169 }
2170
2171 /* Setup Loader Data */
2172 Peb->Ldr = &PebLdr;
2176 PebLdr.Length = sizeof(PEB_LDR_DATA);
2178
2179 /* Allocate a data entry for the Image */
2181
2182 /* Set it up */
2186 LdrpImageEntry->FullDllName = ImageFileName;
2187
2188 if (IsDotNetImage)
2190 else
2191 LdrpImageEntry->Flags = 0;
2192
2193 /* Check if the name is empty */
2194 if (!ImageFileName.Buffer[0])
2195 {
2196 /* Use the same Base name */
2198 }
2199 else
2200 {
2201 /* Find the last slash */
2202 Current = ImageFileName.Buffer;
2203 while (*Current)
2204 {
2205 if (*Current++ == '\\')
2206 {
2207 /* Set this path */
2208 NtDllName = Current;
2209 }
2210 }
2211
2212 /* Did we find anything? */
2213 if (!NtDllName)
2214 {
2215 /* Use the same Base name */
2217 }
2218 else
2219 {
2220 /* Setup the name */
2221 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2224 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2225 }
2226 }
2227
2228 /* Processing done, insert it */
2231
2232 /* Now add an entry for NTDLL */
2234 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2235 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2236 NtLdrEntry->LoadCount = -1;
2237 NtLdrEntry->EntryPointActivationContext = 0;
2238
2239 NtLdrEntry->FullDllName.Length = FullPath.Length;
2240 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2241 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2243
2244 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2246 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2247
2248 /* Processing done, insert it */
2249 LdrpNtDllDataTableEntry = NtLdrEntry;
2250 LdrpInsertMemoryTableEntry(NtLdrEntry);
2251
2252 /* Let the world know */
2253 if (ShowSnaps)
2254 {
2255 DPRINT1("LDR: NEW PROCESS\n");
2256 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2257 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2258 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2259 }
2260
2261 /* Link the Init Order List */
2264
2265 /* Initialize Wine's active context implementation for the current process */
2266 actctx_init(&OldShimData);
2267
2268 /* Set the current directory */
2270 if (!NT_SUCCESS(Status))
2271 {
2272 /* We failed, check if we should free it */
2273 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2274
2275 /* Set it to the NT Root */
2278 }
2279 else
2280 {
2281 /* We're done with it, free it */
2282 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2283 }
2284
2285 /* Check if we should look for a .local file */
2286 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2287 {
2288 LdrpInitializeDotLocalSupport(ProcessParameters);
2289 }
2290
2291 /* Check if the Application Verifier was enabled */
2293 {
2295 if (!NT_SUCCESS(Status))
2296 {
2297 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2298 return Status;
2299 }
2300
2301 }
2302
2303 if (IsDotNetImage)
2304 {
2305 /* FIXME */
2306 DPRINT1("We don't support .NET applications yet\n");
2307 }
2308
2311 {
2312 PVOID Kernel32BaseAddress;
2313 PVOID FunctionAddress;
2314
2315 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2316
2317 if (!NT_SUCCESS(Status))
2318 {
2319 if (ShowSnaps)
2320 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2321 return Status;
2322 }
2323
2324 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2325 &BaseProcessInitPostImportName,
2326 0,
2327 &FunctionAddress);
2328
2329 if (!NT_SUCCESS(Status))
2330 {
2331 if (ShowSnaps)
2332 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", &Kernel32String, Status);
2333 return Status;
2334 }
2335 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2336
2337 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2338 &BaseQueryModuleDataName,
2339 0,
2340 &FunctionAddress);
2341
2342 if (!NT_SUCCESS(Status))
2343 {
2344 if (ShowSnaps)
2345 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", &Kernel32String, Status);
2346 return Status;
2347 }
2348 Kernel32BaseQueryModuleData = FunctionAddress;
2349 }
2350
2351 /* Walk the IAT and load all the DLLs */
2353
2354 /* Check if relocation is needed */
2356 {
2357 DPRINT1("LDR: Performing EXE relocation\n");
2358
2359 /* Change the protection to prepare for relocation */
2360 ViewBase = Peb->ImageBaseAddress;
2361 Status = LdrpSetProtection(ViewBase, FALSE);
2362 if (!NT_SUCCESS(Status)) return Status;
2363
2364 /* Do the relocation */
2366 0LL,
2367 NULL,
2371 if (!NT_SUCCESS(Status))
2372 {
2373 DPRINT1("LdrRelocateImageWithBias() failed\n");
2374 return Status;
2375 }
2376
2377 /* Check if a start context was provided */
2378 if (Context)
2379 {
2380 DPRINT1("WARNING: Relocated EXE Context");
2381 UNIMPLEMENTED; // We should support this
2383 }
2384
2385 /* Restore the protection */
2386 Status = LdrpSetProtection(ViewBase, TRUE);
2387 if (!NT_SUCCESS(Status)) return Status;
2388 }
2389
2390 /* Lock the DLLs */
2391 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2392 NextEntry = ListHead->Flink;
2393 while (ListHead != NextEntry)
2394 {
2395 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2396 NtLdrEntry->LoadCount = -1;
2397 NextEntry = NextEntry->Flink;
2398 }
2399
2400 /* Phase 0 is done */
2402
2403 /* Check whether all static imports were properly loaded and return here */
2404 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2405
2406 /* Initialize TLS */
2408 if (!NT_SUCCESS(Status))
2409 {
2410 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2411 Status);
2412 return Status;
2413 }
2414
2415 /* FIXME Mark the DLL Ranges for Stack Traces later */
2416
2417 /* Notify the debugger now */
2418 if (Peb->BeingDebugged)
2419 {
2420 /* Break */
2421 DbgBreakPoint();
2422
2423 /* Update show snaps again */
2425 }
2426
2427 /* Validate the Image for MP Usage */
2429
2430 /* Check NX options and set them */
2431 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2432 {
2433 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2436 }
2437 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2438 {
2440 }
2443 &ExecuteOptions,
2444 sizeof(ExecuteOptions));
2445 if (!NT_SUCCESS(Status))
2446 {
2447 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2448 ExecuteOptions, Status);
2449 }
2450
2451 // FIXME: Should be done by Application Compatibility features,
2452 // by reading the registry, etc...
2453 // For now, this is the old code from ntdll!RtlGetVersion().
2454 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2455 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2456 {
2457 WCHAR szCSDVersion[128];
2458 LONG i;
2459 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2460 i = _snwprintf(szCSDVersion, Length,
2461 L"Service Pack %d",
2462 ((Peb->OSCSDVersion >> 8) & 0xFF));
2463 if (i < 0)
2464 {
2465 /* Null-terminate if it was overflowed */
2466 szCSDVersion[Length] = UNICODE_NULL;
2467 }
2468
2469 Length *= sizeof(WCHAR);
2470 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2471 0,
2472 Length + sizeof(UNICODE_NULL));
2473 if (Peb->CSDVersion.Buffer)
2474 {
2477
2479 szCSDVersion,
2482 }
2483 }
2484
2485 /* Check if we had Shim Data */
2486 if (OldShimData)
2487 {
2488 /* Load the Shim Engine */
2490 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2491 }
2492 else
2493 {
2494 /* Check for Application Compatibility Goo */
2495 //LdrQueryApplicationCompatibilityGoo(hKey);
2496 DPRINT("Querying app compat hacks is missing!\n");
2497 }
2498
2499 /*
2500 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2501 * incompatible images.
2502 */
2503
2504 /* Now call the Init Routines */
2506 if (!NT_SUCCESS(Status))
2507 {
2508 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2509 Status);
2510 return Status;
2511 }
2512
2513 /* Notify Shim Engine */
2514 if (g_ShimsEnabled)
2515 {
2518 SE_InstallAfterInit(&ImagePathName, OldShimData);
2519 }
2520
2521 /* Check if we have a user-defined Post Process Routine */
2523 {
2524 /* Call it */
2526 }
2527
2528 /* Close the key if we have one opened */
2529 if (OptionsKey) NtClose(OptionsKey);
2530
2531 /* Return status */
2532 return Status;
2533}
2534
2535VOID
2536NTAPI
2538{
2540 PPEB Peb = NtCurrentPeb();
2541
2542 /* Print a debug message */
2543 DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2545
2546 /* Raise a hard error */
2548 {
2550 }
2551}
2552
2553VOID
2554NTAPI
2558{
2560 PTEB Teb = NtCurrentTeb();
2561 NTSTATUS Status, LoaderStatus = STATUS_SUCCESS;
2562 MEMORY_BASIC_INFORMATION MemoryBasicInfo;
2563 PPEB Peb = NtCurrentPeb();
2564
2565 DPRINT("LdrpInit() %p/%p\n",
2566 NtCurrentTeb()->RealClientId.UniqueProcess,
2567 NtCurrentTeb()->RealClientId.UniqueThread);
2568
2569#ifdef _WIN64
2570 /* Set the SList header usage */
2572#endif /* _WIN64 */
2573
2574 /* Check if we have a deallocation stack */
2575 if (!Teb->DeallocationStack)
2576 {
2577 /* We don't, set one */
2579 Teb->NtTib.StackLimit,
2581 &MemoryBasicInfo,
2583 NULL);
2584 if (!NT_SUCCESS(Status))
2585 {
2586 /* Fail */
2589 return;
2590 }
2591
2592 /* Set the stack */
2593 Teb->DeallocationStack = MemoryBasicInfo.AllocationBase;
2594 }
2595
2596 /* Now check if the process is already being initialized */
2598 1,
2599 0) == 1)
2600 {
2601 /* Set the timeout to 30 milliseconds */
2602 Timeout.QuadPart = Int32x32To64(30, -10000);
2603
2604 /* Make sure the status hasn't changed */
2605 while (LdrpProcessInitialized == 1)
2606 {
2607 /* Do the wait */
2609 }
2610 }
2611
2612 /* Check if we have already setup LDR data */
2613 if (!Peb->Ldr)
2614 {
2615 /* Setup the Loader Lock */
2617
2618 /* Let other code know we're initializing */
2620
2621 /* Protect with SEH */
2622 _SEH2_TRY
2623 {
2624 /* Initialize the Process */
2625 LoaderStatus = LdrpInitializeProcess(Context,
2627
2628 /* Check for success and if MinimumStackCommit was requested */
2629 if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit)
2630 {
2631 /* Enforce the limit */
2632 //LdrpTouchThreadStack(Peb->MinimumStackCommit);
2634 }
2635 }
2637 {
2638 /* Fail with the SEH error */
2639 LoaderStatus = _SEH2_GetExceptionCode();
2640 }
2641 _SEH2_END;
2642
2643 /* We're not initializing anymore */
2645
2646 /* Check if init worked */
2647 if (NT_SUCCESS(LoaderStatus))
2648 {
2649 /* Set the process as Initialized */
2651 }
2652 }
2653 else
2654 {
2655 /* Loader data is there... is this a fork() ? */
2657 {
2658 /* Handle the fork() */
2659 //LoaderStatus = LdrpForkProcess();
2660 LoaderStatus = STATUS_NOT_IMPLEMENTED;
2662 }
2663 else
2664 {
2665 /* This is a new thread initializing */
2667 }
2668 }
2669
2670 /* All done, test alert the thread */
2671 NtTestAlert();
2672
2673 /* Return */
2674 if (!NT_SUCCESS(LoaderStatus))
2675 {
2676 /* Fail */
2677 LdrpInitFailure(LoaderStatus);
2678 RtlRaiseStatus(LoaderStatus);
2679 }
2680}
2681
2682/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
#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
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: debug.h:115
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
struct _PEB_LDR_DATA PEB_LDR_DATA
Definition: bufpool.h:45
#define REACTOS_SHIMDATA_MAGIC
Definition: compat_undoc.h:15
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define NTSTATUS
Definition: precomp.h:20
#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 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
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
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:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#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:310
#define FLG_APPLICATION_VERIFIER
Definition: pstypes.h:64
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:82
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:72
NTSYSAPI void WINAPI DbgBreakPoint(void)
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
NTSYSAPI void WINAPI RtlFreeThreadActivationContextStack(void)
Definition: actctx.c:5472
NTSYSAPI void WINAPI LdrShutdownProcess(void)
Definition: ldrinit.c:939
@ ProcessAffinityMask
Definition: winternl.h:877
@ ProcessExecuteFlags
Definition: winternl.h:889
NTSYSAPI void WINAPI LdrShutdownThread(void)
Definition: ldrinit.c:1078
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5515
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
long __cdecl _InterlockedCompareExchange(_Interlocked_operand_ long volatile *_Destination, long _Exchange, long _Comparand)
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
#define NtCurrentTeb
#define REG_SZ
Definition: layer.c:22
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
ULONG RtlpDisableHeapLookaside
Definition: ldrinit.c:92
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:1692
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
WCHAR LdrpKnownDllPathBuffer[128]
Definition: ldrinit.c:64
VOID NTAPI LdrpInit(PCONTEXT Context, PVOID SystemArgument1, PVOID SystemArgument2)
Definition: ldrinit.c:2555
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:65
ULONG RtlpShutdownProcessFlags
Definition: ldrinit.c:93
VOID NTAPI LdrpFreeTls(VOID)
Definition: ldrinit.c:1380
static IN LPSTR IN PVOID IN PVOID Unk3
Definition: ldrinit.c:47
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
NTSTATUS NTAPI LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
Definition: ldrinit.c:1416
RTL_CRITICAL_SECTION FastPebLock
Definition: ldrinit.c:79
LONG LdrpProcessInitialized
Definition: ldrinit.c:31
ULONG LdrpNumberOfTlsEntries
Definition: ldrinit.c:54
LIST_ENTRY LdrpDllNotificationList
Definition: ldrinit.c:61
ULONG LdrpNumberOfProcessors
Definition: ldrinit.c:55
LIST_ENTRY LdrpTlsList
Definition: ldrinit.c:53
PVOID LdrpHeap
Definition: ldrinit.c:59
RTL_BITMAP FlsBitMap
Definition: ldrinit.c:51
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
Definition: ldrinit.c:43
ULONG LdrpActiveUnloadCount
Definition: ldrinit.c:84
RTL_BITMAP TlsBitMap
Definition: ldrinit.c:49
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrinit.c:449
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
NTSTATUS NTAPI LdrQueryImageFileExecutionOptionsEx(IN PUNICODE_STRING SubKey, IN PCWSTR ValueName, IN ULONG Type, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG ReturnedLength OPTIONAL, IN BOOLEAN Wow64)
Definition: ldrinit.c:348
LARGE_INTEGER RtlpTimeout
Definition: critical.c:24
NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase)
HANDLE Wow64ExecOptionsKey
Definition: ldrinit.c:23
static IN LPSTR Unk1
Definition: ldrinit.c:47
#define DEFAULT_SECURITY_COOKIE
Definition: ldrinit.c:102
PTEB LdrpTopLevelDllBeingLoadedTeb
Definition: libsupp.c:18
VOID NTAPI RtlpInitDeferedCriticalSection(VOID)
Definition: critical.c:266
VOID NTAPI RtlInitializeHeapManager(VOID)
Definition: libsupp.c:243
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: ldrinit.c:412
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:83
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1535
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:60
UNICODE_STRING LdrpKnownDllPath
Definition: ldrinit.c:63
NTSTATUS NTAPI LdrpInitializeProcess(IN PCONTEXT Context, IN PVOID SystemArgument1)
Definition: ldrinit.c:1753
RTL_BITMAP TlsExpansionBitMap
Definition: ldrinit.c:50
BOOLEAN LdrpImageHasTls
Definition: ldrinit.c:52
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:637
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug
Definition: ldrinit.c:69
VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID)
Definition: vectoreh.c:30
BOOLEAN NTAPI LdrpDisableProcessCompatGuidDetection(VOID)
Definition: ldrinit.c:1542
void actctx_init(PVOID *pOldShimData)
Definition: actctx.c:5075
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:62
NTSTATUS NTAPI LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey, IN PCWSTR ValueName, IN ULONG Type, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG ReturnedLength OPTIONAL)
Definition: ldrinit.c:386
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
VOID NTAPI LdrpInitFailure(NTSTATUS Status)
Definition: ldrinit.c:2537
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:1576
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1254
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:405
#define VALID_CONFIG_FIELD(Name)
NTSTATUS NTAPI LdrQueryImageFileKeyOption(IN HANDLE KeyHandle, IN PCWSTR ValueName, IN ULONG Type, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG ReturnedLength OPTIONAL)
Definition: ldrinit.c:184
UNICODE_STRING ImageExecOptionsString
Definition: ldrinit.c:24
UNICODE_STRING Kernel32String
Definition: ldrinit.c:27
NTSTATUS NTAPI LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey, IN BOOLEAN Wow64, OUT PHANDLE NewKeyHandle)
Definition: ldrinit.c:112
BOOLEAN RtlpTimeoutDisable
Definition: ldrinit.c:58
UNICODE_STRING Wow64OptionsString
Definition: ldrinit.c:25
VOID NTAPI LdrpInitializeThread(IN PCONTEXT Context)
Definition: ldrinit.c:502
UNICODE_STRING NtDllString
Definition: ldrinit.c:26
NTSTATUS NTAPI LdrpAllocateTls(VOID)
Definition: ldrinit.c:1317
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:67
BOOLEAN RtlpUse16ByteSLists
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
#define LDRP_DONT_CALL_FOR_THREADS
Definition: ldrtypes.h:48
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:52
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
#define LDRP_PROCESS_ATTACH_CALLED
Definition: ldrtypes.h:49
if(dx< 0)
Definition: linetemp.h:194
unsigned int * PULONG
Definition: retypes.h:1
signed char * PCHAR
Definition: retypes.h:7
void * PVOID
Definition: retypes.h:9
signed int * PLONG
Definition: retypes.h:5
unsigned int ULONG
Definition: retypes.h:1
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_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:179
#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)
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 ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
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
int Count
Definition: noreturn.cpp:7
#define BOOL
Definition: nt_native.h:43
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
#define REG_BINARY
Definition: nt_native.h:1496
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define HEAP_CLASS_1
Definition: nt_native.h:1711
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:1657
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:1016
#define HEAP_GROWABLE
Definition: nt_native.h:1693
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define HEAP_CREATE_ALIGN_16
Definition: nt_native.h:1701
#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:473
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:2771
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:612
#define LDR_HASH_TABLE_ENTRIES
Definition: ntdllp.h:11
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1582
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:947
BOOLEAN NTAPI 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:1549
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2663
#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:75
NTSTATUS NTAPI NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter, OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
Definition: profile.c:272
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:4403
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
NTSTATUS NTAPI NtTestAlert(VOID)
Definition: state.c:465
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:558
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_APP_INIT_FAILURE
Definition: ntstatus.h:561
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define L(x)
Definition: ntvdm.h:50
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:237
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define REG_DWORD
Definition: sdbapi.c:596
#define YieldProcessor
Definition: ke.h:48
#define SharedUserData
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5934
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:6011
NTSTATUS NTAPI RtlAllocateActivationContextStack(IN PACTIVATION_CONTEXT_STACK *Stack)
Definition: actctx.c:5906
VOID NTAPI RtlSetUnhandledExceptionFilter(IN PRTLP_UNHANDLED_EXCEPTION_FILTER TopLevelExceptionFilter)
Definition: exception.c:341
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:1436
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1441
#define DPRINT
Definition: sndvol32.h:71
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:1368
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:163
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID EntryPoint
Definition: ntddk_ex.h:203
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
ULONG SizeOfImage
Definition: ldrtypes.h:143
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:140
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:145
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:122
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
ULONG Length
Definition: ntddk_ex.h:221
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
BOOLEAN Initialized
Definition: ntddk_ex.h:222
UNICODE_STRING CSDVersion
Definition: winternl.h:353
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
ULONG FlsBitmapBits[4]
Definition: winternl.h:362
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine
Definition: btrfs_drv.h:1916
PVOID ProcessHeap
Definition: ntddk_ex.h:249
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
LARGE_INTEGER CriticalSectionTimeout
Definition: ntddk_ex.h:274
ULONG TlsExpansionBitmapBits[32]
Definition: winternl.h:347
PVOID AnsiCodePageData
Definition: ntddk_ex.h:264
BYTE BeingDebugged
Definition: btrfs_drv.h:1909
SIZE_T MinimumStackCommit
Definition: winternl.h:358
PVOID FastPebLock
Definition: ntddk_ex.h:250
PVOID TlsBitmap
Definition: ntddk_ex.h:259
PVOID OemCodePageData
Definition: ntddk_ex.h:265
LIST_ENTRY FlsListHead
Definition: winternl.h:360
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
PRTL_BITMAP FlsBitmap
Definition: winternl.h:361
PVOID AppCompatInfo
Definition: winternl.h:352
BOOLEAN InheritedAddressSpace
Definition: ntddk_ex.h:239
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:346
PVOID UnicodeCaseTableData
Definition: ntddk_ex.h:266
LIST_ENTRY ListEntry
Definition: rtltypes.h:1223
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE]
Definition: rtltypes.h:1224
ULONG DeCommitFreeBlockThreshold
Definition: nt_native.h:1670
ULONG VirtualMemoryThreshold
Definition: nt_native.h:1673
ULONG DeCommitTotalFreeThreshold
Definition: nt_native.h:1671
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:150
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define OUT
Definition: typedefs.h:40
#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:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
_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:1432
#define WINAPI
Definition: msvc.h:6
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1104
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
#define NX_SUPPORT_POLICY_ALWAYSOFF
Definition: ketypes.h:1149
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:676
#define NX_SUPPORT_POLICY_ALWAYSON
Definition: ketypes.h:1150
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:677
#define PF_COMPARE_EXCHANGE128
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184