ReactOS  0.4.15-dev-5496-g599ba9c
sysldr.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/mm/ARM3/sysldr.c
5  * PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files.
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * ReactOS Portable Systems Group
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 #define MODULE_INVOLVED_IN_ARM3
17 #include <mm/ARM3/miarm.h>
18 
19 /* GLOBALS ********************************************************************/
20 
27 
29 
32 
35 
39 
40 #ifdef _WIN64
41 #define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
42 #else
43 #define DEFAULT_SECURITY_COOKIE 0xBB40E64E
44 #endif
45 
46 /* FUNCTIONS ******************************************************************/
47 
48 PVOID
49 NTAPI
51 {
52  ULONG DebugSize;
53  PVOID DebugDirectory = NULL;
54  PAGED_CODE();
55 
56  /* Make sure it's safe to access the image */
57  _SEH2_TRY
58  {
59  /* Get the debug directory */
61  TRUE,
63  &DebugSize);
64  }
66  {
67  /* Nothing */
68  }
69  _SEH2_END;
70 
71  /* Return the directory */
72  return DebugDirectory;
73 }
74 
76 NTAPI
78  _Out_ PVOID *ImageBase,
80  _In_ BOOLEAN SessionLoad,
81  _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
82 {
83  PSECTION Section = *SectionPtr;
86  PVOID Base = NULL;
87  SIZE_T ViewSize = 0;
89  LARGE_INTEGER SectionOffset = {{0, 0}};
91  PFN_COUNT PteCount;
92  PMMPTE PointerPte, LastPte;
93  PVOID DriverBase;
94  MMPTE TempPte;
95  KIRQL OldIrql;
96  PFN_NUMBER PageFrameIndex;
97  PAGED_CODE();
98 
99  /* Detect session load */
100  if (SessionLoad)
101  {
102  /* Fail */
103  UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
104  return STATUS_NOT_IMPLEMENTED;
105  }
106 
107  /* Not session load, shouldn't have an entry */
108  ASSERT(LdrEntry == NULL);
109 
110  /* Attach to the system process */
112 
113  /* Check if we need to load symbols */
115  {
116  /* Yes we do */
117  LoadSymbols = TRUE;
119  }
120 
121  /* Map the driver */
123  Status = MmMapViewOfSection(Section,
124  Process,
125  &Base,
126  0,
127  0,
128  &SectionOffset,
129  &ViewSize,
130  ViewUnmap,
131  0,
132  PAGE_EXECUTE);
133 
134  /* Re-enable the flag */
136 
137  /* Check if we failed with distinguished status code */
139  {
140  /* Change it to something more generic */
142  }
143 
144  /* Now check if we failed */
145  if (!NT_SUCCESS(Status))
146  {
147  /* Detach and return */
148  DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
150  return Status;
151  }
152 
153  /* Reserve system PTEs needed */
154  PteCount = ROUND_TO_PAGES(((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize) >> PAGE_SHIFT;
155  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
156  if (!PointerPte)
157  {
158  DPRINT1("MiReserveSystemPtes failed\n");
161  }
162 
163  /* New driver base */
164  LastPte = PointerPte + PteCount;
165  DriverBase = MiPteToAddress(PointerPte);
166 
167  /* The driver is here */
168  *ImageBase = DriverBase;
169  DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
170 
171  /* Lock the PFN database */
172  OldIrql = MiAcquirePfnLock();
173 
174  /* Loop the new driver PTEs */
176  while (PointerPte < LastPte)
177  {
178  /* Make sure the PTE is not valid for whatever reason */
179  ASSERT(PointerPte->u.Hard.Valid == 0);
180 
181  /* Some debug stuff */
183 #if MI_TRACE_PFNS
184  MI_SET_PROCESS_USTR(FileName);
185 #endif
186 
187  /* Grab a page */
188  PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
189 
190  /* Initialize its PFN entry */
191  MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
192 
193  /* Write the PTE */
194  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
195  MI_WRITE_VALID_PTE(PointerPte, TempPte);
196 
197  /* Move on */
198  PointerPte++;
199  }
200 
201  /* Release the PFN lock */
202  MiReleasePfnLock(OldIrql);
203 
204  /* Copy the image */
205  RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
206 
207  /* Now unmap the view */
210 
211  /* Detach and return status */
213  return Status;
214 }
215 
216 PVOID
217 NTAPI
219  IN PCHAR ExportName)
220 {
221  PULONG NameTable;
222  PUSHORT OrdinalTable;
223  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
224  LONG Low = 0, Mid = 0, High, Ret;
225  USHORT Ordinal;
226  PVOID Function;
227  ULONG ExportSize;
228  PULONG ExportTable;
229  PAGED_CODE();
230 
231  /* Get the export directory */
232  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
233  TRUE,
235  &ExportSize);
236  if (!ExportDirectory) return NULL;
237 
238  /* Setup name tables */
239  NameTable = (PULONG)((ULONG_PTR)DllBase +
240  ExportDirectory->AddressOfNames);
241  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
242  ExportDirectory->AddressOfNameOrdinals);
243 
244  /* Do a binary search */
245  High = ExportDirectory->NumberOfNames - 1;
246  while (High >= Low)
247  {
248  /* Get new middle value */
249  Mid = (Low + High) >> 1;
250 
251  /* Compare name */
252  Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);
253  if (Ret < 0)
254  {
255  /* Update high */
256  High = Mid - 1;
257  }
258  else if (Ret > 0)
259  {
260  /* Update low */
261  Low = Mid + 1;
262  }
263  else
264  {
265  /* We got it */
266  break;
267  }
268  }
269 
270  /* Check if we couldn't find it */
271  if (High < Low) return NULL;
272 
273  /* Otherwise, this is the ordinal */
274  Ordinal = OrdinalTable[Mid];
275 
276  /* Resolve the address and write it */
277  ExportTable = (PULONG)((ULONG_PTR)DllBase +
278  ExportDirectory->AddressOfFunctions);
279  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
280 
281  /* Check if the function is actually a forwarder */
282  if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&
283  ((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
284  {
285  /* It is, fail */
286  return NULL;
287  }
288 
289  /* We found it */
290  return Function;
291 }
292 
293 NTSTATUS
294 NTAPI
296  IN PLIST_ENTRY ListHead)
297 {
299  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
300  PMM_DLL_INITIALIZE DllInit;
301  UNICODE_STRING RegPath, ImportName;
303 
304  /* Try to see if the image exports a DllInitialize routine */
305  DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,
306  "DllInitialize");
307  if (!DllInit) return STATUS_SUCCESS;
308 
309  /*
310  * Do a temporary copy of BaseDllName called ImportName
311  * because we'll alter the length of the string.
312  */
313  ImportName.Length = LdrEntry->BaseDllName.Length;
314  ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
315  ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
316 
317  /* Obtain the path to this dll's service in the registry */
318  RegPath.MaximumLength = ServicesKeyName.Length +
319  ImportName.Length + sizeof(UNICODE_NULL);
321  RegPath.MaximumLength,
322  TAG_LDR_WSTR);
323 
324  /* Check if this allocation was unsuccessful */
325  if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
326 
327  /* Build and append the service name itself */
328  RegPath.Length = ServicesKeyName.Length;
329  RtlCopyMemory(RegPath.Buffer,
330  ServicesKeyName.Buffer,
331  ServicesKeyName.Length);
332 
333  /* Check if there is a dot in the filename */
334  if (wcschr(ImportName.Buffer, L'.'))
335  {
336  /* Remove the extension */
337  ImportName.Length = (USHORT)(wcschr(ImportName.Buffer, L'.') -
338  ImportName.Buffer) * sizeof(WCHAR);
339  }
340 
341  /* Append service name (the basename without extension) */
342  RtlAppendUnicodeStringToString(&RegPath, &ImportName);
343 
344  /* Now call the DllInit func */
345  DPRINT("Calling DllInit(%wZ)\n", &RegPath);
346  Status = DllInit(&RegPath);
347 
348  /* Clean up */
350 
351  /* Return status value which DllInitialize returned */
352  return Status;
353 }
354 
355 BOOLEAN
356 NTAPI
358 {
361  PAGED_CODE();
362 
363  /* Get the unload routine */
364  Func = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
365  if (!Func) return FALSE;
366 
367  /* Call it and check for success */
368  Status = Func();
369  if (!NT_SUCCESS(Status)) return FALSE;
370 
371  /* Lie about the load count so we can unload the image */
372  ASSERT(LdrEntry->LoadCount == 0);
373  LdrEntry->LoadCount = 1;
374 
375  /* Unload it and return true */
376  MmUnloadSystemImage(LdrEntry);
377  return TRUE;
378 }
379 
380 NTSTATUS
381 NTAPI
383 {
384  SIZE_T i;
385  LOAD_IMPORTS SingleEntry;
386  PLDR_DATA_TABLE_ENTRY LdrEntry;
387  PVOID CurrentImports;
388  PAGED_CODE();
389 
390  /* Check if there's no imports or if we're a boot driver */
391  if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
392  (ImportList == MM_SYSLDR_BOOT_LOADED) ||
393  (ImportList->Count == 0))
394  {
395  /* Then there's nothing to do */
396  return STATUS_SUCCESS;
397  }
398 
399  /* Check for single-entry */
400  if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
401  {
402  /* Set it up */
403  SingleEntry.Count = 1;
404  SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
405 
406  /* Use this as the import list */
407  ImportList = &SingleEntry;
408  }
409 
410  /* Loop the import list */
411  for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
412  {
413  /* Get the entry */
414  LdrEntry = ImportList->Entry[i];
415  DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
416 
417  /* Skip boot loaded images */
418  if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
419 
420  /* Dereference the entry */
421  ASSERT(LdrEntry->LoadCount >= 1);
422  if (!--LdrEntry->LoadCount)
423  {
424  /* Save the import data in case unload fails */
425  CurrentImports = LdrEntry->LoadedImports;
426 
427  /* This is the last entry */
429  if (MiCallDllUnloadAndUnloadDll(LdrEntry))
430  {
431  /* Unloading worked, parse this DLL's imports too */
432  MiDereferenceImports(CurrentImports);
433 
434  /* Check if we had valid imports */
435  if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) &&
436  (CurrentImports != MM_SYSLDR_NO_IMPORTS) &&
437  !((ULONG_PTR)CurrentImports & MM_SYSLDR_SINGLE_ENTRY))
438  {
439  /* Free them */
440  ExFreePoolWithTag(CurrentImports, TAG_LDR_IMPORTS);
441  }
442  }
443  else
444  {
445  /* Unload failed, restore imports */
446  LdrEntry->LoadedImports = CurrentImports;
447  }
448  }
449  }
450 
451  /* Done */
452  return STATUS_SUCCESS;
453 }
454 
455 VOID
456 NTAPI
458 {
459  PAGED_CODE();
460 
461  /* Check if there's no imports or we're a boot driver or only one entry */
462  if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
463  (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
464  ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
465  {
466  /* Nothing to do */
467  return;
468  }
469 
470  /* Otherwise, free the import list */
471  ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
472  LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
473 }
474 
475 PVOID
476 NTAPI
478  IN PANSI_STRING ExportName)
479 {
480  PULONG NameTable;
481  PUSHORT OrdinalTable;
482  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
483  LONG Low = 0, Mid = 0, High, Ret;
484  USHORT Ordinal;
485  PVOID Function;
486  ULONG ExportSize;
487  PULONG ExportTable;
488  PAGED_CODE();
489 
490  /* Get the export directory */
491  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
492  TRUE,
494  &ExportSize);
495  if (!ExportDirectory) return NULL;
496 
497  /* Setup name tables */
498  NameTable = (PULONG)((ULONG_PTR)DllBase +
499  ExportDirectory->AddressOfNames);
500  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
501  ExportDirectory->AddressOfNameOrdinals);
502 
503  /* Do a binary search */
504  High = ExportDirectory->NumberOfNames - 1;
505  while (High >= Low)
506  {
507  /* Get new middle value */
508  Mid = (Low + High) >> 1;
509 
510  /* Compare name */
511  Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
512  if (Ret < 0)
513  {
514  /* Update high */
515  High = Mid - 1;
516  }
517  else if (Ret > 0)
518  {
519  /* Update low */
520  Low = Mid + 1;
521  }
522  else
523  {
524  /* We got it */
525  break;
526  }
527  }
528 
529  /* Check if we couldn't find it */
530  if (High < Low) return NULL;
531 
532  /* Otherwise, this is the ordinal */
533  Ordinal = OrdinalTable[Mid];
534 
535  /* Validate the ordinal */
536  if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
537 
538  /* Resolve the address and write it */
539  ExportTable = (PULONG)((ULONG_PTR)DllBase +
540  ExportDirectory->AddressOfFunctions);
541  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
542 
543  /* We found it! */
544  ASSERT((Function < (PVOID)ExportDirectory) ||
545  (Function > (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));
546 
547  return Function;
548 }
549 
550 VOID
551 NTAPI
553  IN BOOLEAN Insert)
554 {
555  KIRQL OldIrql;
556 
557  /* Acquire module list lock */
560 
561  /* Acquire the spinlock too as we will insert or remove the entry */
563 
564  /* Insert or remove from the list */
565  if (Insert)
566  InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
567  else
568  RemoveEntryList(&LdrEntry->InLoadOrderLinks);
569 
570  /* Release locks */
574 }
575 
576 CODE_SEG("INIT")
577 VOID
578 NTAPI
580  IN PVOID OldBase,
581  IN PVOID NewBase,
582  IN ULONG Size)
583 {
584  ULONG_PTR OldBaseTop, Delta;
585  PLDR_DATA_TABLE_ENTRY LdrEntry;
586  PLIST_ENTRY NextEntry;
587  ULONG ImportSize;
588  //
589  // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
590  // since a real version of Windows would fail at this point, but they seem
591  // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
592  // a feature which isn't even used by Windows. Priorities, priorities...
593  // Please note that Microsoft WDK EULA and license prohibits using
594  // the information contained within it for the generation of "non-Windows"
595  // drivers, which is precisely what LD will generate, since an LD driver
596  // will not load on Windows.
597  //
598 #ifdef _WORKING_LINKER_
599  ULONG i;
600 #endif
601  PULONG_PTR ImageThunk;
602  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
603 
604  /* Calculate the top and delta */
605  OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
606  Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
607 
608  /* Loop the loader block */
609  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
610  NextEntry != &LoaderBlock->LoadOrderListHead;
611  NextEntry = NextEntry->Flink)
612  {
613  /* Get the loader entry */
614  LdrEntry = CONTAINING_RECORD(NextEntry,
616  InLoadOrderLinks);
617 #ifdef _WORKING_LINKER_
618  /* Get the IAT */
619  ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
620  TRUE,
622  &ImportSize);
623  if (!ImageThunk) continue;
624 
625  /* Make sure we have an IAT */
626  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
627  for (i = 0; i < ImportSize; i++, ImageThunk++)
628  {
629  /* Check if it's within this module */
630  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
631  {
632  /* Relocate it */
633  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
634  ImageThunk, *ImageThunk, *ImageThunk + Delta);
635  *ImageThunk += Delta;
636  }
637  }
638 #else
639  /* Get the import table */
640  ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
641  TRUE,
643  &ImportSize);
644  if (!ImportDescriptor) continue;
645 
646  /* Make sure we have an IAT */
647  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
648  while ((ImportDescriptor->Name) &&
649  (ImportDescriptor->OriginalFirstThunk))
650  {
651  /* Get the image thunk */
652  ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
653  ImportDescriptor->FirstThunk);
654  while (*ImageThunk)
655  {
656  /* Check if it's within this module */
657  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
658  {
659  /* Relocate it */
660  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
661  ImageThunk, *ImageThunk, *ImageThunk + Delta);
662  *ImageThunk += Delta;
663  }
664 
665  /* Go to the next thunk */
666  ImageThunk++;
667  }
668 
669  /* Go to the next import */
670  ImportDescriptor++;
671  }
672 #endif
673  }
674 }
675 
676 NTSTATUS
677 NTAPI
679  IN PVOID ImageBase,
682  IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
683  IN ULONG ExportSize,
684  IN BOOLEAN SnapForwarder,
685  OUT PCHAR *MissingApi)
686 {
687  BOOLEAN IsOrdinal;
688  USHORT Ordinal;
689  PULONG NameTable;
690  PUSHORT OrdinalTable;
691  PIMAGE_IMPORT_BY_NAME NameImport;
692  USHORT Hint;
693  ULONG Low = 0, Mid = 0, High;
694  LONG Ret;
696  PCHAR MissingForwarder;
697  CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
698  PULONG ExportTable;
699  ANSI_STRING DllName;
700  UNICODE_STRING ForwarderName;
701  PLIST_ENTRY NextEntry;
702  PLDR_DATA_TABLE_ENTRY LdrEntry;
703  ULONG ForwardExportSize;
704  PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
705  PIMAGE_IMPORT_BY_NAME ForwardName;
706  SIZE_T ForwardLength;
707  IMAGE_THUNK_DATA ForwardThunk;
708  PAGED_CODE();
709 
710  /* Check if this is an ordinal */
711  IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
712  if ((IsOrdinal) && !(SnapForwarder))
713  {
714  /* Get the ordinal number and set it as missing */
715  Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
716  ExportDirectory->Base);
717  *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
718  }
719  else
720  {
721  /* Get the VA if we don't have to snap */
722  if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
723  NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
724 
725  /* Copy the procedure name */
726  RtlStringCbCopyA(*MissingApi,
728  (PCHAR)&NameImport->Name[0]);
729 
730  /* Setup name tables */
731  DPRINT("Import name: %s\n", NameImport->Name);
732  NameTable = (PULONG)((ULONG_PTR)DllBase +
733  ExportDirectory->AddressOfNames);
734  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
735  ExportDirectory->AddressOfNameOrdinals);
736 
737  /* Get the hint and check if it's valid */
738  Hint = NameImport->Hint;
739  if ((Hint < ExportDirectory->NumberOfNames) &&
740  !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
741  {
742  /* We have a match, get the ordinal number from here */
743  Ordinal = OrdinalTable[Hint];
744  }
745  else
746  {
747  /* Do a binary search */
748  High = ExportDirectory->NumberOfNames - 1;
749  while (High >= Low)
750  {
751  /* Get new middle value */
752  Mid = (Low + High) >> 1;
753 
754  /* Compare name */
755  Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
756  if (Ret < 0)
757  {
758  /* Update high */
759  High = Mid - 1;
760  }
761  else if (Ret > 0)
762  {
763  /* Update low */
764  Low = Mid + 1;
765  }
766  else
767  {
768  /* We got it */
769  break;
770  }
771  }
772 
773  /* Check if we couldn't find it */
774  if (High < Low)
775  {
776  DPRINT1("Warning: Driver failed to load, %s not found\n", NameImport->Name);
778  }
779 
780  /* Otherwise, this is the ordinal */
781  Ordinal = OrdinalTable[Mid];
782  }
783  }
784 
785  /* Check if the ordinal is invalid */
786  if (Ordinal >= ExportDirectory->NumberOfFunctions)
787  {
788  /* Fail */
790  }
791  else
792  {
793  /* In case the forwarder is missing */
794  MissingForwarder = NameBuffer;
795 
796  /* Resolve the address and write it */
797  ExportTable = (PULONG)((ULONG_PTR)DllBase +
798  ExportDirectory->AddressOfFunctions);
799  Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
800 
801  /* Assume success from now on */
803 
804  /* Check if the function is actually a forwarder */
805  if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
806  (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
807  {
808  /* Now assume failure in case the forwarder doesn't exist */
810 
811  /* Build the forwarder name */
812  DllName.Buffer = (PCHAR)Address->u1.Function;
813  DllName.Length = (USHORT)(strchr(DllName.Buffer, '.') -
814  DllName.Buffer) +
815  sizeof(ANSI_NULL);
816  DllName.MaximumLength = DllName.Length;
817 
818  /* Convert it */
819  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
820  &DllName,
821  TRUE)))
822  {
823  /* We failed, just return an error */
824  return Status;
825  }
826 
827  /* Loop the module list */
828  NextEntry = PsLoadedModuleList.Flink;
829  while (NextEntry != &PsLoadedModuleList)
830  {
831  /* Get the loader entry */
832  LdrEntry = CONTAINING_RECORD(NextEntry,
834  InLoadOrderLinks);
835 
836  /* Check if it matches */
837  if (RtlPrefixUnicodeString(&ForwarderName,
838  &LdrEntry->BaseDllName,
839  TRUE))
840  {
841  /* Get the forwarder export directory */
842  ForwardExportDirectory =
844  TRUE,
846  &ForwardExportSize);
847  if (!ForwardExportDirectory) break;
848 
849  /* Allocate a name entry */
850  ForwardLength = strlen(DllName.Buffer + DllName.Length) +
851  sizeof(ANSI_NULL);
852  ForwardName = ExAllocatePoolWithTag(PagedPool,
853  sizeof(*ForwardName) +
854  ForwardLength,
855  TAG_LDR_WSTR);
856  if (!ForwardName) break;
857 
858  /* Copy the data */
859  RtlCopyMemory(&ForwardName->Name[0],
860  DllName.Buffer + DllName.Length,
861  ForwardLength);
862  ForwardName->Hint = 0;
863 
864  /* Set the new address */
865  ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
866 
867  /* Snap the forwarder */
868  Status = MiSnapThunk(LdrEntry->DllBase,
869  ImageBase,
870  &ForwardThunk,
871  &ForwardThunk,
872  ForwardExportDirectory,
873  ForwardExportSize,
874  TRUE,
875  &MissingForwarder);
876 
877  /* Free the forwarder name and set the thunk */
878  ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
879  Address->u1 = ForwardThunk.u1;
880  break;
881  }
882 
883  /* Go to the next entry */
884  NextEntry = NextEntry->Flink;
885  }
886 
887  /* Free the name */
888  RtlFreeUnicodeString(&ForwarderName);
889  }
890  }
891 
892  /* Return status */
893  return Status;
894 }
895 
896 NTSTATUS
897 NTAPI
899 {
900  PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;
901  PVOID BaseAddress = LdrEntry->DllBase;
903  STRING TempName;
904  BOOLEAN HadEntry = FALSE;
905 
906  /* Acquire the loader lock */
910  KernelMode,
911  FALSE,
912  NULL);
913 
914  /* Check if this driver was loaded at boot and didn't get imports parsed */
915  if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) goto Done;
916 
917  /* We should still be alive */
918  ASSERT(LdrEntry->LoadCount != 0);
919  LdrEntry->LoadCount--;
920 
921  /* Check if we're still loaded */
922  if (LdrEntry->LoadCount) goto Done;
923 
924  /* We should cleanup... are symbols loaded */
925  if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)
926  {
927  /* Create the ANSI name */
929  &LdrEntry->BaseDllName,
930  TRUE);
931  if (NT_SUCCESS(Status))
932  {
933  /* Unload the symbols */
934  DbgUnLoadImageSymbols(&TempName,
935  BaseAddress,
937  RtlFreeAnsiString(&TempName);
938  }
939  }
940 
941  /* FIXME: Free the driver */
942  DPRINT1("Leaking driver: %wZ\n", &LdrEntry->BaseDllName);
943  //MmFreeSection(LdrEntry->DllBase);
944 
945  /* Check if we're linked in */
946  if (LdrEntry->InLoadOrderLinks.Flink)
947  {
948  /* Remove us */
949  MiProcessLoaderEntry(LdrEntry, FALSE);
950  HadEntry = TRUE;
951  }
952 
953  /* Dereference and clear the imports */
955  MiClearImports(LdrEntry);
956 
957  /* Check if the entry needs to go away */
958  if (HadEntry)
959  {
960  /* Check if it had a name */
961  if (LdrEntry->FullDllName.Buffer)
962  {
963  /* Free it */
965  }
966 
967  /* Check if we had a section */
968  if (LdrEntry->SectionPointer)
969  {
970  /* Dereference it */
972  }
973 
974  /* Free the entry */
976  }
977 
978  /* Release the system lock and return */
979 Done:
982  return STATUS_SUCCESS;
983 }
984 
985 NTSTATUS
986 NTAPI
988  IN PUNICODE_STRING ImageFileDirectory,
989  IN PUNICODE_STRING NamePrefix OPTIONAL,
990  OUT PCHAR *MissingApi,
991  OUT PWCHAR *MissingDriver,
992  OUT PLOAD_IMPORTS *LoadImports)
993 {
994  static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\");
995  PCHAR MissingApiBuffer = *MissingApi, ImportName;
996  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
997  ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
998  PLOAD_IMPORTS LoadedImports, NewImports;
999  ULONG GdiLink, NormalLink, i;
1000  BOOLEAN ReferenceNeeded, Loaded;
1001  ANSI_STRING TempString;
1002  UNICODE_STRING NameString, DllName;
1003  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
1004  PVOID ImportBase, DllBase;
1005  PLIST_ENTRY NextEntry;
1006  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
1007  NTSTATUS Status;
1008  PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
1009  PAGED_CODE();
1010  DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
1011  __FUNCTION__, ImageBase, ImageFileDirectory);
1012 
1013  /* No name string buffer yet */
1014  NameString.Buffer = NULL;
1015 
1016  /* Assume no imports */
1017  *LoadImports = MM_SYSLDR_NO_IMPORTS;
1018 
1019  /* Get the import descriptor */
1020  ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
1021  TRUE,
1023  &ImportSize);
1024  if (!ImportDescriptor) return STATUS_SUCCESS;
1025 
1026  /* Loop all imports to count them */
1027  for (CurrentImport = ImportDescriptor;
1028  (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
1029  CurrentImport++)
1030  {
1031  /* One more */
1032  ImportCount++;
1033  }
1034 
1035  /* Make sure we have non-zero imports */
1036  if (ImportCount)
1037  {
1038  /* Calculate and allocate the list we'll need */
1039  LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1040  LoadedImports = ExAllocatePoolWithTag(PagedPool,
1041  LoadedImportsSize,
1042  TAG_LDR_IMPORTS);
1043  if (LoadedImports)
1044  {
1045  /* Zero it */
1046  RtlZeroMemory(LoadedImports, LoadedImportsSize);
1047  LoadedImports->Count = ImportCount;
1048  }
1049  }
1050  else
1051  {
1052  /* No table */
1053  LoadedImports = NULL;
1054  }
1055 
1056  /* Reset the import count and loop descriptors again */
1057  ImportCount = GdiLink = NormalLink = 0;
1058  while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
1059  {
1060  /* Get the name */
1061  ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
1062 
1063  /* Check if this is a GDI driver */
1064  GdiLink = GdiLink |
1065  !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
1066 
1067  /* We can also allow dxapi (for Windows compat, allow IRT and coverage) */
1068  NormalLink = NormalLink |
1069  ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
1070  (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
1071  (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
1072  (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
1073 
1074  /* Check if this is a valid GDI driver */
1075  if ((GdiLink) && (NormalLink))
1076  {
1077  /* It's not, it's importing stuff it shouldn't be! */
1079  goto Failure;
1080  }
1081 
1082  /* Check for user-mode printer or video card drivers, which don't belong */
1083  if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
1084  !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
1085  !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
1086  !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
1087  !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
1088  !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
1089  {
1090  /* This is not kernel code */
1092  goto Failure;
1093  }
1094 
1095  /* Check if this is a "core" import, which doesn't get referenced */
1096  if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
1097  !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
1098  !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
1099  {
1100  /* Don't reference this */
1101  ReferenceNeeded = FALSE;
1102  }
1103  else
1104  {
1105  /* Reference these modules */
1106  ReferenceNeeded = TRUE;
1107  }
1108 
1109  /* Now setup a unicode string for the import */
1110  RtlInitAnsiString(&TempString, ImportName);
1111  Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
1112  if (!NT_SUCCESS(Status))
1113  {
1114  /* Failed */
1115  goto Failure;
1116  }
1117 
1118  /* We don't support name prefixes yet */
1119  if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
1120 
1121  /* Remember that we haven't loaded the import at this point */
1122 CheckDllState:
1123  Loaded = FALSE;
1124  ImportBase = NULL;
1125 
1126  /* Loop the driver list */
1127  NextEntry = PsLoadedModuleList.Flink;
1128  while (NextEntry != &PsLoadedModuleList)
1129  {
1130  /* Get the loader entry and compare the name */
1131  LdrEntry = CONTAINING_RECORD(NextEntry,
1133  InLoadOrderLinks);
1134  if (RtlEqualUnicodeString(&NameString,
1135  &LdrEntry->BaseDllName,
1136  TRUE))
1137  {
1138  /* Get the base address */
1139  ImportBase = LdrEntry->DllBase;
1140 
1141  /* Check if we haven't loaded yet, and we need references */
1142  if (!(Loaded) && (ReferenceNeeded))
1143  {
1144  /* Make sure we're not already loading */
1145  if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1146  {
1147  /* Increase the load count */
1148  LdrEntry->LoadCount++;
1149  }
1150  }
1151 
1152  /* Done, break out */
1153  break;
1154  }
1155 
1156  /* Go to the next entry */
1157  NextEntry = NextEntry->Flink;
1158  }
1159 
1160  /* Check if we haven't loaded the import yet */
1161  if (!ImportBase)
1162  {
1163  /* Setup the import DLL name */
1164  DllName.MaximumLength = NameString.Length +
1165  ImageFileDirectory->Length +
1166  sizeof(UNICODE_NULL);
1168  DllName.MaximumLength,
1169  TAG_LDR_WSTR);
1170  if (!DllName.Buffer)
1171  {
1172  /* We're out of resources */
1174  goto Failure;
1175  }
1176 
1177  /* Add the import name to the base directory */
1178  RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1180  &NameString);
1181 
1182  /* Load the image */
1183  Status = MmLoadSystemImage(&DllName,
1184  NamePrefix,
1185  NULL,
1186  FALSE,
1187  (PVOID *)&DllEntry,
1188  &DllBase);
1189 
1190  /* win32k / GDI drivers can also import from system32 folder */
1192  (MI_IS_SESSION_ADDRESS(ImageBase) || 1)) // HACK
1193  {
1194  /* Free the old name buffer */
1196 
1197  /* Calculate size for a string the adds 'drivers\' */
1198  DllName.MaximumLength += DriversFolderName.Length;
1199 
1200  /* Allocate the new buffer */
1202  DllName.MaximumLength,
1203  TAG_LDR_WSTR);
1204  if (!DllName.Buffer)
1205  {
1206  /* We're out of resources */
1208  goto Failure;
1209  }
1210 
1211  /* Copy image directory and append 'drivers\' folder name */
1212  RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1213  RtlAppendUnicodeStringToString(&DllName, &DriversFolderName);
1214 
1215  /* Now add the import name */
1216  RtlAppendUnicodeStringToString(&DllName, &NameString);
1217 
1218  /* Try once again to load the image */
1219  Status = MmLoadSystemImage(&DllName,
1220  NamePrefix,
1221  NULL,
1222  FALSE,
1223  (PVOID *)&DllEntry,
1224  &DllBase);
1225  }
1226 
1227  if (!NT_SUCCESS(Status))
1228  {
1229  /* Fill out the information for the error */
1230  *MissingDriver = DllName.Buffer;
1231  *(PULONG)MissingDriver |= 1;
1232  *MissingApi = NULL;
1233 
1234  DPRINT1("Failed to load dependency: %wZ\n", &DllName);
1235 
1236  /* Don't free the name */
1237  DllName.Buffer = NULL;
1238 
1239  /* Cleanup and return */
1240  goto Failure;
1241  }
1242 
1243  /* We can free the DLL Name */
1245  DllName.Buffer = NULL;
1246 
1247  /* We're now loaded */
1248  Loaded = TRUE;
1249 
1250  /* Sanity check */
1251  ASSERT(DllBase == DllEntry->DllBase);
1252 
1253  /* Call the initialization routines */
1255  if (!NT_SUCCESS(Status))
1256  {
1257  /* We failed, unload the image */
1258  MmUnloadSystemImage(DllEntry);
1259  ERROR_DBGBREAK("MmCallDllInitialize failed with status 0x%x\n", Status);
1260  Loaded = FALSE;
1261  }
1262 
1263  /* Loop again to make sure that everything is OK */
1264  goto CheckDllState;
1265  }
1266 
1267  /* Check if we're support to reference this import */
1268  if ((ReferenceNeeded) && (LoadedImports))
1269  {
1270  /* Make sure we're not already loading */
1271  if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1272  {
1273  /* Add the entry */
1274  LoadedImports->Entry[ImportCount] = LdrEntry;
1275  ImportCount++;
1276  }
1277  }
1278 
1279  /* Free the import name */
1280  RtlFreeUnicodeString(&NameString);
1281 
1282  /* Set the missing driver name and get the export directory */
1283  *MissingDriver = LdrEntry->BaseDllName.Buffer;
1284  ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
1285  TRUE,
1287  &ExportSize);
1288  if (!ExportDirectory)
1289  {
1290  /* Cleanup and return */
1291  DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
1293  goto Failure;
1294  }
1295 
1296  /* Make sure we have an IAT */
1297  if (ImportDescriptor->OriginalFirstThunk)
1298  {
1299  /* Get the first thunks */
1300  OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
1301  ImportDescriptor->OriginalFirstThunk);
1302  FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
1303  ImportDescriptor->FirstThunk);
1304 
1305  /* Loop the IAT */
1306  while (OrigThunk->u1.AddressOfData)
1307  {
1308  /* Snap thunk */
1309  Status = MiSnapThunk(ImportBase,
1310  ImageBase,
1311  OrigThunk++,
1312  FirstThunk++,
1313  ExportDirectory,
1314  ExportSize,
1315  FALSE,
1316  MissingApi);
1317  if (!NT_SUCCESS(Status))
1318  {
1319  /* Cleanup and return */
1320  goto Failure;
1321  }
1322 
1323  /* Reset the buffer */
1324  *MissingApi = MissingApiBuffer;
1325  }
1326  }
1327 
1328  /* Go to the next import */
1329  ImportDescriptor++;
1330  }
1331 
1332  /* Check if we have an import list */
1333  if (LoadedImports)
1334  {
1335  /* Reset the count again, and loop entries */
1336  ImportCount = 0;
1337  for (i = 0; i < LoadedImports->Count; i++)
1338  {
1339  if (LoadedImports->Entry[i])
1340  {
1341  /* Got an entry, OR it with 1 in case it's the single entry */
1342  ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
1344  ImportCount++;
1345  }
1346  }
1347 
1348  /* Check if we had no imports */
1349  if (!ImportCount)
1350  {
1351  /* Free the list and set it to no imports */
1352  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1353  LoadedImports = MM_SYSLDR_NO_IMPORTS;
1354  }
1355  else if (ImportCount == 1)
1356  {
1357  /* Just one entry, we can free the table and only use our entry */
1358  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1359  LoadedImports = (PLOAD_IMPORTS)ImportEntry;
1360  }
1361  else if (ImportCount != LoadedImports->Count)
1362  {
1363  /* Allocate a new list */
1364  LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1365  NewImports = ExAllocatePoolWithTag(PagedPool,
1366  LoadedImportsSize,
1367  TAG_LDR_IMPORTS);
1368  if (NewImports)
1369  {
1370  /* Set count */
1371  NewImports->Count = 0;
1372 
1373  /* Loop all the imports */
1374  for (i = 0; i < LoadedImports->Count; i++)
1375  {
1376  /* Make sure it's valid */
1377  if (LoadedImports->Entry[i])
1378  {
1379  /* Copy it */
1380  NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
1381  NewImports->Count++;
1382  }
1383  }
1384 
1385  /* Free the old copy */
1386  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1387  LoadedImports = NewImports;
1388  }
1389  }
1390 
1391  /* Return the list */
1392  *LoadImports = LoadedImports;
1393  }
1394 
1395  /* Return success */
1396  return STATUS_SUCCESS;
1397 
1398 Failure:
1399 
1400  /* Cleanup and return */
1401  RtlFreeUnicodeString(&NameString);
1402 
1403  if (LoadedImports)
1404  {
1405  MiDereferenceImports(LoadedImports);
1406  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1407  }
1408 
1409  return Status;
1410 }
1411 
1412 VOID
1413 NTAPI
1415  IN PVOID InitEnd)
1416 {
1417  PMMPTE PointerPte;
1418  PFN_NUMBER PagesFreed;
1419 
1420  /* Get the start PTE */
1421  PointerPte = MiAddressToPte(InitStart);
1422  ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1423 
1424  /* Compute the number of pages we expect to free */
1425  PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1426 
1427  /* Try to actually free them */
1428  PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1429  PagesFreed,
1430  0,
1431  NULL);
1432 }
1433 
1434 CODE_SEG("INIT")
1435 VOID
1436 NTAPI
1438  OUT PVOID *EndVa)
1439 {
1440  ULONG Size, SectionCount, Alignment;
1441  PLDR_DATA_TABLE_ENTRY LdrEntry;
1442  ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1443  PLIST_ENTRY NextEntry;
1444  PIMAGE_NT_HEADERS NtHeader;
1445  PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1446  BOOLEAN InitFound;
1447  DBG_UNREFERENCED_LOCAL_VARIABLE(InitSection);
1448 
1449  /* So we don't free our own code yet */
1450  InitCode = (ULONG_PTR)&MiFindInitializationCode;
1451 
1452  /* Assume failure */
1453  *StartVa = NULL;
1454 
1455  /* Acquire the necessary locks while we loop the list */
1459  KernelMode,
1460  FALSE,
1461  NULL);
1463 
1464  /* Loop all loaded modules */
1465  NextEntry = PsLoadedModuleList.Flink;
1466  while (NextEntry != &PsLoadedModuleList)
1467  {
1468  /* Get the loader entry and its DLL base */
1469  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1470  DllBase = (ULONG_PTR)LdrEntry->DllBase;
1471 
1472  /* Only process boot loaded images. Other drivers are processed by
1473  MmFreeDriverInitialization */
1474  if (LdrEntry->Flags & LDRP_MM_LOADED)
1475  {
1476  /* Keep going */
1477  NextEntry = NextEntry->Flink;
1478  continue;
1479  }
1480 
1481  /* Get the NT header */
1482  NtHeader = RtlImageNtHeader((PVOID)DllBase);
1483  if (!NtHeader)
1484  {
1485  /* Keep going */
1486  NextEntry = NextEntry->Flink;
1487  continue;
1488  }
1489 
1490  /* Get the first section, the section count, and scan them all */
1491  Section = IMAGE_FIRST_SECTION(NtHeader);
1492  SectionCount = NtHeader->FileHeader.NumberOfSections;
1493  InitStart = 0;
1494  while (SectionCount > 0)
1495  {
1496  /* Assume failure */
1497  InitFound = FALSE;
1498 
1499  /* Is this the INIT section or a discardable section? */
1500  if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1502  {
1503  /* Remember this */
1504  InitFound = TRUE;
1505  InitSection = Section;
1506  }
1507 
1508  if (InitFound)
1509  {
1510  /* Pick the biggest size -- either raw or virtual */
1511  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1512 
1513  /* Read the section alignment */
1515 
1516  /* Get the start and end addresses */
1517  InitStart = DllBase + Section->VirtualAddress;
1518  InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1519 
1520  /* Align the addresses to PAGE_SIZE */
1521  InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1522  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1523 
1524  /* Have we reached the last section? */
1525  if (SectionCount == 1)
1526  {
1527  /* Remember this */
1528  LastSection = Section;
1529  }
1530  else
1531  {
1532  /* We have not, loop all the sections */
1533  LastSection = NULL;
1534  do
1535  {
1536  /* Keep going until we find a non-discardable section range */
1537  SectionCount--;
1538  Section++;
1540  {
1541  /* Discardable, so record it, then keep going */
1542  LastSection = Section;
1543  }
1544  else
1545  {
1546  /* Non-contigous discard flag, or no flag, break out */
1547  break;
1548  }
1549  }
1550  while (SectionCount > 1);
1551  }
1552 
1553  /* Have we found a discardable or init section? */
1554  if (LastSection)
1555  {
1556  /* Pick the biggest size -- either raw or virtual */
1557  Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1558 
1559  /* Use this as the end of the section address */
1560  InitEnd = DllBase + LastSection->VirtualAddress + Size;
1561 
1562  /* Have we reached the last section yet? */
1563  if (SectionCount != 1)
1564  {
1565  /* Then align this accross the session boundary */
1566  InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1567  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1568  }
1569  }
1570 
1571  /* Make sure we don't let the init section go past the image */
1572  ImageEnd = DllBase + LdrEntry->SizeOfImage;
1573  if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1574 
1575  /* Make sure we have a valid, non-zero init section */
1576  if (InitStart < InitEnd)
1577  {
1578  /* Make sure we are not within this code itself */
1579  if ((InitCode >= InitStart) && (InitCode < InitEnd))
1580  {
1581  /* Return it, we can't free ourselves now */
1582  ASSERT(*StartVa == 0);
1583  *StartVa = (PVOID)InitStart;
1584  *EndVa = (PVOID)InitEnd;
1585  }
1586  else
1587  {
1588  /* This isn't us -- go ahead and free it */
1589  ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1590  DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1591  (PVOID)InitStart,
1592  (PVOID)InitEnd,
1593  &LdrEntry->BaseDllName,
1594  LdrEntry->DllBase,
1595  InitSection->Name);
1596  MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1597  }
1598  }
1599  }
1600 
1601  /* Move to the next section */
1602  SectionCount--;
1603  Section++;
1604  }
1605 
1606  /* Move to the next module */
1607  NextEntry = NextEntry->Flink;
1608  }
1609 
1610  /* Release the locks and return */
1614 }
1615 
1616 /*
1617  * Note: This function assumes that all discardable sections are at the end of
1618  * the PE file. It searches backwards until it finds the non-discardable section
1619  */
1620 VOID
1621 NTAPI
1623 {
1624  PMMPTE StartPte, EndPte;
1625  PFN_NUMBER PageCount;
1626  PVOID DllBase;
1627  ULONG i;
1628  PIMAGE_NT_HEADERS NtHeader;
1629  PIMAGE_SECTION_HEADER Section, DiscardSection;
1630 
1631  /* Get the base address and the page count */
1632  DllBase = LdrEntry->DllBase;
1633  PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1634 
1635  /* Get the last PTE in this image */
1636  EndPte = MiAddressToPte(DllBase) + PageCount;
1637 
1638  /* Get the NT header */
1639  NtHeader = RtlImageNtHeader(DllBase);
1640  if (!NtHeader) return;
1641 
1642  /* Get the last section and loop each section backwards */
1643  Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1644  DiscardSection = NULL;
1645  for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1646  {
1647  /* Go back a section and check if it's discardable */
1648  Section--;
1650  {
1651  /* It is, select it for freeing */
1652  DiscardSection = Section;
1653  }
1654  else
1655  {
1656  /* No more discardable sections exist, bail out */
1657  break;
1658  }
1659  }
1660 
1661  /* Bail out if there's nothing to free */
1662  if (!DiscardSection) return;
1663 
1664  /* Push the DLL base to the first disacrable section, and get its PTE */
1665  DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1666  ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1667  StartPte = MiAddressToPte(DllBase);
1668 
1669  /* Check how many pages to free total */
1670  PageCount = (PFN_NUMBER)(EndPte - StartPte);
1671  if (!PageCount) return;
1672 
1673  /* Delete this many PTEs */
1674  MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1675 }
1676 
1677 CODE_SEG("INIT")
1678 VOID
1679 NTAPI
1681 {
1682  PLIST_ENTRY NextEntry;
1683  ULONG i = 0;
1684  PIMAGE_NT_HEADERS NtHeader;
1685  PLDR_DATA_TABLE_ENTRY LdrEntry;
1686  PIMAGE_FILE_HEADER FileHeader;
1687  BOOLEAN ValidRelocs;
1688  PIMAGE_DATA_DIRECTORY DataDirectory;
1689  PVOID DllBase, NewImageAddress;
1690  NTSTATUS Status;
1691  PMMPTE PointerPte, StartPte, LastPte;
1692  PFN_COUNT PteCount;
1693  PMMPFN Pfn1;
1694  MMPTE TempPte, OldPte;
1695 
1696  /* Loop driver list */
1697  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1698  NextEntry != &LoaderBlock->LoadOrderListHead;
1699  NextEntry = NextEntry->Flink)
1700  {
1701  /* Get the loader entry and NT header */
1702  LdrEntry = CONTAINING_RECORD(NextEntry,
1704  InLoadOrderLinks);
1705  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1706 
1707  /* Debug info */
1708  DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1709  LdrEntry->DllBase,
1710  (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1711  &LdrEntry->FullDllName);
1712 
1713  /* Get the first PTE and the number of PTEs we'll need */
1714  PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1715  PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1716  LastPte = StartPte + PteCount;
1717 
1718 #if MI_TRACE_PFNS
1719  /* Loop the PTEs */
1720  while (PointerPte < LastPte)
1721  {
1722  ULONG len;
1723  ASSERT(PointerPte->u.Hard.Valid == 1);
1724  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1725  len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1726  snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1727  PointerPte++;
1728  }
1729 #endif
1730  /* Skip kernel and HAL */
1731  /* ROS HACK: Skip BOOTVID/KDCOM too */
1732  i++;
1733  if (i <= 4) continue;
1734 
1735  /* Skip non-drivers */
1736  if (!NtHeader) continue;
1737 
1738  /* Get the file header and make sure we can relocate */
1739  FileHeader = &NtHeader->FileHeader;
1740  if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1741  if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1743 
1744  /* Everything made sense until now, check the relocation section too */
1745  DataDirectory = &NtHeader->OptionalHeader.
1746  DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1747  if (!DataDirectory->VirtualAddress)
1748  {
1749  /* We don't really have relocations */
1750  ValidRelocs = FALSE;
1751  }
1752  else
1753  {
1754  /* Make sure the size is valid */
1755  if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1756  LdrEntry->SizeOfImage)
1757  {
1758  /* They're not, skip */
1759  continue;
1760  }
1761 
1762  /* We have relocations */
1763  ValidRelocs = TRUE;
1764  }
1765 
1766  /* Remember the original address */
1767  DllBase = LdrEntry->DllBase;
1768 
1769  /* Loop the PTEs */
1770  PointerPte = StartPte;
1771  while (PointerPte < LastPte)
1772  {
1773  /* Mark the page modified in the PFN database */
1774  ASSERT(PointerPte->u.Hard.Valid == 1);
1775  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1776  ASSERT(Pfn1->u3.e1.Rom == 0);
1777  Pfn1->u3.e1.Modified = TRUE;
1778 
1779  /* Next */
1780  PointerPte++;
1781  }
1782 
1783  /* Now reserve system PTEs for the image */
1784  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1785  if (!PointerPte)
1786  {
1787  /* Shouldn't happen */
1788  ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1789  return;
1790  }
1791 
1792  /* This is the new virtual address for the module */
1793  LastPte = PointerPte + PteCount;
1794  NewImageAddress = MiPteToAddress(PointerPte);
1795 
1796  /* Sanity check */
1797  DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1799 
1800  /* Loop the new driver PTEs */
1802  while (PointerPte < LastPte)
1803  {
1804  /* Copy the old data */
1805  OldPte = *StartPte;
1806  ASSERT(OldPte.u.Hard.Valid == 1);
1807 
1808  /* Set page number from the loader's memory */
1809  TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber;
1810 
1811  /* Write it */
1812  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1813 
1814  /* Move on */
1815  PointerPte++;
1816  StartPte++;
1817  }
1818 
1819  /* Update position */
1820  PointerPte -= PteCount;
1821 
1822  /* Sanity check */
1823  ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1824 
1825  /* Set the image base to the address where the loader put it */
1826  NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1827 
1828  /* Check if we had relocations */
1829  if (ValidRelocs)
1830  {
1831  /* Relocate the image */
1832  Status = LdrRelocateImageWithBias(NewImageAddress,
1833  0,
1834  "SYSLDR",
1838  if (!NT_SUCCESS(Status))
1839  {
1840  /* This shouldn't happen */
1841  ERROR_FATAL("Relocations failed!\n");
1842  return;
1843  }
1844  }
1845 
1846  /* Update the loader entry */
1847  LdrEntry->DllBase = NewImageAddress;
1848 
1849  /* Update the thunks */
1850  DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1851  MiUpdateThunks(LoaderBlock,
1852  DllBase,
1853  NewImageAddress,
1854  LdrEntry->SizeOfImage);
1855 
1856  /* Update the loader entry */
1857  LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1858  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1860  LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1861 
1862  /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1863  }
1864 }
1865 
1866 CODE_SEG("INIT")
1867 NTSTATUS
1868 NTAPI
1870 {
1871  PLIST_ENTRY NextEntry, NextEntry2;
1872  PLDR_DATA_TABLE_ENTRY LdrEntry, KernelEntry, HalEntry, LdrEntry2, LastEntry;
1873  PLDR_DATA_TABLE_ENTRY* EntryArray;
1874  UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
1876  PLOAD_IMPORTS LoadedImports;
1877  ULONG LoadedImportsSize, ImportSize;
1878  PULONG_PTR ImageThunk;
1879  ULONG_PTR DllBase, DllEnd;
1880  ULONG Modules = 0, i, j = 0;
1881  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
1882 
1883  /* Initialize variables */
1884  KernelEntry = HalEntry = LastEntry = NULL;
1885 
1886  /* Loop the loaded module list... we are early enough that no lock is needed */
1887  NextEntry = PsLoadedModuleList.Flink;
1888  while (NextEntry != &PsLoadedModuleList)
1889  {
1890  /* Get the entry */
1891  LdrEntry = CONTAINING_RECORD(NextEntry,
1893  InLoadOrderLinks);
1894 
1895  /* Check if it's the kernel or HAL */
1896  if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
1897  {
1898  /* Found it */
1899  KernelEntry = LdrEntry;
1900  }
1901  else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
1902  {
1903  /* Found it */
1904  HalEntry = LdrEntry;
1905  }
1906 
1907  /* Check if this is a driver DLL */
1908  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1909  {
1910  /* Check if this is the HAL or kernel */
1911  if ((LdrEntry == HalEntry) || (LdrEntry == KernelEntry))
1912  {
1913  /* Add a reference */
1914  LdrEntry->LoadCount = 1;
1915  }
1916  else
1917  {
1918  /* No referencing needed */
1919  LdrEntry->LoadCount = 0;
1920  }
1921  }
1922  else
1923  {
1924  /* Add a reference for all other modules as well */
1925  LdrEntry->LoadCount = 1;
1926  }
1927 
1928  /* Remember this came from the loader */
1930 
1931  /* Keep looping */
1932  NextEntry = NextEntry->Flink;
1933  Modules++;
1934  }
1935 
1936  /* We must have at least found the kernel and HAL */
1937  if (!(HalEntry) || (!KernelEntry)) return STATUS_NOT_FOUND;
1938 
1939  /* Allocate the list */
1940  EntryArray = ExAllocatePoolWithTag(PagedPool, Modules * sizeof(PVOID), TAG_LDR_IMPORTS);
1941  if (!EntryArray) return STATUS_INSUFFICIENT_RESOURCES;
1942 
1943  /* Loop the loaded module list again */
1944  NextEntry = PsLoadedModuleList.Flink;
1945  while (NextEntry != &PsLoadedModuleList)
1946  {
1947  /* Get the entry */
1948  LdrEntry = CONTAINING_RECORD(NextEntry,
1950  InLoadOrderLinks);
1951 #ifdef _WORKING_LOADER_
1952  /* Get its imports */
1953  ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1954  TRUE,
1956  &ImportSize);
1957  if (!ImageThunk)
1958 #else
1959  /* Get its imports */
1960  ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1961  TRUE,
1963  &ImportSize);
1964  if (!ImportDescriptor)
1965 #endif
1966  {
1967  /* None present */
1968  LdrEntry->LoadedImports = MM_SYSLDR_NO_IMPORTS;
1969  NextEntry = NextEntry->Flink;
1970  continue;
1971  }
1972 
1973  /* Clear the list and count the number of IAT thunks */
1974  RtlZeroMemory(EntryArray, Modules * sizeof(PVOID));
1975 #ifdef _WORKING_LOADER_
1976  ImportSize /= sizeof(ULONG_PTR);
1977 
1978  /* Scan the thunks */
1979  for (i = 0, DllBase = 0, DllEnd = 0; i < ImportSize; i++, ImageThunk++)
1980 #else
1981  DllBase = DllEnd = i = 0;
1982  while ((ImportDescriptor->Name) &&
1983  (ImportDescriptor->OriginalFirstThunk))
1984  {
1985  /* Get the image thunk */
1986  ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
1987  ImportDescriptor->FirstThunk);
1988  while (*ImageThunk)
1989 #endif
1990  {
1991  /* Do we already have an address? */
1992  if (DllBase)
1993  {
1994  /* Is the thunk in the same address? */
1995  if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
1996  {
1997  /* Skip it, we already have a reference for it */
1998  ASSERT(EntryArray[j]);
1999  ImageThunk++;
2000  continue;
2001  }
2002  }
2003 
2004  /* Loop the loaded module list to locate this address owner */
2005  j = 0;
2006  NextEntry2 = PsLoadedModuleList.Flink;
2007  while (NextEntry2 != &PsLoadedModuleList)
2008  {
2009  /* Get the entry */
2010  LdrEntry2 = CONTAINING_RECORD(NextEntry2,
2012  InLoadOrderLinks);
2013 
2014  /* Get the address range for this module */
2015  DllBase = (ULONG_PTR)LdrEntry2->DllBase;
2016  DllEnd = DllBase + LdrEntry2->SizeOfImage;
2017 
2018  /* Check if this IAT entry matches it */
2019  if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
2020  {
2021  /* Save it */
2022  //DPRINT1("Found imported dll: %wZ\n", &LdrEntry2->BaseDllName);
2023  EntryArray[j] = LdrEntry2;
2024  break;
2025  }
2026 
2027  /* Keep searching */
2028  NextEntry2 = NextEntry2->Flink;
2029  j++;
2030  }
2031 
2032  /* Do we have a thunk outside the range? */
2033  if ((*ImageThunk < DllBase) || (*ImageThunk >= DllEnd))
2034  {
2035  /* Could be 0... */
2036  if (*ImageThunk)
2037  {
2038  /* Should not be happening */
2039  ERROR_FATAL("Broken IAT entry for %p at %p (%lx)\n",
2040  LdrEntry, ImageThunk, *ImageThunk);
2041  }
2042 
2043  /* Reset if we hit this */
2044  DllBase = 0;
2045  }
2046 #ifndef _WORKING_LOADER_
2047  ImageThunk++;
2048  }
2049 
2050  i++;
2051  ImportDescriptor++;
2052 #endif
2053  }
2054 
2055  /* Now scan how many imports we really have */
2056  for (i = 0, ImportSize = 0; i < Modules; i++)
2057  {
2058  /* Skip HAL and kernel */
2059  if ((EntryArray[i]) &&
2060  (EntryArray[i] != HalEntry) &&
2061  (EntryArray[i] != KernelEntry))
2062  {
2063  /* A valid reference */
2064  LastEntry = EntryArray[i];
2065  ImportSize++;
2066  }
2067  }
2068 
2069  /* Do we have any imports after all? */
2070  if (!ImportSize)
2071  {
2072  /* No */
2073  LdrEntry->LoadedImports = MM_SYSLDR_NO_IMPORTS;
2074  }
2075  else if (ImportSize == 1)
2076  {
2077  /* A single entry import */
2078  LdrEntry->LoadedImports = (PVOID)((ULONG_PTR)LastEntry | MM_SYSLDR_SINGLE_ENTRY);
2079  LastEntry->LoadCount++;
2080  }
2081  else
2082  {
2083  /* We need an import table */
2084  LoadedImportsSize = ImportSize * sizeof(PVOID) + sizeof(SIZE_T);
2085  LoadedImports = ExAllocatePoolWithTag(PagedPool,
2086  LoadedImportsSize,
2087  TAG_LDR_IMPORTS);
2088  ASSERT(LoadedImports);
2089 
2090  /* Save the count */
2091  LoadedImports->Count = ImportSize;
2092 
2093  /* Now copy all imports */
2094  for (i = 0, j = 0; i < Modules; i++)
2095  {
2096  /* Skip HAL and kernel */
2097  if ((EntryArray[i]) &&
2098  (EntryArray[i] != HalEntry) &&
2099  (EntryArray[i] != KernelEntry))
2100  {
2101  /* A valid reference */
2102  //DPRINT1("Found valid entry: %p\n", EntryArray[i]);
2103  LoadedImports->Entry[j] = EntryArray[i];
2104  EntryArray[i]->LoadCount++;
2105  j++;
2106  }
2107  }
2108 
2109  /* Should had as many entries as we expected */
2110  ASSERT(j == ImportSize);
2111  LdrEntry->LoadedImports = LoadedImports;
2112  }
2113 
2114  /* Next */
2115  NextEntry = NextEntry->Flink;
2116  }
2117 
2118  /* Free the initial array */
2119  ExFreePoolWithTag(EntryArray, TAG_LDR_IMPORTS);
2120 
2121  /* FIXME: Might not need to keep the HAL/Kernel imports around */
2122 
2123  /* Kernel and HAL are loaded at boot */
2124  KernelEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
2126 
2127  /* All worked well */
2128  return STATUS_SUCCESS;
2129 }
2130 
2131 CODE_SEG("INIT")
2132 VOID
2133 NTAPI
2135 {
2136  ULONG_PTR DllBase;
2137  PIMAGE_NT_HEADERS NtHeaders;
2138  PIMAGE_SECTION_HEADER SectionHeader;
2139  ULONG Sections, Size;
2140 
2141  /* Get the kernel section header */
2142  DllBase = (ULONG_PTR)LdrEntry->DllBase;
2143  NtHeaders = RtlImageNtHeader((PVOID)DllBase);
2144  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
2145 
2146  /* Loop all the sections */
2147  for (Sections = NtHeaders->FileHeader.NumberOfSections;
2148  Sections > 0; --Sections, ++SectionHeader)
2149  {
2150  /* Grab the size of the section */
2151  Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
2152 
2153  /* Check for .RSRC section */
2154  if (*(PULONG)SectionHeader->Name == 'rsr.')
2155  {
2156  /* Remember the PTEs so we can modify them later */
2158  SectionHeader->VirtualAddress);
2160  SectionHeader->VirtualAddress + Size));
2161  }
2162  else if (*(PULONG)SectionHeader->Name == 'LOOP')
2163  {
2164  /* POOLCODE vs. POOLMI */
2165  if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
2166  {
2167  /* Found Ex* Pool code */
2168  ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2170  }
2171  else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
2172  {
2173  /* Found Mm* Pool code */
2174  MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2176  }
2177  }
2178  else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
2179  (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
2180  {
2181  /* Found MISYSPTE (Mm System PTE code) */
2182  MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
2184  }
2185  }
2186 }
2187 
2188 CODE_SEG("INIT")
2189 BOOLEAN
2190 NTAPI
2192 {
2193  PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2194  PLIST_ENTRY ListHead, NextEntry;
2195  ULONG EntrySize;
2196 
2197  /* Setup the loaded module list and locks */
2201 
2202  /* Get loop variables and the kernel entry */
2203  ListHead = &LoaderBlock->LoadOrderListHead;
2204  NextEntry = ListHead->Flink;
2205  LdrEntry = CONTAINING_RECORD(NextEntry,
2207  InLoadOrderLinks);
2208  PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2209 
2210  /* Locate resource section, pool code, and system pte code */
2211  MiLocateKernelSections(LdrEntry);
2212 
2213  /* Loop the loader block */
2214  while (NextEntry != ListHead)
2215  {
2216  /* Get the loader entry */
2217  LdrEntry = CONTAINING_RECORD(NextEntry,
2219  InLoadOrderLinks);
2220 
2221  /* FIXME: ROS HACK. Make sure this is a driver */
2222  if (!RtlImageNtHeader(LdrEntry->DllBase))
2223  {
2224  /* Skip this entry */
2225  NextEntry = NextEntry->Flink;
2226  continue;
2227  }
2228 
2229  /* Calculate the size we'll need and allocate a copy */
2230  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
2231  LdrEntry->BaseDllName.MaximumLength +
2232  sizeof(UNICODE_NULL);
2234  if (!NewEntry) return FALSE;
2235 
2236  /* Copy the entry over */
2237  *NewEntry = *LdrEntry;
2238 
2239  /* Allocate the name */
2240  NewEntry->FullDllName.Buffer =
2242  LdrEntry->FullDllName.MaximumLength +
2243  sizeof(UNICODE_NULL),
2244  TAG_LDR_WSTR);
2245  if (!NewEntry->FullDllName.Buffer)
2246  {
2248  return FALSE;
2249  }
2250 
2251  /* Set the base name */
2252  NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2253 
2254  /* Copy the full and base name */
2255  RtlCopyMemory(NewEntry->FullDllName.Buffer,
2256  LdrEntry->FullDllName.Buffer,
2257  LdrEntry->FullDllName.MaximumLength);
2258  RtlCopyMemory(NewEntry->BaseDllName.Buffer,
2259  LdrEntry->BaseDllName.Buffer,
2260  LdrEntry->BaseDllName.MaximumLength);
2261 
2262  /* Null-terminate the base name */
2263  NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2264  sizeof(WCHAR)] = UNICODE_NULL;
2265 
2266  /* Insert the entry into the list */
2268  NextEntry = NextEntry->Flink;
2269  }
2270 
2271  /* Build the import lists for the boot drivers */
2273 
2274  /* We're done */
2275  return TRUE;
2276 }
2277 
2278 BOOLEAN
2279 NTAPI
2281 {
2282  PMMPTE PointerPte;
2283  MMPTE TempPte;
2284 
2285  /* Don't do anything if the resource section is already writable */
2287  return FALSE;
2288 
2289  /* If the resource section is physical, we cannot change its protection */
2291  return FALSE;
2292 
2293  /* Loop the PTEs */
2294  for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2295  {
2296  /* Read the PTE */
2297  TempPte = *PointerPte;
2298 
2299  /* Update the protection */
2300  MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2301  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2302  }
2303 
2304  /* Only flush the current processor's TLB */
2305  KeFlushCurrentTb();
2306  return TRUE;
2307 }
2308 
2309 VOID
2310 NTAPI
2312 {
2313  /* Don't do anything if the resource section is already writable */
2315  return;
2316 
2317  /* If the resource section is physical, we cannot change its protection */
2319  return;
2320 
2322  {
2323  /*
2324  * Invalidate the cached resource section PTEs
2325  * so as to not change its protection again later.
2326  */
2329  }
2330 }
2331 
2332 LOGICAL
2333 NTAPI
2335  IN OUT PVOID *ImageBaseAddress,
2336  IN PUNICODE_STRING BaseImageName,
2337  IN BOOLEAN BootDriver)
2338 {
2339  PLIST_ENTRY NextEntry;
2340  BOOLEAN DriverFound = FALSE;
2341  PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2343  ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2344 
2345 #ifdef _X86_
2346  if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2347  if (!(__readcr4() & CR4_PSE)) return FALSE;
2348 #endif
2349 
2350  /* Make sure there's enough system PTEs for a large page driver */
2352  {
2353  return FALSE;
2354  }
2355 
2356  /* This happens if the registry key had a "*" (wildcard) in it */
2357  if (MiLargePageAllDrivers == 0)
2358  {
2359  /* It didn't, so scan the list */
2360  NextEntry = MiLargePageDriverList.Flink;
2361  while (NextEntry != &MiLargePageDriverList)
2362  {
2363  /* Check if the driver name matches */
2364  LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2366  Links);
2367  if (RtlEqualUnicodeString(BaseImageName,
2368  &LargePageDriverEntry->BaseName,
2369  TRUE))
2370  {
2371  /* Enable large pages for this driver */
2372  DriverFound = TRUE;
2373  break;
2374  }
2375 
2376  /* Keep trying */
2377  NextEntry = NextEntry->Flink;
2378  }
2379 
2380  /* If we didn't find the driver, it doesn't need large pages */
2381  if (DriverFound == FALSE) return FALSE;
2382  }
2383 
2384  /* Nothing to do yet */
2385  DPRINT1("Large pages not supported!\n");
2386  return FALSE;
2387 }
2388 
2389 VOID
2390 NTAPI
2392  _In_ PMMPTE FirstPte,
2393  _In_ PMMPTE LastPte,
2394  _In_ ULONG Protection)
2395 {
2396  PMMPTE PointerPte;
2397  MMPTE TempPte;
2398 
2399  /* Loop the PTEs */
2400  for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2401  {
2402  /* Read the PTE */
2403  TempPte = *PointerPte;
2404 
2405  /* Make sure it's valid */
2406  if (TempPte.u.Hard.Valid != 1)
2407  {
2408  DPRINT1("CORE-16449: FirstPte=%p, LastPte=%p, Protection=%lx\n", FirstPte, LastPte, Protection);
2409  DPRINT1("CORE-16449: PointerPte=%p, TempPte=%lx\n", PointerPte, TempPte.u.Long);
2410  DPRINT1("CORE-16449: Please issue the 'mod' and 'bt' (KDBG) or 'lm' and 'kp' (WinDbg) commands. Then report this in Jira.\n");
2411  ASSERT(TempPte.u.Hard.Valid == 1);
2412  break;
2413  }
2414 
2415  /* Update the protection */
2416  TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2417 #if _MI_HAS_NO_EXECUTE
2418  TempPte.u.Hard.NoExecute = !BooleanFlagOn(Protection, IMAGE_SCN_MEM_EXECUTE);
2419 #endif
2420 
2421  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2422  }
2423 
2424  /* Flush it all */
2426 }
2427 
2428 VOID
2429 NTAPI
2431  _In_ PVOID ImageBase)
2432 {
2433  PIMAGE_NT_HEADERS NtHeaders;
2434  PIMAGE_SECTION_HEADER SectionHeaders, Section;
2435  ULONG i;
2436  PVOID SectionBase, SectionEnd;
2437  ULONG SectionSize;
2438  ULONG Protection;
2439  PMMPTE FirstPte, LastPte;
2440 
2441  /* Check if the registry setting is on or not */
2443  {
2444  /* Ignore section protection */
2445  return;
2446  }
2447 
2448  /* Large page mapped images are not supported */
2449  NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2450 
2451  /* Session images are not yet supported */
2452  NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2453 
2454  /* Get the NT headers */
2455  NtHeaders = RtlImageNtHeader(ImageBase);
2456  if (NtHeaders == NULL)
2457  {
2458  DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2459  return;
2460  }
2461 
2462  /* Don't touch NT4 drivers */
2463  if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2464  (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2465  {
2466  DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2467  return;
2468  }
2469 
2470  /* Get the section headers */
2471  SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2472 
2473  /* Get the base address of the first section */
2474  SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2475 
2476  /* Start protecting the image header as R/W */
2477  FirstPte = MiAddressToPte(ImageBase);
2478  LastPte = MiAddressToPte(SectionBase) - 1;
2479  Protection = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
2480  if (LastPte >= FirstPte)
2481  {
2482  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2483  }
2484 
2485  /* Loop the sections */
2486  for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2487  {
2488  /* Get the section base address and size */
2489  Section = &SectionHeaders[i];
2490  SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2491  SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2492 
2493  /* Get the first PTE of this section */
2494  FirstPte = MiAddressToPte(SectionBase);
2495 
2496  /* Check for overlap with the previous range */
2497  if (FirstPte == LastPte)
2498  {
2499  /* Combine the old and new protection by ORing them */
2500  Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2501 
2502  /* Update the protection for this PTE */
2503  MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2504 
2505  /* Skip this PTE */
2506  FirstPte++;
2507  }
2508 
2509  /* There can not be gaps! */
2510  NT_ASSERT(FirstPte == (LastPte + 1));
2511 
2512  /* Get the end of the section and the last PTE */
2513  SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2514  NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2515  LastPte = MiAddressToPte(SectionEnd);
2516 
2517  /* If there are no more pages (after an overlap), skip this section */
2518  if (LastPte < FirstPte)
2519  {
2520  NT_ASSERT(FirstPte == (LastPte + 1));
2521  continue;
2522  }
2523 
2524  /* Get the section protection */
2525  Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2526 
2527  /* Update the protection for this section */
2528  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2529  }
2530 
2531  /* Image should end with the last section */
2532  if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2533  Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2534  {
2535  DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2536  ImageBase,
2537  NtHeaders->OptionalHeader.SizeOfImage,
2538  i,
2539  Section->VirtualAddress,
2540  Section->SizeOfRawData,
2541  Section->Misc.VirtualSize);
2542  }
2543 }
2544 
2545 VOID
2546 NTAPI
2548  IN PMMPTE LastPte)
2549 {
2550 #ifdef ENABLE_MISETPAGINGOFDRIVER
2551  PVOID ImageBase;
2552  PETHREAD CurrentThread = PsGetCurrentThread();
2553  PFN_COUNT PageCount = 0;
2554  PFN_NUMBER PageFrameIndex;
2555  PMMPFN Pfn1;
2556 #endif // ENABLE_MISETPAGINGOFDRIVER
2557 
2558  PAGED_CODE();
2559 
2560 #ifndef ENABLE_MISETPAGINGOFDRIVER
2561  /* The page fault handler is broken and doesn't page back in! */
2562  DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2563 #else // ENABLE_MISETPAGINGOFDRIVER
2564  /* Get the driver's base address */
2565  ImageBase = MiPteToAddress(PointerPte);
2566  ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(ImageBase) == FALSE);
2567 
2568  /* If this is a large page, it's stuck in physical memory */
2569  if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2570 
2571  /* Lock the working set */
2572  MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2573 
2574  /* Loop the PTEs */
2575  while (PointerPte <= LastPte)
2576  {
2577  /* Check for valid PTE */
2578  if (PointerPte->u.Hard.Valid == 1)
2579  {
2580  PageFrameIndex = PFN_FROM_PTE(PointerPte);
2581  Pfn1 = MiGetPfnEntry(PageFrameIndex);
2582  ASSERT(Pfn1->u2.ShareCount == 1);
2583 
2584  /* No working sets in ReactOS yet */
2585  PageCount++;
2586  }
2587 
2588  ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2589  PointerPte++;
2590  }
2591 
2592  /* Release the working set */
2593  MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2594 
2595  /* Do we have any driver pages? */
2596  if (PageCount)
2597  {
2598  /* Update counters */
2600  }
2601 #endif // ENABLE_MISETPAGINGOFDRIVER
2602 }
2603 
2604 VOID
2605 NTAPI
2607 {
2608  ULONG_PTR ImageBase;
2609  PIMAGE_NT_HEADERS NtHeaders;
2610  ULONG Sections, Alignment, Size;
2611  PIMAGE_SECTION_HEADER Section;
2612  PMMPTE PointerPte = NULL, LastPte = NULL;
2613  if (MmDisablePagingExecutive) return;
2614 
2615  /* Get the driver base address and its NT header */
2616  ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2617  NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2618  if (!NtHeaders) return;
2619 
2620  /* Get the sections and their alignment */
2621  Sections = NtHeaders->FileHeader.NumberOfSections;
2622  Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2623 
2624  /* Loop each section */
2625  Section = IMAGE_FIRST_SECTION(NtHeaders);
2626  while (Sections)
2627  {
2628  /* Find PAGE or .edata */
2629  if ((*(PULONG)Section->Name == 'EGAP') ||
2630  (*(PULONG)Section->Name == 'ade.'))
2631  {
2632  /* Had we already done some work? */
2633  if (!PointerPte)
2634  {
2635  /* Nope, setup the first PTE address */
2636  PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2637  Section->VirtualAddress));
2638  }
2639 
2640  /* Compute the size */
2641  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2642 
2643  /* Find the last PTE that maps this section */
2644  LastPte = MiAddressToPte(ImageBase +
2645  Section->VirtualAddress +
2646  Alignment + Size - PAGE_SIZE);
2647  }
2648  else
2649  {
2650  /* Had we found a section before? */
2651  if (PointerPte)
2652  {
2653  /* Mark it as pageable */
2654  MiSetPagingOfDriver(PointerPte, LastPte);
2655  PointerPte = NULL;
2656  }
2657  }
2658 
2659  /* Keep searching */
2660  Sections--;
2661  Section++;
2662  }
2663 
2664  /* Handle the straggler */
2665  if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2666 }
2667 
2668 BOOLEAN
2669 NTAPI
2671 {
2672  PIMAGE_NT_HEADERS NtHeader;
2673  PAGED_CODE();
2674 
2675  /* Get NT Headers */
2676  NtHeader = RtlImageNtHeader(BaseAddress);
2677  if (NtHeader)
2678  {
2679  /* Check if this image is only safe for UP while we have 2+ CPUs */
2680  if ((KeNumberProcessors > 1) &&
2682  {
2683  /* Fail */
2684  return FALSE;
2685  }
2686  }
2687 
2688  /* Otherwise, it's safe */
2689  return TRUE;
2690 }
2691 
2692 NTSTATUS
2693 NTAPI
2695  IN BOOLEAN PurgeSection)
2696 {
2697  NTSTATUS Status;
2698  HANDLE SectionHandle;
2699  PVOID ViewBase = NULL;
2700  SIZE_T ViewSize = 0;
2702  FILE_STANDARD_INFORMATION FileStandardInfo;
2704  PIMAGE_NT_HEADERS NtHeaders;
2706  PAGED_CODE();
2707 
2708  /* Setup the object attributes */
2710  NULL,
2712  NULL,
2713  NULL);
2714 
2715  /* Create a section for the DLL */
2716  Status = ZwCreateSection(&SectionHandle,
2719  NULL,
2720  PAGE_EXECUTE,
2721  SEC_IMAGE,
2722  ImageHandle);
2723  if (!NT_SUCCESS(Status))
2724  {
2725  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2726  return Status;
2727  }
2728 
2729  /* Make sure we're in the system process */
2731 
2732  /* Map it */
2733  Status = ZwMapViewOfSection(SectionHandle,
2734  NtCurrentProcess(),
2735  &ViewBase,
2736  0,
2737  0,
2738  NULL,
2739  &ViewSize,
2740  ViewShare,
2741  0,
2742  PAGE_EXECUTE);
2743  if (!NT_SUCCESS(Status))
2744  {
2745  /* We failed, close the handle and return */
2746  DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2748  ZwClose(SectionHandle);
2749  return Status;
2750  }
2751 
2752  /* Now query image information */
2753  Status = ZwQueryInformationFile(ImageHandle,
2754  &IoStatusBlock,
2755  &FileStandardInfo,
2756  sizeof(FileStandardInfo),
2758  if (NT_SUCCESS(Status))
2759  {
2760  /* First, verify the checksum */
2762  ViewSize,
2763  FileStandardInfo.
2764  EndOfFile.LowPart))
2765  {
2766  /* Set checksum failure */
2768  goto Fail;
2769  }
2770 
2771  /* Make sure it's a real image */
2772  NtHeaders = RtlImageNtHeader(ViewBase);
2773  if (!NtHeaders)
2774  {
2775  /* Set checksum failure */
2777  goto Fail;
2778  }
2779 
2780  /* Make sure it's for the correct architecture */
2781  if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2783  {
2784  /* Set protection failure */
2786  goto Fail;
2787  }
2788 
2789  /* Check that it's a valid SMP image if we have more then one CPU */
2790  if (!MmVerifyImageIsOkForMpUse(ViewBase))
2791  {
2792  /* Otherwise it's not the right image */
2794  }
2795  }
2796 
2797  /* Unmap the section, close the handle, and return status */
2798 Fail:
2799  ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2801  ZwClose(SectionHandle);
2802  return Status;
2803 }
2804 
2805 
2806 PVOID
2807 NTAPI
2809 {
2810  PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDir;
2811  ULONG DirSize;
2812  PVOID Cookie = NULL;
2813 
2814  /* Check NT header first */
2815  if (!RtlImageNtHeader(BaseAddress)) return NULL;
2816 
2817  /* Get the pointer to the config directory */
2819  TRUE,
2821  &DirSize);
2822 
2823  /* Check for sanity */
2824  if (!ConfigDir ||
2825  DirSize < FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerTable) || /* SEHandlerTable is after SecurityCookie */
2826  (ConfigDir->Size != DirSize))
2827  {
2828  /* Invalid directory*/
2829  return NULL;
2830  }
2831 
2832  /* Now get the cookie */
2833  Cookie = (PVOID)ConfigDir->SecurityCookie;
2834 
2835  /* Check this cookie */
2836  if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
2837  (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
2838  {
2839  Cookie = NULL;
2840  }
2841 
2842  /* Return validated security cookie */
2843  return Cookie;
2844 }
2845 
2846 PVOID
2847 NTAPI
2849 {
2851  ULONG_PTR NewCookie;
2852 
2853  /* Fetch address of the cookie */
2855 
2856  if (Cookie)
2857  {
2858  /* Check if it's a default one */
2859  if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
2860  (*Cookie == 0))
2861  {
2863  /* The address should be unique */
2864  NewCookie = (ULONG_PTR)Cookie;
2865 
2866  /* We just need a simple tick, don't care about precision and whatnot */
2867  NewCookie ^= (ULONG_PTR)Counter.LowPart;
2868 
2869  /* If the result is 0 or the same as we got, just add one to the default value */
2870  if ((NewCookie == 0) || (NewCookie == *Cookie))
2871  {
2872  NewCookie = DEFAULT_SECURITY_COOKIE + 1;
2873  }
2874 
2875  /* Set the new cookie value */
2876  *Cookie = NewCookie;
2877  }
2878  }
2879 
2880  return Cookie;
2881 }
2882 
2883 NTSTATUS
2884 NTAPI
2886  IN PUNICODE_STRING NamePrefix OPTIONAL,
2887  IN PUNICODE_STRING LoadedName OPTIONAL,
2888  IN ULONG Flags,
2889  OUT PVOID *ModuleObject,
2890  OUT PVOID *ImageBaseAddress)
2891 {
2892  PVOID ModuleLoadBase = NULL;
2893  NTSTATUS Status;
2897  PIMAGE_NT_HEADERS NtHeader;
2898  UNICODE_STRING BaseName, BaseDirectory, PrefixName;
2899  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2900  ULONG EntrySize, DriverSize;
2901  PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2902  PCHAR MissingApiName, Buffer;
2903  PWCHAR MissingDriverName;
2904  HANDLE SectionHandle;
2906  PSECTION Section = NULL;
2907  BOOLEAN LockOwned = FALSE;
2908  PLIST_ENTRY NextEntry;
2909  IMAGE_INFO ImageInfo;
2910 
2911  PAGED_CODE();
2912 
2913  /* Detect session-load */
2914  if (Flags)
2915  {
2916  /* Sanity checks */
2917  ASSERT(NamePrefix == NULL);
2918  ASSERT(LoadedName == NULL);
2919 
2920  /* Make sure the process is in session too */
2921  if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2922  }
2923 
2924  /* Allocate a buffer we'll use for names */
2927  TAG_LDR_WSTR);
2929 
2930  /* Check for a separator */
2931  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2932  {
2933  PWCHAR p;
2934  ULONG BaseLength;
2935 
2936  /* Loop the path until we get to the base name */
2937  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2938  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2939 
2940  /* Get the length */
2941  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2942  BaseLength *= sizeof(WCHAR);
2943 
2944  /* Setup the string */
2945  BaseName.Length = (USHORT)BaseLength;
2946  BaseName.Buffer = p;
2947  }
2948  else
2949  {
2950  /* Otherwise, we already have a base name */
2951  BaseName.Length = FileName->Length;
2952  BaseName.Buffer = FileName->Buffer;
2953  }
2954 
2955  /* Setup the maximum length */
2956  BaseName.MaximumLength = BaseName.Length;
2957 
2958  /* Now compute the base directory */
2959  BaseDirectory = *FileName;
2960  BaseDirectory.Length -= BaseName.Length;
2961  BaseDirectory.MaximumLength = BaseDirectory.Length;
2962 
2963  /* And the prefix, which for now is just the name itself */
2964  PrefixName = *FileName;
2965 
2966  /* Check if we have a prefix */
2967  if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n");
2968 
2969  /* Check if we already have a name, use it instead */
2970  if (LoadedName) BaseName = *LoadedName;
2971 
2972  /* Check for loader snap debugging */
2974  {
2975  /* Print out standard string */
2976  DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
2977  &PrefixName, &BaseName, Flags ? "in session space" : "");
2978  }
2979 
2980  /* Acquire the load lock */
2981 LoaderScan:
2982  ASSERT(LockOwned == FALSE);
2983  LockOwned = TRUE;
2987  KernelMode,
2988  FALSE,
2989  NULL);
2990 
2991  /* Scan the module list */
2992  NextEntry = PsLoadedModuleList.Flink;
2993  while (NextEntry != &PsLoadedModuleList)
2994  {
2995  /* Get the entry and compare the names */
2996  LdrEntry = CONTAINING_RECORD(NextEntry,
2998  InLoadOrderLinks);
2999  if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3000  {
3001  /* Found it, break out */
3002  break;
3003  }
3004 
3005  /* Keep scanning */
3006  NextEntry = NextEntry->Flink;
3007  }
3008 
3009  /* Check if we found the image */
3010  if (NextEntry != &PsLoadedModuleList)
3011  {
3012  /* Check if we had already mapped a section */
3013  if (Section)
3014  {
3015  /* Dereference and clear */
3016  ObDereferenceObject(Section);
3017  Section = NULL;
3018  }
3019 
3020  /* Check if this was supposed to be a session load */
3021  if (!Flags)
3022  {
3023  /* It wasn't, so just return the data */
3024  *ModuleObject = LdrEntry;
3025  *ImageBaseAddress = LdrEntry->DllBase;
3027  }
3028  else
3029  {
3030  /* We don't support session loading yet */
3031  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3033  }
3034 
3035  /* Do cleanup */
3036  goto Quickie;
3037  }
3038  else if (!Section)
3039  {
3040  /* It wasn't loaded, and we didn't have a previous attempt */
3043  LockOwned = FALSE;
3044 
3045  /* Check if KD is enabled */
3047  {
3048  /* FIXME: Attempt to get image from KD */
3049  }
3050 
3051  /* We don't have a valid entry */
3052  LdrEntry = NULL;
3053 
3054  /* Setup image attributes */
3056  FileName,
3058  NULL,
3059  NULL);
3060 
3061  /* Open the image */
3063  FILE_EXECUTE,
3065  &IoStatusBlock,
3067  0);
3068  if (!NT_SUCCESS(Status))
3069  {
3070  DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3071  FileName, Status);
3072  goto Quickie;
3073  }
3074 
3075  /* Validate it */
3080  {
3081  /* Fail loading */
3082  goto Quickie;
3083  }
3084 
3085  /* Check if this is a session-load */
3086  if (Flags)
3087  {
3088  /* Then we only need read and execute */
3090  }
3091  else
3092  {
3093  /* Otherwise, we can allow write access */
3095  }
3096 
3097  /* Initialize the attributes for the section */
3099  NULL,
3101  NULL,
3102  NULL);
3103 
3104  /* Create the section */
3105  Status = ZwCreateSection(&SectionHandle,
3106  DesiredAccess,
3108  NULL,
3109  PAGE_EXECUTE,
3110  SEC_IMAGE,
3111  FileHandle);
3112  if (!NT_SUCCESS(Status))
3113  {
3114  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
3115  goto Quickie;
3116  }
3117 
3118  /* Now get the section pointer */
3119  Status = ObReferenceObjectByHandle(SectionHandle,
3122  KernelMode,
3123  (PVOID*)&Section,
3124  NULL);
3125  ZwClose(SectionHandle);
3126  if (!NT_SUCCESS(Status)) goto Quickie;
3127 
3128  /* Check if this was supposed to be a session-load */
3129  if (Flags)
3130  {
3131  /* We don't support session loading yet */
3132  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3133  goto Quickie;
3134  }
3135 
3136  /* Check the loader list again, we should end up in the path below */
3137  goto LoaderScan;
3138  }
3139  else
3140  {
3141  /* We don't have a valid entry */
3142  LdrEntry = NULL;
3143  }
3144 
3145  /* Load the image */
3146  Status = MiLoadImageSection(&Section,
3147  &ModuleLoadBase,
3148  FileName,
3149  FALSE,
3150  NULL);
3152 
3153  /* Get the size of the driver */
3154  DriverSize = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize;
3155 
3156  /* Make sure we're not being loaded into session space */
3157  if (!Flags)
3158  {
3159  /* Check for success */
3160  if (NT_SUCCESS(Status))
3161  {
3162  /* Support large pages for drivers */
3163  MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3164  &ModuleLoadBase,
3165  &BaseName,
3166  TRUE);
3167  }
3168 
3169  /* Dereference the section */
3170  ObDereferenceObject(Section);
3171  Section = NULL;
3172  }
3173 
3174  /* Check for failure of the load earlier */
3175  if (!NT_SUCCESS(Status))
3176  {
3177  DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3178  goto Quickie;
3179  }
3180 
3181  /* Relocate the driver */
3182  Status = LdrRelocateImageWithBias(ModuleLoadBase,
3183  0,
3184  "SYSLDR",
3188  if (!NT_SUCCESS(Status))
3189  {
3190  DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3191  goto Quickie;
3192  }
3193 
3194  /* Get the NT Header */
3195  NtHeader = RtlImageNtHeader(ModuleLoadBase);
3196 
3197  /* Calculate the size we'll need for the entry and allocate it */
3198  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
3199  BaseName.Length +
3200  sizeof(UNICODE_NULL);
3201 
3202  /* Allocate the entry */
3204  if (!LdrEntry)
3205  {
3206  /* Fail */
3208  goto Quickie;
3209  }
3210 
3211  /* Setup the entry */
3212  LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3213  LdrEntry->LoadCount = 1;
3214  LdrEntry->LoadedImports = LoadedImports;
3215  LdrEntry->PatchInformation = NULL;
3216 
3217  /* Check the version */
3218  if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3219  (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3220  {
3221  /* Mark this image as a native image */
3222  LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3223  }
3224 
3225  /* Setup the rest of the entry */
3226  LdrEntry->DllBase = ModuleLoadBase;
3227  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3229  LdrEntry->SizeOfImage = DriverSize;
3230  LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3231  LdrEntry->SectionPointer = Section;
3232 
3233  /* Now write the DLL name */
3234  LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3235  LdrEntry->BaseDllName.Length = BaseName.Length;
3236  LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3237 
3238  /* Copy and null-terminate it */
3239  RtlCopyMemory(LdrEntry->BaseDllName.Buffer,
3240  BaseName.Buffer,
3241  BaseName.Length);
3242  LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3243 
3244  /* Now allocate the full name */
3246  PrefixName.Length +
3247  sizeof(UNICODE_NULL),
3248  TAG_LDR_WSTR);
3249  if (!LdrEntry->FullDllName.Buffer)
3250  {
3251  /* Don't fail, just set it to zero */
3252  LdrEntry->FullDllName.Length = 0;
3253  LdrEntry->FullDllName.MaximumLength = 0;
3254  }
3255  else
3256  {
3257  /* Set it up */
3258  LdrEntry->FullDllName.Length = PrefixName.Length;
3259  LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3260 
3261  /* Copy and null-terminate */
3262  RtlCopyMemory(LdrEntry->FullDllName.Buffer,
3263  PrefixName.Buffer,
3264  PrefixName.Length);
3265  LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3266  }
3267 
3268  /* Add the entry */
3269  MiProcessLoaderEntry(LdrEntry, TRUE);
3270 
3271  /* Resolve imports */
3272  MissingApiName = Buffer;
3273  MissingDriverName = NULL;
3274  Status = MiResolveImageReferences(ModuleLoadBase,
3275  &BaseDirectory,
3276  NULL,
3277  &MissingApiName,
3278  &MissingDriverName,
3279  &LoadedImports);
3280  if (!NT_SUCCESS(Status))
3281  {
3282  BOOLEAN NeedToFreeString = FALSE;
3283 
3284  /* If the lowest bit is set to 1, this is a hint that we need to free */
3285  if (*(ULONG_PTR*)&MissingDriverName & 1)
3286  {
3287  NeedToFreeString = TRUE;
3288  *(ULONG_PTR*)&MissingDriverName &= ~1;
3289  }
3290 
3291  DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3292  DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3293  MissingDriverName, MissingApiName);
3294 
3295  if (NeedToFreeString)
3296  {
3297  ExFreePoolWithTag(MissingDriverName, TAG_LDR_WSTR);
3298  }
3299 
3300  /* Fail */
3301  MiProcessLoaderEntry(LdrEntry, FALSE);
3302 
3303  /* Check if we need to free the name */
3304  if (LdrEntry->FullDllName.Buffer)
3305  {
3306  /* Free it */
3308  }
3309 
3310  /* Free the entry itself */
3312  LdrEntry = NULL;
3313  goto Quickie;
3314  }
3315 
3316  /* Update the loader entry */
3317  LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
3319  LDRP_MM_LOADED);
3320  LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
3321  LdrEntry->LoadedImports = LoadedImports;
3322 
3323  /* FIXME: Call driver verifier's loader function */
3324 
3325  /* Write-protect the system image */
3327 
3328  /* Initialize the security cookie (Win7 is not doing this yet!) */
3329  LdrpInitSecurityCookie(LdrEntry);
3330 
3331  /* Check if notifications are enabled */
3333  {
3334  /* Fill out the notification data */
3335  ImageInfo.Properties = 0;
3337  ImageInfo.SystemModeImage = TRUE;
3338  ImageInfo.ImageSize = LdrEntry->SizeOfImage;
3339  ImageInfo.ImageBase = LdrEntry->DllBase;
3340  ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
3341 
3342  /* Send the notification */
3344  }
3345 
3346 #ifdef __ROS_ROSSYM__
3347  /* MiCacheImageSymbols doesn't detect rossym */
3348  if (TRUE)
3349 #else
3350  /* Check if there's symbols */
3351  if (MiCacheImageSymbols(LdrEntry->DllBase))
3352 #endif
3353  {
3354  UNICODE_STRING UnicodeTemp;
3355  STRING AnsiTemp;
3356 
3357  /* Check if the system root is present */
3358  if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
3359  !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
3360  {
3361  /* Add the system root */
3362  UnicodeTemp = PrefixName;
3363  UnicodeTemp.Buffer += 11;
3364  UnicodeTemp.Length -= (11 * sizeof(WCHAR));
3367  "%ws%wZ",
3368  &SharedUserData->NtSystemRoot[2],
3369  &UnicodeTemp);
3370  }
3371  else
3372  {
3373  /* Build the name */
3375  "%wZ", &BaseName);
3376  }
3377 
3378  /* Setup the ANSI string */
3379  RtlInitString(&AnsiTemp, Buffer);
3380 
3381  /* Notify the debugger */
3382  DbgLoadImageSymbols(&AnsiTemp,
3383  LdrEntry->DllBase,
3385  LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
3386  }
3387 
3388  /* Page the driver */
3389  ASSERT(Section == NULL);
3390  MiEnablePagingOfDriver(LdrEntry);
3391 
3392  /* Return pointers */
3393  *ModuleObject = LdrEntry;
3394  *ImageBaseAddress = LdrEntry->DllBase;
3395 
3396 Quickie:
3397  /* Check if we have the lock acquired */
3398  if (LockOwned)
3399  {
3400  /* Release the lock */
3403  LockOwned = FALSE;
3404  }
3405 
3406  /* If we have a file handle, close it */
3408 
3409  /* Check if we had a prefix (not supported yet - PrefixName == *FileName now) */
3410  /* if (NamePrefix) ExFreePool(PrefixName.Buffer); */
3411 
3412  /* Free the name buffer and return status */
3414  return Status;
3415 }
3416 
3418 NTAPI
3420 {
3421  PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3422  PLIST_ENTRY NextEntry;
3423  PAGED_CODE();
3424 
3425  /* Loop entries */
3426  NextEntry = PsLoadedModuleList.Flink;
3427  do
3428  {
3429  /* Get the loader entry */
3430  LdrEntry = CONTAINING_RECORD(NextEntry,
3432  InLoadOrderLinks);
3433 
3434  /* Check if the address matches */
3435  if ((Address >= LdrEntry->DllBase) &&
3436  (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3437  LdrEntry->SizeOfImage)))
3438  {
3439  /* Found a match */
3440  FoundEntry = LdrEntry;
3441  break;
3442  }
3443 
3444  /* Move on */
3445  NextEntry = NextEntry->Flink;
3446  } while(NextEntry != &PsLoadedModuleList);
3447 
3448  /* Return the entry */
3449  return FoundEntry;
3450 }
3451 
3452 /* PUBLIC FUNCTIONS ***********************************************************/
3453 
3454 /*
3455  * @implemented
3456  */
3457 PVOID
3458 NTAPI
3459 MmPageEntireDriver(IN PVOID AddressWithinSection)
3460 {
3461  PMMPTE StartPte, EndPte;
3462  PLDR_DATA_TABLE_ENTRY LdrEntry;
3463  PAGED_CODE();
3464 
3465  /* Get the loader entry */
3466  LdrEntry = MiLookupDataTableEntry(AddressWithinSection);
3467  if (!LdrEntry) return NULL;
3468 
3469  /* Check if paging of kernel mode is disabled or if the driver is mapped as an image */
3470  if ((MmDisablePagingExecutive) || (LdrEntry->SectionPointer))
3471  {
3472  /* Don't do anything, just return the base address */
3473  return LdrEntry->DllBase;
3474  }
3475 
3476  /* Wait for active DPCs to finish before we page out the driver */
3478 
3479  /* Get the PTE range for the whole driver image */
3480  StartPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase);
3481  EndPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
3482 
3483  /* Enable paging for the PTE range */
3484  ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(AddressWithinSection) == FALSE);
3485  MiSetPagingOfDriver(StartPte, EndPte);
3486 
3487  /* Return the base address */
3488  return LdrEntry->DllBase;
3489 }
3490 
3491 /*
3492  * @unimplemented
3493  */
3494 VOID
3495 NTAPI
3496 MmResetDriverPaging(IN PVOID AddressWithinSection)
3497 {
3498  UNIMPLEMENTED;
3499 }
3500 
3501 /*
3502  * @implemented
3503  */
3504 PVOID
3505 NTAPI
3507 {
3508  PVOID ProcAddress = NULL;
3509  ANSI_STRING AnsiRoutineName;
3510  NTSTATUS Status;
3511  PLIST_ENTRY NextEntry;
3512  PLDR_DATA_TABLE_ENTRY LdrEntry;
3513  BOOLEAN Found = FALSE;
3514  UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3516  ULONG Modules = 0;
3517 
3518  /* Convert routine to ANSI name */
3519  Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3520  SystemRoutineName,
3521  TRUE);
3522  if (!NT_SUCCESS(Status)) return NULL;
3523 
3524  /* Lock the list */
3527 
3528  /* Loop the loaded module list */
3529  NextEntry = PsLoadedModuleList.Flink;
3530  while (NextEntry != &PsLoadedModuleList)
3531  {
3532  /* Get the entry */
3533  LdrEntry = CONTAINING_RECORD(NextEntry,
3535  InLoadOrderLinks);
3536 
3537  /* Check if it's the kernel or HAL */
3538  if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3539  {
3540  /* Found it */
3541  Found = TRUE;
3542  Modules++;
3543  }
3544  else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3545  {
3546  /* Found it */
3547  Found = TRUE;
3548  Modules++;
3549  }
3550 
3551  /* Check if we found a valid binary */
3552  if (Found)
3553  {
3554  /* Find the procedure name */
3555  ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
3556  &AnsiRoutineName);
3557 
3558  /* Break out if we found it or if we already tried both modules */
3559  if (ProcAddress) break;
3560  if (Modules == 2) break;
3561  }
3562 
3563  /* Keep looping */
3564  NextEntry = NextEntry->Flink;
3565  }
3566 
3567  /* Release the lock */
3570 
3571  /* Free the string and return */
3572  RtlFreeAnsiString(&AnsiRoutineName);
3573  return ProcAddress;
3574 }
3575 
3576 /* EOF */
_SEH2_TRY
Definition: create.c:4226
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
signed char * PCHAR
Definition: retypes.h:7
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:42
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:83
NTSTATUS NTAPI MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
Definition: sysldr.c:295
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:962
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
VOID NTAPI MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
Definition: sysldr.c:552
#define max(a, b)
Definition: svc.c:63
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2134
#define DEFAULT_SECURITY_COOKIE
Definition: sysldr.c:43
KAPC_STATE
Definition: ketypes.h:1285
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:36
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG_PTR MmPoolCodeStart
Definition: sysldr.c:37
#define Add2Ptr(PTR, INC)
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:898
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
#define _Inout_
Definition: ms_sal.h:378
VOID NTAPI MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: sysldr.c:1680
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG ImageAddressingMode
Definition: pstypes.h:200
PSEGMENT Segment
Definition: mmtypes.h:809
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define _Out_
Definition: ms_sal.h:345
union _MMPTE::@2288 u
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
ULONG PFN_COUNT
Definition: mmtypes.h:102
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:25
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
ULONG ImageSelector
Definition: pstypes.h:208
#define CR4_PSE
Definition: ketypes.h:88
PVOID ImageBase
Definition: pstypes.h:207
PFN_NUMBER MmTotalSystemDriverPages
Definition: sysldr.c:28
char CHAR
Definition: xmlstorage.h:175
LIST_ENTRY MiLargePageDriverList
Definition: largepag.c:26
SIZE_T ImageSize
Definition: pstypes.h:209
ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]
Definition: syspte.c:25
union _IMAGE_SECTION_HEADER::@1517 Misc
LONG NTSTATUS
Definition: precomp.h:26
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2547
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2427
ULONG_PTR MmPoolCodeEnd
Definition: sysldr.c:37
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:382
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2854
union _MMPFN::@1757 u3
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:237
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
ULONG SizeOfImage
Definition: ldrtypes.h:143
#define MM_READWRITE
Definition: bootanim.c:19
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define STATUS_DRIVER_ORDINAL_NOT_FOUND
Definition: ntstatus.h:735
#define snprintf
Definition: wintirpc.h:48
USHORT Modified
Definition: mm.h:360
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
Definition: strmini.h:380
ULONG KeFeatureBits
Definition: krnlinit.c:22
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
#define TAG_LDR_IMPORTS
Definition: tag.h:103
uint16_t * PWCHAR
Definition: typedefs.h:56
_SEH2_END
Definition: create.c:4400
#define InsertTailList(ListHead, Entry)
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
int Fail
Definition: ehthrow.cxx:24
PVOID NTAPI MiCacheImageSymbols(IN PVOID BaseAddress)
Definition: sysldr.c:50
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID NTAPI MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:457
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
UNICODE_STRING BaseName
Definition: miarm.h:403
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define FILE_SHARE_READ
Definition: compat.h:136
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:23
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
Definition: fs_rec.h:187
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:736
DWORD AddressOfNameOrdinals
Definition: compat.h:167
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
#define ERROR_FATAL(...)
Definition: debug.h:238
ULONG_PTR MmPteCodeStart
Definition: sysldr.c:38
#define KF_LARGE_PAGE
Definition: ketypes.h:148
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PVOID DllBase
Definition: btrfs_drv.h:1880
VOID NTAPI MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:1622
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:397
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:82
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1414
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
return STATUS_NOT_IMPLEMENTED
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define TAG_LDR_WSTR
Definition: tag.h:102
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
#define UNICODE_NULL
#define ANSI_NULL
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
ULONG_PTR ShareCount
Definition: mm.h:390
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
PVOID NTAPI MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
Definition: sysldr.c:3506
VOID NTAPI MiSetSystemCodeProtection(_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
Definition: sysldr.c:2391
long LONG
Definition: pedump.c:60
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LIST_ENTRY MmLoadedUserImageList
Definition: sysldr.c:22
PVOID EntryPoint
Definition: ntddk_ex.h:203
VOID NTAPI MiWriteProtectSystemImage(_In_ PVOID ImageBase)
Definition: sysldr.c:2430
PWCHAR HalName
Definition: halacpi.c:45
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
union Alignment_ Alignment
#define IMAGE_SCN_PROTECTION_MASK
Definition: miarm.h:160
#define PsGetCurrentProcess
Definition: psfuncs.h:17
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:240
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:717
BOOLEAN NTAPI MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: sysldr.c:2191
unsigned char BOOLEAN
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: sysldr.c:2808
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
static WCHAR Address[46]
Definition: ping.c:68
#define _In_
Definition: ms_sal.h:308
#define PAGE_EXECUTE
Definition: nt_native.h:1306
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1356
Definition: bufpool.h:45
ULONG_PTR MmPteCodeEnd
Definition: sysldr.c:38
#define MI_SET_USAGE(x)
Definition: mm.h:317
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3918
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
return Found
Definition: dirsup.c:1270
void * PVOID
Definition: retypes.h:9
Definition: miarm.h:400
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define InterlockedExchangeAdd
Definition: interlocked.h:181
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
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:438
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:677
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 GLint GLint j
Definition: glfuncs.h:250
#define PCHAR
Definition: match.c:90
VOID NTAPI MmMakeKernelResourceSectionWritable(VOID)
Definition: sysldr.c:2311
Status
Definition: gdiplustypes.h:24
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
PVOID PatchInformation
Definition: ldrtypes.h:164
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
VOID NTAPI DbgUnLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3117
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2850
#define STATUS_NOT_FOUND
Definition: shellext.h:72
CONST CHAR * PCCH
Definition: ntbasedef.h:392
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG SystemModeImage
Definition: pstypes.h:201
union _IMAGE_THUNK_DATA32::@2092 u1
ULONG_PTR ExPoolCodeStart
Definition: sysldr.c:37
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PVOID MmUnloadedDrivers
Definition: sysldr.c:30
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOLEAN PsImageNotifyEnabled
Definition: psnotify.c:18
#define LDRP_ENTRY_NATIVE
Definition: ldrtypes.h:57
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PVOID LoadedImports
Definition: ldrtypes.h:161
NTSTATUS NTAPI MmCheckSystemImage(IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
Definition: sysldr.c:2694
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: pstypes.h:194
ULONG64 Valid
Definition: mmtypes.h:150
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
ULONG CheckSum
Definition: btrfs_drv.h:1886
PVOID NTAPI MmPageEntireDriver(IN PVOID AddressWithinSection)
Definition: sysldr.c:3459
#define ObDereferenceObject
Definition: obfuncs.h:203
#define LDRP_DEBUG_SYMBOLS_LOADED
Definition: ldrtypes.h:50
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
BOOLEAN MiLargePageAllDrivers
Definition: largepag.c:27
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
POBJECT_TYPE MmSectionObjectType
Definition: section.c:195
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
VOID NTAPI MmResetDriverPaging(IN PVOID AddressWithinSection)
Definition: sysldr.c:3496
#define MUTANT_INCREMENT
Definition: extypes.h:84
Definition: strmini.h:378
PVOID MmLastUnloadedDrivers
Definition: sysldr.c:31
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2670
std::wstring STRING
Definition: fontsub.cpp:33
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
FORCEINLINE VOID PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
Definition: ps_x.h:84
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define SharedUserData
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:128
ULONG_PTR ExPoolCodeEnd
Definition: sysldr.c:37
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define IMAGE_FILE_UP_SYSTEM_ONLY
Definition: pedump.c:170
NTSTATUS NTAPI MiResolveImageReferences(IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
Definition: sysldr.c:987
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
#define SECTION_MAP_READ
Definition: compat.h:139
#define FILE_EXECUTE
Definition: nt_native.h:642
union _MMPFN::@1756 u2
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: mm.h:373
Definition: btrfs_drv.h:1876
ULONG LowPart
Definition: typedefs.h:106
NTSTATUS NTAPI MmLoadSystemImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
Definition: sysldr.c:2885
ULONG ExpInitializationPhase
Definition: init.c:68
GLenum GLsizei len
Definition: glext.h:6722
ULONG ImageSectionNumber
Definition: pstypes.h:210
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
KPROCESS Pcb
Definition: pstypes.h:1262
BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:357
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1825
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:205
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
SIZE_T Count
Definition: ldrtypes.h:172
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
#define ALIGN_DOWN_BY(size, align)
PVOID SectionPointer
Definition: ntddk_ex.h:213
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
ULONG_PTR SIZE_T
Definition: typedefs.h:80
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1230
struct _FileName FileName
Definition: fatprocs.h:893
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
LOGICAL NTAPI MiUseLargeDriverPage(IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
Definition: sysldr.c:2334
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
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
BOOLEAN MmEnforceWriteProtection
Definition: sysldr.c:34
#define ROUND_TO_PAGES(Size)
unsigned short USHORT
Definition: pedump.c:61
void(* Func)(int)
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:57
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask)
Definition: sysldr.c:2280
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static ULONG Delta
Definition: xboxvideo.c:33
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1869
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1727
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
USHORT Rom
Definition: mm.h:368
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define NULL
Definition: types.h:112
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2848
#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD
Definition: pstypes.h:73
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:358
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
KIRQL FASTCALL KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
Definition: spinlock.c:62
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
VOID NTAPI DbgLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
#define RtlImageNtHeader
Definition: compat.h:806
static LARGE_INTEGER Counter
Definition: clock.c:43
PVOID NTAPI MiLocateExportName(IN PVOID DllBase, IN PCHAR ExportName)
Definition: sysldr.c:218
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
BOOLEAN MmMakeLowMemory
Definition: sysldr.c:33
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)
Definition: miarm.h:168
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
VOID NTAPI MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2606
#define OUT
Definition: typedefs.h:40
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define TAG_MODULE_OBJECT
Definition: tag.h:101
ULONG Flags
Definition: ntddk_ex.h:207
ULONG ERESOURCE
Definition: env_spec_w32.h:594
VOID NTAPI MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:579
unsigned int ULONG
Definition: retypes.h:1
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define PDE_MAPPED_VA
Definition: mm.h:39
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define SEC_IMAGE
Definition: mmtypes.h:96
#define ALIGN_UP_BY(size, align)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:29
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID NTAPI MiFindExportedRoutineByName(IN PVOID DllBase, IN PANSI_STRING ExportName)
Definition: sysldr.c:477
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:778
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1270
GLfloat GLfloat p
Definition: glext.h:8902
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
UCHAR MmDisablePagingExecutive
Definition: mminit.c:25
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
ULONG NtGlobalFlag
Definition: init.c:54
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:982
#define __FUNCTION__
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
signed int * PLONG
Definition: retypes.h:5
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:36
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1437
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
NTSTATUS NTAPI MiLoadImageSection(_Inout_ PSECTION *SectionPtr, _Out_ PVOID *ImageBase, _In_ PUNICODE_STRING FileName, _In_ BOOLEAN SessionLoad, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:77
#define LDRP_MM_LOADED
Definition: ldrtypes.h:60
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PFN_FROM_PTE(v)
Definition: mm.h:92
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
#define MmSystemRangeStart
Definition: mm.h:32
unsigned short * PUSHORT
Definition: retypes.h:2
ULONG ACCESS_MASK
Definition: nt_native.h:40
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry(IN PVOID Address)
Definition: sysldr.c:3419
ULONG Properties
Definition: pstypes.h:198
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:347
USHORT LoadCount
Definition: ntddk_ex.h:208
NTSTATUS NTAPI MiSnapThunk(IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA Name, IN PIMAGE_THUNK_DATA Address, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN SnapForwarder, OUT PCHAR *MissingApi)
Definition: sysldr.c:678
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:506
#define PAGED_CODE()
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:54
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NT_ASSERT
Definition: rtlfuncs.h:3310
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235