2 WinNt emulator of pre-SEC phase. It's really a Win32 application, but this is
3 Ok since all the other modules for NT32 are NOT Win32 applications.
5 This program gets NT32 PCD setting and figures out what the memory layout
6 will be, how may FD's will be loaded and also what the boot mode is.
8 This code produces 128 K of temporary memory for the SEC stack by directly
9 allocate memory space with ReadWrite and Execute attribute.
11 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
12 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
13 This program and the accompanying materials
14 are licensed and made available under the terms and conditions of the BSD License
15 which accompanies this distribution. The full text of the license may be found at
16 http://opensource.org/licenses/bsd-license.php
18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 #ifndef SE_TIME_ZONE_NAME
25 #define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege")
29 // Default information about where the FD is located.
30 // This array gets filled in with information from PcdWinNtFirmwareVolume
31 // The number of array elements is allocated base on parsing
32 // PcdWinNtFirmwareVolume and the memory is never freed.
34 UINTN gFdInfoCount
= 0;
38 // Array that supports seperate memory rantes.
39 // The memory ranges are set by PcdWinNtMemorySizeForSecMain.
40 // The number of array elements is allocated base on parsing
41 // PcdWinNtMemorySizeForSecMain value and the memory is never freed.
43 UINTN gSystemMemoryCount
= 0;
44 NT_SYSTEM_MEMORY
*gSystemMemory
;
49 This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
50 It allows discontinuous memory regions to be supported by the emulator.
51 It uses gSystemMemory[] and gSystemMemoryCount that were created by
52 parsing the host environment variable EFI_MEMORY_SIZE.
53 The size comes from the varaible and the address comes from the call to
57 Index - Which memory region to use
58 MemoryBase - Return Base address of memory region
59 MemorySize - Return size in bytes of the memory region
62 EFI_SUCCESS - If memory region was mapped
63 EFI_UNSUPPORTED - If Index is not supported
69 OUT EFI_PHYSICAL_ADDRESS
*MemoryBase
,
70 OUT UINT64
*MemorySize
73 if (Index
>= gSystemMemoryCount
) {
74 return EFI_UNSUPPORTED
;
78 // Allocate enough memory space for emulator
80 gSystemMemory
[Index
].Memory
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) VirtualAlloc (NULL
, (SIZE_T
) (gSystemMemory
[Index
].Size
), MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
81 if (gSystemMemory
[Index
].Memory
== 0) {
82 return EFI_OUT_OF_RESOURCES
;
85 *MemoryBase
= gSystemMemory
[Index
].Memory
;
86 *MemorySize
= gSystemMemory
[Index
].Size
;
94 Return the FD Size and base address. Since the FD is loaded from a
95 file into host memory only the SEC will know it's address.
98 Index - Which FD, starts at zero.
99 FdSize - Size of the FD in bytes
100 FdBase - Start address of the FD. Assume it points to an FV Header
101 FixUp - Difference between actual FD address and build address
104 EFI_SUCCESS - Return the Base address and size of the FV
105 EFI_UNSUPPORTED - Index does nto map to an FD in the system
111 IN OUT EFI_PHYSICAL_ADDRESS
*FdBase
,
112 IN OUT UINT64
*FdSize
,
113 IN OUT EFI_PHYSICAL_ADDRESS
*FixUp
116 if (Index
>= gFdInfoCount
) {
117 return EFI_UNSUPPORTED
;
121 *FdBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)gFdInfo
[Index
].Address
;
122 *FdSize
= (UINT64
)gFdInfo
[Index
].Size
;
125 if (*FdBase
== 0 && *FdSize
== 0) {
126 return EFI_UNSUPPORTED
;
131 // FD 0 has XIP code and well known PCD values
132 // If the memory buffer could not be allocated at the FD build address
133 // the Fixup is the difference.
135 *FixUp
= *FdBase
- PcdGet64 (PcdEmuFdBaseAddress
);
144 Since the SEC is the only Unix program in stack it must export
145 an interface to do POSIX calls. gUnix is initialized in UnixThunk.c.
148 InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);
149 InterfaceBase - Address of the gUnix global
152 EFI_SUCCESS - Data returned
160 return &gEmuThunkProtocol
;
164 EMU_THUNK_PPI mSecEmuThunkPpi
= {
178 CHAR8 Buffer
[0x1000];
180 va_start (Marker
, Format
);
182 _vsnprintf (Buffer
, sizeof (Buffer
), Format
, Marker
);
186 CharCount
= strlen (Buffer
);
188 GetStdHandle (STD_OUTPUT_HANDLE
),
199 Check to see if an address range is in the EFI GCD memory map.
201 This is all of GCD for system memory passed to DXE Core. FV
202 mapping and other device mapped into system memory are not
203 inlcuded in the check.
206 Index - Which memory region to use
207 MemoryBase - Return Base address of memory region
208 MemorySize - Return size in bytes of the memory region
211 TRUE - Address is in the EFI GCD memory map
212 FALSE - Address is NOT in memory map
216 EfiSystemMemoryRange (
217 IN VOID
*MemoryAddress
221 EFI_PHYSICAL_ADDRESS MemoryBase
;
223 MemoryBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)MemoryAddress
;
224 for (Index
= 0; Index
< gSystemMemoryCount
; Index
++) {
225 if ((MemoryBase
>= gSystemMemory
[Index
].Memory
) &&
226 (MemoryBase
< (gSystemMemory
[Index
].Memory
+ gSystemMemory
[Index
].Size
)) ) {
237 IN CHAR16
*FileName
, OPTIONAL
239 IN DWORD CreationDisposition
,
240 IN OUT VOID
**BaseAddress
,
246 Opens and memory maps a file using WinNt services. If *BaseAddress is non zero
247 the process will try and allocate the memory starting at BaseAddress.
250 FileName - The name of the file to open and map
251 MapSize - The amount of the file to map in bytes
252 CreationDisposition - The flags to pass to CreateFile(). Use to create new files for
253 memory emulation, and exiting files for firmware volume emulation
254 BaseAddress - The base address of the mapped file in the user address space.
255 If *BaseAddress is 0, the new memory region is used.
256 If *BaseAddress is not 0, the request memory region is used for
257 the mapping of the file into the process space.
258 Length - The size of the mapped region in bytes
261 EFI_SUCCESS - The file was opened and mapped.
262 EFI_NOT_FOUND - FileName was not found in the current directory
263 EFI_DEVICE_ERROR - An error occured attempting to map the opened file
269 VOID
*VirtualAddress
;
273 // Use Win API to open/create a file
275 NtFileHandle
= INVALID_HANDLE_VALUE
;
276 if (FileName
!= NULL
) {
277 NtFileHandle
= CreateFile (
279 GENERIC_READ
| GENERIC_WRITE
| GENERIC_EXECUTE
,
283 FILE_ATTRIBUTE_NORMAL
,
286 if (NtFileHandle
== INVALID_HANDLE_VALUE
) {
287 return EFI_NOT_FOUND
;
291 // Map the open file into a memory range
293 NtMapHandle
= CreateFileMapping (
296 PAGE_EXECUTE_READWRITE
,
301 if (NtMapHandle
== NULL
) {
302 return EFI_DEVICE_ERROR
;
305 // Get the virtual address (address in the emulator) of the mapped file
307 VirtualAddress
= MapViewOfFileEx (
309 FILE_MAP_EXECUTE
| FILE_MAP_ALL_ACCESS
,
315 if (VirtualAddress
== NULL
) {
316 return EFI_DEVICE_ERROR
;
321 // Seek to the end of the file to figure out the true file size.
323 FileSize
= SetFilePointer (
329 if (FileSize
== -1) {
330 return EFI_DEVICE_ERROR
;
338 *BaseAddress
= VirtualAddress
;
353 Main entry point to SEC for WinNt. This is a Windows program
356 Argc - Number of command line arguments
357 Argv - Array of command line argument strings
358 Envp - Array of environment variable strings
368 TOKEN_PRIVILEGES TokenPrivileges
;
370 UINT32 TemporaryRamSize
;
377 EFI_PEI_FILE_HANDLE FileHandle
;
379 CHAR16
*MemorySizeStr
;
380 CHAR16
*FirmwareVolumesStr
;
381 UINT32 ProcessAffinityMask
;
382 UINT32 SystemAffinityMask
;
386 // Enable the privilege so that RTC driver can successfully run SetTime()
388 OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
|TOKEN_QUERY
, &Token
);
389 if (LookupPrivilegeValue(NULL
, SE_TIME_ZONE_NAME
, &TokenPrivileges
.Privileges
[0].Luid
)) {
390 TokenPrivileges
.PrivilegeCount
= 1;
391 TokenPrivileges
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
392 AdjustTokenPrivileges(Token
, FALSE
, &TokenPrivileges
, 0, (PTOKEN_PRIVILEGES
) NULL
, 0);
395 MemorySizeStr
= (CHAR16
*) PcdGetPtr (PcdEmuMemorySize
);
396 FirmwareVolumesStr
= (CHAR16
*) PcdGetPtr (PcdEmuFirmwareVolume
);
398 SecPrint ("\nEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n");
401 // Determine the first thread available to this process.
403 if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask
, &SystemAffinityMask
)) {
404 LowBit
= (INT32
)LowBitSet32 (ProcessAffinityMask
);
407 // Force the system to bind the process to a single thread to work
408 // around odd semaphore type crashes.
410 SetProcessAffinityMask (GetCurrentProcess (), (INTN
)(BIT0
<< LowBit
));
415 // Make some Windows calls to Set the process to the highest priority in the
416 // idle class. We need this to have good performance.
418 SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS
);
419 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST
);
421 SecInitializeThunk ();
423 // PPIs pased into PEI_CORE
425 AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI
, &gEmuThunkPpiGuid
, &mSecEmuThunkPpi
);
428 // Emulator Bus Driver Thunks
430 AddThunkProtocol (&mWinNtWndThunkIo
, (CHAR16
*)PcdGetPtr (PcdEmuGop
), TRUE
);
433 // Allocate space for gSystemMemory Array
435 gSystemMemoryCount
= CountSeparatorsInString (MemorySizeStr
, '!') + 1;
436 gSystemMemory
= calloc (gSystemMemoryCount
, sizeof (NT_SYSTEM_MEMORY
));
437 if (gSystemMemory
== NULL
) {
438 SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", MemorySizeStr
);
443 // Allocate space for gSystemMemory Array
445 gFdInfoCount
= CountSeparatorsInString (FirmwareVolumesStr
, '!') + 1;
446 gFdInfo
= calloc (gFdInfoCount
, sizeof (NT_FD_INFO
));
447 if (gFdInfo
== NULL
) {
448 SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", FirmwareVolumesStr
);
454 SecPrint (" BootMode 0x%02x\n", PcdGet32 (PcdEmuBootMode
));
457 // Allocate 128K memory to emulate temp memory for PEI.
458 // on a real platform this would be SRAM, or using the cache as RAM.
459 // Set TemporaryRam to zero so WinNtOpenFile will allocate a new mapping
461 TemporaryRamSize
= TEMPORARY_RAM_SIZE
;
462 TemporaryRam
= VirtualAlloc (NULL
, (SIZE_T
) (TemporaryRamSize
), MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
463 if (TemporaryRam
== NULL
) {
464 SecPrint ("ERROR : Can not allocate enough space for SecStack\n");
467 SetMemN (TemporaryRam
, TemporaryRamSize
, PcdGet32 (PcdInitValueInTempStack
));
469 SecPrint (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n",
470 TemporaryRamSize
/ SIZE_1KB
,
475 // If enabled use the magic page to communicate between modules
476 // This replaces the PI PeiServicesTable pointer mechanism that
477 // deos not work in the emulator. It also allows the removal of
478 // writable globals from SEC, PEI_CORE (libraries), PEIMs
480 EmuMagicPage
= (VOID
*)(UINTN
)(FixedPcdGet64 (PcdPeiServicesTablePage
) & MAX_UINTN
);
481 if (EmuMagicPage
!= NULL
) {
483 Status
= WinNtOpenFile (
490 if (EFI_ERROR (Status
)) {
491 SecPrint ("ERROR : Could not allocate PeiServicesTablePage @ %p\n", EmuMagicPage
);
492 return EFI_DEVICE_ERROR
;
497 // Open All the firmware volumes and remember the info in the gFdInfo global
498 // Meanwhile, find the SEC Core.
500 FileNamePtr
= AllocateCopyPool (StrSize (FirmwareVolumesStr
), FirmwareVolumesStr
);
501 if (FileNamePtr
== NULL
) {
502 SecPrint ("ERROR : Can not allocate memory for firmware volume string\n");
506 for (Done
= FALSE
, Index
= 0, SecFile
= NULL
; !Done
; Index
++) {
507 FileName
= FileNamePtr
;
508 for (Index1
= 0; (FileNamePtr
[Index1
] != '!') && (FileNamePtr
[Index1
] != 0); Index1
++)
510 if (FileNamePtr
[Index1
] == 0) {
513 FileNamePtr
[Index1
] = '\0';
514 FileNamePtr
= &FileNamePtr
[Index1
+ 1];
518 // Open the FD and remember where it got mapped into our processes address space
520 Status
= WinNtOpenFile (
524 &gFdInfo
[Index
].Address
,
527 if (EFI_ERROR (Status
)) {
528 SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X). Exiting.\n", FileName
, Status
);
532 SecPrint (" FD loaded from %S\n", FileName
);
534 if (SecFile
== NULL
) {
536 // Assume the beginning of the FD is an FV and look for the SEC Core.
537 // Load the first one we find.
540 Status
= PeiServicesFfsFindNextFile (
541 EFI_FV_FILETYPE_SECURITY_CORE
,
542 (EFI_PEI_FV_HANDLE
)gFdInfo
[Index
].Address
,
545 if (!EFI_ERROR (Status
)) {
546 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_PE32
, FileHandle
, &SecFile
);
547 if (!EFI_ERROR (Status
)) {
548 SecPrint (" contains SEC Core");
556 // Calculate memory regions and store the information in the gSystemMemory
557 // global for later use. The autosizing code will use this data to
558 // map this memory into the SEC process memory space.
560 for (Index
= 0, Done
= FALSE
; !Done
; Index
++) {
562 // Save the size of the memory and make a Unicode filename SystemMemory00, ...
564 gSystemMemory
[Index
].Size
= _wtoi (MemorySizeStr
) * SIZE_1MB
;
567 // Find the next region
569 for (Index1
= 0; MemorySizeStr
[Index1
] != '!' && MemorySizeStr
[Index1
] != 0; Index1
++)
571 if (MemorySizeStr
[Index1
] == 0) {
575 MemorySizeStr
= MemorySizeStr
+ Index1
+ 1;
581 // Hand off to SEC Core
583 SecLoadSecCore ((UINTN
)TemporaryRam
, TemporaryRamSize
, gFdInfo
[0].Address
, gFdInfo
[0].Size
, SecFile
);
586 // If we get here, then the SEC Core returned. This is an error as SEC should
587 // always hand off to PEI Core and then on to DXE Core.
589 SecPrint ("ERROR : SEC returned\n");
595 IN UINTN TemporaryRam
,
596 IN UINTN TemporaryRamSize
,
597 IN VOID
*BootFirmwareVolumeBase
,
598 IN UINTN BootFirmwareVolumeSize
,
599 IN VOID
*SecCorePe32File
604 This is the service to load the SEC Core from the Firmware Volume
607 TemporaryRam - Memory to use for SEC.
608 TemporaryRamSize - Size of Memory to use for SEC
609 BootFirmwareVolumeBase - Start of the Boot FV
610 SecCorePe32File - SEC Core PE32
613 Success means control is transfered and thus we should never return
619 VOID
*SecCoreEntryPoint
;
620 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
624 // Compute Top Of Memory for Stack and PEI Core Allocations
626 SecStackSize
= TemporaryRamSize
>> 1;
629 // |-----------| <---- TemporaryRamBase + TemporaryRamSize
632 // |-----------| <---- StackBase / PeiTemporaryMemoryBase
635 // |-----------| <---- TemporaryRamBase
637 TopOfStack
= (VOID
*)(TemporaryRam
+ SecStackSize
);
640 // Reservet space for storing PeiCore's parament in stack.
642 TopOfStack
= (VOID
*)((UINTN
)TopOfStack
- sizeof (EFI_SEC_PEI_HAND_OFF
) - CPU_STACK_ALIGNMENT
);
643 TopOfStack
= ALIGN_POINTER (TopOfStack
, CPU_STACK_ALIGNMENT
);
646 // Bind this information into the SEC hand-off state
648 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*)(UINTN
)TopOfStack
;
649 SecCoreData
->DataSize
= sizeof (EFI_SEC_PEI_HAND_OFF
);
650 SecCoreData
->BootFirmwareVolumeBase
= BootFirmwareVolumeBase
;
651 SecCoreData
->BootFirmwareVolumeSize
= BootFirmwareVolumeSize
;
652 SecCoreData
->TemporaryRamBase
= (VOID
*)TemporaryRam
;
653 SecCoreData
->TemporaryRamSize
= TemporaryRamSize
;
654 SecCoreData
->StackBase
= SecCoreData
->TemporaryRamBase
;
655 SecCoreData
->StackSize
= SecStackSize
;
656 SecCoreData
->PeiTemporaryRamBase
= (VOID
*) ((UINTN
) SecCoreData
->TemporaryRamBase
+ SecStackSize
);
657 SecCoreData
->PeiTemporaryRamSize
= TemporaryRamSize
- SecStackSize
;
660 // Load the PEI Core from a Firmware Volume
662 Status
= SecPeCoffGetEntryPoint (
666 if (EFI_ERROR (Status
)) {
671 // Transfer control to the SEC Core
674 (SWITCH_STACK_ENTRY_POINT
)SecCoreEntryPoint
,
680 // If we get here, then the SEC Core returned. This is an error
687 SecPeCoffGetEntryPoint (
689 IN OUT VOID
**EntryPoint
693 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
695 ZeroMem (&ImageContext
, sizeof (ImageContext
));
696 ImageContext
.Handle
= Pe32Data
;
698 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) SecImageRead
;
700 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
701 if (EFI_ERROR (Status
)) {
705 // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribute.
706 // Extra space is for alignment
708 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) VirtualAlloc (NULL
, (SIZE_T
) (ImageContext
.ImageSize
+ (ImageContext
.SectionAlignment
* 2)), MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
709 if (ImageContext
.ImageAddress
== 0) {
710 return EFI_OUT_OF_RESOURCES
;
713 // Align buffer on section boundary
715 ImageContext
.ImageAddress
+= ImageContext
.SectionAlignment
- 1;
716 ImageContext
.ImageAddress
&= ~((EFI_PHYSICAL_ADDRESS
)ImageContext
.SectionAlignment
- 1);
718 Status
= PeCoffLoaderLoadImage (&ImageContext
);
719 if (EFI_ERROR (Status
)) {
723 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
724 if (EFI_ERROR (Status
)) {
728 *EntryPoint
= (VOID
*)(UINTN
)ImageContext
.EntryPoint
;
738 IN OUT UINTN
*ReadSize
,
744 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
747 FileHandle - The handle to the PE/COFF file
748 FileOffset - The offset, in bytes, into the file to read
749 ReadSize - The number of bytes to read from the file starting at FileOffset
750 Buffer - A pointer to the buffer to read the data into.
753 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
761 Destination8
= Buffer
;
762 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
765 *(Destination8
++) = *(Source8
++);
774 IN UINTN
*StrLen OPTIONAL
779 Convert the passed in Ascii string to Unicode.
780 Optionally return the length of the strings.
783 Ascii - Ascii string to convert
784 StrLen - Length of string
787 Pointer to malloc'ed Unicode version of Ascii
795 // Allocate a buffer for unicode string
797 for (Index
= 0; Ascii
[Index
] != '\0'; Index
++)
799 Unicode
= malloc ((Index
+ 1) * sizeof (CHAR16
));
800 if (Unicode
== NULL
) {
804 for (Index
= 0; Ascii
[Index
] != '\0'; Index
++) {
805 Unicode
[Index
] = (CHAR16
) Ascii
[Index
];
808 Unicode
[Index
] = '\0';
810 if (StrLen
!= NULL
) {
818 CountSeparatorsInString (
819 IN CONST CHAR16
*String
,
825 Count the number of separators in String
828 String - String to process
829 Separator - Item to count
832 Number of Separator in String
838 for (Count
= 0; *String
!= '\0'; String
++) {
839 if (*String
== Separator
) {
850 PeCoffLoaderRelocateImageExtraAction (
851 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
859 ASSERT (ImageContext
!= NULL
);
861 // If we load our own PE COFF images the Windows debugger can not source
862 // level debug our code. If a valid PDB pointer exists usw it to load
863 // the *.dll file as a library using Windows* APIs. This allows
864 // source level debug. The image is still loaded and relocated
865 // in the Framework memory space like on a real system (by the code above),
866 // but the entry point points into the DLL loaded by the code bellow.
869 DllEntryPoint
= NULL
;
872 // Load the DLL if it's not an EBC image.
874 if ((ImageContext
->PdbPointer
!= NULL
) &&
875 (ImageContext
->Machine
!= EFI_IMAGE_MACHINE_EBC
)) {
877 // Convert filename from ASCII to Unicode
879 DllFileName
= AsciiToUnicode (ImageContext
->PdbPointer
, &Index
);
882 // Check that we have a valid filename
884 if (Index
< 5 || DllFileName
[Index
- 4] != '.') {
888 // Never return an error if PeCoffLoaderRelocateImage() succeeded.
889 // The image will run, but we just can't source level debug. If we
890 // return an error the image will not run.
895 // Replace .PDB with .DLL on the filename
897 DllFileName
[Index
- 3] = 'D';
898 DllFileName
[Index
- 2] = 'L';
899 DllFileName
[Index
- 1] = 'L';
902 // Load the .DLL file into the user process's address space for source
905 Library
= LoadLibraryEx (DllFileName
, NULL
, DONT_RESOLVE_DLL_REFERENCES
);
906 if (Library
!= NULL
) {
908 // InitializeDriver is the entry point we put in all our EFI DLL's. The
909 // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() suppresses the
910 // normal DLL entry point of DllMain, and prevents other modules that are
911 // referenced in side the DllFileName from being loaded. There is no error
912 // checking as the we can point to the PE32 image loaded by Tiano. This
913 // step is only needed for source level debugging
915 DllEntryPoint
= (VOID
*) (UINTN
) GetProcAddress (Library
, "InitializeDriver");
919 if ((Library
!= NULL
) && (DllEntryPoint
!= NULL
)) {
920 ImageContext
->EntryPoint
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) DllEntryPoint
;
921 SecPrint ("LoadLibraryEx (%S,\n NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName
);
923 SecPrint ("WARNING: No source level debug %S. \n", DllFileName
);
932 PeCoffLoaderUnloadImageExtraAction (
933 IN PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
936 ASSERT (ImageContext
!= NULL
);