ReactOS  0.4.14-dev-614-gbfd8a84
image.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING.ARM in the top level directory
3  * PROJECT: ReactOS UEFI Boot Library
4  * FILE: boot/environ/lib/misc/image.c
5  * PURPOSE: Boot Library Image Routines
6  * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "bl.h"
12 #include <bcd.h>
13 
14 /* DATA VARIABLES ************************************************************/
15 
19 
20 #ifndef _M_ARM
28 #endif
29 
30 /* FUNCTIONS *****************************************************************/
31 
36  )
37 {
39  ULONG Size;
41 
42  /* Check if the file was memory mapped */
43  if (File->Flags & BL_IMG_MEMORY_FILE)
44  {
45  /* Just read the size of the mapping */
46  Size = File->FileSize;
47  }
48  else
49  {
50  /* Do file I/O to get the file size */
53  if (!NT_SUCCESS(Status))
54  {
55  return Status;
56  }
57 
58  /* We only support files less than 4GB in the Image Mapped */
59  Size = FileInformation.Size;
60  if (FileInformation.Size > ULONG_MAX)
61  {
62  return STATUS_NOT_SUPPORTED;
63  }
64  }
65 
66  /* Return the size and success */
67  *FileSize = Size;
68  return STATUS_SUCCESS;
69 }
70 
74  _In_ ULONG Size,
78  )
79 {
81 
82  /* Check what if this is a mapped file or not */
83  if (File->Flags & BL_IMG_MEMORY_FILE)
84  {
85  /* Check if the boundaries are within the file size */
86  if ((ByteOffset + Size) <= File->FileSize)
87  {
88  /* Yep, copy into the caller-supplied buffer */
90  (PVOID)((ULONG_PTR)File->BaseAddress + (ULONG_PTR)ByteOffset),
91  Size);
92 
93  /* If caller wanted to know, return the size copied */
94  if (BytesReturned)
95  {
97  }
98 
99  /* All good */
101  }
102  else
103  {
104  /* Doesn't fit */
106  }
107  }
108  else
109  {
110  /* Issue the file I/O instead */
111  Status = BlFileReadAtOffsetEx(File->FileId,
112  Size,
113  ByteOffset,
114  Buffer,
116  0);
117  }
118 
119  /* Return the final status */
120  return Status;
121 }
122 
123 NTSTATUS
125  _In_ ULONG DeviceId,
127  _In_ ULONG Flags,
128  _Out_ PBL_IMG_FILE NewFile
129  )
130 {
132  ULONG FileSize;
133  ULONGLONG RemoteFileSize;
134  PVOID RemoteFileAddress;
135  ULONG FileId;
136 
137  /* First, try to see if BD has this file remotely */
139  &RemoteFileAddress,
140  &RemoteFileSize);
141  if (NT_SUCCESS(Status))
142  {
143  /* Yep, get the file size and make sure it's < 4GB */
144  FileSize = RemoteFileSize;
145  if (RemoteFileSize <= ULONG_MAX)
146  {
147  /* Remember this is a memory mapped remote file */
148  NewFile->Flags |= (BL_IMG_MEMORY_FILE | BL_IMG_REMOTE_FILE);
149  NewFile->FileSize = FileSize;
150  NewFile->BaseAddress = RemoteFileAddress;
151  goto Quickie;
152  }
153  }
154 
155  /* Use File I/O instead */
156  Status = BlFileOpen(DeviceId,
157  FileName,
159  &FileId);
160  if (!NT_SUCCESS(Status))
161  {
162  /* Bail out on failure */
163  return Status;
164  }
165 
166  /* Make sure nobody thinks this is a memory file */
167  NewFile->Flags &= ~BL_IMG_MEMORY_FILE;
168  NewFile->FileId = FileId;
169 
170 Quickie:
171  /* Set common data for both memory and I/O based file */
172  NewFile->Flags |= BL_IMG_VALID_FILE;
173  NewFile->FileName = FileName;
174  return Status;
175 }
176 
177 NTSTATUS
180  )
181 {
183 
184  /* Make sure this is a valid file, otherwise no-op */
186  if (File->Flags & BL_IMG_VALID_FILE)
187  {
188  /* Is this a memory mapped file? */
189  if (!(File->Flags & BL_IMG_MEMORY_FILE))
190  {
191  /* Nope, close the file handle */
192  return BlFileClose(File->FileId);
193  }
194 
195  /* Is this a remote file? */
196  if (File->Flags & BL_IMG_REMOTE_FILE)
197  {
198  /* Then only free the memory in that scenario */
199  return MmPapFreePages(File->BaseAddress, BL_MM_INCLUDE_MAPPED_ALLOCATED);
200  }
201  }
202 
203  /* Return the final status */
204  return Status;
205 }
206 
207 NTSTATUS
209  _In_ PVOID ImageBase,
210  _In_ ULONG ImageSize,
212  )
213 {
216 
217  /* Make sure required parameters are present */
218  if (!(ImageBase) || !(ImageSize))
219  {
221  }
222 
223  /* Check if this was a physical allocation */
225  {
227  }
228 
229  /* It's virtual, so translate it first */
231  {
233  }
234 
235  /* Unmap the virtual mapping */
236  Status = BlMmUnmapVirtualAddressEx(ImageBase, ROUND_TO_PAGES(ImageSize));
237  if (NT_SUCCESS(Status))
238  {
239  /* Now free the physical pages */
241  }
242 
243  /* All done */
244  return Status;
245 }
246 
247 NTSTATUS
249  _Inout_ PVOID* ImageBuffer,
250  _In_ ULONG MemoryType,
251  _In_ ULONGLONG ImageSize,
253  )
254 {
256  ULONGLONG Pages, Size;
260 
261  /* Read and reset the current buffer address */
262  CurrentBuffer = *ImageBuffer;
263  *ImageBuffer = NULL;
264 
265  /* Align the image size to page */
266  Size = ROUND_TO_PAGES(ImageSize);
267 
268  /* Not sure what this attribute does yet */
269  Attributes = 0;
271  {
272  Attributes = 0x10000;
273  }
274 
275  /* Check if the caller wants a virtual buffer */
277  {
278  /* Set the physical address to the current buffer */
280  Pages = Size >> PAGE_SHIFT;
281 
282  /* Allocate the physical pages */
284  Pages,
285  MemoryType,
286  Attributes,
287  0);
288  if (!NT_SUCCESS(Status))
289  {
290  /* If that failed, remove allocation attributes */
294  Pages,
295  MemoryType,
296  Attributes,
297  0);
298  }
299 
300  /* Check if either attempts succeeded */
301  if (!NT_SUCCESS(Status))
302  {
303  return Status;
304  }
305 
306  /* Now map the physical buffer at the address requested */
310  Size,
312  if (!NT_SUCCESS(Status))
313  {
314  /* Free on failure if needed */
316  return Status;
317  }
318  }
319  else
320  {
321  /* Otherwise, allocate raw physical pages */
323  Pages = Size >> PAGE_SHIFT;
325  MemoryType,
326  Pages,
327  Attributes,
328  0,
329  NULL,
330  0);
331  if (!NT_SUCCESS(Status))
332  {
333  /* If that failed, try without allocation attributes */
334  MappedBase = NULL;
337  MemoryType,
338  Pages,
339  Attributes,
340  0,
341  NULL,
342  0);
343  }
344 
345  /* Check if either attempts succeeded */
346  if (!NT_SUCCESS(Status))
347  {
348  return Status;
349  }
350  }
351 
352  /* Success path, returned allocated address */
353  *ImageBuffer = MappedBase;
354  return STATUS_SUCCESS;
355 }
356 
357 NTSTATUS
359  _In_ ULONG DeviceId,
360  _In_ BL_MEMORY_TYPE MemoryType,
363  _Inout_ PULONG MappedSize,
365  _In_ BOOLEAN ShowProgress,
366  _Out_opt_ PUCHAR* HashBuffer,
367  _Out_opt_ PULONG HashSize
368  )
369 {
372  ULONG RemainingLength, CurrentSize, ImageSize, ReadSize;
373  BOOLEAN ComputeSignature, ComputeHash, Completed;
377 
378  /* Initialize variables */
379  BaseAddress = 0;
380  ImageSize = 0;
381  Completed = FALSE;
383 
384  /* Check for missing parameters */
385  if (!MappedBase)
386  {
388  goto Quickie;
389  }
390  if (!FileName)
391  {
393  goto Quickie;
394  }
395  if (!MappedSize)
396  {
398  goto Quickie;
399  }
400 
401  /* Check if the image buffer is being provided */
403  {
404  /* An existing base must already exist */
405  if (!(*MappedBase))
406  {
408  goto Quickie;
409  }
410  }
411 
412  /* Check of a hash is being requested */
414  {
415  /* Make sure we can return the hash */
416  if (!HashBuffer)
417  {
419  goto Quickie;
420  }
421  if (!HashSize)
422  {
424  goto Quickie;
425  }
426  }
427 
428  /* Check for invalid combination of parameters */
429  if ((ImageFlags & BL_LOAD_IMG_COMPUTE_HASH) && (ImageFlags & 0x270))
430  {
432  goto Quickie;
433  }
434 
435  /* Initialize hash if requested by caller */
436  if (HashBuffer)
437  {
438  *HashBuffer = 0;
439  }
440 
441  /* Do the same for the hash size */
442  if (HashSize)
443  {
444  *HashSize = 0;
445  }
446 
447  /* Open the image file */
448  Status = ImgpOpenFile(DeviceId, FileName, DeviceId, &FileHandle);
449  if (!NT_SUCCESS(Status))
450  {
451  EfiPrintf(L"Error opening file: %lx\r\n", Status);
452  goto Quickie;
453  }
454 
455  /* Get the size of the image */
456  Status = ImgpGetFileSize(&FileHandle, &ImageSize);
457  if (!NT_SUCCESS(Status))
458  {
459  EfiPrintf(L"Error getting file size: %lx\r\n", Status);
460  goto Quickie;
461  }
462 
463  /* Read the current base address */
466  {
467  /* Check if the current buffer is too small */
468  if (*MappedSize < ImageSize)
469  {
470  /* Return the required size of the buffer */
471  *MappedSize = ImageSize;
473  }
474  }
475  else
476  {
477  /* A buffer was not provided, allocate one ourselves */
479  MemoryType,
480  ImageSize,
481  ImageFlags);
482  }
483 
484  /* Bail out if allocation failed */
485  if (!NT_SUCCESS(Status))
486  {
487  goto Quickie;
488  }
489 
490  /* Set the initial byte offset and length to read */
491  RemainingLength = ImageSize;
492  ByteOffset = 0;
494 
495  /* Update the initial progress */
496  Completed = FALSE;
497  if (ShowProgress)
498  {
499  BlUtlUpdateProgress(0, &Completed);
500  ShowProgress &= (Completed != 0) - 1;
501  }
502 
503  /* Set the chunk size for each read */
504  ReadSize = 0x100000;
505  if (ReadSize > ImageSize)
506  {
507  ReadSize = ImageSize;
508  }
509 
510  /* Check if we should compute hash and/or signatures */
511  ComputeSignature = ImageFlags & BL_LOAD_IMG_COMPUTE_SIGNATURE;
512  ComputeHash = FALSE;
513  if ((ComputeSignature) || (ImageFlags & BL_LOAD_IMG_COMPUTE_HASH))
514  {
515  ComputeHash = TRUE;
516  // todo: crypto is hard
517  }
518 
519  /* Begin the read loop */
520  while (RemainingLength)
521  {
522  /* Check if we've got more than a chunk left to read */
523  if (RemainingLength > ReadSize)
524  {
525  /* Read a chunk*/
526  CurrentSize = ReadSize;
527  }
528  else
529  {
530  /* Read only what's left */
531  CurrentSize = RemainingLength;
532  }
533 
534  /* Read the chunk */
536  CurrentSize,
537  ByteOffset,
538  Buffer,
539  0);
540  if (!NT_SUCCESS(Status))
541  {
542  goto Quickie;
543  }
544 
545  /* Check if we need to compute the hash of this chunk */
546  if (ComputeHash)
547  {
548  // todo: crypto is hard
549  }
550 
551  /* Update our position and read information */
552  Buffer = (PVOID)((ULONG_PTR)Buffer + CurrentSize);
553  RemainingLength -= CurrentSize;
554  ByteOffset += CurrentSize;
555 
556  /* Check if we should update the progress bar */
557  if (ShowProgress)
558  {
559  /* Compute new percentage completed, check if we're done */
560  BlUtlUpdateProgress(100 - 100 * RemainingLength / ImageSize,
561  &Completed);
562  ShowProgress &= (Completed != 0) - 1;
563  }
564  }
565 
566  /* Is the read fully complete? We need to finalize the hash if requested */
567  if (ComputeHash)
568  {
569  // todo: CRYPTO IS HARD
570  }
571 
572  /* Success path, return back the buffer and the size of the image */
574  *MappedSize = ImageSize;
575 
576 Quickie:
577  /* Close the file handle */
579 
580  /* Check if we failed and had allocated a buffer */
581  if (!(NT_SUCCESS(Status)) &&
582  (BaseAddress) &&
584  {
585  /* Check what kind of buffer we had allocated */
587  {
588  /* Unmap and free the virtual buffer */
592  }
593  else
594  {
595  /* Free the physical buffer */
597  }
598  }
599 
600  /* If we hadn't gotten to 100% yet, do it now */
601  if (ShowProgress)
602  {
603  BlUtlUpdateProgress(100, &Completed);
604  }
605 
606  /* Return the final status */
607  return Status;
608 }
609 
612  _In_ PVOID ImageBase,
613  _In_ ULONG ImageSize
614  )
615 {
616  PIMAGE_SECTION_HEADER FoundSection;
617  ULONG i;
618  PIMAGE_SECTION_HEADER SectionHeader;
619  PIMAGE_NT_HEADERS NtHeader;
621 
622  /* Assume failure */
623  FoundSection = NULL;
624 
625  /* Make sure the image is valid */
626  Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeader);
627  if (NT_SUCCESS(Status))
628  {
629  /* Get the first section and loop through them all */
630  SectionHeader = IMAGE_FIRST_SECTION(NtHeader);
631  for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
632  {
633  /* Check if this is the resource section */
634  if (!_stricmp((PCCH)SectionHeader->Name, ".rsrc"))
635  {
636  /* Yep, we're done */
637  FoundSection = SectionHeader;
638  break;
639  }
640 
641  /* Nope, keep going */
642  SectionHeader++;
643  }
644  }
645 
646  /* Return the matching section */
647  return FoundSection;
648 }
649 
650 VOID
652  _In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry,
653  _Out_ PBOOLEAN IntegrityChecksDisabled,
654  _Out_ PBOOLEAN TestSigning
655  )
656 {
657 
659  BOOLEAN Value;
660 
661  /* Check if /DISABLEINTEGRITYCHECKS is on */
662  Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData,
664  &Value);
665  *IntegrityChecksDisabled = NT_SUCCESS(Status) && (Value);
666 
667  /* Check if /TESTSIGNING is on */
668  Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData,
670  &Value);
671  *TestSigning = NT_SUCCESS(Status) && (Value);
672 }
673 
674 NTSTATUS
676  _In_ PVOID ImageBase,
677  _In_ ULONG ImageSize,
679  )
680 {
681  /* Check for missing parameters */
682  if (!(ImageSize) || !(ImageBase))
683  {
684  /* Bail out */
686  }
687 
688  /* Unallocate the image buffer */
689  return BlImgUnallocateImageBuffer(ImageBase, ImageSize, ImageFlags);
690 }
691 
692 NTSTATUS
695  _In_ BL_MEMORY_TYPE MemoryType,
696  _Inout_ PVOID* ImageBase,
697  _Out_opt_ PULONG ImageSize,
700  )
701 {
703  ULONG FileSize, HeaderSize;
704  BL_IMG_FILE LocalFileBuffer;
705  PBL_IMG_FILE LocalFile;
706  PVOID VirtualAddress, PreferredBase, ImageBuffer, CertBuffer, HashBuffer;
707  ULONGLONG VirtualSize;
708  PIMAGE_DATA_DIRECTORY CertDirectory;
710  PIMAGE_NT_HEADERS NtHeaders;
711  USHORT SectionCount, CheckSum, PartialSum, FinalSum;
712  PIMAGE_SECTION_HEADER Section;
713  ULONG_PTR EndOfHeaders, SectionStart, Slack, SectionEnd;
714  ULONG i, SectionSize, RawSize, BytesRead, RemainingLength, Offset, AlignSize;
715  BOOLEAN First, ImageHashValid;
716  UCHAR LocalBuffer[1024];
717  UCHAR TrustedBootInformation[52];
718  ULONG WorkaroundForBinutils;
719 
720  /* Initialize locals */
721  WorkaroundForBinutils = 0;
722  LocalFile = NULL;
723  ImageBuffer = NULL;
724  FileSize = 0;
725  First = FALSE;
727  CertBuffer = NULL;
728  CertDirectory = NULL;
729  HashBuffer = NULL;
730  Offset = 0;
731  VirtualSize = 0;
732  ImageHashValid = FALSE;
733  RtlZeroMemory(&TrustedBootInformation, sizeof(TrustedBootInformation));
734 
735  /* Get the size of the image */
737  if (!NT_SUCCESS(Status))
738  {
739  return STATUS_FILE_INVALID;
740  }
741 
742  /* Allocate a flat buffer for it */
744  if (!NT_SUCCESS(Status))
745  {
746  goto Quickie;
747  }
748 
749  /* Read the whole file flat for now */
750  Status = ImgpReadAtFileOffset(ImageFile, FileSize, 0, ImageBuffer, NULL);
751  if (!NT_SUCCESS(Status))
752  {
753  goto Quickie;
754  }
755 
756  /* Build a local file handle */
757  LocalFile = &LocalFileBuffer;
758  LocalFileBuffer.FileName = ImageFile->FileName;
759  LocalFileBuffer.Flags = BL_IMG_MEMORY_FILE | BL_IMG_VALID_FILE;
760  LocalFileBuffer.BaseAddress = ImageBuffer;
761  LocalFileBuffer.FileSize = FileSize;
762 
763  /* Get the NT headers of the file */
764  Status = RtlImageNtHeaderEx(0, ImageBuffer, FileSize, &NtHeaders);
765  if (!NT_SUCCESS(Status))
766  {
767  goto Quickie;
768  }
769 
770  /* Check if we should validate the machine type */
772  {
773  /* Is it different than our current machine type? */
774 #if _M_AMD64
775  if (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
776 #else
777  if (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
778 #endif
779  {
780  /* Is it x86 (implying we are x64) ? */
781  if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
782  {
783  /* Return special error code */
785  }
786  else if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
787  {
788  /* Otherwise, it's x64 but we are x86 */
790  }
791  else
792  {
793  /* Or it's ARM or something... */
795  }
796 
797  /* Return with the distinguished error code */
798  goto Quickie;
799  }
800  }
801 
802  /* Check if we should validate the subsystem */
804  {
805  /* It must be a Windows boot Application */
806  if (NtHeaders->OptionalHeader.Subsystem !=
808  {
810  goto Quickie;
811  }
812  }
813 
814  /* Check if we should validate the /INTEGRITYCHECK flag */
816  {
817  /* Check if it's there */
818  if (!(NtHeaders->OptionalHeader.DllCharacteristics &
820  {
821  /* Nope, fail otherwise */
823  goto Quickie;
824  }
825  }
826 
827  /* Check if we should compute the image hash */
829  {
830  EfiPrintf(L"No hash support\r\n");
831  }
832 
833  /* Read the current base address, if any */
834  VirtualAddress = *ImageBase;
835 
836  /* Get the virtual size of the image */
837  VirtualSize = NtHeaders->OptionalHeader.SizeOfImage;
838 
839  /* Safely align the virtual size to a page */
840  Status = RtlULongLongAdd(VirtualSize,
841  PAGE_SIZE - 1,
842  &VirtualSize);
843  if (!NT_SUCCESS(Status))
844  {
845  goto Quickie;
846  }
847  VirtualSize = ALIGN_DOWN_BY(VirtualSize, PAGE_SIZE);
848 
849  /* Make sure the image isn't larger than 4GB */
850  if (VirtualSize > ULONG_MAX)
851  {
853  goto Quickie;
854  }
855 
856  /* Check if we have a buffer already */
858  {
859  /* Check if it's too small */
860  if (*ImageSize < VirtualSize)
861  {
862  /* Fail, letting the caller know how big to make it */
863  *ImageSize = VirtualSize;
865  }
866  }
867  else
868  {
869  /* Allocate the buffer with the flags and type the caller wants */
871  MemoryType,
872  VirtualSize,
873  Flags);
874  }
875 
876  /* Bail out if allocation failed, or existing buffer is too small */
877  if (!NT_SUCCESS(Status))
878  {
879  goto Quickie;
880  }
881 
882  /* Read the size of the headers */
883  HeaderSize = NtHeaders->OptionalHeader.SizeOfHeaders;
884  if (VirtualSize < HeaderSize)
885  {
886  /* Bail out if they're bigger than the image! */
888  goto Quickie;
889  }
890 
891  /* Now read the header into the buffer */
892  Status = ImgpReadAtFileOffset(LocalFile, HeaderSize, 0, VirtualAddress, NULL);
893  if (!NT_SUCCESS(Status))
894  {
895  goto Quickie;
896  }
897 
898  /* Get the NT headers of the file */
899  Status = RtlImageNtHeaderEx(0, VirtualAddress, HeaderSize, &NtHeaders);
900  if (!NT_SUCCESS(Status))
901  {
902  goto Quickie;
903  }
904 
905  First = FALSE;
906 
907  /* Record how many sections we have */
908  SectionCount = NtHeaders->FileHeader.NumberOfSections;
909 
910  /* Capture the current checksum and reset it */
911  CheckSum = NtHeaders->OptionalHeader.CheckSum;
912  NtHeaders->OptionalHeader.CheckSum = 0;
913 
914  /* Calculate the checksum of the header, and restore the original one */
915  PartialSum = BlUtlCheckSum(0,
917  HeaderSize,
920  NtHeaders->OptionalHeader.CheckSum = CheckSum;
921 
922  /* Record our current position (right after the headers) */
923  EndOfHeaders = (ULONG_PTR)VirtualAddress + HeaderSize;
924 
925  /* Get the first section and iterate through each one */
926  Section = IMAGE_FIRST_SECTION(NtHeaders);
927  for (i = 0; i < SectionCount; i++)
928  {
929  /* Compute where this section starts */
930  SectionStart = (ULONG_PTR)VirtualAddress + Section->VirtualAddress;
931 
932  /* Make sure that the section fits within the image */
933  if ((VirtualSize < Section->VirtualAddress) ||
934  ((PVOID)SectionStart < VirtualAddress))
935  {
936  EfiPrintf(L"fail 1\r\n");
938  goto Quickie;
939  }
940 
941  /* Check if there's slack space between header end and the section */
942  if (!(First) && (EndOfHeaders < SectionStart))
943  {
944  /* Zero it out */
945  Slack = SectionStart - EndOfHeaders;
946  RtlZeroMemory((PVOID)EndOfHeaders, Slack);
947  }
948 
949  /* Get the section virtual size and the raw size */
950  SectionSize = Section->Misc.VirtualSize;
951  RawSize = Section->SizeOfRawData;
952 
953  /* Safely align the raw size by 2 */
954  Status = RtlULongAdd(RawSize, 1, &AlignSize);
955  if (!NT_SUCCESS(Status))
956  {
957  goto Quickie;
958  }
959  AlignSize = ALIGN_DOWN_BY(AlignSize, 2);
960 
961  /* IF we don't have a virtual size, use the raw size */
962  if (!SectionSize)
963  {
964  SectionSize = RawSize;
965  }
966 
967  /* If we don't have raw data, ignore the raw size */
968  if (!Section->PointerToRawData)
969  {
970  RawSize = 0;
971  }
972  else if (SectionSize < RawSize)
973  {
974  /* And if the virtual size is smaller, use it as the final size */
975  RawSize = SectionSize;
976  }
977 
978  /* Make sure that the section doesn't overflow in memory */
979  Status = RtlULongPtrAdd(Section->VirtualAddress,
980  SectionSize,
981  &SectionEnd);
982  if (!NT_SUCCESS(Status))
983  {
984  EfiPrintf(L"fail 21\r\n");
986  goto Quickie;
987  }
988 
989  /* Make sure that it fits within the image */
990  if (VirtualSize < SectionEnd)
991  {
993  goto Quickie;
994  }
995 
996  /* Make sure it doesn't overflow on disk */
997  Status = RtlULongPtrAdd(Section->VirtualAddress,
998  AlignSize,
999  &SectionEnd);
1000  if (!NT_SUCCESS(Status))
1001  {
1002  EfiPrintf(L"fail 31\r\n");
1004  goto Quickie;
1005  }
1006 
1007  /* Make sure that it fits within the disk image as well */
1008  if (VirtualSize < SectionEnd)
1009  {
1011  goto Quickie;
1012  }
1013 
1014  /* So does this section have a valid size after all? */
1015  if (RawSize)
1016  {
1017  /* Are we in the first iteration? */
1018  if (!First)
1019  {
1020  /* FUCK YOU BINUTILS */
1021  if (NtHeaders->OptionalHeader.MajorLinkerVersion < 7)
1022  {
1023  if ((*(PULONG)&Section->Name == 'ler.') && (RawSize < AlignSize))
1024  {
1025  /* Piece of shit won't build relocations when you tell it to,
1026  * either by using --emit-relocs or --dynamicbase. People online
1027  * have found out that by using -pie-executable you can get this
1028  * to happen, but then it turns out that the .reloc section is
1029  * incorrectly sized, and results in a corrupt PE. However, they
1030  * still compute the checksum using the correct value. What idiots.
1031  */
1032  WorkaroundForBinutils = AlignSize - RawSize;
1033  AlignSize -= WorkaroundForBinutils;
1034  }
1035  }
1036 
1037  /* Yes, read the section data */
1038  Status = ImgpReadAtFileOffset(LocalFile,
1039  AlignSize,
1040  Section->PointerToRawData,
1041  (PVOID)SectionStart,
1042  NULL);
1043  if (!NT_SUCCESS(Status))
1044  {
1045  goto Quickie;
1046  }
1047 
1048  /* Update our current offset */
1049  Offset = AlignSize + Section->PointerToRawData;
1050 
1051  /* Update the checksum to include this section */
1052  PartialSum = BlUtlCheckSum(PartialSum,
1053  (PUCHAR)SectionStart,
1054  AlignSize,
1057  AlignSize += WorkaroundForBinutils;
1058  }
1059  }
1060 
1061  /* Are we in the first iteration? */
1062  if (!First)
1063  {
1064  /* Is there space at the end of the section? */
1065  if (RawSize < SectionSize)
1066  {
1067  /* Zero out the slack space that's there */
1068  Slack = SectionSize - RawSize;
1069  RtlZeroMemory((PVOID)(SectionStart + RawSize), Slack);
1070  }
1071 
1072  /* Update our tail offset */
1073  EndOfHeaders = SectionStart + SectionSize;
1074  }
1075 
1076  /* Move to the next section */
1077  Section++;
1078  }
1079 
1080  /* Are we in the first iteration? */
1081  if (!First)
1082  {
1083  /* Go to the end of the file */
1084  SectionStart = (ULONG_PTR)VirtualAddress + VirtualSize;
1085 
1086  /* Is there still some slack space left? */
1087  if (EndOfHeaders < SectionStart)
1088  {
1089  /* Zero it out */
1090  Slack = SectionStart - EndOfHeaders;
1091  RtlZeroMemory((PVOID)EndOfHeaders, Slack);
1092  }
1093  }
1094 
1095  /* Did the first iteration complete OK? */
1096  if ((NT_SUCCESS(Status)) && !(First))
1097  {
1098  /* Check how many non-image bytes are left in the file */
1099  RemainingLength = FileSize - Offset;
1100  while (RemainingLength)
1101  {
1102  /* See if the read will fit into our local buffer */
1103  if (RemainingLength >= sizeof(LocalBuffer))
1104  {
1105  /* Nope, cap it */
1106  BytesRead = sizeof(LocalBuffer);
1107  }
1108  else
1109  {
1110  /* Yes, but there's less to read */
1111  BytesRead = RemainingLength;
1112  }
1113 
1114  /* Read 1024 bytes into the local buffer */
1115  Status = ImgpReadAtFileOffset(LocalFile,
1116  BytesRead,
1117  Offset,
1118  LocalBuffer,
1119  &BytesRead);
1120  if (!(NT_SUCCESS(Status)) || !(BytesRead))
1121  {
1123  goto Quickie;
1124  }
1125 
1126  /* Advance the offset and reduce the length */
1127  RemainingLength -= BytesRead;
1128  Offset += BytesRead;
1129 
1130  /* Compute the checksum of this leftover space */
1131  PartialSum = BlUtlCheckSum(PartialSum,
1132  LocalBuffer,
1133  BytesRead,
1136  }
1137 
1138  /* Finally, calculate the final checksum and compare it */
1139  FinalSum = FileSize + PartialSum + WorkaroundForBinutils;
1140  if ((FinalSum != CheckSum) && (PartialSum == 0xFFFF))
1141  {
1142  /* It hit overflow, so set it to the file size */
1143  FinalSum = FileSize;
1144  }
1145 
1146  /* If the checksum doesn't match, and caller is enforcing, bail out */
1147  if ((FinalSum != CheckSum) &&
1149  {
1151  goto Quickie;
1152  }
1153  }
1154 
1155  /* Check if the .rsrc section should be checked with the filename */
1157  {
1158  EfiPrintf(L"Not yet supported\r\n");
1159  Status = 0xC0430007; // STATUS_SECUREBOOT_FILE_REPLACED
1160  goto Quickie;
1161  }
1162 
1163  /* Check if we should relocate */
1165  {
1166  /* Check if we loaded at a different address */
1167  PreferredBase = (PVOID)NtHeaders->OptionalHeader.ImageBase;
1168  if (VirtualAddress != PreferredBase)
1169  {
1170  /* Yep -- do relocations */
1172  "Boot Environment Library",
1176  if (!NT_SUCCESS(Status))
1177  {
1178  /* That's bad */
1179  goto Quickie;
1180  }
1181  }
1182  }
1183 
1184 #if BL_TPM_SUPPORT
1185  /* Check if the image hash was valid */
1186  if (!ImageHashValid)
1187  {
1188  /* Send a TPM/SI notification without a context */
1189  BlEnNotifyEvent(0x10000002, NULL);
1190  }
1191 
1192  /* Now send a TPM/SI notification with the hash of the loaded image */
1194  Context.HashAlgorithm = HashAlgorithm;
1195  Context.HashSize = HashSize;
1196  Context.FileName = ImageFile->FileName;
1197  Context.ImageSize = VirtualSize;
1198  Context.HashValid = ImageHashValid;
1199  Context.Hash = Hash;
1200  BlEnNotifyEvent(0x10000002, &Context);
1201 #endif
1202 
1203  /* Return the loaded address to the caller */
1204  *ImageBase = VirtualAddress;
1205 
1206  /* If the caller wanted the image size, return it too */
1207  if (ImageSize)
1208  {
1209  *ImageSize = VirtualSize;
1210  }
1211 
1212 Quickie:
1213  /* Check if we computed the image hash OK */
1214  if (ImageHashValid)
1215  {
1216  /* Then free the information that ImgpValidateImageHash set up */
1217  EfiPrintf(L"leadking trusted boot\r\n");
1218  //ImgpDestroyTrustedBootInformation(&TrustedBootInformation);
1219  }
1220 
1221  /* Check if we had a hash buffer */
1222  if (HashBuffer)
1223  {
1224  /* Free it */
1226  }
1227 
1228  /* Check if we have a certificate directory */
1229  if ((CertBuffer) && (CertDirectory))
1230  {
1231  /* Free it */
1232  BlImgUnallocateImageBuffer(CertBuffer, CertDirectory->Size, 0);
1233  }
1234 
1235  /* Check if we had an image buffer allocated */
1236  if ((ImageBuffer) && (FileSize))
1237  {
1238  /* Free it */
1239  BlImgUnallocateImageBuffer(ImageBuffer, FileSize, 0);
1240  }
1241 
1242  /* Check if we had a local file handle */
1243  if (LocalFile)
1244  {
1245  /* Close it */
1246  ImgpCloseFile(LocalFile);
1247  }
1248 
1249  /* Check if this is the failure path */
1250  if (!NT_SUCCESS(Status))
1251  {
1252  /* Check if we had started mapping in the image already */
1254  {
1255  /* Into a virtual buffer? */
1257  {
1258  /* Unmap and free it */
1262  }
1263  else
1264  {
1265  /* Into a physical buffer -- free it */
1267  }
1268  }
1269  }
1270 
1271  /* Return back to caller */
1272  return Status;
1273 }
1274 
1275 NTSTATUS
1277  _In_ ULONG DeviceId,
1278  _In_ BL_MEMORY_TYPE MemoryType,
1279  _In_ PWCHAR Path,
1280  _Out_ PVOID* ImageBase,
1281  _Out_ PULONG ImageSize,
1282  _Out_ PVOID Hash,
1283  _In_ ULONG Flags
1284  )
1285 {
1287  NTSTATUS Status;
1288 
1289  /* Initialize the image file structure */
1290  ImageFile.Flags = 0;
1291  ImageFile.FileName = NULL;
1292 
1293  /* Check if the required parameter are missing */
1294  if (!(ImageBase) || !(Path))
1295  {
1296  return STATUS_INVALID_PARAMETER;
1297  }
1298 
1299  /* If we are loading a pre-allocated image, make sure we have it */
1300  if ((Flags & BL_LOAD_IMG_EXISTING_BUFFER) && (!(*ImageBase) || !(ImageSize)))
1301  {
1302  return STATUS_INVALID_PARAMETER;
1303  }
1304 
1305  /* Load the file from disk */
1306  Status = ImgpOpenFile(DeviceId, Path, 0, &ImageFile);
1307  if (NT_SUCCESS(Status))
1308  {
1309  /* If that worked, do the PE parsing */
1311  MemoryType,
1312  ImageBase,
1313  ImageSize,
1314  Hash,
1315  Flags);
1316  }
1317 
1318  /* Close the image file and return back to caller */
1320  return Status;
1321 }
1322 
1323 NTSTATUS
1326  _Out_ PULONG AppHandle
1327  )
1328 {
1329  NTSTATUS Status;
1330  PULONGLONG AllowedList;
1331  ULONGLONG AllowedCount;
1332  ULONG i, DeviceId, ImageSize, Flags, ListSize;
1334  PVOID UnlockCode, ImageBase;
1335  PBL_DEVICE_DESCRIPTOR Device, BitLockerDevice;
1336  PWCHAR Path;
1337  PBL_APPLICATION_ENTRY AppEntry;
1339  BOOLEAN DisableIntegrity, TestSigning;
1340  UCHAR Hash[64];
1341  PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry;
1342 
1343  /* Initialize all locals */
1344  BitLockerDevice = NULL;
1345  UnlockCode = NULL;
1346  ImageFile = NULL;
1347  DeviceId = -1;
1348  Device = NULL;
1349  ImageAppEntry = NULL;
1350  AppEntry = NULL;
1351  Path = NULL;
1352  ImageSize = 0;
1353  ImageBase = NULL;
1354 
1355  /* Check for "allowed in-memory settings" */
1356  Status = BlpGetBootOptionIntegerList(BootEntry->BcdData,
1358  &AllowedList,
1359  &AllowedCount,
1360  TRUE);
1361  if (Status == STATUS_SUCCESS)
1362  {
1363  /* Loop through the list of allowed setting */
1364  for (i = 0; i < AllowedCount; i++)
1365  {
1366  /* Find the super undocumented one */
1367  if (AllowedList[i] == BcdLibraryInteger_UndocumentedMagic)
1368  {
1369  /* If it's present, append the current perf frequence to it */
1371  BlAppendBootOptionInteger(BootEntry,
1374  }
1375  }
1376  }
1377 
1378 #if BL_BITLOCKER_SUPPORT
1379  /* Do bitlocker stuff */
1380  Status = BlFveSecureBootUnlockBootDevice(BootEntry, &BitLockerDevice, &UnlockCode);
1381  if (!NT_SUCCESS(Status))
1382  {
1383  goto Quickie;
1384  }
1385 #endif
1386 
1387  /* Get the device on which this application is on*/
1388  Status = BlGetBootOptionDevice(BootEntry->BcdData,
1390  &Device,
1391  NULL);
1392  if (!NT_SUCCESS(Status))
1393  {
1394  goto Quickie;
1395  }
1396 
1397  /* Get the path of the application */
1398  Status = BlGetBootOptionString(BootEntry->BcdData,
1400  &Path);
1401  if (!NT_SUCCESS(Status))
1402  {
1403  goto Quickie;
1404  }
1405 
1406  /* Open the device */
1409  0,
1410  &DeviceId);
1411  if (!NT_SUCCESS(Status))
1412  {
1413  goto Quickie;
1414  }
1415 
1416  /* Check for integrity BCD options */
1418  &DisableIntegrity,
1419  &TestSigning);
1420 
1421 #if BL_TPM_SUPPORT
1422  RtlZeroMemory(&Context, sizeof(Context);
1423  Context.BootEntry = BootEntry;
1424  BlEnNotifyEvent(0x10000003, &Context);
1425 #endif
1426 
1427  /* Enable signing and hashing checks if integrity is enabled */
1428  Flags = 0;
1429  if (!DisableIntegrity)
1430  {
1431  Flags = 0x8070;
1432  }
1433 
1434  /* Now call the PE loader to load the image */
1435  Status = BlImgLoadPEImageEx(DeviceId,
1437  Path,
1438  &ImageBase,
1439  &ImageSize,
1440  Hash,
1441  Flags);
1442  if (!NT_SUCCESS(Status))
1443  {
1444  goto Quickie;
1445  }
1446 
1447 #if BL_KD_SUPPORT
1448  /* Check if we should notify the debugger of load */
1449  if (BdDebugTransitions)
1450  {
1451  /* Initialize it */
1452  BdForceDebug = 1;
1453  Status = BlBdInitialize();
1454  if (NT_SUCCESS(Status))
1455  {
1456  /* Check if it's enabled */
1457  if (BlBdDebuggerEnabled())
1458  {
1459  /* Send it an image load notification */
1461  RtlInitUnicodeString(&PathString, Path);
1462  BlBdLoadImageSymbols(&PathString, ImageBase);
1463  }
1464  }
1465  }
1466 #endif
1467 
1468 #if BL_BITLOCKER_SUPPORT
1469  /* Do bitlocker stuff */
1470  Status = BlSecureBootCheckPolicyOnFveDevice(BitLockerDevice);
1471  if (!NT_SUCCESS(Status))
1472  {
1473  goto Quickie;
1474  }
1475 #endif
1476 
1477 #if BL_BITLOCKER_SUPPORT
1478  /* Do bitlocker stuff */
1479  Status = BlFveSecureBootCheckpointBootApp(BootEntry, BitLockerDevice, Hash, UnlockCode);
1480  if (!NT_SUCCESS(Status))
1481  {
1482  goto Quickie;
1483  }
1484 #endif
1485 
1486  /* Get the BCD option size */
1487  ListSize = BlGetBootOptionListSize(BootEntry->BcdData);
1488 
1489  /* Allocate an entry with all the BCD options */
1490  AppEntry = BlMmAllocateHeap(ListSize + sizeof(*AppEntry));
1491  if (!AppEntry)
1492  {
1494  goto Quickie;
1495  }
1496 
1497  /* Zero it out */
1498  RtlZeroMemory(AppEntry, sizeof(*AppEntry));
1499 
1500  /* Initialize it */
1501  strcpy(AppEntry->Signature, "BTAPENT");
1502  AppEntry->Guid = BootEntry->Guid;
1503  AppEntry->Flags = BootEntry->Flags;
1504 
1505  /* Copy the BCD options */
1506  RtlCopyMemory(&AppEntry->BcdData, BootEntry->BcdData, ListSize);
1507 
1508  /* Allocate the image entry */
1509  ImageAppEntry = BlMmAllocateHeap(sizeof(*ImageAppEntry));
1510  if (!ImageAppEntry)
1511  {
1513  goto Quickie;
1514  }
1515 
1516  /* Initialize it */
1517  ImageAppEntry->ImageBase = ImageBase;
1518  ImageAppEntry->ImageSize = ImageSize;
1519  ImageAppEntry->AppEntry = AppEntry;
1520 
1521  /* Check if this is the first entry */
1522  if (!IapTableEntries)
1523  {
1524  /* Allocate two entries */
1526  IapTableEntries = 2;
1528  if (!IapImageTable)
1529  {
1531  goto Quickie;
1532  }
1533 
1534  /* Zero out the entries for now */
1536  }
1537 
1538  /* Set this entry into the table */
1540  &IapTableEntries,
1541  ImageAppEntry,
1542  AppHandle,
1544 
1545 Quickie:
1546  /* Is the device open? Close it if so */
1547  if (DeviceId != 1)
1548  {
1549  BlDeviceClose(DeviceId);
1550  }
1551 
1552  /* Is there an allocated device? Free it */
1553  if (Device)
1554  {
1556  }
1557 
1558  /* Is there an allocated path? Free it */
1559  if (Path)
1560  {
1561  BlMmFreeHeap(Path);
1562  }
1563 
1564  /* Is there a bitlocker device? Free it */
1565  if (BitLockerDevice)
1566  {
1567  BlMmFreeHeap(BitLockerDevice);
1568  }
1569 
1570  /* Is there a bitlocker unlock code? Free it */
1571  if (UnlockCode)
1572  {
1573  BlMmFreeHeap(UnlockCode);
1574  }
1575 
1576  /* Did we succeed in creating an entry? */
1577  if (NT_SUCCESS(Status))
1578  {
1579  /* Remember there's one more in the table */
1581 
1582  /* Return success */
1583  return Status;
1584  }
1585 
1586  /* Did we load an image after all? */
1587  if (ImageBase)
1588  {
1589  /* Unload it */
1590  BlImgUnLoadImage(ImageBase, ImageSize, 0);
1591  }
1592 
1593  /* Did we allocate an app entry? Free it */
1594  if (AppEntry)
1595  {
1596  BlMmFreeHeap(AppEntry);
1597  }
1598 
1599  /* Do we have an image file entry? Free it */
1600  if (ImageFile)
1601  {
1603  }
1604 
1605  /* Do we no longer have a single entry in the table? */
1607  {
1608  /* Free and destroy the table */
1610  IapTableEntries = 0;
1611  IapImageTable = NULL;
1612  }
1613 
1614  /* Return the failure code */
1615  return Status;
1616 }
1617 
1618 NTSTATUS
1620  _In_ PBL_RETURN_ARGUMENTS ReturnArguments
1621  )
1622 {
1623  /* Check if any custom data was returned */
1624  if (ReturnArguments->DataPage == 0)
1625  {
1626  /* Nope, nothing to do */
1627  return STATUS_SUCCESS;
1628  }
1629 
1630  /* Yes, we have to parse it */
1631  EfiPrintf(L"Return arguments not supported\r\n");
1632  return STATUS_NOT_IMPLEMENTED;
1633 }
1634 
1635 NTSTATUS
1637  __in PBL_DEVICE_DESCRIPTOR DestinationDevice,
1639  )
1640 {
1641  /* Is this a partition device? */
1642  if (SourceDevice->DeviceType != PartitionDevice)
1643  {
1644  /* It's not -- a simple copy will do */
1645  RtlCopyMemory(DestinationDevice, SourceDevice, SourceDevice->Size);
1646  return STATUS_SUCCESS;
1647  }
1648 
1649  /* TODO */
1650  EfiPrintf(L"Partition copy not supported\r\n");
1651  return STATUS_NOT_IMPLEMENTED;
1652 
1653 }
1654 
1655 NTSTATUS
1657  _In_ PBL_BUFFER_DESCRIPTOR ImageParameters,
1658  _In_ PBL_APPLICATION_ENTRY AppEntry,
1659  _In_ PVOID ImageBase,
1660  _In_ ULONG ImageSize
1661  )
1662 {
1663  NTSTATUS Status;
1664  PIMAGE_NT_HEADERS NtHeaders;
1665  BL_BUFFER_DESCRIPTOR MemoryParameters;
1666  LIST_ENTRY MemoryList;
1667  PBL_FIRMWARE_DESCRIPTOR FirmwareParameters;
1669  PBL_MEMORY_DATA MemoryData;
1670  PBL_APPLICATION_ENTRY BootAppEntry;
1671  PBL_RETURN_ARGUMENTS ReturnArguments;
1672  PBOOT_APPLICATION_PARAMETER_BLOCK ParameterBlock;
1674 
1675  /* Get the image headers and validate it */
1676  Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
1677  if (!NT_SUCCESS(Status))
1678  {
1679  return Status;
1680  }
1681 
1682  /* Get the size of the entire non-firmware, allocated, memory map */
1683  MemoryParameters.BufferSize = 0;
1684  Status = BlMmGetMemoryMap(&MemoryList,
1685  &MemoryParameters,
1691  0);
1693  {
1694  /* We failed due to an unknown reason -- bail out */
1695  return Status;
1696  }
1697 
1698  /* Compute the list of the BCD plus the application entry */
1699  EntrySize = BlGetBootOptionListSize(&AppEntry->BcdData) +
1701 
1702  /* Compute the total size required for the entire structure */
1703  BufferSize = EntrySize +
1704  BlpBootDevice->Size +
1705  MemoryParameters.BufferSize +
1706  sizeof(*ReturnArguments) +
1707  sizeof(*MemoryData) +
1708  sizeof(*FirmwareParameters) +
1709  sizeof(*ParameterBlock);
1710 
1711  /* Check if this gives us enough space */
1712  if (ImageParameters->BufferSize < BufferSize)
1713  {
1714  /* It does not -- free the existing buffer */
1715  if (ImageParameters->BufferSize)
1716  {
1717  BlMmFreeHeap(ImageParameters->Buffer);
1718  }
1719 
1720  /* Allocate a new buffer of sufficient size */
1721  ImageParameters->BufferSize = BufferSize;
1722  ImageParameters->Buffer = BlMmAllocateHeap(BufferSize);
1723  if (!ImageParameters->Buffer)
1724  {
1725  /* Bail out if we couldn't allocate it */
1726  return STATUS_NO_MEMORY;
1727  }
1728  }
1729 
1730  /* Zero out the parameter block */
1731  ParameterBlock = (PBOOT_APPLICATION_PARAMETER_BLOCK)ImageParameters->Buffer;
1732  RtlZeroMemory(ParameterBlock, BufferSize);
1733 
1734  /* Initialize it */
1735  ParameterBlock->Version = BOOT_APPLICATION_VERSION;
1736  ParameterBlock->Size = BufferSize;
1737  ParameterBlock->Signature[0] = BOOT_APPLICATION_SIGNATURE_1;
1738  ParameterBlock->Signature[1] = BOOT_APPLICATION_SIGNATURE_2;
1739  ParameterBlock->MemoryTranslationType = MmTranslationType;
1740  ParameterBlock->ImageType = IMAGE_FILE_MACHINE_I386;
1741  ParameterBlock->ImageBase = (ULONG_PTR)ImageBase;
1742  ParameterBlock->ImageSize = NtHeaders->OptionalHeader.SizeOfImage;
1743 
1744  /* Get the offset to the memory data */
1745  ParameterBlock->MemoryDataOffset = sizeof(*ParameterBlock);
1746 
1747  /* Fill it out */
1748  MemoryData = (PBL_MEMORY_DATA)((ULONG_PTR)ParameterBlock +
1749  ParameterBlock->MemoryDataOffset);
1750  MemoryData->Version = BL_MEMORY_DATA_VERSION;
1751  MemoryData->MdListOffset = sizeof(*MemoryData);
1752  MemoryData->DescriptorSize = sizeof(BL_MEMORY_DESCRIPTOR);
1753  MemoryData->DescriptorOffset = FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage);
1754 
1755  /* And populate the memory map */
1756  MemoryParameters.Buffer = MemoryData + 1;
1757  Status = BlMmGetMemoryMap(&MemoryList,
1758  &MemoryParameters,
1764  0);
1765  if (!NT_SUCCESS(Status))
1766  {
1767  return Status;
1768  }
1769 
1770  /* Now that we have the map, indicate the number of descriptors */
1771  MemoryData->DescriptorCount = MemoryParameters.ActualSize /
1772  MemoryData->DescriptorSize;
1773 
1774  /* Get the offset to the application entry */
1775  ParameterBlock->AppEntryOffset = ParameterBlock->MemoryDataOffset +
1776  MemoryData->MdListOffset +
1777  MemoryParameters.BufferSize;
1778 
1779  /* Fill it out */
1780  BootAppEntry = (PBL_APPLICATION_ENTRY)((ULONG_PTR)ParameterBlock +
1781  ParameterBlock->AppEntryOffset);
1782  RtlCopyMemory(BootAppEntry, AppEntry, EntrySize);
1783 
1784  /* Get the offset to the boot device */
1785  ParameterBlock->BootDeviceOffset = ParameterBlock->AppEntryOffset +
1786  EntrySize;
1787 
1788  /* Fill it out */
1789  BootDevice = (PBL_DEVICE_DESCRIPTOR)((ULONG_PTR)ParameterBlock +
1790  ParameterBlock->BootDeviceOffset);
1792  if (!NT_SUCCESS(Status))
1793  {
1794  return Status;
1795  }
1796 
1797  /* Get the offset to the firmware data */
1798  ParameterBlock->FirmwareParametersOffset = ParameterBlock->BootDeviceOffset +
1799  BootDevice->Size;
1800 
1801  /* Fill it out */
1802  FirmwareParameters = (PBL_FIRMWARE_DESCRIPTOR)((ULONG_PTR)ParameterBlock +
1803  ParameterBlock->
1804  FirmwareParametersOffset);
1805  Status = BlFwGetParameters(FirmwareParameters);
1806  if (!NT_SUCCESS(Status))
1807  {
1808  return Status;
1809  }
1810 
1811  /* Get the offset to the return arguments */
1812  ParameterBlock->ReturnArgumentsOffset = ParameterBlock->FirmwareParametersOffset +
1813  sizeof(BL_FIRMWARE_DESCRIPTOR);
1814 
1815  /* Fill them out */
1816  ReturnArguments = (PBL_RETURN_ARGUMENTS)((ULONG_PTR)ParameterBlock +
1817  ParameterBlock->
1818  ReturnArgumentsOffset);
1819  ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION;
1820  ReturnArguments->DataPage = 0;
1821  ReturnArguments->DataSize = 0;
1822 
1823  /* Structure complete */
1824  ImageParameters->ActualSize = ParameterBlock->ReturnArgumentsOffset +
1825  sizeof(*ReturnArguments);
1826  return STATUS_SUCCESS;
1827 }
1828 
1829 NTSTATUS
1831  _In_ PBL_APPLICATION_ENTRY AppEntry,
1832  _In_ PVOID ImageBase,
1833  _In_ ULONG ImageSize,
1834  _In_ PBL_RETURN_ARGUMENTS ReturnArguments
1835  )
1836 {
1837 #ifndef _M_ARM
1838  KDESCRIPTOR Gdt, Idt;
1839  ULONG BootSizeNeeded;
1840  NTSTATUS Status;
1841  PVOID BootData;
1842  PIMAGE_NT_HEADERS NtHeaders;
1843  PVOID NewStack, NewGdt, NewIdt;
1845 
1846  /* Read the current IDT and GDT */
1847  _sgdt(&Gdt.Limit);
1848  __sidt(&Idt.Limit);
1849 
1850  /* Allocate space for the IDT, GDT, and 24 pages of stack */
1851  BootSizeNeeded = (ULONG_PTR)PAGE_ALIGN(Idt.Limit + Gdt.Limit + 1 + 25 * PAGE_SIZE);
1852  Status = MmPapAllocatePagesInRange(&BootData,
1854  BootSizeNeeded >> PAGE_SHIFT,
1855  0,
1856  0,
1857  NULL,
1858  0);
1859  if (!NT_SUCCESS(Status))
1860  {
1861  goto Quickie;
1862  }
1863 
1864  /* Zero the boot data */
1865  RtlZeroMemory(BootData, BootSizeNeeded);
1866 
1867  /* Set the new stack, GDT and IDT */
1868  NewStack = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE) - 8);
1869  NewGdt = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE));
1870  NewIdt = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE) + Gdt.Limit + 1);
1871 
1872  /* Copy the current (firmware) GDT and IDT */
1873  RtlCopyMemory(NewGdt, (PVOID)Gdt.Base, Gdt.Limit + 1);
1874  RtlCopyMemory(NewIdt, (PVOID)Idt.Base, Idt.Limit + 1);
1875 
1876  /* Read the NT headers so that we can get the entrypoint later on */
1877  RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
1878 
1879  /* Prepare the application parameters */
1880  RtlZeroMemory(&Parameters, sizeof(Parameters));
1882  AppEntry,
1883  ImageBase,
1884  ImageSize);
1885  if (NT_SUCCESS(Status))
1886  {
1887  /* Set the firmware GDT/IDT as the one the application will use */
1888  BootAppGdtRegister = Gdt;
1889  BootAppIdtRegister = Idt;
1890 
1891  /* Set the entrypoint, parameters, and stack */
1892  BootApp32EntryRoutine = (PVOID)((ULONG_PTR)ImageBase +
1893  NtHeaders->OptionalHeader.
1894  AddressOfEntryPoint);
1896  BootApp32Stack = NewStack;
1897 
1898 #if BL_KD_SUPPORT
1899  /* Disable the kernel debugger */
1900  BlBdStop();
1901 #endif
1902  /* Make it so */
1904 
1905  /* Not yet implemented. This is the last step! */
1906  EfiPrintf(L"EFI APPLICATION RETURNED!!!\r\n");
1907  EfiStall(100000000);
1908 
1909 #if BL_KD_SUPPORT
1910  /* Re-enable the kernel debugger */
1911  BlBdStart();
1912 #endif
1913  }
1914 
1915 Quickie:
1916  /* Check if we had boot data allocated */
1917  if (BootData)
1918  {
1919  /* Free it */
1921  }
1922 #else
1923  EfiPrintf(L"ImgArchEfiStartBootApplication not implemented for this platform.\r\n");
1924 #endif
1925 
1926  /* All done */
1927  return STATUS_NOT_IMPLEMENTED;
1928 }
1929 
1930 NTSTATUS
1932  _In_ ULONG AppHandle,
1933  _Inout_opt_ PBL_RETURN_ARGUMENTS ReturnArguments
1934  )
1935 {
1936  PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry;
1937  BL_RETURN_ARGUMENTS LocalReturnArgs;
1939  PLIST_ENTRY NextEntry, ListHead;
1940  NTSTATUS Status;
1941 
1942  /* Check if we don't have an argument structure */
1943  if (!ReturnArguments)
1944  {
1945  /* Initialize a local copy and use it instead */
1946  LocalReturnArgs.Version = BL_RETURN_ARGUMENTS_VERSION;
1947  LocalReturnArgs.Status = STATUS_SUCCESS;
1948  LocalReturnArgs.Flags = 0;
1949  LocalReturnArgs.DataPage = 0;
1950  LocalReturnArgs.DataSize = 0;
1951  ReturnArguments = &LocalReturnArgs;
1952  }
1953 
1954  /* Make sure the handle index is valid */
1955  if (IapTableEntries <= AppHandle)
1956  {
1957  return STATUS_INVALID_PARAMETER;
1958  }
1959 
1960  /* Get the entry for this handle, making sure it exists */
1961  ImageAppEntry = IapImageTable[AppHandle];
1962  if (!ImageAppEntry)
1963  {
1964  return STATUS_INVALID_PARAMETER;
1965  }
1966 
1967  /* Loop the registered file systems */
1968  ListHead = &RegisteredFileSystems;
1969  NextEntry = RegisteredFileSystems.Flink;
1970  while (NextEntry != ListHead)
1971  {
1972  /* Get the filesystem entry */
1973  FileSystem = CONTAINING_RECORD(NextEntry,
1975  ListEntry);
1976 
1977  /* See if it has a purge callback */
1978  if (FileSystem->PurgeCallback)
1979  {
1980  /* Call it */
1981  FileSystem->PurgeCallback();
1982  }
1983 
1984  /* Move to the next entry */
1985  NextEntry = NextEntry->Flink;
1986  }
1987 
1988  /* TODO -- flush the block I/O cache too */
1989  //BlockIoPurgeCache();
1990 
1991  /* Call into EFI land to start the boot application */
1993  ImageAppEntry->ImageBase,
1994  ImageAppEntry->ImageSize,
1995  ReturnArguments);
1996 
1997  /* Parse any arguments we got on the way back */
1998  BlpPdParseReturnArguments(ReturnArguments);
1999 
2000 #if BL_BITLOCKER_SUPPORT
2001  /* Bitlocker stuff */
2002  FvebpCheckAllPartitions(TRUE);
2003 #endif
2004 
2005 #if BL_TPM_SUPPORT
2006  /* Notify a TPM/SI event */
2007  BlEnNotifyEvent(0x10000005, NULL);
2008 #endif
2009 
2010  /* Reset the display */
2012 
2013  /* TODO -- reset ETW */
2014  //BlpLogInitialize();
2015 
2016  /* All done */
2017  return Status;
2018 }
2019 
2020 NTSTATUS
2022  _In_ ULONG AppHandle
2023  )
2024 {
2025  PBL_IMAGE_APPLICATION_ENTRY ImageAppEntry;
2026  NTSTATUS Status;
2027 
2028  /* Make sure the handle index is valid */
2029  if (IapTableEntries <= AppHandle)
2030  {
2031  return STATUS_INVALID_PARAMETER;
2032  }
2033 
2034  /* Get the entry for this handle, making sure it exists */
2035  ImageAppEntry = IapImageTable[AppHandle];
2036  if (!ImageAppEntry)
2037  {
2038  return STATUS_INVALID_PARAMETER;
2039  }
2040 
2041  /* Unload the image */
2042  Status = BlImgUnLoadImage(ImageAppEntry->ImageBase,
2043  ImageAppEntry->ImageSize,
2044  0);
2045  if (NT_SUCCESS(Status))
2046  {
2047  /* Normalize the success code */
2049  }
2050  else
2051  {
2052  /* Normalize the failure code */
2054  }
2055 
2056  /* Free the entry and the image entry as well */
2057  BlMmFreeHeap(ImageAppEntry->AppEntry);
2058  BlMmFreeHeap(ImageAppEntry);
2059 
2060  /* Clear the handle */
2061  IapImageTable[AppHandle] = NULL;
2062 
2063  /* Free one entry */
2064  if (!(--IapAllocatedTableEntries))
2065  {
2066  /* There are no more, so get rid of the table itself */
2068  IapImageTable = NULL;
2069  IapTableEntries = 0;
2070  }
2071 
2072  /* All good */
2073  return Status;
2074 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define BL_LOAD_IMG_COMPUTE_HASH
Definition: bl.h:176
static PWSTR ImageFile
Definition: imagefile.c:10
static int Hash(const char *)
Definition: reader.c:2257
PBL_DEVICE_DESCRIPTOR BlpBootDevice
Definition: bootlib.c:16
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:887
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
NTSTATUS BlFileGetInformation(_In_ ULONG FileId, _In_ PBL_FILE_INFORMATION FileInfo)
Definition: file.c:564
ULONG BlGetBootOptionListSize(_In_ PBL_BCD_OPTION BcdOption)
Definition: bcdopt.c:79
ULONG DescriptorSize
Definition: bl.h:803
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define BL_MM_INCLUDE_PERSISTENT_MEMORY
Definition: bl.h:105
NTSTATUS BlFileOpen(_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PULONG FileId)
Definition: file.c:477
NTSTATUS BlImgStartBootApplication(_In_ ULONG AppHandle, _Inout_opt_ PBL_RETURN_ARGUMENTS ReturnArguments)
Definition: image.c:1931
NTSTATUS BlDeviceClose(_In_ ULONG DeviceId)
Definition: device.c:2073
#define BL_LOAD_PE_IMG_COMPUTE_HASH
Definition: bl.h:181
NTSTATUS BlMmMapPhysicalAddressEx(_In_ PVOID *VirtualAddress, _In_ ULONG Attributes, _In_ ULONGLONG Size, _In_ PHYSICAL_ADDRESS PhysicalAddress)
Definition: mm.c:192
PWCHAR FileSystem
Definition: format.c:72
Definition: bl.h:1052
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
#define BL_IMG_VALID_FILE
Definition: bl.h:168
#define BL_LOAD_IMG_UNKNOWN_BUFFER_FLAG
Definition: bl.h:174
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:1003
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define BL_LOAD_PE_IMG_SKIP_RELOCATIONS
Definition: bl.h:183
NTSTATUS ImgpInitializeBootApplicationParameters(_In_ PBL_BUFFER_DESCRIPTOR ImageParameters, _In_ PBL_APPLICATION_ENTRY AppEntry, _In_ PVOID ImageBase, _In_ ULONG ImageSize)
Definition: image.c:1656
KDESCRIPTOR BootAppIdtRegister
Definition: image.c:24
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
ULONG Version
Definition: bl.h:817
NTSTATUS BlFwGetParameters(_In_ PBL_FIRMWARE_DESCRIPTOR Parameters)
Definition: firmware.c:2359
NTSTATUS ImgpCloseFile(_In_ PBL_IMG_FILE File)
Definition: image.c:178
_In_ BOOLEAN _In_ ULONG HashAlgorithm
Definition: rtlfuncs.h:2039
#define STATUS_INVALID_IMAGE_WIN_32
Definition: ntstatus.h:886
unsigned char * PUCHAR
Definition: retypes.h:3
GUID Guid
Definition: bl.h:859
NTSTATUS TblDoNotPurgeEntry(_In_ PVOID Entry)
Definition: util.c:495
Definition: bl.h:252
LONG NTSTATUS
Definition: precomp.h:26
#define BL_LOAD_IMG_EXISTING_BUFFER
Definition: bl.h:173
struct _BL_MEMORY_DESCRIPTOR BL_MEMORY_DESCRIPTOR
#define BOOT_APPLICATION_SIGNATURE_2
Definition: bl.h:57
PWCHAR FileName
Definition: bl.h:1281
#define BL_LOAD_PE_IMG_EXISTING_BUFFER
Definition: bl.h:180
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
NTSTATUS BlMmAllocatePhysicalPages(_Inout_ PPHYSICAL_ADDRESS Address, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG PageCount, _In_ ULONG Attributes, _In_ ULONG Alignment)
CHAR Signature[8]
Definition: bl.h:857
NTSTATUS BlImgUnLoadImage(_In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ ULONG ImageFlags)
Definition: image.c:675
NTSTATUS BlImgLoadImageWithProgress2(_In_ ULONG DeviceId, _In_ BL_MEMORY_TYPE MemoryType, _In_ PWCHAR FileName, _Inout_ PVOID *MappedBase, _Inout_ PULONG MappedSize, _In_ ULONG ImageFlags, _In_ BOOLEAN ShowProgress, _Out_opt_ PUCHAR *HashBuffer, _Out_opt_ PULONG HashSize)
Definition: image.c:358
_Must_inspect_result_ __drv_aliasesMem PDEVICE_OBJECT SourceDevice
Definition: iofuncs.h:688
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
Definition: ntimage.h:456
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1187
uint16_t * PWCHAR
Definition: typedefs.h:54
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
DWORD PointerToRawData
Definition: pedump.c:290
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
PVOID * IapImageTable
Definition: image.c:18
#define _stricmp
Definition: cat.c:22
#define BL_LOAD_IMG_VIRTUAL_BUFFER
Definition: bl.h:172
#define BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH
Definition: bl.h:185
PVOID Base
Definition: ketypes.h:486
VOID BlImgQueryCodeIntegrityBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, _Out_ PBOOLEAN IntegrityChecksDisabled, _Out_ PBOOLEAN TestSigning)
Definition: image.c:651
NTSTATUS BlImgUnloadBootApplication(_In_ ULONG AppHandle)
Definition: image.c:2021
#define BL_MM_INCLUDE_RESERVED_ALLOCATED
Definition: bl.h:101
struct _BL_FIRMWARE_DESCRIPTOR * PBL_FIRMWARE_DESCRIPTOR
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
KDESCRIPTOR BootAppGdtRegister
Definition: image.c:23
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT Limit
Definition: ketypes.h:485
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION
Definition: ntimage.h:448
NTSTATUS ImgpReadAtFileOffset(_In_ PBL_IMG_FILE File, _In_ ULONG Size, _In_ ULONGLONG ByteOffset, _In_ PVOID Buffer, _Out_ PULONG BytesReturned)
Definition: image.c:72
ULONGLONG DataPage
Definition: bl.h:821
ImageFlags
Definition: gdiplusenums.h:329
NTSTATUS ImgpGetFileSize(_In_ PBL_IMG_FILE File, _Out_ PULONG FileSize)
Definition: image.c:33
WCHAR First[]
Definition: FormatMessage.c:11
HANDLE FileHandle
Definition: stats.c:38
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
PIMAGE_SECTION_HEADER BlImgFindSection(_In_ PVOID ImageBase, _In_ ULONG ImageSize)
Definition: image.c:611
Definition: bl.h:855
#define BL_LOAD_PE_IMG_CHECK_SUBSYSTEM
Definition: bl.h:182
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSTATUS BlBdPullRemoteFile(_In_ PWCHAR FilePath, _Out_ PVOID BaseAddress, _Out_ PULONGLONG FileSize)
Definition: debug.c:34
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:1920
ULONGLONG BlTimeQueryPerformanceCounter(_Out_opt_ PLARGE_INTEGER Frequency)
Definition: time.c:101
NTSTATUS ImgArchEfiStartBootApplication(_In_ PBL_APPLICATION_ENTRY AppEntry, _In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ PBL_RETURN_ARGUMENTS ReturnArguments)
Definition: image.c:1830
struct _BOOT_APPLICATION_PARAMETER_BLOCK * PBOOT_APPLICATION_PARAMETER_BLOCK
BL_TRANSLATION_TYPE MmTranslationType
Definition: mm.c:17
PVOID ImageBase
Definition: bl.h:1287
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS BlGetBootOptionBoolean(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBOOLEAN Value)
Definition: bcdopt.c:504
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
NTSTATUS ImgpOpenFile(_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PBL_IMG_FILE NewFile)
Definition: image.c:124
#define _Out_
Definition: no_sal2.h:323
Definition: bufpool.h:45
Definition: bl.h:864
void * PVOID
Definition: retypes.h:9
NTSTATUS BlpGetBootOptionIntegerList(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PULONGLONG *Value, _Out_ PULONGLONG Count, _In_ BOOLEAN NoCopy)
Definition: bcdopt.c:541
PVOID BootApp32Stack
Definition: image.c:27
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS BlpPdParseReturnArguments(_In_ PBL_RETURN_ARGUMENTS ReturnArguments)
Definition: image.c:1619
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:663
#define BL_MM_INCLUDE_MAPPED_ALLOCATED
Definition: bl.h:97
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
#define _Out_opt_
Definition: no_sal2.h:339
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
CONST CHAR * PCCH
Definition: ntbasedef.h:399
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define BL_LOAD_PE_IMG_VIRTUAL_BUFFER
Definition: bl.h:178
ULONG FileSize
Definition: bl.h:1280
UCHAR Flags
Definition: bl.h:1274
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:345
NTSTATUS BlMmGetMemoryMap(_In_ PLIST_ENTRY MemoryMap, _In_ PBL_BUFFER_DESCRIPTOR MemoryParameters, _In_ ULONG WhichTypes, _In_ ULONG Flags)
Definition: pagealloc.c:1222
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONGLONG DataSize
Definition: bl.h:820
uint64_t ULONGLONG
Definition: typedefs.h:65
NTSTATUS BlImgLoadPEImageEx(_In_ ULONG DeviceId, _In_ BL_MEMORY_TYPE MemoryType, _In_ PWCHAR Path, _Out_ PVOID *ImageBase, _Out_ PULONG ImageSize, _Out_ PVOID Hash, _In_ ULONG Flags)
Definition: image.c:1276
ULONG IapAllocatedTableEntries
Definition: image.c:16
ULONG IapTableEntries
Definition: image.c:17
static FILE_SYSTEM RegisteredFileSystems[]
Definition: fsutil.c:42
#define BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY
Definition: bl.h:184
#define BufferSize
Definition: classpnp.h:419
#define PAGE_ALIGN(Va)
BOOLEAN BdDebuggerNotPresent
Definition: debug.c:16
UCHAR CheckSum(LPSTR p, ULONG Len)
Definition: serial.c:197
struct _BL_FIRMWARE_DESCRIPTOR BL_FIRMWARE_DESCRIPTOR
#define _Inout_
Definition: no_sal2.h:244
NTSTATUS BlMmUnmapVirtualAddressEx(_In_ PVOID VirtualAddress, _In_ ULONGLONG Size)
Definition: mm.c:487
ULONG DescriptorOffset
Definition: bl.h:804
NTSTATUS BlImgLoadBootApplication(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG AppHandle)
Definition: image.c:1324
enum _BL_MEMORY_TYPE BL_MEMORY_TYPE
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define BOOT_APPLICATION_VERSION
Definition: bl.h:62
ULONG ActualSize
Definition: bl.h:1294
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN BlBdDebuggerEnabled(VOID)
Definition: debug.c:53
#define BL_LOAD_IMG_COMPUTE_SIGNATURE
Definition: bl.h:175
char * PBOOLEAN
Definition: retypes.h:11
ULONG BufferSize
Definition: bl.h:1295
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS BlGetBootOptionString(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PWCHAR *Value)
Definition: bcdopt.c:146
#define BL_MM_INCLUDE_UNMAPPED_ALLOCATED
Definition: bl.h:99
#define BL_MM_INCLUDE_MAPPED_UNALLOCATED
Definition: bl.h:98
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define BL_LOAD_PE_IMG_CHECK_MACHINE
Definition: bl.h:179
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
NTSTATUS MmPapFreePages(_In_ PVOID Address, _In_ ULONG WhichList)
Definition: pagealloc.c:1196
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
NTSTATUS BlImgUnallocateImageBuffer(_In_ PVOID ImageBase, _In_ ULONG ImageSize, _In_ ULONG ImageFlags)
Definition: image.c:208
ULONG Flags
Definition: bl.h:858
__INTRIN_INLINE void _sgdt(void *Destination)
Definition: intrin_x86.h:1925
VOID BlUtlUpdateProgress(_In_ ULONG Percentage, _Out_opt_ PBOOLEAN Completed)
Definition: util.c:181
Status
Definition: gdiplustypes.h:24
#define BL_IMG_MEMORY_FILE
Definition: bl.h:169
PBOOT_APPLICATION_PARAMETER_BLOCK BootApp32Parameters
Definition: image.c:26
KDESCRIPTOR GdtRegister
Definition: image.c:21
NTSTATUS BlFileClose(_In_ ULONG FileId)
Definition: file.c:220
PVOID BootApp32EntryRoutine
Definition: image.c:25
#define ALIGN_DOWN_BY(size, align)
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
#define _In_
Definition: no_sal2.h:204
NTSTATUS ImgpCopyApplicationBootDevice(__in PBL_DEVICE_DESCRIPTOR DestinationDevice, __in PBL_DEVICE_DESCRIPTOR SourceDevice)
Definition: image.c:1636
#define BL_DEVICE_READ_ACCESS
Definition: bl.h:153
KDESCRIPTOR IdtRegister
Definition: image.c:22
NTSTATUS BlGetBootOptionDevice(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBL_DEVICE_DESCRIPTOR *Value, _In_opt_ PBL_BCD_OPTION *ExtraOptions)
Definition: bcdopt.c:321
struct _FileName FileName
Definition: fatprocs.h:884
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
PRTL_UNICODE_STRING_BUFFER Path
#define BL_UTL_CHECKSUM_USHORT_BUFFER
Definition: bl.h:192
#define BL_FILE_READ_ACCESS
Definition: bl.h:148
#define STATUS_MEMORY_NOT_ALLOCATED
Definition: ntstatus.h:382
#define ROUND_TO_PAGES(Size)
unsigned short USHORT
Definition: pedump.c:61
ULONG ImageSize
Definition: bl.h:1288
ULONG Version
Definition: bl.h:800
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME
Definition: bl.h:186
static PVOID CurrentBuffer
_In_ FILTER_INFORMATION_CLASS _In_ ULONG _Out_ PULONG BytesReturned
Definition: fltkernel.h:1716
#define BL_UTL_CHECKSUM_COMPLEMENT
Definition: bl.h:188
FORCEINLINE PVOID PhysicalAddressToPtr(_In_ PHYSICAL_ADDRESS PhysicalAddress)
Definition: bl.h:1390
ULONG NTAPI LdrRelocateImage(IN PVOID BaseAddress, IN PCCH LoaderName, IN ULONG Success, IN ULONG Conflict, IN ULONG Invalid)
Definition: image.c:442
unsigned int * PULONG
Definition: retypes.h:1
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BL_MEMORY_DATA_VERSION
Definition: bl.h:63
ULONG MdListOffset
Definition: bl.h:801
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
static LARGE_INTEGER Frequency
Definition: clock.c:41
#define BOOT_APPLICATION_SIGNATURE_1
Definition: bl.h:56
VOID Archx86TransferTo32BitApplicationAsm(VOID)
Definition: arch.c:51
_Must_inspect_result_ _Outptr_result_bytebuffer_ ViewSize PVOID * MappedBase
Definition: mmfuncs.h:493
NTSTATUS BlTblSetEntry(_Inout_ PVOID **Table, _Inout_ PULONG Count, _In_ PVOID Entry, _Out_ PULONG EntryIndex, _In_ PBL_TBL_SET_ROUTINE Callback)
Definition: util.c:321
NTSTATUS BlpDisplayReinitialize(VOID)
Definition: display.c:542
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
NTSTATUS BlImgAllocateImageBuffer(_Inout_ PVOID *ImageBuffer, _In_ ULONG MemoryType, _In_ ULONGLONG ImageSize, _In_ ULONG Flags)
Definition: image.c:248
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _BL_APPLICATION_ENTRY * PBL_APPLICATION_ENTRY
#define ULONG_PTR
Definition: config.h:101
#define BL_RETURN_ARGUMENTS_VERSION
Definition: bl.h:64
NTSTATUS BlpDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ ULONG Flags, _In_ ULONG Unknown, _Out_ PULONG DeviceId)
Definition: device.c:2111
Definition: File.h:15
Definition: bl.h:1284
BOOLEAN BlMmTranslateVirtualAddress(_In_ PVOID VirtualAddress, _Out_ PPHYSICAL_ADDRESS PhysicalAddress)
Definition: mm.c:525
struct _BL_MEMORY_DATA * PBL_MEMORY_DATA
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSTATUS MmPapAllocatePagesInRange(_Inout_ PVOID *PhysicalAddress, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG Pages, _In_ ULONG Attributes, _In_ ULONG Alignment, _In_opt_ PBL_ADDRESS_RANGE Range, _In_ ULONG Type)
Definition: pagealloc.c:707
#define __in
Definition: dbghelp.h:35
NTSTATUS NTAPI RtlImageNtHeaderEx(_In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size, _Out_ PIMAGE_NT_HEADERS *OutHeaders)
Definition: image.c:141
union _IMAGE_SECTION_HEADER::@1543 Misc
ULONG BlUtlCheckSum(_In_ ULONG PartialSum, _In_ PUCHAR Buffer, _In_ ULONG Length, _In_ ULONG Flags)
Definition: util.c:777
NTSTATUS BlAppendBootOptionInteger(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ ULONG OptionId, _In_ ULONGLONG Value)
Definition: bcdopt.c:657
NTSTATUS ImgpLoadPEImage(_In_ PBL_IMG_FILE ImageFile, _In_ BL_MEMORY_TYPE MemoryType, _Inout_ PVOID *ImageBase, _Out_opt_ PULONG ImageSize, _Inout_opt_ PVOID Hash, _In_ ULONG Flags)
Definition: image.c:693
PBL_APPLICATION_ENTRY AppEntry
Definition: bl.h:1286
NTSTATUS Status
Definition: bl.h:818
#define BL_IMG_REMOTE_FILE
Definition: bl.h:170
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
PVOID BaseAddress
Definition: bl.h:1277
#define ULONG_MAX
Definition: limits.h:44
LONGLONG QuadPart
Definition: typedefs.h:112
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
#define _Inout_opt_
Definition: no_sal2.h:258
BL_BCD_OPTION BcdData
Definition: bl.h:861
NTSTATUS BlFileReadAtOffsetEx(_In_ ULONG FileId, _In_ ULONG Size, _In_ ULONGLONG ByteOffset, _In_ PVOID Buffer, _Out_ PULONG BytesReturned, _In_ ULONG Flags)
Definition: file.c:788
struct _BL_RETURN_ARGUMENTS * PBL_RETURN_ARGUMENTS
ULONG DescriptorCount
Definition: bl.h:802