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