ReactOS  0.4.14-dev-614-gbfd8a84
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 
24 UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options");
29 
36 
38 
42 extern PTEB LdrpTopLevelDllBeingLoadedTeb; // defined in rtlsupp.c!
45 
46 static NTSTATUS (WINAPI *Kernel32ProcessInitPostImportFunction)(VOID);
47 static 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 
92 ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c
94 
96 void 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  */
110 NTSTATUS
111 NTAPI
113  IN BOOLEAN Wow64,
114  OUT PHANDLE NewKeyHandle)
115 {
116  PHANDLE RootKeyLocation;
117  HANDLE RootKey;
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 */
148  NtClose(RootKey);
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  */
182 NTSTATUS
183 NTAPI
186  IN ULONG Type,
187  OUT PVOID Buffer,
190 {
191  ULONG KeyInfo[256];
192  UNICODE_STRING ValueNameString, IntegerString;
193  ULONG KeyInfoSize, ResultSize;
194  PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)&KeyInfo;
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  */
346 NTSTATUS
347 NTAPI
350  IN ULONG Type,
351  OUT PVOID Buffer,
354  IN BOOLEAN Wow64)
355 {
358 
359  /* Open a handle to the key */
360  Status = LdrOpenImageFileOptionsKey(SubKey, Wow64, &KeyHandle);
361 
362  /* Check for success */
363  if (NT_SUCCESS(Status))
364  {
365  /* Query the data */
367  ValueName,
368  Type,
369  Buffer,
370  BufferSize,
372 
373  /* Close the key */
375  }
376 
377  /* Return to caller */
378  return Status;
379 }
380 
381 /*
382  * @implemented
383  */
384 NTSTATUS
385 NTAPI
388  IN ULONG Type,
389  OUT PVOID Buffer,
392 {
393  /* Call the newer function */
395  ValueName,
396  Type,
397  Buffer,
398  BufferSize,
400  FALSE);
401 }
402 
403 VOID
404 NTAPI
406 {
407  // Ignored atm
408 }
409 
410 PVOID
411 NTAPI
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 */
437  if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
438  (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
439  {
440  Cookie = NULL;
441  }
442 
443  /* Return validated security cookie */
444  return Cookie;
445 }
446 
447 PVOID
448 NTAPI
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 */
461  if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
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  {
475  YieldProcessor();
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 
500 VOID
501 NTAPI
503 {
504  PPEB Peb = NtCurrentPeb();
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 */
528  LdrpAllocateTls();
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 */
559  LdrEntry->EntryPointActivationContext);
560 
561  _SEH2_TRY
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 
617  _SEH2_TRY
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 
635 NTSTATUS
636 NTAPI
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;
647  PPEB Peb = NtCurrentPeb();
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 */
662  if ((Count = LdrpClearLoadInProgress()))
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 */
762  OldTldTeb = LdrpTopLevelDllBeingLoadedTeb;
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 */
808  DbgBreakPoint();
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 */
825  LdrEntry->EntryPointActivationContext);
826 
827  _SEH2_TRY
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 */
862  LdrEntry->Flags |= LDRP_PROCESS_ATTACH_CALLED;
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 */
892  if (LdrpImageHasTls && Context)
893  {
894  /* Set up the Act Ctx */
895  ActCtx.Size = sizeof(ActCtx);
896  ActCtx.Format = 1;
898 
899  /* Activate the ActCtx */
902 
903  _SEH2_TRY
904  {
905  /* Do TLS callbacks */
907  }
909  {
910  /* Do nothing */
911  }
912  _SEH2_END;
913 
914  /* Deactivate the ActCtx */
916  }
917 
918 Quickie:
919  /* Restore old TEB */
920  LdrpTopLevelDllBeingLoadedTeb = OldTldTeb;
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  */
937 NTSTATUS
938 NTAPI
940 {
941  PPEB Peb = NtCurrentPeb();
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  {
955  SE_ProcessDying();
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  */
1076 NTSTATUS
1077 NTAPI
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 */
1101  ListHead = &Peb->Ldr->InInitializationOrderModuleList;
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 
1252 NTSTATUS
1253 NTAPI
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 
1315 NTSTATUS
1316 NTAPI
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,
1362  TlsData->TlsDirectory.Characteristics,
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 
1378 VOID
1379 NTAPI
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 
1414 NTSTATUS
1415 NTAPI
1417 {
1418  NTSTATUS Status;
1419  HANDLE KeyHandle;
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 */
1464  UNIMPLEMENTED;
1465  }
1466 
1467  /* Get various option values */
1469  L"DisableHeapLookaside",
1470  REG_DWORD,
1472  sizeof(RtlpDisableHeapLookaside),
1473  NULL);
1474 
1476  L"ShutdownFlags",
1477  REG_DWORD,
1479  sizeof(RtlpShutdownProcessFlags),
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 
1533 VOID
1534 NTAPI
1536 {
1537  UNIMPLEMENTED;
1538 }
1539 
1540 VOID
1541 NTAPI
1542 LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData)
1543 {
1544  static const struct
1545  {
1546  const GUID* Guid;
1547  const DWORD Version;
1548  } KnownCompatGuids[] = {
1549  { &COMPAT_GUID_WIN10, _WIN32_WINNT_WIN10 },
1550  { &COMPAT_GUID_WIN81, _WIN32_WINNT_WINBLUE },
1551  { &COMPAT_GUID_WIN8, _WIN32_WINNT_WIN8 },
1552  { &COMPAT_GUID_WIN7, _WIN32_WINNT_WIN7 },
1553  { &COMPAT_GUID_VISTA, _WIN32_WINNT_VISTA },
1554  };
1555 
1556  ULONG Buffer[(sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 10 + sizeof(ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION)) / sizeof(ULONG)];
1557  ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION* ContextCompatInfo;
1558  SIZE_T SizeRequired;
1559  NTSTATUS Status;
1560  DWORD n, cur;
1561  ReactOS_ShimData* pShimData = *pOldShimData;
1562 
1563  if (pShimData)
1564  {
1565  if (pShimData->dwMagic != REACTOS_SHIMDATA_MAGIC ||
1566  pShimData->dwSize != sizeof(ReactOS_ShimData))
1567  {
1568  DPRINT1("LdrpInitializeProcessCompat: Corrupt pShimData (0x%x, %u)\n", pShimData->dwMagic, pShimData->dwSize);
1569  return;
1570  }
1571  if (pShimData->dwRosProcessCompatVersion)
1572  {
1574  {
1575  DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion set to ignore manifest\n");
1576  }
1577  else
1578  {
1579  DPRINT1("LdrpInitializeProcessCompat: ProcessCompatVersion already set to 0x%x\n", pShimData->dwRosProcessCompatVersion);
1580  }
1581  return;
1582  }
1583  }
1584 
1585  SizeRequired = sizeof(Buffer);
1587  pProcessActctx,
1588  NULL,
1589  CompatibilityInformationInActivationContext,
1590  Buffer,
1591  sizeof(Buffer),
1592  &SizeRequired);
1593 
1594  if (!NT_SUCCESS(Status))
1595  {
1596  DPRINT1("LdrpInitializeProcessCompat: Unable to query process actctx with status %x\n", Status);
1597  return;
1598  }
1599 
1600  ContextCompatInfo = (ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*)Buffer;
1601  /* No Compatibility elements present, bail out */
1602  if (ContextCompatInfo->ElementCount == 0)
1603  return;
1604 
1605  /* Search for known GUID's, starting from newest to oldest. */
1606  for (cur = 0; cur < RTL_NUMBER_OF(KnownCompatGuids); ++cur)
1607  {
1608  for (n = 0; n < ContextCompatInfo->ElementCount; ++n)
1609  {
1610  if (ContextCompatInfo->Elements[n].Type == ACTCX_COMPATIBILITY_ELEMENT_TYPE_OS &&
1611  RtlCompareMemory(&ContextCompatInfo->Elements[n].Id, KnownCompatGuids[cur].Guid, sizeof(GUID)) == sizeof(GUID))
1612  {
1613  /* If this process did not need shim data before, allocate and store it */
1614  if (pShimData == NULL)
1615  {
1616  PPEB Peb = NtCurrentPeb();
1617 
1618  ASSERT(Peb->pShimData == NULL);
1619  pShimData = RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*pShimData));
1620 
1621  if (!pShimData)
1622  {
1623  DPRINT1("LdrpInitializeProcessCompat: Unable to allocated %u bytes\n", sizeof(*pShimData));
1624  return;
1625  }
1626 
1627  pShimData->dwSize = sizeof(*pShimData);
1628  pShimData->dwMagic = REACTOS_SHIMDATA_MAGIC;
1629 
1630  Peb->pShimData = pShimData;
1631  *pOldShimData = pShimData;
1632  }
1633 
1634  /* Store the highest found version, and bail out. */
1635  pShimData->dwRosProcessCompatVersion = KnownCompatGuids[cur].Version;
1636  DPRINT1("LdrpInitializeProcessCompat: Found guid for winver 0x%x\n", KnownCompatGuids[cur].Version);
1637  return;
1638  }
1639  }
1640  }
1641 }
1642 
1643 VOID
1644 NTAPI
1646 {
1647  UNICODE_STRING ImagePathName = ProcessParameters->ImagePathName;
1648  WCHAR LocalBuffer[MAX_PATH];
1649  UNICODE_STRING DotLocal;
1650  NTSTATUS Status;
1652 
1653  RequiredSize = ImagePathName.Length + LdrpDotLocal.Length + sizeof(UNICODE_NULL);
1654  if (RequiredSize <= sizeof(LocalBuffer))
1655  {
1656  RtlInitEmptyUnicodeString(&DotLocal, LocalBuffer, sizeof(LocalBuffer));
1657  }
1659  {
1660  DotLocal.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RequiredSize);
1661  DotLocal.Length = 0;
1662  DotLocal.MaximumLength = RequiredSize;
1663  if (!DotLocal.Buffer)
1664  DPRINT1("LDR: Failed to allocate memory for .local check\n");
1665  }
1666  else
1667  {
1668  DotLocal.Buffer = NULL;
1669  DotLocal.Length = 0;
1670  DotLocal.MaximumLength = 0;
1671  DPRINT1("LDR: String too big for .local check\n");
1672  }
1673 
1674  if (DotLocal.Buffer)
1675  {
1676  Status = RtlAppendUnicodeStringToString(&DotLocal, &ImagePathName);
1678  if (NT_SUCCESS(Status))
1679  {
1682  }
1683 
1684  if (NT_SUCCESS(Status))
1685  {
1686  if (RtlDoesFileExists_UStr(&DotLocal))
1687  {
1689  }
1690  }
1691  else
1692  {
1693  DPRINT1("LDR: Failed to append: 0x%lx\n", Status);
1694  }
1695 
1696  if (DotLocal.Buffer != LocalBuffer)
1697  {
1698  RtlFreeHeap(RtlGetProcessHeap(), 0, DotLocal.Buffer);
1699  }
1700  }
1701 }
1702 
1703 
1704 NTSTATUS
1705 NTAPI
1708 {
1709  RTL_HEAP_PARAMETERS HeapParameters;
1710  ULONG ComSectionSize;
1711  ANSI_STRING BaseProcessInitPostImportName = RTL_CONSTANT_STRING("BaseProcessInitPostImport");
1712  ANSI_STRING BaseQueryModuleDataName = RTL_CONSTANT_STRING("BaseQueryModuleData");
1713  PVOID OldShimData;
1715  //UNICODE_STRING LocalFileName, FullImageName;
1716  HANDLE SymLinkHandle;
1717  //ULONG DebugHeapOnly;
1718  UNICODE_STRING CommandLine, NtSystemRoot, ImagePathName, FullPath, ImageFileName, KnownDllString;
1719  PPEB Peb = NtCurrentPeb();
1720  BOOLEAN IsDotNetImage = FALSE;
1721  BOOLEAN FreeCurDir = FALSE;
1722  //HANDLE CompatKey;
1723  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
1724  //LPWSTR ImagePathBuffer;
1725  ULONG ConfigSize;
1727  HANDLE OptionsKey;
1728  ULONG HeapFlags;
1729  PIMAGE_NT_HEADERS NtHeader;
1730  LPWSTR NtDllName = NULL;
1731  NTSTATUS Status, ImportStatus;
1732  NLSTABLEINFO NlsTable;
1734  PTEB Teb = NtCurrentTeb();
1735  PLIST_ENTRY ListHead;
1736  PLIST_ENTRY NextEntry;
1737  ULONG i;
1738  PWSTR ImagePath;
1739  ULONG DebugProcessHeapOnly = 0;
1740  PLDR_DATA_TABLE_ENTRY NtLdrEntry;
1741  PWCHAR Current;
1742  ULONG ExecuteOptions = 0;
1743  PVOID ViewBase;
1744 
1745  /* Set a NULL SEH Filter */
1747 
1748  /* Get the image path */
1749  ImagePath = Peb->ProcessParameters->ImagePathName.Buffer;
1750 
1751  /* Check if it's not normalized */
1753  {
1754  /* Normalize it*/
1755  ImagePath = (PWSTR)((ULONG_PTR)ImagePath + (ULONG_PTR)Peb->ProcessParameters);
1756  }
1757 
1758  /* Create a unicode string for the Image Path */
1759  ImagePathName.Length = Peb->ProcessParameters->ImagePathName.Length;
1760  ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);
1761  ImagePathName.Buffer = ImagePath;
1762 
1763  /* Get the NT Headers */
1764  NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress);
1765 
1766  /* Get the execution options */
1767  Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
1768 
1769  /* Check if this is a .NET executable */
1771  TRUE,
1773  &ComSectionSize))
1774  {
1775  /* Remember this for later */
1776  IsDotNetImage = TRUE;
1777  }
1778 
1779  /* Save the NTDLL Base address */
1781 
1782  /* If this is a Native Image */
1784  {
1785  /* Then do DLL Validation */
1787  }
1788 
1789  /* Save the old Shim Data */
1790  OldShimData = Peb->pShimData;
1791 
1792  /* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
1793  //Peb->pShimData = NULL;
1794 
1795  /* Save the number of processors and CS Timeout */
1798 
1799  /* Normalize the parameters */
1800  ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
1801  if (ProcessParameters)
1802  {
1803  /* Save the Image and Command Line Names */
1804  ImageFileName = ProcessParameters->ImagePathName;
1805  CommandLine = ProcessParameters->CommandLine;
1806  }
1807  else
1808  {
1809  /* It failed, initialize empty strings */
1810  RtlInitUnicodeString(&ImageFileName, NULL);
1811  RtlInitUnicodeString(&CommandLine, NULL);
1812  }
1813 
1814  /* Initialize NLS data */
1818  &NlsTable);
1819 
1820  /* Reset NLS Translations */
1821  RtlResetRtlTranslations(&NlsTable);
1822 
1823  /* Get the Image Config Directory */
1825  TRUE,
1827  &ConfigSize);
1828 
1829  /* Setup the Heap Parameters */
1830  RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1831  HeapFlags = HEAP_GROWABLE;
1832  HeapParameters.Length = sizeof(HeapParameters);
1833 
1834  /* Check if we have Configuration Data */
1835  if ((LoadConfig) && (ConfigSize == sizeof(IMAGE_LOAD_CONFIG_DIRECTORY)))
1836  {
1837  /* FIXME: Custom heap settings and misc. */
1838  DPRINT1("We don't support LOAD_CONFIG data yet\n");
1839  }
1840 
1841  /* Check for custom affinity mask */
1843  {
1844  /* Set it */
1848  sizeof(Peb->ImageProcessAffinityMask));
1849  }
1850 
1851  /* Check if verbose debugging (ShowSnaps) was requested */
1853 
1854  /* Start verbose debugging messages right now if they were requested */
1855  if (ShowSnaps)
1856  {
1857  DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
1858  Teb->ClientId.UniqueProcess,
1859  &CommandLine);
1860  }
1861 
1862  /* If the timeout is too long */
1863  if (RtlpTimeout.QuadPart < Int32x32To64(3600, -10000000))
1864  {
1865  /* Then disable CS Timeout */
1867  }
1868 
1869  /* Initialize Critical Section Data */
1871 
1872  /* Initialize VEH Call lists */
1874 
1875  /* Set TLS/FLS Bitmap data */
1876  Peb->FlsBitmap = &FlsBitMap;
1877  Peb->TlsBitmap = &TlsBitMap;
1879 
1880  /* Initialize FLS Bitmap */
1882  Peb->FlsBitmapBits,
1884  RtlSetBit(&FlsBitMap, 0);
1886 
1887  /* Initialize TLS Bitmap */
1889  Peb->TlsBitmapBits,
1891  RtlSetBit(&TlsBitMap, 0);
1896 
1897  /* Initialize the Hash Table */
1898  for (i = 0; i < LDR_HASH_TABLE_ENTRIES; i++)
1899  {
1901  }
1902 
1903  /* Initialize the Loader Lock */
1904  // FIXME: What's the point of initing it manually, if two lines lower
1905  // a call to RtlInitializeCriticalSection() is being made anyway?
1906  //InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
1907  //LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
1910 
1911  /* Check if User Stack Trace Database support was requested */
1913  {
1914  DPRINT1("We don't support user stack trace databases yet\n");
1915  }
1916 
1917  /* Setup Fast PEB Lock */
1920  //Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
1921  //Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
1922 
1923  /* Setup Callout Lock and Notification list */
1924  //RtlInitializeCriticalSection(&RtlpCalloutEntryLock);
1926 
1927  /* For old executables, use 16-byte aligned heap */
1928  if ((NtHeader->OptionalHeader.MajorSubsystemVersion <= 3) &&
1929  (NtHeader->OptionalHeader.MinorSubsystemVersion < 51))
1930  {
1931  HeapFlags |= HEAP_CREATE_ALIGN_16;
1932  }
1933 
1934  /* Setup the Heap */
1936  Peb->ProcessHeap = RtlCreateHeap(HeapFlags,
1937  NULL,
1939  NtHeader->OptionalHeader.SizeOfHeapCommit,
1940  NULL,
1941  &HeapParameters);
1942 
1943  if (!Peb->ProcessHeap)
1944  {
1945  DPRINT1("Failed to create process heap\n");
1946  return STATUS_NO_MEMORY;
1947  }
1948 
1949  /* Allocate an Activation Context Stack */
1951  if (!NT_SUCCESS(Status)) return Status;
1952 
1953  RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
1954  HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
1955  HeapParameters.Length = sizeof(HeapParameters);
1956  LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
1957  if (!LdrpHeap)
1958  {
1959  DPRINT1("Failed to create loader private heap\n");
1960  return STATUS_NO_MEMORY;
1961  }
1962 
1963  /* Check for Debug Heap */
1964  if (OptionsKey)
1965  {
1966  /* Query the setting */
1967  Status = LdrQueryImageFileKeyOption(OptionsKey,
1968  L"DebugProcessHeapOnly",
1969  REG_DWORD,
1970  &DebugProcessHeapOnly,
1971  sizeof(ULONG),
1972  NULL);
1973 
1974  if (NT_SUCCESS(Status))
1975  {
1976  /* Reset DPH if requested */
1977  if (RtlpPageHeapEnabled && DebugProcessHeapOnly)
1978  {
1981  }
1982  }
1983  }
1984 
1985  /* Build the NTDLL Path */
1986  FullPath.Buffer = StringBuffer;
1987  FullPath.Length = 0;
1988  FullPath.MaximumLength = sizeof(StringBuffer);
1991  RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
1992 
1993  /* Open the Known DLLs directory */
1994  RtlInitUnicodeString(&KnownDllString, L"\\KnownDlls");
1996  &KnownDllString,
1998  NULL,
1999  NULL);
2002  &ObjectAttributes);
2003 
2004  /* Check if it exists */
2005  if (NT_SUCCESS(Status))
2006  {
2007  /* Open the Known DLLs Path */
2008  RtlInitUnicodeString(&KnownDllString, L"KnownDllPath");
2010  &KnownDllString,
2013  NULL);
2014  Status = NtOpenSymbolicLinkObject(&SymLinkHandle,
2016  &ObjectAttributes);
2017  if (NT_SUCCESS(Status))
2018  {
2019  /* Query the path */
2023  Status = ZwQuerySymbolicLinkObject(SymLinkHandle, &LdrpKnownDllPath, NULL);
2024  NtClose(SymLinkHandle);
2025  if (!NT_SUCCESS(Status))
2026  {
2027  DPRINT1("LDR: %s - failed call to ZwQuerySymbolicLinkObject with status %x\n", "", Status);
2028  return Status;
2029  }
2030  }
2031  }
2032 
2033  /* Check if we failed */
2034  if (!NT_SUCCESS(Status))
2035  {
2036  /* Assume System32 */
2039  LdrpKnownDllPath.Length -= sizeof(WCHAR);
2040  }
2041 
2042  /* If we have process parameters, get the default path and current path */
2043  if (ProcessParameters)
2044  {
2045  /* Check if we have a Dll Path */
2046  if (ProcessParameters->DllPath.Length)
2047  {
2048  /* Get the path */
2049  LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
2050  }
2051  else
2052  {
2053  /* We need a valid path */
2054  DPRINT1("No valid DllPath was given!\n");
2056  }
2057 
2058  /* Set the current directory */
2059  CurrentDirectory = ProcessParameters->CurrentDirectory.DosPath;
2060 
2061  /* Check if it's empty or invalid */
2062  if ((!CurrentDirectory.Buffer) ||
2063  (CurrentDirectory.Buffer[0] == UNICODE_NULL) ||
2064  (!CurrentDirectory.Length))
2065  {
2066  /* Allocate space for the buffer */
2068  0,
2069  3 * sizeof(WCHAR) +
2070  sizeof(UNICODE_NULL));
2071  if (!CurrentDirectory.Buffer)
2072  {
2073  DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
2074  // FIXME: And what?
2075  }
2076 
2077  /* Copy the drive of the system root */
2079  SharedUserData->NtSystemRoot,
2080  3 * sizeof(WCHAR));
2081  CurrentDirectory.Buffer[3] = UNICODE_NULL;
2082  CurrentDirectory.Length = 3 * sizeof(WCHAR);
2083  CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
2084 
2085  FreeCurDir = TRUE;
2086  DPRINT("Using dynamically allocd curdir\n");
2087  }
2088  else
2089  {
2090  /* Use the local buffer */
2091  DPRINT("Using local system root\n");
2092  }
2093  }
2094 
2095  /* Setup Loader Data */
2096  Peb->Ldr = &PebLdr;
2100  PebLdr.Length = sizeof(PEB_LDR_DATA);
2102 
2103  /* Allocate a data entry for the Image */
2105 
2106  /* Set it up */
2108  LdrpImageEntry->LoadCount = -1;
2110  LdrpImageEntry->FullDllName = ImageFileName;
2111 
2112  if (IsDotNetImage)
2114  else
2115  LdrpImageEntry->Flags = 0;
2116 
2117  /* Check if the name is empty */
2118  if (!ImageFileName.Buffer[0])
2119  {
2120  /* Use the same Base name */
2122  }
2123  else
2124  {
2125  /* Find the last slash */
2126  Current = ImageFileName.Buffer;
2127  while (*Current)
2128  {
2129  if (*Current++ == '\\')
2130  {
2131  /* Set this path */
2132  NtDllName = Current;
2133  }
2134  }
2135 
2136  /* Did we find anything? */
2137  if (!NtDllName)
2138  {
2139  /* Use the same Base name */
2141  }
2142  else
2143  {
2144  /* Setup the name */
2145  LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
2147  LdrpImageEntry->BaseDllName.Buffer = (PWSTR)((ULONG_PTR)ImageFileName.Buffer +
2148  (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
2149  }
2150  }
2151 
2152  /* Processing done, insert it */
2155 
2156  /* Now add an entry for NTDLL */
2158  NtLdrEntry->Flags = LDRP_IMAGE_DLL;
2159  NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
2160  NtLdrEntry->LoadCount = -1;
2161  NtLdrEntry->EntryPointActivationContext = 0;
2162 
2163  NtLdrEntry->FullDllName.Length = FullPath.Length;
2164  NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
2165  NtLdrEntry->FullDllName.Buffer = StringBuffer;
2167 
2168  NtLdrEntry->BaseDllName.Length = NtDllString.Length;
2170  NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
2171 
2172  /* Processing done, insert it */
2173  LdrpNtDllDataTableEntry = NtLdrEntry;
2174  LdrpInsertMemoryTableEntry(NtLdrEntry);
2175 
2176  /* Let the world know */
2177  if (ShowSnaps)
2178  {
2179  DPRINT1("LDR: NEW PROCESS\n");
2180  DPRINT1(" Image Path: %wZ (%wZ)\n", &LdrpImageEntry->FullDllName, &LdrpImageEntry->BaseDllName);
2181  DPRINT1(" Current Directory: %wZ\n", &CurrentDirectory);
2182  DPRINT1(" Search Path: %wZ\n", &LdrpDefaultPath);
2183  }
2184 
2185  /* Link the Init Order List */
2188 
2189  /* Initialize Wine's active context implementation for the current process */
2190  actctx_init(&OldShimData);
2191 
2192  /* Set the current directory */
2194  if (!NT_SUCCESS(Status))
2195  {
2196  /* We failed, check if we should free it */
2197  if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2198 
2199  /* Set it to the NT Root */
2202  }
2203  else
2204  {
2205  /* We're done with it, free it */
2206  if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory);
2207  }
2208 
2209  /* Check if we should look for a .local file */
2210  if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH))
2211  {
2212  LdrpInitializeDotLocalSupport(ProcessParameters);
2213  }
2214 
2215  /* Check if the Application Verifier was enabled */
2217  {
2219  if (!NT_SUCCESS(Status))
2220  {
2221  DPRINT1("LDR: AVrfInitializeVerifier failed (ntstatus 0x%x)\n", Status);
2222  return Status;
2223  }
2224 
2225  }
2226 
2227  if (IsDotNetImage)
2228  {
2229  /* FIXME */
2230  DPRINT1("We don't support .NET applications yet\n");
2231  }
2232 
2235  {
2236  PVOID Kernel32BaseAddress;
2237  PVOID FunctionAddress;
2238 
2239  Status = LdrLoadDll(NULL, NULL, &Kernel32String, &Kernel32BaseAddress);
2240 
2241  if (!NT_SUCCESS(Status))
2242  {
2243  if (ShowSnaps)
2244  DPRINT1("LDR: Unable to load %wZ, Status=0x%08lx\n", &Kernel32String, Status);
2245  return Status;
2246  }
2247 
2248  Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2249  &BaseProcessInitPostImportName,
2250  0,
2251  &FunctionAddress);
2252 
2253  if (!NT_SUCCESS(Status))
2254  {
2255  if (ShowSnaps)
2256  DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", &Kernel32String, Status);
2257  return Status;
2258  }
2259  Kernel32ProcessInitPostImportFunction = FunctionAddress;
2260 
2261  Status = LdrGetProcedureAddress(Kernel32BaseAddress,
2262  &BaseQueryModuleDataName,
2263  0,
2264  &FunctionAddress);
2265 
2266  if (!NT_SUCCESS(Status))
2267  {
2268  if (ShowSnaps)
2269  DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", &Kernel32String, Status);
2270  return Status;
2271  }
2272  Kernel32BaseQueryModuleData = FunctionAddress;
2273  }
2274 
2275  /* Walk the IAT and load all the DLLs */
2277 
2278  /* Check if relocation is needed */
2279  if (Peb->ImageBaseAddress != (PVOID)NtHeader->OptionalHeader.ImageBase)
2280  {
2281  DPRINT1("LDR: Performing EXE relocation\n");
2282 
2283  /* Change the protection to prepare for relocation */
2284  ViewBase = Peb->ImageBaseAddress;
2285  Status = LdrpSetProtection(ViewBase, FALSE);
2286  if (!NT_SUCCESS(Status)) return Status;
2287 
2288  /* Do the relocation */
2289  Status = LdrRelocateImageWithBias(ViewBase,
2290  0LL,
2291  NULL,
2295  if (!NT_SUCCESS(Status))
2296  {
2297  DPRINT1("LdrRelocateImageWithBias() failed\n");
2298  return Status;
2299  }
2300 
2301  /* Check if a start context was provided */
2302  if (Context)
2303  {
2304  DPRINT1("WARNING: Relocated EXE Context");
2305  UNIMPLEMENTED; // We should support this
2307  }
2308 
2309  /* Restore the protection */
2310  Status = LdrpSetProtection(ViewBase, TRUE);
2311  if (!NT_SUCCESS(Status)) return Status;
2312  }
2313 
2314  /* Lock the DLLs */
2315  ListHead = &Peb->Ldr->InLoadOrderModuleList;
2316  NextEntry = ListHead->Flink;
2317  while (ListHead != NextEntry)
2318  {
2319  NtLdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
2320  NtLdrEntry->LoadCount = -1;
2321  NextEntry = NextEntry->Flink;
2322  }
2323 
2324  /* Phase 0 is done */
2326 
2327  /* Check whether all static imports were properly loaded and return here */
2328  if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
2329 
2330  /* Initialize TLS */
2332  if (!NT_SUCCESS(Status))
2333  {
2334  DPRINT1("LDR: LdrpProcessInitialization failed to initialize TLS slots; status %x\n",
2335  Status);
2336  return Status;
2337  }
2338 
2339  /* FIXME Mark the DLL Ranges for Stack Traces later */
2340 
2341  /* Notify the debugger now */
2342  if (Peb->BeingDebugged)
2343  {
2344  /* Break */
2345  DbgBreakPoint();
2346 
2347  /* Update show snaps again */
2349  }
2350 
2351  /* Validate the Image for MP Usage */
2353 
2354  /* Check NX Options */
2355  if (SharedUserData->NXSupportPolicy == 1)
2356  {
2357  ExecuteOptions = 0xD;
2358  }
2359  else if (!SharedUserData->NXSupportPolicy)
2360  {
2361  ExecuteOptions = 0xA;
2362  }
2363 
2364  /* Let Mm know */
2367  &ExecuteOptions,
2368  sizeof(ULONG));
2369 
2370  // FIXME: Should be done by Application Compatibility features,
2371  // by reading the registry, etc...
2372  // For now, this is the old code from ntdll!RtlGetVersion().
2373  RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
2374  if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
2375  {
2376  WCHAR szCSDVersion[128];
2377  LONG i;
2378  USHORT Length = (USHORT)ARRAYSIZE(szCSDVersion) - 1;
2379  i = _snwprintf(szCSDVersion, Length,
2380  L"Service Pack %d",
2381  ((Peb->OSCSDVersion >> 8) & 0xFF));
2382  if (i < 0)
2383  {
2384  /* Null-terminate if it was overflowed */
2385  szCSDVersion[Length] = UNICODE_NULL;
2386  }
2387 
2388  Length *= sizeof(WCHAR);
2389  Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
2390  0,
2391  Length + sizeof(UNICODE_NULL));
2392  if (Peb->CSDVersion.Buffer)
2393  {
2396 
2398  szCSDVersion,
2401  }
2402  }
2403 
2404  /* Check if we had Shim Data */
2405  if (OldShimData)
2406  {
2407  /* Load the Shim Engine */
2408  Peb->AppCompatInfo = NULL;
2409  LdrpLoadShimEngine(OldShimData, &ImagePathName, OldShimData);
2410  }
2411  else
2412  {
2413  /* Check for Application Compatibility Goo */
2414  //LdrQueryApplicationCompatibilityGoo(hKey);
2415  DPRINT("Querying app compat hacks is missing!\n");
2416  }
2417 
2418  /*
2419  * FIXME: Check for special images, SecuROM, SafeDisc and other NX-
2420  * incompatible images.
2421  */
2422 
2423  /* Now call the Init Routines */
2425  if (!NT_SUCCESS(Status))
2426  {
2427  DPRINT1("LDR: LdrpProcessInitialization failed running initialization routines; status %x\n",
2428  Status);
2429  return Status;
2430  }
2431 
2432  /* Notify Shim Engine */
2433  if (g_ShimsEnabled)
2434  {
2437  SE_InstallAfterInit(&ImagePathName, OldShimData);
2438  }
2439 
2440  /* Check if we have a user-defined Post Process Routine */
2442  {
2443  /* Call it */
2445  }
2446 
2447  /* Close the key if we have one opened */
2448  if (OptionsKey) NtClose(OptionsKey);
2449 
2450  /* Return status */
2451  return Status;
2452 }
2453 
2454 VOID
2455 NTAPI
2457 {
2458  ULONG Response;
2459  PPEB Peb = NtCurrentPeb();
2460 
2461  /* Print a debug message */
2462  DPRINT1("LDR: Process initialization failure for %wZ; NTSTATUS = %08lx\n",
2464 
2465  /* Raise a hard error */
2467  {
2469  }
2470 }
2471 
2472 VOID
2473 NTAPI
2477 {
2479  PTEB Teb = NtCurrentTeb();
2480  NTSTATUS Status, LoaderStatus = STATUS_SUCCESS;
2481  MEMORY_BASIC_INFORMATION MemoryBasicInfo;
2482  PPEB Peb = NtCurrentPeb();
2483 
2484  DPRINT("LdrpInit() %p/%p\n",
2485  NtCurrentTeb()->RealClientId.UniqueProcess,
2486  NtCurrentTeb()->RealClientId.UniqueThread);
2487 
2488 #ifdef _WIN64
2489  /* Set the SList header usage */
2491 #endif /* _WIN64 */
2492 
2493  /* Check if we have a deallocation stack */
2494  if (!Teb->DeallocationStack)
2495  {
2496  /* We don't, set one */
2498  Teb->NtTib.StackLimit,
2500  &MemoryBasicInfo,
2501  sizeof(MEMORY_BASIC_INFORMATION),
2502  NULL);
2503  if (!NT_SUCCESS(Status))
2504  {
2505  /* Fail */
2508  return;
2509  }
2510 
2511  /* Set the stack */
2512  Teb->DeallocationStack = MemoryBasicInfo.AllocationBase;
2513  }
2514 
2515  /* Now check if the process is already being initialized */
2517  1,
2518  0) == 1)
2519  {
2520  /* Set the timeout to 30 milliseconds */
2521  Timeout.QuadPart = Int32x32To64(30, -10000);
2522 
2523  /* Make sure the status hasn't changed */
2524  while (LdrpProcessInitialized == 1)
2525  {
2526  /* Do the wait */
2528  }
2529  }
2530 
2531  /* Check if we have already setup LDR data */
2532  if (!Peb->Ldr)
2533  {
2534  /* Setup the Loader Lock */
2536 
2537  /* Let other code know we're initializing */
2538  LdrpInLdrInit = TRUE;
2539 
2540  /* Protect with SEH */
2541  _SEH2_TRY
2542  {
2543  /* Initialize the Process */
2544  LoaderStatus = LdrpInitializeProcess(Context,
2545  SystemArgument1);
2546 
2547  /* Check for success and if MinimumStackCommit was requested */
2548  if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit)
2549  {
2550  /* Enforce the limit */
2551  //LdrpTouchThreadStack(Peb->MinimumStackCommit);
2552  UNIMPLEMENTED;
2553  }
2554  }
2556  {
2557  /* Fail with the SEH error */
2558  LoaderStatus = _SEH2_GetExceptionCode();
2559  }
2560  _SEH2_END;
2561 
2562  /* We're not initializing anymore */
2563  LdrpInLdrInit = FALSE;
2564 
2565  /* Check if init worked */
2566  if (NT_SUCCESS(LoaderStatus))
2567  {
2568  /* Set the process as Initialized */
2570  }
2571  }
2572  else
2573  {
2574  /* Loader data is there... is this a fork() ? */
2576  {
2577  /* Handle the fork() */
2578  //LoaderStatus = LdrpForkProcess();
2579  LoaderStatus = STATUS_NOT_IMPLEMENTED;
2580  UNIMPLEMENTED;
2581  }
2582  else
2583  {
2584  /* This is a new thread initializing */
2586  }
2587  }
2588 
2589  /* All done, test alert the thread */
2590  NtTestAlert();
2591 
2592  /* Return */
2593  if (!NT_SUCCESS(LoaderStatus))
2594  {
2595  /* Fail */
2596  LdrpInitFailure(LoaderStatus);
2597  RtlRaiseStatus(LoaderStatus);
2598  }
2599 }
2600 
2601 /* EOF */
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
PRTL_BITMAP TlsExpansionBitmap
Definition: winternl.h:346
BOOLEAN Initialized
Definition: ntddk_ex.h:222
signed char * PCHAR
Definition: retypes.h:7
VOID NTAPI LdrpCallTlsInitializers(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason)
Definition: ldrutils.c:473
UNICODE_STRING ImageExecOptionsString
Definition: ldrinit.c:24
#define PF_COMPARE_EXCHANGE128
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG RtlpShutdownProcessFlags
Definition: ldrinit.c:93
NTSYSAPI NTSTATUS NTAPI ZwRaiseHardError(_In_ NTSTATUS ErrorStatus, _In_ ULONG NumberOfParameters, _In_ ULONG UnicodeStringParameterMask, _In_ PULONG_PTR Parameters, _In_ ULONG ValidResponseOptions, _Out_ PULONG Response)
BOOLEAN LdrpDllValidation
Definition: ldrinit.c:37
#define HEAP_CLASS_1
Definition: nt_native.h:1711
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
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
NTSYSAPI VOID NTAPI RtlResetRtlTranslations(_In_ PNLSTABLEINFO NlsTable)
BOOLEAN g_ShimsEnabled
Definition: ldrutils.c:21
IMAGE_TLS_DIRECTORY TlsDirectory
Definition: ntdllp.h:29
VOID NTAPI LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID *pOldShimData)
Definition: ldrinit.c:1542
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define HEAP_CREATE_ALIGN_16
Definition: nt_native.h:1701
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
#define LL
Definition: tui.h:85
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
long __cdecl _InterlockedCompareExchange(_Interlocked_operand_ long volatile *_Destination, long _Exchange, long _Comparand)
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
PPEB Peb
Definition: dllmain.c:27
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
UNICODE_STRING Kernel32String
Definition: ldrinit.c:27
RTL_BITMAP FlsBitMap
Definition: ldrinit.c:51
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:122
UNICODE_STRING LdrpKnownDllPath
Definition: ldrinit.c:63
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
LARGE_INTEGER RtlpTimeout
Definition: critical.c:24
static PMEMKEY RootKey
Definition: registry.c:55
UNICODE_STRING NtSystemRoot
Definition: init.c:72
RTL_BITMAP TlsExpansionBitMap
Definition: ldrinit.c:50
Type
Definition: Type.h:6
#define LDRP_DONT_CALL_FOR_THREADS
Definition: ldrtypes.h:48
NTSTATUS NTAPI LdrShutdownProcess(VOID)
Definition: ldrinit.c:939
ULONG ImageProcessAffinityMask
Definition: ntddk_ex.h:307
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
PVOID g_pfnSE_ProcessDying
Definition: ldrutils.c:27
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_APP_INIT_FAILURE
Definition: ntstatus.h:547
static IN LPSTR IN PVOID Unk2
Definition: ldrinit.c:47
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
#define REG_BINARY
Definition: nt_native.h:1496
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define DLL_THREAD_ATTACH
Definition: compat.h:121
#define TLS_EXPANSION_SLOTS
Definition: pstypes.h:294
uint16_t * PWSTR
Definition: typedefs.h:54
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1404
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
ULONG TlsExpansionBitmapBits[32]
Definition: winternl.h:347
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry
Definition: ldrinit.c:44
LIST_ENTRY LdrpTlsList
Definition: ldrinit.c:53
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1872
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
NTSYSAPI NTSTATUS NTAPI ZwDelayExecution(_In_ BOOLEAN Alertable, _In_ LARGE_INTEGER *Interval)
VOID NTAPI SE_InstallAfterInit(PUNICODE_STRING ProcessImage, PVOID pShimData)
Definition: shimeng.c:1422
GLdouble n
Definition: glext.h:7729
NTSTATUS NTAPI NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter, OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
Definition: profile.c:278
ULONG SizeOfImage
Definition: ldrtypes.h:143
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
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:4284
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
ULONG FlsBitmapBits[4]
Definition: winternl.h:362
VOID NTAPI RtlReleasePebLock(VOID)
Definition: libsupp.c:82
#define REACTOS_COMPATVERSION_IGNOREMANIFEST
Definition: hsdb.c:32
BYTE BeingDebugged
Definition: btrfs_drv.h:1886
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
void actctx_init(PVOID *pOldShimData)
Definition: actctx.c:5003
#define _WIN32_WINNT_WINBLUE
Definition: sdkddkver.h:30
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:1270
uint16_t * PWCHAR
Definition: typedefs.h:54
HANDLE LdrpKnownDllObjectDirectory
Definition: ldrinit.c:62
static IN LPSTR IN PVOID IN PVOID IN PVOID Unk4
Definition: ldrinit.c:47
#define InsertTailList(ListHead, Entry)
char * LPSTR
Definition: xmlstorage.h:182
HANDLE UniqueProcess
Definition: compat.h:482
void DbgBreakPoint()
Definition: mach.c:553
#define UNICODE_STRING_MAX_BYTES
NTSTATUS NTAPI LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey, IN BOOLEAN Wow64, OUT PHANDLE NewKeyHandle)
Definition: ldrinit.c:112
BOOLEAN RtlpPageHeapEnabled
Definition: heappage.c:106
#define DLL_THREAD_DETACH
Definition: compat.h:122
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define DEFAULT_SECURITY_COOKIE
Definition: ldrinit.c:102
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS NTAPI RtlNormalizeProcessParams(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
VOID NTAPI LdrpInitializeDotLocalSupport(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
Definition: ldrinit.c:1645
CLIENT_ID ClientId
Definition: compat.h:496
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
PVOID DllBase
Definition: btrfs_drv.h:1857
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
PVOID NtDllBase
Definition: ldrinit.c:56
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
PVOID ThreadLocalStoragePointer
Definition: compat.h:498
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
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
USHORT TlsIndex
Definition: ntddk_ex.h:209
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
NTSTATUS NTAPI LdrpInitializeTls(VOID)
Definition: ldrinit.c:1254
BOOLEAN LdrpLoaderLockInit
Definition: ldrinit.c:32
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
long LONG
Definition: pedump.c:60
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
RTL_CRITICAL_SECTION_DEBUG LdrpLoaderLockDebug
Definition: ldrinit.c:69
VOID NTAPI RtlpInitDeferedCriticalSection(VOID)
Definition: critical.c:267
LIST_ENTRY TlsLinks
Definition: ntdllp.h:28
PVOID EntryPoint
Definition: ntddk_ex.h:203
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES]
Definition: ldrinit.c:60
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH
Definition: rtltypes.h:52
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
WCHAR LdrpKnownDllPathBuffer[128]
Definition: ldrinit.c:64
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
unsigned char BOOLEAN
ULONG RtlpDphGlobalFlags
Definition: heappage.c:107
PVOID NTAPI LdrpFetchAddressOfEntryPoint(PVOID ImageBase)
static GUID * Guid
Definition: apphelp.c:93
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
#define FLG_APPLICATION_VERIFIER
Definition: pstypes.h:64
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
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
void DPRINT(...)
Definition: polytest.cpp:61
BOOLEAN ReadImageFileExecOptions
Definition: ntddk_ex.h:240
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
RTL_BITMAP TlsBitMap
Definition: ldrinit.c:49
NTSTATUS NTAPI LdrpInitializeProcess(IN PCONTEXT Context, IN PVOID SystemArgument1)
Definition: ldrinit.c:1706
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
ULONG Length
Definition: ntddk_ex.h:221
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS NTAPI LdrpInitializeApplicationVerifierPackage(IN HANDLE KeyHandle, IN PPEB Peb, IN BOOLEAN SystemWide, IN BOOLEAN ReadAdvancedOptions)
PVOID LdrpHeap
Definition: ldrinit.c:59
#define DLL_PROCESS_DETACH
Definition: compat.h:119
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define PCHAR
Definition: match.c:90
#define REACTOS_SHIMDATA_MAGIC
Definition: compat_undoc.h:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
LIST_ENTRY FlsListHead
Definition: winternl.h:360
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
#define _WIN32_WINNT_WIN8
Definition: sdkddkver.h:29
VOID NTAPI LdrpInitFailure(NTSTATUS Status)
Definition: ldrinit.c:2456
RTL_CRITICAL_SECTION LdrpLoaderLock
Definition: ldrinit.c:70
ULONG LdrpNumberOfTlsEntries
Definition: ldrinit.c:54
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
VOID NTAPI SE_ProcessDying(VOID)
Definition: shimeng.c:1427
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
PUNICODE_STRING LdrpTopLevelDllBeingLoaded
Definition: ldrinit.c:40
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
NTSYSAPI VOID NTAPI RtlInitNlsTables(_In_ PUSHORT AnsiTableBase, _In_ PUSHORT OemTableBase, _In_ PUSHORT CaseTableBase, _Out_ PNLSTABLEINFO NlsTable)
LONG LdrpProcessInitialized
Definition: ldrinit.c:31
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
VOID NTAPI LdrpFreeTls(VOID)
Definition: ldrinit.c:1380
UNICODE_STRING NtDllString
Definition: ldrinit.c:26
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
BOOLEAN RtlpTimeoutDisable
Definition: ldrinit.c:58
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: ldrinit.c:412
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
VOID NTAPI LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
Definition: ldrutils.c:2766
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
static NTSTATUS(WINAPI *Kernel32ProcessInitPostImportFunction)(VOID)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID DeallocationStack
Definition: compat.h:535
VOID NTAPI LdrpInit(PCONTEXT Context, PVOID SystemArgument1, PVOID SystemArgument2)
Definition: ldrinit.c:2474
PVOID FiberData
Definition: compat.h:384
PEB_LDR_DATA PebLdr
Definition: ldrinit.c:67
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
#define FLG_HEAP_PAGE_ALLOCS
Definition: pstypes.h:84
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
#define HEAP_GROWABLE
Definition: nt_native.h:1693
PVOID ProcessHeap
Definition: ntddk_ex.h:249
#define BufferSize
Definition: classpnp.h:419
unsigned long DWORD
Definition: ntddk_ex.h:95
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:5939
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
static VOID LoadConfig(HWND hwndDlg, PPOWER_SCHEMES_PAGE_DATA pPageData, PPOWER_SCHEME pScheme)
Definition: powershemes.c:237
LARGE_INTEGER CriticalSectionTimeout
Definition: ntddk_ex.h:274
PLDR_DATA_TABLE_ENTRY LdrpImageEntry
Definition: ldrinit.c:39
static IN LPSTR Unk1
Definition: ldrinit.c:47
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PTEB LdrpTopLevelDllBeingLoadedTeb
Definition: libsupp.c:18
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
SIZE_T MinimumStackCommit
Definition: winternl.h:358
VOID NTAPI LdrpEnsureLoaderLockIsHeld(VOID)
Definition: ldrinit.c:405
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
Definition: ncftp.h:89
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
BOOLEAN LdrpLdrDatabaseIsSetup
Definition: ldrinit.c:33
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID g_pfnSE_InstallAfterInit
Definition: ldrutils.c:26
#define SharedUserData
ULONG NTAPI LdrpClearLoadInProgress(VOID)
Definition: ldrutils.c:2658
IMAGE_LOAD_CONFIG_DIRECTORY32 IMAGE_LOAD_CONFIG_DIRECTORY
Definition: ntimage.h:155
PVOID FastPebLock
Definition: ntddk_ex.h:250
UNICODE_STRING ImagePathName
Definition: btrfs_drv.h:1878
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE]
Definition: rtltypes.h:1220
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI void WINAPI RtlFreeThreadActivationContextStack(void)
Definition: actctx.c:5400
#define RtlImageDirectoryEntryToData
Definition: compat.h:468
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1890
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define VOID
Definition: acefi.h:82
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
Definition: btrfs_drv.h:1853
ULONG LowPart
Definition: typedefs.h:104
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
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)
UNICODE_STRING Wow64OptionsString
Definition: ldrinit.c:25
#define GENERIC_READ
Definition: compat.h:124
Definition: typedefs.h:117
UNICODE_STRING CommandLine
Definition: btrfs_drv.h:1879
PVOID UnicodeCaseTableData
Definition: ntddk_ex.h:266
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
Definition: ldrinit.c:1535
PVOID LoaderLock
Definition: ntddk_ex.h:295
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
#define LDR_HASH_TABLE_ENTRIES
Definition: ntdllp.h:11
PVOID AppCompatInfo
Definition: winternl.h:352
VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrutils.c:1577
ULONG LdrpNumberOfProcessors
Definition: ldrinit.c:55
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
NTSTATUS NTAPI AVrfInitializeVerifier(VOID)
Definition: verifier.c:612
VOID NTAPI RtlInitializeHeapManager(VOID)
Definition: libsupp.c:243
#define Int64ShrlMod32(a, b)
LIST_ENTRY LdrpDllNotificationList
Definition: ldrinit.c:61
static IN LPSTR IN PVOID IN PVOID Unk3
Definition: ldrinit.c:47
ULONG_PTR SIZE_T
Definition: typedefs.h:78
LIST_ENTRY ListEntry
Definition: rtltypes.h:1219
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:544
Definition: compat.h:492
VOID NTAPI LdrpInitializeThread(IN PCONTEXT Context)
Definition: ldrinit.c:502
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine
Definition: btrfs_drv.h:1893
#define LDRP_COR_IMAGE
Definition: ldrtypes.h:52
struct _GUID GUID
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: pedump.c:269
_SEH2_END
Definition: create.c:4424
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:83
VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID)
Definition: vectoreh.c:30
static ULONG Timeout
Definition: ping.c:61
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1112
NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase, BOOLEAN Restore)
Definition: ldrutils.c:944
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1101
UNICODE_STRING LdrpDefaultPath
Definition: ldrinit.c:65
#define NtCurrentPeb()
Definition: FLS.c:20
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI RtlDoesFileExists_UStr(IN PUNICODE_STRING FileName)
Definition: path.c:1384
RTL_CRITICAL_SECTION FastPebLock
Definition: ldrinit.c:79
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:57
PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
Definition: ldrutils.c:1544
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1889
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
HANDLE ImageExecOptionsKey
Definition: ldrinit.c:22
HANDLE Wow64ExecOptionsKey
Definition: ldrinit.c:23
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1859
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
NTSTATUS NTAPI LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
Definition: ldrinit.c:1416
ULONG NumberOfProcessors
Definition: ntddk_ex.h:269
unsigned int * PULONG
Definition: retypes.h:1
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
BOOLEAN RtlpUse16ByteSLists
PACTIVATION_CONTEXT EntryPointActivationContext
Definition: ldrtypes.h:163
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer
Definition: ldrinit.c:43
ULONG TlsBitmapBits[2]
Definition: ntddk_ex.h:260
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5443
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
VOID NTAPI RtlAcquirePebLock(VOID)
Definition: libsupp.c:72
#define DPH_FLAG_DLL_NOTIFY
Definition: ntdllp.h:24
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
Definition: ldrinit.c:637
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI NtTestAlert(VOID)
Definition: state.c:465
#define RtlImageNtHeader
Definition: compat.h:465
UNICODE_STRING DosPath
Definition: rtltypes.h:1362
static LARGE_INTEGER Counter
Definition: clock.c:43
PVOID OemCodePageData
Definition: ntddk_ex.h:265
static BOOL(WINAPI *Kernel32BaseQueryModuleData)(IN LPSTR ModuleName
NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U(_In_ PUNICODE_STRING name)
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5862
DWORD dwRosProcessCompatVersion
Definition: compat_undoc.h:11
#define LDRP_IMAGE_DLL
Definition: ldrtypes.h:39
NTSTATUS NTAPI LdrpAllocateTls(VOID)
Definition: ldrinit.c:1317
#define OUT
Definition: typedefs.h:39
NTSTATUS NTAPI RtlAllocateActivationContextStack(IN PACTIVATION_CONTEXT_STACK *Stack)
Definition: actctx.c:5834
NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase)
PRTL_BITMAP FlsBitmap
Definition: winternl.h:361
ULONG Flags
Definition: ntddk_ex.h:207
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
unsigned int ULONG
Definition: retypes.h:1
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
struct Response Response
struct _PEB_LDR_DATA PEB_LDR_DATA
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrinit.c:449
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
const UNICODE_STRING LdrpDotLocal
Definition: ldrinit.c:28
UNICODE_STRING CSDVersion
Definition: winternl.h:353
PVOID StackLimit
Definition: compat.h:381
PVOID * TlsExpansionSlots
Definition: compat.h:551
#define FLG_USER_STACK_TRACE_DB
Definition: pstypes.h:67
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED
Definition: rtltypes.h:41
PVOID ActivationContextStackPointer
Definition: compat.h:511
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
BOOLEAN InheritedAddressSpace
Definition: ntddk_ex.h:239
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH
Definition: rtltypes.h:53
NTSTATUS NTAPI LdrShutdownThread(VOID)
Definition: ldrinit.c:1078
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:247
return STATUS_SUCCESS
Definition: btrfs.c:2938
PVOID TlsBitmap
Definition: ntddk_ex.h:259
#define REG_DWORD
Definition: sdbapi.c:596
signed int * PLONG
Definition: retypes.h:5
ULONG StartAddressOfRawData
Definition: ntimage.h:546
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
ULONG RtlpDisableHeapLookaside
Definition: ldrinit.c:92
#define LDRP_PROCESS_ATTACH_CALLED
Definition: ldrtypes.h:49
#define UInt32x32To64(a, b)
Definition: intsafe.h:258
NT_TIB NtTib
Definition: ntddk_ex.h:332
ULONG LdrpActiveUnloadCount
Definition: ldrinit.c:84
PVOID AnsiCodePageData
Definition: ntddk_ex.h:264
VOID NTAPI RtlSetUnhandledExceptionFilter(IN PRTLP_UNHANDLED_EXCEPTION_FILTER TopLevelExceptionFilter)
Definition: exception.c:319
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:140
#define Int32x32To64(a, b)
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
BOOLEAN LdrpImageHasTls
Definition: ldrinit.c:52
USHORT LoadCount
Definition: ntddk_ex.h:208
LONGLONG QuadPart
Definition: typedefs.h:112
#define TLS_MINIMUM_AVAILABLE
Definition: ntddk_ex.h:236
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context)
Definition: ldrutils.c:100
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_NO_ADDREF
Definition: rtltypes.h:119
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NTSYSAPI NTSTATUS NTAPI ZwSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)