ReactOS 0.4.16-dev-747-gbc52d5f
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
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_ PUNICODE_STRING SubKey,
114 _In_ BOOLEAN Wow64,
115 _Out_ PHANDLE NewKeyHandle)
116{
117 PHANDLE RootKeyLocation;
119 UNICODE_STRING SubKeyString;
122 PWCHAR p1;
123
124 /* Check which root key to open */
125 if (Wow64)
126 RootKeyLocation = &Wow64ExecOptionsKey;
127 else
128 RootKeyLocation = &ImageExecOptionsKey;
129
130 /* Get the current key */
131 RootKey = *RootKeyLocation;
132
133 /* Setup the object attributes */
135 Wow64 ?
138 NULL,
139 NULL);
140
141 /* Open the root key */
143 if (NT_SUCCESS(Status))
144 {
145 /* Write the key handle */
146 if (InterlockedCompareExchangePointer(RootKeyLocation, RootKey, NULL) != NULL)
147 {
148 /* Someone already opened it, use it instead */
150 RootKey = *RootKeyLocation;
151 }
152
153 /* Extract the name */
154 SubKeyString = *SubKey;
155 p1 = (PWCHAR)((ULONG_PTR)SubKeyString.Buffer + SubKeyString.Length);
156 while (SubKeyString.Length)
157 {
158 if (p1[-1] == L'\\') break;
159 p1--;
160 SubKeyString.Length -= sizeof(*p1);
161 }
162 SubKeyString.Buffer = p1;
163 SubKeyString.Length = SubKey->Length - SubKeyString.Length;
164
165 /* Setup the object attributes */
167 &SubKeyString,
169 RootKey,
170 NULL);
171
172 /* Open the setting key */
173 Status = ZwOpenKey((PHANDLE)NewKeyHandle, GENERIC_READ, &ObjectAttributes);
174 }
175
176 /* Return to caller */
177 return Status;
178}
179
180/*
181 * @implemented
182 */
184NTAPI
192{
193 ULONG KeyInfo[256];
194 UNICODE_STRING ValueNameString, IntegerString;
195 ULONG KeyInfoSize, ResultSize;
197 BOOLEAN FreeHeap = FALSE;
199
200 /* Build a string for the value name */
201 Status = RtlInitUnicodeStringEx(&ValueNameString, ValueName);
202 if (!NT_SUCCESS(Status)) return Status;
203
204 /* Query the value */
205 Status = ZwQueryValueKey(KeyHandle,
206 &ValueNameString,
208 KeyValueInformation,
209 sizeof(KeyInfo),
210 &ResultSize);
212 {
213 /* Our local buffer wasn't enough, allocate one */
214 KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
215 KeyValueInformation->DataLength;
216 KeyValueInformation = RtlAllocateHeap(RtlGetProcessHeap(),
217 0,
218 KeyInfoSize);
219 if (KeyValueInformation != NULL)
220 {
221 /* Try again */
222 Status = ZwQueryValueKey(KeyHandle,
223 &ValueNameString,
225 KeyValueInformation,
226 KeyInfoSize,
227 &ResultSize);
228 FreeHeap = TRUE;
229 }
230 else
231 {
232 /* Give up this time */
234 }
235 }
236
237 /* Check for success */
238 if (NT_SUCCESS(Status))
239 {
240 /* Handle binary data */
241 if (KeyValueInformation->Type == REG_BINARY)
242 {
243 /* Check validity */
244 if ((Buffer) && (KeyValueInformation->DataLength <= BufferSize))
245 {
246 /* Copy into buffer */
248 &KeyValueInformation->Data,
249 KeyValueInformation->DataLength);
250 }
251 else
252 {
254 }
255
256 /* Copy the result length */
257 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
258 }
259 else if (KeyValueInformation->Type == REG_DWORD)
260 {
261 /* Check for valid type */
262 if (KeyValueInformation->Type != Type)
263 {
264 /* Error */
266 }
267 else
268 {
269 /* Check validity */
270 if ((Buffer) &&
271 (BufferSize == sizeof(ULONG)) &&
272 (KeyValueInformation->DataLength <= BufferSize))
273 {
274 /* Copy into buffer */
276 &KeyValueInformation->Data,
277 KeyValueInformation->DataLength);
278 }
279 else
280 {
282 }
283
284 /* Copy the result length */
285 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
286 }
287 }
288 else if (KeyValueInformation->Type != REG_SZ)
289 {
290 /* We got something weird */
292 }
293 else
294 {
295 /* String, check what you requested */
296 if (Type == REG_DWORD)
297 {
298 /* Validate */
299 if (BufferSize != sizeof(ULONG))
300 {
301 /* Invalid size */
302 BufferSize = 0;
304 }
305 else
306 {
307 /* OK, we know what you want... */
308 IntegerString.Buffer = (PWSTR)KeyValueInformation->Data;
309 IntegerString.Length = (USHORT)KeyValueInformation->DataLength -
310 sizeof(WCHAR);
311 IntegerString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
312 Status = RtlUnicodeStringToInteger(&IntegerString, 0, (PULONG)Buffer);
313 }
314 }
315 else
316 {
317 /* Validate */
318 if (KeyValueInformation->DataLength > BufferSize)
319 {
320 /* Invalid */
322 }
323 else
324 {
325 /* Set the size */
326 BufferSize = KeyValueInformation->DataLength;
327 }
328
329 /* Copy the string */
330 RtlMoveMemory(Buffer, &KeyValueInformation->Data, BufferSize);
331 }
332
333 /* Copy the result length */
334 if (ReturnedLength) *ReturnedLength = KeyValueInformation->DataLength;
335 }
336 }
337
338 /* Check if buffer was in heap */
339 if (FreeHeap) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
340
341 /* Return status */
342 return Status;
343}
344
345/*
346 * @implemented
347 */
349NTAPI
351 _In_ PUNICODE_STRING SubKey,
357 _In_ BOOLEAN Wow64)
358{
361
362 /* Open a handle to the key */
364
365 /* Check for success */
366 if (NT_SUCCESS(Status))
367 {
368 /* Query the data */
370 ValueName,
371 Type,
372 Buffer,
375
376 /* Close the key */
378 }
379
380 /* Return to caller */
381 return Status;
382}
383
384/*
385 * @implemented
386 */
388NTAPI
390 _In_ PUNICODE_STRING SubKey,
396{
397 /* Call the newer function */
399 ValueName,
400 Type,
401 Buffer,
404 FALSE);
405}
406
407VOID
408NTAPI
410{
411 // Ignored atm
412}
413
414PVOID
415NTAPI
417{
419 ULONG DirSize;
420 PVOID Cookie = NULL;
421
422 /* Check NT header first */
423 if (!RtlImageNtHeader(BaseAddress)) return NULL;
424
425 /* Get the pointer to the config directory */
427 TRUE,
429 &DirSize);
430
431 /* Check for sanity */
432 if (!ConfigDir ||
433 (DirSize != 64 && ConfigDir->Size != DirSize) ||
434 (ConfigDir->Size < 0x48))
435 return NULL;
436
437 /* Now get the cookie */
438 Cookie = (PVOID)ConfigDir->SecurityCookie;
439
440 /* Check this cookie */
442 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
443 {
444 Cookie = NULL;
445 }
446
447 /* Return validated security cookie */
448 return Cookie;
449}
450
451PVOID
452NTAPI
454{
457 ULONG_PTR NewCookie;
458
459 /* Fetch address of the cookie */
461
462 if (Cookie)
463 {
464 /* Check if it's a default one */
466 (*Cookie == 0xBB40))
467 {
468 /* Make up a cookie from a bunch of values which may uniquely represent
469 current moment of time, environment, etc */
471
472 NewCookie = Counter.LowPart ^ Counter.HighPart;
473 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueProcess;
474 NewCookie ^= (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueThread;
475
476 /* Loop like it's done in KeQueryTickCount(). We don't want to call it directly. */
477 while (SharedUserData->SystemTime.High1Time != SharedUserData->SystemTime.High2Time)
478 {
480 };
481
482 /* Calculate the milliseconds value and xor it to the cookie */
483 NewCookie ^= Int64ShrlMod32(UInt32x32To64(SharedUserData->TickCountMultiplier, SharedUserData->TickCount.LowPart), 24) +
484 (SharedUserData->TickCountMultiplier * (SharedUserData->TickCount.High1Time << 8));
485
486 /* Make the cookie 16bit if necessary */
487 if (*Cookie == 0xBB40) NewCookie &= 0xFFFF;
488
489 /* If the result is 0 or the same as we got, just subtract one from the existing value
490 and that's it */
491 if ((NewCookie == 0) || (NewCookie == *Cookie))
492 {
493 NewCookie = *Cookie - 1;
494 }
495
496 /* Set the new cookie value */
497 *Cookie = NewCookie;
498 }
499 }
500
501 return Cookie;
502}
503
504VOID
505NTAPI
507{
509 PLDR_DATA_TABLE_ENTRY LdrEntry;
510 PLIST_ENTRY NextEntry, ListHead;
511 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
513 PVOID EntryPoint;
514
515 DPRINT("LdrpInitializeThread() called for %wZ (%p/%p)\n",
517 NtCurrentTeb()->RealClientId.UniqueProcess,
518 NtCurrentTeb()->RealClientId.UniqueThread);
519
520 /* Acquire the loader Lock */
522
523 /* Allocate an Activation Context Stack */
524 DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
525 Status = RtlAllocateActivationContextStack(&NtCurrentTeb()->ActivationContextStackPointer);
526 if (!NT_SUCCESS(Status))
527 {
528 DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
529 }
530
531 /* Make sure we are not shutting down */
533
534 /* Allocate TLS */
536
537 /* Start at the beginning */
538 ListHead = &Peb->Ldr->InMemoryOrderModuleList;
539 NextEntry = ListHead->Flink;
540 while (NextEntry != ListHead)
541 {
542 /* Get the current entry */
543 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
544
545 /* Make sure it's not ourselves */
546 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
547 {
548 /* Check if we should call */
549 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS))
550 {
551 /* Get the entrypoint */
552 EntryPoint = LdrEntry->EntryPoint;
553
554 /* Check if we are ready to call it */
555 if ((EntryPoint) &&
556 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
557 (LdrEntry->Flags & LDRP_IMAGE_DLL))
558 {
559 /* Set up the Act Ctx */
560 ActCtx.Size = sizeof(ActCtx);
561 ActCtx.Format = 1;
563
564 /* Activate the ActCtx */
565 RtlActivateActivationContextUnsafeFast(&ActCtx,
567
569 {
570 /* Check if it has TLS */
571 if (LdrEntry->TlsIndex)
572 {
573 /* Make sure we're not shutting down */
575 {
576 /* Call TLS */
578 }
579 }
580
581 /* Make sure we're not shutting down */
583 {
584 /* Call the Entrypoint */
585 DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
586 &LdrEntry->BaseDllName, LdrEntry->EntryPoint,
587 NtCurrentTeb()->RealClientId.UniqueProcess,
588 NtCurrentTeb()->RealClientId.UniqueThread);
590 LdrEntry->DllBase,
592 NULL);
593 }
594 }
596 {
597 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_ATTACH) for %wZ\n",
598 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
599 }
600 _SEH2_END;
601
602 /* Deactivate the ActCtx */
603 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
604 }
605 }
606 }
607
608 /* Next entry */
609 NextEntry = NextEntry->Flink;
610 }
611
612 /* Check for TLS */
614 {
615 /* Set up the Act Ctx */
616 ActCtx.Size = sizeof(ActCtx);
617 ActCtx.Format = 1;
619
620 /* Activate the ActCtx */
621 RtlActivateActivationContextUnsafeFast(&ActCtx,
623
625 {
626 /* Do TLS callbacks */
628 }
630 {
631 /* Do nothing */
632 }
633 _SEH2_END;
634
635 /* Deactivate the ActCtx */
636 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
637 }
638
639Exit:
640
641 /* Release the loader lock */
643
644 DPRINT("LdrpInitializeThread() done\n");
645}
646
648NTAPI
650{
651 PLDR_DATA_TABLE_ENTRY LocalArray[16];
652 PLIST_ENTRY ListHead;
653 PLIST_ENTRY NextEntry;
654 PLDR_DATA_TABLE_ENTRY LdrEntry, *LdrRootEntry, OldInitializer;
655 PVOID EntryPoint;
656 ULONG Count, i;
657 //ULONG BreakOnInit;
660 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
661 ULONG BreakOnDllLoad;
662 PTEB OldTldTeb;
663 BOOLEAN DllStatus;
664
665 DPRINT("LdrpRunInitializeRoutines() called for %wZ (%p/%p)\n",
667 NtCurrentTeb()->RealClientId.UniqueProcess,
668 NtCurrentTeb()->RealClientId.UniqueThread);
669
670 /* Check the Loader Lock */
672
673 /* Get the number of entries to call */
675 {
676 /* Check if we can use our local buffer */
677 if (Count > 16)
678 {
679 /* Allocate space for all the entries */
680 LdrRootEntry = RtlAllocateHeap(LdrpHeap,
681 0,
682 Count * sizeof(*LdrRootEntry));
683 if (!LdrRootEntry) return STATUS_NO_MEMORY;
684 }
685 else
686 {
687 /* Use our local array */
688 LdrRootEntry = LocalArray;
689 }
690 }
691 else
692 {
693 /* Don't need one */
694 LdrRootEntry = NULL;
695 }
696
697 /* Show debug message */
698 if (ShowSnaps)
699 {
700 DPRINT1("[%p,%p] LDR: Real INIT LIST for Process %wZ\n",
701 NtCurrentTeb()->RealClientId.UniqueThread,
702 NtCurrentTeb()->RealClientId.UniqueProcess,
704 }
705
706 /* Loop in order */
708 NextEntry = ListHead->Flink;
709 i = 0;
710 while (NextEntry != ListHead)
711 {
712 /* Get the Data Entry */
713 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
714
715 /* Check if we have a Root Entry */
716 if (LdrRootEntry)
717 {
718 /* Check flags */
719 if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
720 {
721 /* Setup the Cookie for the DLL */
722 LdrpInitSecurityCookie(LdrEntry);
723
724 /* Check for valid entrypoint */
725 if (LdrEntry->EntryPoint)
726 {
727 /* Write in array */
728 ASSERT(i < Count);
729 LdrRootEntry[i] = LdrEntry;
730
731 /* Display debug message */
732 if (ShowSnaps)
733 {
734 DPRINT1("[%p,%p] LDR: %wZ init routine %p\n",
735 NtCurrentTeb()->RealClientId.UniqueThread,
736 NtCurrentTeb()->RealClientId.UniqueProcess,
737 &LdrEntry->FullDllName,
738 LdrEntry->EntryPoint);
739 }
740 i++;
741 }
742 }
743 }
744
745 /* Set the flag */
746 LdrEntry->Flags |= LDRP_ENTRY_PROCESSED;
747 NextEntry = NextEntry->Flink;
748 }
749
751
752 /* If we got a context, then we have to call Kernel32 for TS support */
753 if (Context)
754 {
755 /* Check if we have one */
756 if (Kernel32ProcessInitPostImportFunction)
757 {
758 /* Call it */
759 Status = Kernel32ProcessInitPostImportFunction();
760 if (!NT_SUCCESS(Status))
761 {
762 DPRINT1("LDR: LdrpRunInitializeRoutines - Failed running kernel32 post-import function, Status=0x%08lx\n", Status);
763 }
764 }
765 /* Clear it */
766 Kernel32ProcessInitPostImportFunction = NULL;
767 }
768
769 /* No root entry? return */
770 if (!LdrRootEntry)
771 return Status;
772
773 /* Set the TLD TEB */
776
777 /* Loop */
778 i = 0;
779 while (i < Count)
780 {
781 /* Get an entry */
782 LdrEntry = LdrRootEntry[i];
783
784 /* FIXME: Verify NX Compat */
785
786 /* Move to next entry */
787 i++;
788
789 /* Get its entrypoint */
790 EntryPoint = LdrEntry->EntryPoint;
791
792 /* Are we being debugged? */
793 BreakOnDllLoad = 0;
795 {
796 /* Check if we should break on load */
798 L"BreakOnDllLoad",
799 REG_DWORD,
800 &BreakOnDllLoad,
801 sizeof(ULONG),
802 NULL);
803 if (!NT_SUCCESS(Status)) BreakOnDllLoad = 0;
804
805 /* Reset status back to STATUS_SUCCESS */
807 }
808
809 /* Break if aksed */
810 if (BreakOnDllLoad)
811 {
812 /* Check if we should show a message */
813 if (ShowSnaps)
814 {
815 DPRINT1("LDR: %wZ loaded.", &LdrEntry->BaseDllName);
816 DPRINT1(" - About to call init routine at %p\n", EntryPoint);
817 }
818
819 /* Break in debugger */
821 }
822
823 /* Make sure we have an entrypoint */
824 if (EntryPoint)
825 {
826 /* Save the old Dll Initializer and write the current one */
827 OldInitializer = LdrpCurrentDllInitializer;
828 LdrpCurrentDllInitializer = LdrEntry;
829
830 /* Set up the Act Ctx */
831 ActCtx.Size = sizeof(ActCtx);
832 ActCtx.Format = 1;
834
835 /* Activate the ActCtx */
836 RtlActivateActivationContextUnsafeFast(&ActCtx,
838
840 {
841 /* Check if it has TLS */
842 if (LdrEntry->TlsIndex && Context)
843 {
844 /* Call TLS */
846 }
847
848 /* Call the Entrypoint */
849 if (ShowSnaps)
850 {
851 DPRINT1("%wZ - Calling entry point at %p for DLL_PROCESS_ATTACH\n",
852 &LdrEntry->BaseDllName, EntryPoint);
853 }
854 DllStatus = LdrpCallInitRoutine(EntryPoint,
855 LdrEntry->DllBase,
857 Context);
858 }
860 {
861 DllStatus = FALSE;
862 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_ATTACH) for %wZ\n",
863 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
864 }
865 _SEH2_END;
866
867 /* Deactivate the ActCtx */
868 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
869
870 /* Save the Current DLL Initializer */
871 LdrpCurrentDllInitializer = OldInitializer;
872
873 /* Mark the entry as processed */
875
876 /* Fail if DLL init failed */
877 if (!DllStatus)
878 {
879 DPRINT1("LDR: DLL_PROCESS_ATTACH for dll \"%wZ\" (InitRoutine: %p) failed\n",
880 &LdrEntry->BaseDllName, EntryPoint);
881
883 goto Quickie;
884 }
885 }
886 }
887
888 /* Loop in order */
890 NextEntry = NextEntry->Flink;
891 while (NextEntry != ListHead)
892 {
893 /* Get the Data Entry */
894 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
895
896 /* FIXME: Verify NX Compat */
897 // LdrpCheckNXCompatibility()
898
899 /* Next entry */
900 NextEntry = NextEntry->Flink;
901 }
902
903 /* Check for TLS */
905 {
906 /* Set up the Act Ctx */
907 ActCtx.Size = sizeof(ActCtx);
908 ActCtx.Format = 1;
910
911 /* Activate the ActCtx */
912 RtlActivateActivationContextUnsafeFast(&ActCtx,
914
916 {
917 /* Do TLS callbacks */
919 }
921 {
922 /* Do nothing */
923 }
924 _SEH2_END;
925
926 /* Deactivate the ActCtx */
927 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
928 }
929
930Quickie:
931 /* Restore old TEB */
933
934 /* Check if the array is in the heap */
935 if (LdrRootEntry != LocalArray)
936 {
937 /* Free the array */
938 RtlFreeHeap(LdrpHeap, 0, LdrRootEntry);
939 }
940
941 /* Return to caller */
942 DPRINT("LdrpRunInitializeRoutines() done\n");
943 return Status;
944}
945
946/*
947 * @implemented
948 */
950NTAPI
952{
954 PLDR_DATA_TABLE_ENTRY LdrEntry;
955 PLIST_ENTRY NextEntry, ListHead;
956 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
957 PVOID EntryPoint;
958
959 DPRINT("LdrShutdownProcess() called for %wZ\n", &LdrpImageEntry->BaseDllName);
961
962 /* Tell the Shim Engine */
963 if (g_ShimsEnabled)
964 {
968 }
969
970 /* Tell the world */
971 if (ShowSnaps)
972 {
973 DPRINT1("\n");
974 }
975
976 /* Set the shutdown variables */
977 LdrpShutdownThreadId = NtCurrentTeb()->RealClientId.UniqueThread;
979
980 /* Enter the Loader Lock */
982
983 /* Cleanup trace logging data (Etw) */
984 if (SharedUserData->TraceLogging)
985 {
986 /* FIXME */
987 DPRINT1("We don't support Etw yet.\n");
988 }
989
990 /* Start at the end */
992 NextEntry = ListHead->Blink;
993 while (NextEntry != ListHead)
994 {
995 /* Get the current entry */
996 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
997 NextEntry = NextEntry->Blink;
998
999 /* Make sure it's not ourselves */
1000 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1001 {
1002 /* Get the entrypoint */
1003 EntryPoint = LdrEntry->EntryPoint;
1004
1005 /* Check if we are ready to call it */
1006 if (EntryPoint &&
1007 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1008 LdrEntry->Flags)
1009 {
1010 /* Set up the Act Ctx */
1011 ActCtx.Size = sizeof(ActCtx);
1012 ActCtx.Format = 1;
1014
1015 /* Activate the ActCtx */
1016 RtlActivateActivationContextUnsafeFast(&ActCtx,
1017 LdrEntry->EntryPointActivationContext);
1018
1019 _SEH2_TRY
1020 {
1021 /* Check if it has TLS */
1022 if (LdrEntry->TlsIndex)
1023 {
1024 /* Call TLS */
1026 }
1027
1028 /* Call the Entrypoint */
1029 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1030 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1031 LdrpCallInitRoutine(EntryPoint,
1032 LdrEntry->DllBase,
1034 (PVOID)1);
1035 }
1037 {
1038 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
1039 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1040 }
1041 _SEH2_END;
1042
1043 /* Deactivate the ActCtx */
1044 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1045 }
1046 }
1047 }
1048
1049 /* Check for TLS */
1050 if (LdrpImageHasTls)
1051 {
1052 /* Set up the Act Ctx */
1053 ActCtx.Size = sizeof(ActCtx);
1054 ActCtx.Format = 1;
1056
1057 /* Activate the ActCtx */
1058 RtlActivateActivationContextUnsafeFast(&ActCtx,
1060
1061 _SEH2_TRY
1062 {
1063 /* Do TLS callbacks */
1065 }
1067 {
1068 /* Do nothing */
1069 }
1070 _SEH2_END;
1071
1072 /* Deactivate the ActCtx */
1073 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1074 }
1075
1076 /* FIXME: Do Heap detection and Etw final shutdown */
1077
1078 /* Release the lock */
1080 DPRINT("LdrpShutdownProcess() done\n");
1081
1082 return STATUS_SUCCESS;
1083}
1084
1085/*
1086 * @implemented
1087 */
1089NTAPI
1091{
1092 PPEB Peb = NtCurrentPeb();
1093 PTEB Teb = NtCurrentTeb();
1094 PLDR_DATA_TABLE_ENTRY LdrEntry;
1095 PLIST_ENTRY NextEntry, ListHead;
1096 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
1097 PVOID EntryPoint;
1098
1099 DPRINT("LdrShutdownThread() called for %wZ\n",
1101
1102 /* Cleanup trace logging data (Etw) */
1103 if (SharedUserData->TraceLogging)
1104 {
1105 /* FIXME */
1106 DPRINT1("We don't support Etw yet.\n");
1107 }
1108
1109 /* Get the Ldr Lock */
1111
1112 /* Start at the end */
1114 NextEntry = ListHead->Blink;
1115 while (NextEntry != ListHead)
1116 {
1117 /* Get the current entry */
1118 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
1119 NextEntry = NextEntry->Blink;
1120
1121 /* Make sure it's not ourselves */
1122 if (Peb->ImageBaseAddress != LdrEntry->DllBase)
1123 {
1124 /* Check if we should call */
1125 if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
1126 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
1127 (LdrEntry->Flags & LDRP_IMAGE_DLL))
1128 {
1129 /* Get the entrypoint */
1130 EntryPoint = LdrEntry->EntryPoint;
1131
1132 /* Check if we are ready to call it */
1133 if (EntryPoint)
1134 {
1135 /* Set up the Act Ctx */
1136 ActCtx.Size = sizeof(ActCtx);
1137 ActCtx.Format = 1;
1139
1140 /* Activate the ActCtx */
1141 RtlActivateActivationContextUnsafeFast(&ActCtx,
1142 LdrEntry->EntryPointActivationContext);
1143
1144 _SEH2_TRY
1145 {
1146 /* Check if it has TLS */
1147 if (LdrEntry->TlsIndex)
1148 {
1149 /* Make sure we're not shutting down */
1151 {
1152 /* Call TLS */
1154 }
1155 }
1156
1157 /* Make sure we're not shutting down */
1159 {
1160 /* Call the Entrypoint */
1161 DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
1162 &LdrEntry->BaseDllName, LdrEntry->EntryPoint);
1163 LdrpCallInitRoutine(EntryPoint,
1164 LdrEntry->DllBase,
1166 NULL);
1167 }
1168 }
1170 {
1171 DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_THREAD_DETACH) for %wZ\n",
1172 _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
1173 }
1174 _SEH2_END;
1175
1176 /* Deactivate the ActCtx */
1177 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1178 }
1179 }
1180 }
1181 }
1182
1183 /* Check for TLS */
1184 if (LdrpImageHasTls)
1185 {
1186 /* Set up the Act Ctx */
1187 ActCtx.Size = sizeof(ActCtx);
1188 ActCtx.Format = 1;
1190
1191 /* Activate the ActCtx */
1192 RtlActivateActivationContextUnsafeFast(&ActCtx,
1194
1195 _SEH2_TRY
1196 {
1197 /* Do TLS callbacks */
1199 }
1201 {
1202 /* Do nothing */
1203 }
1204 _SEH2_END;
1205
1206 /* Deactivate the ActCtx */
1207 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
1208 }
1209
1210 /* Free TLS */
1211 LdrpFreeTls();
1213
1214 /* Check for expansion slots */
1215 if (Teb->TlsExpansionSlots)
1216 {
1217 /* Free expansion slots */
1218 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->TlsExpansionSlots);
1219 }
1220
1221 /* Check for FLS Data */
1222 if (Teb->FlsData)
1223 {
1224 /* Mimic BaseRundownFls */
1225 ULONG n, FlsHighIndex;
1226 PRTL_FLS_DATA pFlsData;
1227 PFLS_CALLBACK_FUNCTION lpCallback;
1228
1229 pFlsData = Teb->FlsData;
1230
1232 FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
1233 RemoveEntryList(&pFlsData->ListEntry);
1235
1236 for (n = 1; n <= FlsHighIndex; ++n)
1237 {
1238 lpCallback = NtCurrentPeb()->FlsCallback[n];
1239 if (lpCallback && pFlsData->Data[n])
1240 {
1241 lpCallback(pFlsData->Data[n]);
1242 }
1243 }
1244
1245 RtlFreeHeap(RtlGetProcessHeap(), 0, pFlsData);
1246 Teb->FlsData = NULL;
1247 }
1248
1249 /* Check for Fiber data */
1250 if (Teb->HasFiberData)
1251 {
1252 /* Free Fiber data*/
1253 RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->NtTib.FiberData);
1254 Teb->NtTib.FiberData = NULL;
1255 }
1256
1257 /* Free the activation context stack */
1259 DPRINT("LdrShutdownThread() done\n");
1260
1261 return STATUS_SUCCESS;
1262}
1263
1265NTAPI
1267{
1268 PLIST_ENTRY NextEntry, ListHead;
1269 PLDR_DATA_TABLE_ENTRY LdrEntry;
1270 PIMAGE_TLS_DIRECTORY TlsDirectory;
1271 PLDRP_TLS_DATA TlsData;
1272 ULONG Size;
1273
1274 /* Initialize the TLS List */
1276
1277 /* Loop all the modules */
1278 ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
1279 NextEntry = ListHead->Flink;
1280 while (ListHead != NextEntry)
1281 {
1282 /* Get the entry */
1283 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1284 NextEntry = NextEntry->Flink;
1285
1286 /* Get the TLS directory */
1287 TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1288 TRUE,
1290 &Size);
1291
1292 /* Check if we have a directory */
1293 if (!TlsDirectory) continue;
1294
1295 /* Check if the image has TLS */
1297
1298 /* Show debug message */
1299 if (ShowSnaps)
1300 {
1301 DPRINT1("LDR: Tls Found in %wZ at %p\n",
1302 &LdrEntry->BaseDllName,
1303 TlsDirectory);
1304 }
1305
1306 /* Allocate an entry */
1307 TlsData = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LDRP_TLS_DATA));
1308 if (!TlsData) return STATUS_NO_MEMORY;
1309
1310 /* Lock the DLL and mark it for TLS Usage */
1311 LdrEntry->LoadCount = -1;
1312 LdrEntry->TlsIndex = -1;
1313
1314 /* Save the cached TLS data */
1315 TlsData->TlsDirectory = *TlsDirectory;
1316 InsertTailList(&LdrpTlsList, &TlsData->TlsLinks);
1317
1318 /* Update the index */
1321 }
1322
1323 /* Done setting up TLS, allocate entries */
1324 return LdrpAllocateTls();
1325}
1326
1328NTAPI
1330{
1331 PTEB Teb = NtCurrentTeb();
1332 PLIST_ENTRY NextEntry, ListHead;
1333 PLDRP_TLS_DATA TlsData;
1334 SIZE_T TlsDataSize;
1335 PVOID *TlsVector;
1336
1337 /* Check if we have any entries */
1339 return STATUS_SUCCESS;
1340
1341 /* Allocate the vector array */
1342 TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
1343 0,
1344 LdrpNumberOfTlsEntries * sizeof(PVOID));
1345 if (!TlsVector) return STATUS_NO_MEMORY;
1346 Teb->ThreadLocalStoragePointer = TlsVector;
1347
1348 /* Loop the TLS Array */
1349 ListHead = &LdrpTlsList;
1350 NextEntry = ListHead->Flink;
1351 while (NextEntry != ListHead)
1352 {
1353 /* Get the entry */
1354 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1355 NextEntry = NextEntry->Flink;
1356
1357 /* Allocate this vector */
1358 TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
1360 TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
1361 0,
1362 TlsDataSize);
1363 if (!TlsVector[TlsData->TlsDirectory.Characteristics])
1364 {
1365 /* Out of memory */
1366 return STATUS_NO_MEMORY;
1367 }
1368
1369 /* Show debug message */
1370 if (ShowSnaps)
1371 {
1372 DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
1373 TlsVector,
1375 &TlsVector[TlsData->TlsDirectory.Characteristics],
1377 TlsVector[TlsData->TlsDirectory.Characteristics]);
1378 }
1379
1380 /* Copy the data */
1381 RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
1383 TlsDataSize);
1384 }
1385
1386 /* Done */
1387 return STATUS_SUCCESS;
1388}
1389
1390VOID
1391NTAPI
1393{
1394 PLIST_ENTRY ListHead, NextEntry;
1395 PLDRP_TLS_DATA TlsData;
1396 PVOID *TlsVector;
1397 PTEB Teb = NtCurrentTeb();
1398
1399 /* Get a pointer to the vector array */
1400 TlsVector = Teb->ThreadLocalStoragePointer;
1401 if (!TlsVector) return;
1402
1403 /* Loop through it */
1404 ListHead = &LdrpTlsList;
1405 NextEntry = ListHead->Flink;
1406 while (NextEntry != ListHead)
1407 {
1408 TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks);
1409 NextEntry = NextEntry->Flink;
1410
1411 /* Free each entry */
1412 if (TlsVector[TlsData->TlsDirectory.Characteristics])
1413 {
1414 RtlFreeHeap(RtlGetProcessHeap(),
1415 0,
1416 TlsVector[TlsData->TlsDirectory.Characteristics]);
1417 }
1418 }
1419
1420 /* Free the array itself */
1421 RtlFreeHeap(RtlGetProcessHeap(),
1422 0,
1423 TlsVector);
1424}
1425
1427NTAPI
1429{
1432 ULONG ExecuteOptions, MinimumStackCommit = 0, GlobalFlag;
1433
1434 /* Return error if we were not provided a pointer where to save the options key handle */
1435 if (!OptionsKey) return STATUS_INVALID_HANDLE;
1436
1437 /* Zero initialize the options key pointer */
1438 *OptionsKey = NULL;
1439
1440 /* Open the options key */
1441 Status = LdrOpenImageFileOptionsKey(ImagePathName, 0, &KeyHandle);
1442
1443 /* Save it if it was opened successfully */
1444 if (NT_SUCCESS(Status))
1445 *OptionsKey = KeyHandle;
1446
1447 if (KeyHandle)
1448 {
1449 /* There are image specific options, read them starting with NXCOMPAT */
1451 L"ExecuteOptions",
1452 4,
1453 &ExecuteOptions,
1454 sizeof(ExecuteOptions),
1455 0);
1456
1457 if (NT_SUCCESS(Status))
1458 {
1459 /* TODO: Set execution options for the process */
1460 /*
1461 if (ExecuteOptions == 0)
1462 ExecuteOptions = 1;
1463 else
1464 ExecuteOptions = 2;
1465 ZwSetInformationProcess(NtCurrentProcess(),
1466 ProcessExecuteFlags,
1467 &ExecuteOptions,
1468 sizeof(ULONG));*/
1469
1470 }
1471
1472 /* Check if this image uses large pages */
1473 if (Peb->ImageUsesLargePages)
1474 {
1475 /* TODO: If it does, open large page key */
1477 }
1478
1479 /* Get various option values */
1481 L"DisableHeapLookaside",
1482 REG_DWORD,
1485 NULL);
1486
1488 L"ShutdownFlags",
1489 REG_DWORD,
1492 NULL);
1493
1495 L"MinimumStackCommitInBytes",
1496 REG_DWORD,
1497 &MinimumStackCommit,
1498 sizeof(MinimumStackCommit),
1499 NULL);
1500
1501 /* Update PEB's minimum stack commit if it's lower */
1502 if (Peb->MinimumStackCommit < MinimumStackCommit)
1503 Peb->MinimumStackCommit = MinimumStackCommit;
1504
1505 /* Set the global flag */
1507 L"GlobalFlag",
1508 REG_DWORD,
1509 &GlobalFlag,
1510 sizeof(GlobalFlag),
1511 NULL);
1512
1513 if (NT_SUCCESS(Status))
1514 Peb->NtGlobalFlag = GlobalFlag;
1515 else
1516 GlobalFlag = 0;
1517
1518 /* Call AVRF if necessary */
1520 {
1522 if (!NT_SUCCESS(Status))
1523 {
1524 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1525 }
1526 }
1527 }
1528 else
1529 {
1530 /* There are no image-specific options, so perform global initialization */
1532 {
1533 /* Initialize app verifier package */
1535 if (!NT_SUCCESS(Status))
1536 {
1537 DPRINT1("AVRF: LdrpInitializeApplicationVerifierPackage failed with %08X\n", Status);
1538 }
1539 }
1540 }
1541
1542 return STATUS_SUCCESS;
1543}
1544
1545VOID
1546NTAPI
1548{
1549 DPRINT("LdrpValidateImageForMp is unimplemented\n");
1550 // TODO:
1551 // Scan the LockPrefixTable in the load config directory
1552}
1553
1554BOOLEAN
1555NTAPI
1557{
1558 UNICODE_STRING PolicyKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\Software\\Policies\\Microsoft\\Windows\\AppCompat");
1559 UNICODE_STRING DisableDetection = RTL_CONSTANT_STRING(L"DisableCompatGuidDetection");
1565
1566 Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &PolicyKeyAttributes);
1567 if (NT_SUCCESS(Status))
1568 {
1570 &DisableDetection,
1572 &KeyInfo,
1573 sizeof(KeyInfo),
1574 &ResultLength);
1576 if ((NT_SUCCESS(Status)) &&
1577 (KeyInfo.Type == REG_DWORD) &&
1578 (KeyInfo.DataLength == sizeof(ULONG)) &&
1579 (KeyInfo.Data[0] == TRUE))
1580 {
1581 return TRUE;
1582 }
1583 }
1584 return FALSE;
1585}
1586
1587
1588VOID
1589NTAPI
1590LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData)
1591{
1592 static const struct
1593 {
1594 const GUID* Guid;
1595 const DWORD Version;
1596 } KnownCompatGuids[] = {
1597 { &COMPAT_GUID_WIN10, _WIN32_WINNT_WIN10 },
1598 { &COMPAT_GUID_WIN81, _WIN32_WINNT_WINBLUE },
1599 { &COMPAT_GUID_WIN8, _WIN32_WINNT_WIN8 },
1600 { &COMPAT_GUID_WIN7, _WIN32_WINNT_WIN7 },
1601 { &COMPAT_GUID_VISTA, _WIN32_WINNT_VISTA },
1602 };
1603
1604 ULONG Buffer[(sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 10 + sizeof(ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION)) / sizeof(ULONG)];
1605 ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION* ContextCompatInfo;
1606 SIZE_T SizeRequired;
1608 DWORD n, cur;
1609 ReactOS_ShimData* pShimData = *pOldShimData;
1610
1611 if (pShimData)
1612 {
1613 if (pShimData->dwMagic != REACTOS_SHIMDATA_MAGIC ||
1614 pShimData->dwSize != sizeof(ReactOS_ShimData))
1615 {
1616 DPRINT1("LdrpInitializeProcessCompat: Corrupt pShimData (0x%x, %u)\n", pShimData->dwMagic, pShimData->dwSize);
1617 return;
1618 }
1619 if (pShimData->dwRosProcessCompatVersion)
1620 {
1622 {
1623 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion set to ignore manifest\n");
1624 }
1625 else
1626 {
1627 DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion already set to 0x%x\n", pShimData->dwRosProcessCompatVersion);
1628 }
1629 return;
1630 }
1631 }
1632
1633 SizeRequired = sizeof(Buffer);
1635 pProcessActctx,
1636 NULL,
1637 CompatibilityInformationInActivationContext,
1638 Buffer,
1639 sizeof(Buffer),
1640 &SizeRequired);
1641
1642 if (!NT_SUCCESS(Status))
1643 {
1644 DPRINT1("LdrpInitializeProcessCompat: Unable to query process actctx with status %x\n", Status);
1645 return;
1646 }
1647
1648 ContextCompatInfo = (ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*)Buffer;
1649 /* No Compatibility elements present, bail out */
1650 if (ContextCompatInfo->ElementCount == 0)
1651 return;
1652
1653 /* Search for known GUIDs, starting from oldest to newest.
1654 Note that on Windows it is somewhat reversed, starting from the latest known
1655 version, going down. But we are not Windows, trying to allow a lower version,
1656 we are ReactOS trying to fake a higher version. So we interpret what Windows
1657 does as "try the closest version to the actual version", so we start with the
1658 lowest version, which is closest to Windows 2003, which we mostly are. */
1659 for (cur = RTL_NUMBER_OF(KnownCompatGuids) - 1; cur != -1; --cur)
1660 {
1661 for (n = 0; n < ContextCompatInfo->ElementCount; ++n)
1662 {
1663 if (ContextCompatInfo->Elements[n].Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS &&
1664 RtlCompareMemory(&ContextCompatInfo->Elements[n].Id, KnownCompatGuids[cur].Guid, sizeof(GUID)) == sizeof(GUID))
1665 {
1667 {
1668 DPRINT1("LdrpInitializeProcessCompat: Not applying automatic fix for winver 0x%x due to policy\n", KnownCompatGuids[cur].Version);
1669 return;
1670 }
1671
1672 /* If this process did not need shim data before, allocate and store it */
1673 if (pShimData == NULL)
1674 {
1675 PPEB Peb = NtCurrentPeb();
1676
1677 ASSERT(Peb->pShimData == NULL);
1678 pShimData = RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*pShimData));
1679
1680 if (!pShimData)
1681 {
1682 DPRINT1("LdrpInitializeProcessCompat: Unable to allocated %u bytes\n", sizeof(*pShimData));
1683 return;
1684 }
1685
1686 pShimData->dwSize = sizeof(*pShimData);
1687 pShimData->dwMagic = REACTOS_SHIMDATA_MAGIC;
1688
1689 Peb->pShimData = pShimData;
1690 *pOldShimData = pShimData;
1691 }
1692
1693 /* Store the lowest found version, and bail out. */
1694 pShimData->dwRosProcessCompatVersion = KnownCompatGuids[cur].Version;
1695 DPRINT1("LdrpInitializeProcessCompat: Found guid for winver 0x%x in manifest from %wZ\n",
1696 KnownCompatGuids[cur].Version,
1697 &(NtCurrentPeb()->ProcessParameters->ImagePathName));
1698 return;
1699 }
1700 }
1701 }
1702}
1703
1704VOID
1705NTAPI
1707{
1708 UNICODE_STRING ImagePathName = ProcessParameters->ImagePathName;
1709 WCHAR LocalBuffer[MAX_PATH];
1710 UNICODE_STRING DotLocal;
1713
1714 RequiredSize = ImagePathName.Length + LdrpDotLocal.Length + sizeof(UNICODE_NULL);
1715 if (RequiredSize <= sizeof(LocalBuffer))
1716 {
1717 RtlInitEmptyUnicodeString(&DotLocal, LocalBuffer, sizeof(LocalBuffer));
1718 }
1720 {
1721 DotLocal.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RequiredSize);
1722 DotLocal.Length = 0;
1723 DotLocal.MaximumLength = RequiredSize;
1724 if (!DotLocal.Buffer)
1725 DPRINT1("LDR: Failed to allocate memory for .local check\n");
1726 }
1727 else
1728 {
1729 DotLocal.Buffer = NULL;
1730 DotLocal.Length = 0;
1731 DotLocal.MaximumLength = 0;
1732 DPRINT1("LDR: String too big for .local check\n");
1733 }
1734
1735 if (DotLocal.Buffer)
1736 {
1737 Status = RtlAppendUnicodeStringToString(&DotLocal, &ImagePathName);
1739 if (NT_SUCCESS(Status))
1740 {
1743 }
1744
1745 if (NT_SUCCESS(Status))
1746 {
1747 if (RtlDoesFileExists_UStr(&DotLocal))
1748 {
1750 }
1751 }
1752 else
1753 {
1754 DPRINT1("LDR: Failed to append: 0x%lx\n", Status);
1755 }
1756
1757 if (DotLocal.Buffer != LocalBuffer)
1758 {
1759 RtlFreeHeap(RtlGetProcessHeap(), 0, DotLocal.Buffer);
1760 }
1761 }
1762}
1763
1764
1766NTAPI
1769{
1770 RTL_HEAP_PARAMETERS HeapParameters;
1771 ULONG ComSectionSize;
1772 ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1773 ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1774 PVOID OldShimData;
1776 //UNICODE_STRING LocalFileName, FullImageName;
1777 HANDLE SymLinkHandle;
1778 //ULONG DebugHeapOnly;
1779 UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1780 PPEB Peb = NtCurrentPeb();
1781 BOOLEAN IsDotNetImage = FALSE;
1782 BOOLEAN FreeCurDir = FALSE;
1783 //HANDLE CompatKey;
1784 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1785 //LPWSTR ImagePathBuffer;
1786 ULONG ConfigSize;
1788 HANDLE OptionsKey;
1789 ULONG HeapFlags;
1790 PIMAGE_NT_HEADERS NtHeader;
1791 LPWSTR NtDllName = NULL;
1792 NTSTATUS Status, ImportStatus;
1793 NLSTABLEINFO NlsTable;
1795 PTEB Teb = NtCurrentTeb();
1796 PLIST_ENTRY ListHead;
1797 PLIST_ENTRY NextEntry;
1798 ULONG i;
1799 PWSTR ImagePath;
1800 ULONG DebugProcessHeapOnly = 0;
1801 PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1802 PWCHAR Current;
1803 ULONG ExecuteOptions = 0;
1804 PVOID ViewBase;
1805
1806 /* Set a NULL SEH Filter */
1808
1809 /* Get the image path */
1811
1812 /* Check if it's not normalized */
1814 {
1815 /* Normalize it*/
1816 ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1817 }
1818
1819 /* Create a unicode string for the Image Path */
1821 ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1822 ImagePathName.Buffer = ImagePath;
1823
1824 /* Get the NT Headers */
1826
1827 /* Get the execution options */
1828 Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1829
1830 /* Check if this is a .NET executable */
1832 TRUE,
1834 &ComSectionSize))
1835 {
1836 /* Remember this for later */
1837 IsDotNetImage = TRUE;
1838 }
1839
1840 /* Save the NTDLL Base address */
1842
1843 /* If this is a Native Image */
1845 {
1846 /* Then do DLL Validation */
1848 }
1849
1850 /* Save the old Shim Data */
1851 OldShimData = Peb->pShimData;
1852
1853 /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1854 //Peb->pShimData = NULL;
1855
1856 /* Save the number of processors and CS timeout */
1859
1860 /* Normalize the parameters */
1861 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1862 if (ProcessParameters)
1863 {
1864 /* Save the Image and Command Line Names */
1865 ImageFileName = ProcessParameters->ImagePathName;
1866 CommandLine = ProcessParameters->CommandLine;
1867 }
1868 else
1869 {
1870 /* It failed, initialize empty strings */
1871 RtlInitUnicodeString(&ImageFileName, NULL);
1872 RtlInitUnicodeString(&CommandLine, NULL);
1873 }
1874
1875 /* Initialize NLS data */
1879 &NlsTable);
1880
1881 /* Reset NLS Translations */
1882 RtlResetRtlTranslations(&NlsTable);
1883
1884 /* Get the Image Config Directory */
1886 TRUE,
1888 &ConfigSize);
1889
1890 /* Setup the Heap Parameters */
1891 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1892 HeapFlags = HEAP_GROWABLE;
1893 HeapParameters.Length = sizeof(HeapParameters);
1894
1895 /* Check if we have Configuration Data */
1896#define VALID_CONFIG_FIELD(Name) (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
1897 /* The 'original' load config ends after SecurityCookie */
1898 if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
1899 {
1900 if (ConfigSize != sizeof(IMAGE_LOAD_CONFIG_DIRECTORY))
1901 DPRINT1("WARN: Accepting different LOAD_CONFIG size!\n");
1902 else
1903 DPRINT1("Applying LOAD_CONFIG\n");
1904
1905 if (VALID_CONFIG_FIELD(GlobalFlagsSet) && LoadConfig->GlobalFlagsSet)
1906 Peb->NtGlobalFlag |= LoadConfig->GlobalFlagsSet;
1907
1908 if (VALID_CONFIG_FIELD(GlobalFlagsClear) && LoadConfig->GlobalFlagsClear)
1909 Peb->NtGlobalFlag &= ~LoadConfig->GlobalFlagsClear;
1910
1911 /* Convert the default CS timeout from milliseconds to 100ns units */
1912 if (VALID_CONFIG_FIELD(CriticalSectionDefaultTimeout) && LoadConfig->CriticalSectionDefaultTimeout)
1913 RtlpTimeout.QuadPart = Int32x32To64(LoadConfig->CriticalSectionDefaultTimeout, -10000);
1914
1915 if (VALID_CONFIG_FIELD(DeCommitFreeBlockThreshold) && LoadConfig->DeCommitFreeBlockThreshold)
1916 HeapParameters.DeCommitFreeBlockThreshold = LoadConfig->DeCommitFreeBlockThreshold;
1917
1918 if (VALID_CONFIG_FIELD(DeCommitTotalFreeThreshold) && LoadConfig->DeCommitTotalFreeThreshold)
1919 HeapParameters.DeCommitTotalFreeThreshold = LoadConfig->DeCommitTotalFreeThreshold;
1920
1921 if (VALID_CONFIG_FIELD(MaximumAllocationSize) && LoadConfig->MaximumAllocationSize)
1922 HeapParameters.MaximumAllocationSize = LoadConfig->MaximumAllocationSize;
1923
1924 if (VALID_CONFIG_FIELD(VirtualMemoryThreshold) && LoadConfig->VirtualMemoryThreshold)
1925 HeapParameters.VirtualMemoryThreshold = LoadConfig->VirtualMemoryThreshold;
1926
1927 if (VALID_CONFIG_FIELD(ProcessHeapFlags) && LoadConfig->ProcessHeapFlags)
1928 HeapFlags = LoadConfig->ProcessHeapFlags;
1929 }
1930#undef VALID_CONFIG_FIELD
1931
1932 /* Check for custom affinity mask */
1934 {
1935 /* Set it */
1939 sizeof(Peb->ImageProcessAffinityMask));
1940 }
1941
1942 /* Check if verbose debugging (ShowSnaps) was requested */
1944
1945 /* Start verbose debugging messages right now if they were requested */
1946 if (ShowSnaps)
1947 {
1948 DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1950 &CommandLine);
1951 }
1952
1953 /* If the CS timeout is longer than 1 hour, disable it */
1954 if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1956
1957 /* Initialize Critical Section Data */
1959
1960 /* Initialize VEH Call lists */
1962
1963 /* Set TLS/FLS Bitmap data */
1967
1968 /* Initialize FLS Bitmap */
1972 RtlSetBit(&FlsBitMap, 0);
1974
1975 /* Initialize TLS Bitmap */
1979 RtlSetBit(&TlsBitMap, 0);
1984
1985 /* Initialize the Hash Table */
1986 for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1987 {
1989 }
1990
1991 /* Initialize the Loader Lock */
1992 // FIXME: What's the point of initing it manually, if two lines lower
1993 // a call to RtlInitializeCriticalSection() is being made anyway?
1994 //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
1995 //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
1998
1999 /* Check if User Stack Trace Database support was requested */
2001 {
2002 DPRINT1("We don't support user stack trace databases yet\n");
2003 }
2004
2005 /* Setup Fast PEB Lock */
2008 //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
2009 //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
2010
2011 /* Setup Callout Lock and Notification list */
2012 //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
2014
2015 /* For old executables, use 16-byte aligned heap */
2016 if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
2017 (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
2018 {
2019 HeapFlags |= HEAP_CREATE_ALIGN_16;
2020 }
2021
2022 /* Setup the Heap */
2024 Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
2025 NULL,
2028 NULL,
2029 &HeapParameters);
2030
2031 if (!Peb->ProcessHeap)
2032 {
2033 DPRINT1("Failed to create process heap\n");
2034 return STATUS_NO_MEMORY;
2035 }
2036
2037 /* Allocate an Activation Context Stack */
2038 Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
2039 if (!NT_SUCCESS(Status)) return Status;
2040
2041 RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
2042 HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
2043 HeapParameters.Length = sizeof(HeapParameters);
2044 LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
2045 if (!LdrpHeap)
2046 {
2047 DPRINT1("Failed to create loader private heap\n");
2048 return STATUS_NO_MEMORY;
2049 }
2050
2051 /* Check for Debug Heap */
2052 if (OptionsKey)
2053 {
2054 /* Query the setting */
2056 L"DebugProcessHeapOnly",
2057 REG_DWORD,
2058 &DebugProcessHeapOnly,
2059 sizeof(ULONG),
2060 NULL);
2061
2062 if (NT_SUCCESS(Status))
2063 {
2064 /* Reset DPH if requested */
2065 if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
2066 {
2067 RtlpDphGlobalFlags &= ~DPH_FLAG_DLL_NOTIFY;
2069 }
2070 }
2071 }
2072
2073 /* Build the NTDLL Path */
2074 FullPath.Buffer = StringBuffer;
2075 FullPath.Length = 0;
2076 FullPath.MaximumLength = sizeof(StringBuffer);
2079 RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
2080
2081 /* Open the Known DLLs directory */
2082 RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
2084 &KnownDllString,
2086 NULL,
2087 NULL);
2091
2092 /* Check if it exists */
2093 if (NT_SUCCESS(Status))
2094 {
2095 /* Open the Known DLLs Path */
2096 RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2098 &KnownDllString,
2101 NULL);
2102 Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2105 if (NT_SUCCESS(Status))
2106 {
2107 /* Query the path */
2111 Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2112 NtClose(SymLinkHandle);
2113 if (!NT_SUCCESS(Status))
2114 {
2115 DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2116 return Status;
2117 }
2118 }
2119 }
2120
2121 /* Check if we failed */
2122 if (!NT_SUCCESS(Status))
2123 {
2124 /* Assume System32 */
2127 LdrpKnownDllPath.Length -= sizeof(WCHAR);
2128 }
2129
2130 /* If we have process parameters, get the default path and current path */
2131 if (ProcessParameters)
2132 {
2133 /* Check if we have a Dll Path */
2134 if (ProcessParameters->DllPath.Length)
2135 {
2136 /* Get the path */
2137 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2138 }
2139 else
2140 {
2141 /* We need a valid path */
2142 DPRINT1("No valid DllPath was given!\n");
2144 }
2145
2146 /* Set the current directory */
2147 CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2148
2149 /* Check if it's empty or invalid */
2150 if ((!CurrentDirectory.Buffer) ||
2151 (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2152 (!CurrentDirectory.Length))
2153 {
2154 /* Allocate space for the buffer */
2156 0,
2157 3 * sizeof(WCHAR) +
2158 sizeof(UNICODE_NULL));
2159 if (!CurrentDirectory.Buffer)
2160 {
2161 DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2162 // FIXME: And what?
2163 }
2164
2165 /* Copy the drive of the system root */
2167 SharedUserData->NtSystemRoot,
2168 3 * sizeof(WCHAR));
2169 CurrentDirectory.Buffer[3] = UNICODE_NULL;
2170 CurrentDirectory.Length = 3 * sizeof(WCHAR);
2171 CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2172
2173 FreeCurDir = TRUE;
2174 DPRINT("Using dynamically allocd curdir\n");
2175 }
2176 else
2177 {
2178 /* Use the local buffer */
2179 DPRINT("Using local system root\n");
2180 }
2181 }
2182
2183 /* Setup Loader Data */
2184 Peb->Ldr = &PebLdr;
2188 PebLdr.Length = sizeof(PEB_LDR_DATA);
2190
2191 /* Allocate a data entry for the Image */
2193
2194 /* Set it up */
2198 LdrpImageEntry->FullDllName = ImageFileName;
2199
2200 if (IsDotNetImage)
2202 else
2203 LdrpImageEntry->Flags = 0;
2204
2205 /* Check if the name is empty */
2206 if (!ImageFileName.Buffer[0])
2207 {
2208 /* Use the same Base name */
2210 }
2211 else
2212 {
2213 /* Find the last slash */
2214 Current = ImageFileName.Buffer;
2215 while (*Current)
2216 {
2217 if (*Current++ == '\\')
2218 {
2219 /* Set this path */
2220 NtDllName = Current;
2221 }
2222 }
2223
2224 /* Did we find anything? */
2225 if (!NtDllName)
2226 {
2227 /* Use the same Base name */
2229 }
2230 else
2231 {
2232 /* Setup the name */
2233 LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2236 (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2237 }
2238 }
2239
2240 /* Processing done, insert it */
2243
2244 /* Now add an entry for NTDLL */
2246 NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2247 NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2248 NtLdrEntry->LoadCount = -1;
2249 NtLdrEntry->EntryPointActivationContext = 0;
2250
2251 NtLdrEntry->FullDllName.Length = FullPath.Length;
2252 NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2253 NtLdrEntry->FullDllName.Buffer = StringBuffer;
2255
2256 NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2258 NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2259
2260 /* Processing done, insert it */
2261 LdrpNtDllDataTableEntry = NtLdrEntry;
2262 LdrpInsertMemoryTableEntry(NtLdrEntry);
2263
2264 /* Let the world know */
2265 if (ShowSnaps)
2266 {
2267 DPRINT1("LDR: NEW PROCESS\n");
2268 DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2269 DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2270 DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2271 }
2272
2273 /* Link the Init Order List */
2276
2277 /* Initialize Wine's active context implementation for the current process */
2278 RtlpInitializeActCtx(&OldShimData);
2279
2280 /* Set the current directory */
2282 if (!NT_SUCCESS(Status))
2283 {
2284 /* We failed, check if we should free it */
2285 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2286
2287 /* Set it to the NT Root */
2290 }
2291 else
2292 {
2293 /* We're done with it, free it */
2294 if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2295 }
2296
2297 /* Check if we should look for a .local file */
2298 if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2299 {
2300 LdrpInitializeDotLocalSupport(ProcessParameters);
2301 }
2302
2303 /* Check if the Application Verifier was enabled */
2305 {
2307 if (!NT_SUCCESS(Status))
2308 {
2309 DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2310 return Status;
2311 }
2312
2313 }
2314
2315 if (IsDotNetImage)
2316 {
2317 /* FIXME */
2318 DPRINT1("We don't support .NET applications yet\n");
2319 }
2320
2323 {
2324 PVOID Kernel32BaseAddress;
2325 PVOID FunctionAddress;
2326
2327 Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2328
2329 if (!NT_SUCCESS(Status))
2330 {
2331 if (ShowSnaps)
2332 DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2333 return Status;
2334 }
2335
2336 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2337 &BaseProcessInitPostImportName,
2338 0,
2339 &FunctionAddress);
2340
2341 if (!NT_SUCCESS(Status))
2342 {
2343 if (ShowSnaps)
2344 DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", Status);
2345 return Status;
2346 }
2347 Kernel32ProcessInitPostImportFunction = FunctionAddress;
2348
2349 Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2350 &BaseQueryModuleDataName,
2351 0,
2352 &FunctionAddress);
2353
2354 if (!NT_SUCCESS(Status))
2355 {
2356 if (ShowSnaps)
2357 DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", Status);
2358 return Status;
2359 }
2360 Kernel32BaseQueryModuleData = FunctionAddress;
2361 }
2362
2363 /* Walk the IAT and load all the DLLs */
2365
2366 /* Check if relocation is needed */
2368 {
2369 DPRINT1("LDR: Performing EXE relocation\n");
2370
2371 /* Change the protection to prepare for relocation */
2372 ViewBase = Peb->ImageBaseAddress;
2373 Status = LdrpSetProtection(ViewBase, FALSE);
2374 if (!NT_SUCCESS(Status)) return Status;
2375
2376 /* Do the relocation */
2378 0LL,
2379 NULL,
2383 if (!NT_SUCCESS(Status))
2384 {
2385 DPRINT1("LdrRelocateImageWithBias() failed\n");
2386 return Status;
2387 }
2388
2389 /* Check if a start context was provided */
2390 if (Context)
2391 {
2392 DPRINT1("WARNING: Relocated EXE Context");
2393 UNIMPLEMENTED; // We should support this
2395 }
2396
2397 /* Restore the protection */
2398 Status = LdrpSetProtection(ViewBase, TRUE);
2399 if (!NT_SUCCESS(Status)) return Status;
2400 }
2401
2402 /* Lock the DLLs */
2403 ListHead = &Peb->Ldr->InLoadOrderModuleList;
2404 NextEntry = ListHead->Flink;
2405 while (ListHead != NextEntry)
2406 {
2407 NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2408 NtLdrEntry->LoadCount = -1;
2409 NextEntry = NextEntry->Flink;
2410 }
2411
2412 /* Phase 0 is done */
2414
2415 /* Check whether all static imports were properly loaded and return here */
2416 if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2417
2418 /* Following two calls are for Vista+ support, required for winesync */
2419 /* Initialize the keyed event for condition variables */
2422
2423 /* Initialize TLS */
2425 if (!NT_SUCCESS(Status))
2426 {
2427 DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2428 Status);
2429 return Status;
2430 }
2431
2432 /* FIXME Mark the DLL Ranges for Stack Traces later */
2433
2434 /* Notify the debugger now */
2435 if (Peb->BeingDebugged)
2436 {
2437 /* Break */
2438 DbgBreakPoint();
2439
2440 /* Update show snaps again */
2442 }
2443
2444 /* Validate the Image for MP Usage */
2446
2447 /* Check NX options and set them */
2448 if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSON)
2449 {
2450 ExecuteOptions = MEM_EXECUTE_OPTION_DISABLE |
2453 }
2454 else if (SharedUserData->NXSupportPolicy == NX_SUPPORT_POLICY_ALWAYSOFF)
2455 {
2457 }
2460 &ExecuteOptions,
2461 sizeof(ExecuteOptions));
2462 if (!NT_SUCCESS(Status))
2463 {
2464 DPRINT1("LDR: Could not set process execute flags 0x%x; status %x\n",
2465 ExecuteOptions, Status);
2466 }
2467
2468 // FIXME: Should be done by Application Compatibility features,
2469 // by reading the registry, etc...
2470 // For now, this is the old code from ntdll!RtlGetVersion().
2471 RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2472 if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2473 {
2474 WCHAR szCSDVersion[128];
2475 LONG i;
2476 USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2477 i = _snwprintf(szCSDVersion, Length,
2478 L"Service Pack %d",
2479 ((Peb->OSCSDVersion >> 8) & 0xFF));
2480 if (i < 0)
2481 {
2482 /* Null-terminate if it was overflowed */
2483 szCSDVersion[Length] = UNICODE_NULL;
2484 }
2485
2486 Length *= sizeof(WCHAR);
2487 Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2488 0,
2489 Length + sizeof(UNICODE_NULL));
2490 if (Peb->CSDVersion.Buffer)
2491 {
2494
2496 szCSDVersion,
2499 }
2500 }
2501
2502 /* Check if we had Shim Data */
2503 if (OldShimData)
2504 {
2505 /* Load the Shim Engine */
2507 LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2508 }
2509 else
2510 {
2511 /* Check for Application Compatibility Goo */
2512 //LdrQueryApplicationCompatibilityGoo(hKey);
2513 DPRINT("Querying app compat hacks is missing!\n");
2514 }
2515
2516 /*
2517 * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2518 * incompatible images.
2519 */
2520
2521 /* Now call the Init Routines */
2523 if (!NT_SUCCESS(Status))
2524 {
2525 DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2526 Status);
2527 return Status;
2528 }
2529
2530 /* Notify Shim Engine */
2531 if (g_ShimsEnabled)
2532 {
2535 SE_InstallAfterInit(&ImagePathName, OldShimData);
2536 }
2537
2538 /* Check if we have a user-defined Post Process Routine */
2540 {
2541 /* Call it */
2543 }
2544
2545 /* Close the key if we have one opened */
2546 if (OptionsKey) NtClose(OptionsKey);
2547
2548 /* Return status */
2549 return Status;
2550}
2551
2552VOID
2553NTAPI
2555{
2557 PPEB Peb = NtCurrentPeb();
2558
2559 /* Print a debug message */
2560 DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2562
2563 /* Raise a hard error */
2565 {
2567 }
2568}
2569
2570VOID
2571NTAPI
2575{
2577 PTEB Teb = NtCurrentTeb();
2578 NTSTATUS Status, LoaderStatus = STATUS_SUCCESS;
2579 MEMORY_BASIC_INFORMATION MemoryBasicInfo;
2580 PPEB Peb = NtCurrentPeb();
2581
2582 DPRINT("LdrpInit() %p/%p\n",
2583 NtCurrentTeb()->RealClientId.UniqueProcess,
2584 NtCurrentTeb()->RealClientId.UniqueThread);
2585
2586#ifdef _WIN64
2587 /* Set the SList header usage */
2589#endif /* _WIN64 */
2590
2591 /* Check if we have a deallocation stack */
2592 if (!Teb->DeallocationStack)
2593 {
2594 /* We don't, set one */
2596 Teb->NtTib.StackLimit,
2598 &MemoryBasicInfo,
2600 NULL);
2601 if (!NT_SUCCESS(Status))
2602 {
2603 /* Fail */
2606 return;
2607 }
2608
2609 /* Set the stack */
2610 Teb->DeallocationStack = MemoryBasicInfo.AllocationBase;
2611 }
2612
2613 /* Now check if the process is already being initialized */
2615 1,
2616 0) == 1)
2617 {
2618 /* Set the timeout to 30 milliseconds */
2619 Timeout.QuadPart = Int32x32To64(30, -10000);
2620
2621 /* Make sure the status hasn't changed */
2622 while (LdrpProcessInitialized == 1)
2623 {
2624 /* Do the wait */
2626 }
2627 }
2628
2629 /* Check if we have already setup LDR data */
2630 if (!Peb->Ldr)
2631 {
2632 /* Setup the Loader Lock */
2634
2635 /* Let other code know we're initializing */
2637
2638 /* Protect with SEH */
2639 _SEH2_TRY
2640 {
2641 /* Initialize the Process */
2642 LoaderStatus = LdrpInitializeProcess(Context,
2644
2645 /* Check for success and if MinimumStackCommit was requested */
2646 if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit)
2647 {
2648 /* Enforce the limit */
2649 //LdrpTouchThreadStack(Peb->MinimumStackCommit);
2651 }
2652 }
2654 {
2655 /* Fail with the SEH error */
2656 LoaderStatus = _SEH2_GetExceptionCode();
2657 }
2658 _SEH2_END;
2659
2660 /* We're not initializing anymore */
2662
2663 /* Check if init worked */
2664 if (NT_SUCCESS(LoaderStatus))
2665 {
2666 /* Set the process as Initialized */
2668 }
2669 }
2670 else
2671 {
2672 /* Loader data is there... is this a fork() ? */
2674 {
2675 /* Handle the fork() */
2676 //LoaderStatus = LdrpForkProcess();
2677 LoaderStatus = STATUS_NOT_IMPLEMENTED;
2679 }
2680 else
2681 {
2682 /* This is a new thread initializing */
2684 }
2685 }
2686
2687 /* All done, test alert the thread */
2688 NtTestAlert();
2689
2690 /* Return */
2691 if (!NT_SUCCESS(LoaderStatus))
2692 {
2693 /* Fail */
2694 LdrpInitFailure(LoaderStatus);
2695 RtlRaiseStatus(LoaderStatus);
2696 }
2697}
2698
2699/* 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: 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:15
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 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
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 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 OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:84
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:5515
NTSYSAPI void WINAPI LdrShutdownProcess(void)
Definition: ldrinit.c:951
@ ProcessAffinityMask
Definition: winternl.h:877
@ ProcessExecuteFlags
Definition: winternl.h:889
NTSYSAPI void WINAPI LdrShutdownThread(void)
Definition: ldrinit.c:1090
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5572
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#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 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
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:1706
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:2572
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:65
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:350
ULONG RtlpShutdownProcessFlags
Definition: ldrinit.c:93
VOID NTAPI LdrpFreeTls(VOID)
Definition: ldrinit.c:1392
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:1428
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
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:389
RTL_BITMAP TlsBitMap
Definition: ldrinit.c:49
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrinit.c:453
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
#define DEFAULT_SECURITY_COOKIE
Definition: ldrinit.c:102
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:185
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:112
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: ldrinit.c:416
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:83
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1547
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:1767
RTL_BITMAP TlsExpansionBitMap
Definition: ldrinit.c:50
BOOLEAN LdrpImageHasTls
Definition: ldrinit.c:52
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:649
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:1556
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:62
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
VOID NTAPI LdrpInitFailure(NTSTATUS Status)
Definition: ldrinit.c:2554
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:1590
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1266
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:409
#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:506
UNICODE_STRING NtDllString
Definition: ldrinit.c:26
NTSTATUS NTAPI RtlpInitializeActCtx(PVOID *pOldShimData)
NTSTATUS NTAPI LdrpAllocateTls(VOID)
Definition: ldrinit.c:1329
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
#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: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
#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: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:2752
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 RtlpInitializeThreadPooling(VOID)
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1556
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:1523
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2644
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: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:4409
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1154
NTSTATUS NTAPI NtTestAlert(VOID)
Definition: state.c:465
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:558
#define STATUS_APP_INIT_FAILURE
Definition: ntstatus.h:561
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#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:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define REG_DWORD
Definition: sdbapi.c:596
#define YieldProcessor
Definition: ke.h:48
#define SharedUserData
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:73
static void Exit(void)
Definition: sock.c:1330
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
Definition: ncftp.h:89
HANDLE UniqueProcess
Definition: compat.h:825
UNICODE_STRING DosPath
Definition: rtltypes.h: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:166
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
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: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:1469
#define WINAPI
Definition: msvc.h:6
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1099
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
#define NX_SUPPORT_POLICY_ALWAYSOFF
Definition: ketypes.h:1260
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
#define NX_SUPPORT_POLICY_ALWAYSON
Definition: ketypes.h:1261
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689
#define PF_COMPARE_EXCHANGE128
Definition: ketypes.h:138
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184