EmulatorPkg/Win: Add Windows host support

This is the initial patch to make it boot to early DXE
phase without display (only debug message).

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Cc: Andrew Fish <afish@apple.com>
This commit is contained in:
Ruiyu Ni 2018-08-23 13:02:52 +08:00
parent 47c04c382e
commit 3c859dfebb
7 changed files with 1716 additions and 0 deletions

View File

@ -251,6 +251,13 @@
EmulatorPkg/Unix/Host/Host.inf
!endif
!ifdef $(WIN_SEC_BUILD)
##
# Emulator, OS WIN application
##
EmulatorPkg/Win/Host/WinHost.inf
!endif
!ifndef $(SKIP_MAIN_BUILD)
#
# Generic SEC

View File

@ -0,0 +1,940 @@
/**@file
WinNt emulator of pre-SEC phase. It's really a Win32 application, but this is
Ok since all the other modules for NT32 are NOT Win32 applications.
This program gets NT32 PCD setting and figures out what the memory layout
will be, how may FD's will be loaded and also what the boot mode is.
This code produces 128 K of temporary memory for the SEC stack by directly
allocate memory space with ReadWrite and Execute attribute.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "WinHost.h"
#ifndef SE_TIME_ZONE_NAME
#define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege")
#endif
//
// Default information about where the FD is located.
// This array gets filled in with information from PcdWinNtFirmwareVolume
// The number of array elements is allocated base on parsing
// PcdWinNtFirmwareVolume and the memory is never freed.
//
UINTN gFdInfoCount = 0;
NT_FD_INFO *gFdInfo;
//
// Array that supports seperate memory rantes.
// The memory ranges are set by PcdWinNtMemorySizeForSecMain.
// The number of array elements is allocated base on parsing
// PcdWinNtMemorySizeForSecMain value and the memory is never freed.
//
UINTN gSystemMemoryCount = 0;
NT_SYSTEM_MEMORY *gSystemMemory;
/*++
Routine Description:
This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
It allows discontinuous memory regions to be supported by the emulator.
It uses gSystemMemory[] and gSystemMemoryCount that were created by
parsing the host environment variable EFI_MEMORY_SIZE.
The size comes from the varaible and the address comes from the call to
UnixOpenFile.
Arguments:
Index - Which memory region to use
MemoryBase - Return Base address of memory region
MemorySize - Return size in bytes of the memory region
Returns:
EFI_SUCCESS - If memory region was mapped
EFI_UNSUPPORTED - If Index is not supported
**/
EFI_STATUS
WinPeiAutoScan (
IN UINTN Index,
OUT EFI_PHYSICAL_ADDRESS *MemoryBase,
OUT UINT64 *MemorySize
)
{
if (Index >= gSystemMemoryCount) {
return EFI_UNSUPPORTED;
}
//
// Allocate enough memory space for emulator
//
gSystemMemory[Index].Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (gSystemMemory[Index].Size), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (gSystemMemory[Index].Memory == 0) {
return EFI_OUT_OF_RESOURCES;
}
*MemoryBase = gSystemMemory[Index].Memory;
*MemorySize = gSystemMemory[Index].Size;
return EFI_SUCCESS;
}
/*++
Routine Description:
Return the FD Size and base address. Since the FD is loaded from a
file into host memory only the SEC will know it's address.
Arguments:
Index - Which FD, starts at zero.
FdSize - Size of the FD in bytes
FdBase - Start address of the FD. Assume it points to an FV Header
FixUp - Difference between actual FD address and build address
Returns:
EFI_SUCCESS - Return the Base address and size of the FV
EFI_UNSUPPORTED - Index does nto map to an FD in the system
**/
EFI_STATUS
WinFdAddress (
IN UINTN Index,
IN OUT EFI_PHYSICAL_ADDRESS *FdBase,
IN OUT UINT64 *FdSize,
IN OUT EFI_PHYSICAL_ADDRESS *FixUp
)
{
if (Index >= gFdInfoCount) {
return EFI_UNSUPPORTED;
}
*FdBase = (EFI_PHYSICAL_ADDRESS)(UINTN)gFdInfo[Index].Address;
*FdSize = (UINT64)gFdInfo[Index].Size;
*FixUp = 0;
if (*FdBase == 0 && *FdSize == 0) {
return EFI_UNSUPPORTED;
}
if (Index == 0) {
//
// FD 0 has XIP code and well known PCD values
// If the memory buffer could not be allocated at the FD build address
// the Fixup is the difference.
//
*FixUp = *FdBase - PcdGet64 (PcdEmuFdBaseAddress);
}
return EFI_SUCCESS;
}
/*++
Routine Description:
Since the SEC is the only Unix program in stack it must export
an interface to do POSIX calls. gUnix is initialized in UnixThunk.c.
Arguments:
InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);
InterfaceBase - Address of the gUnix global
Returns:
EFI_SUCCESS - Data returned
**/
VOID *
WinThunk (
VOID
)
{
return &gEmuThunkProtocol;
}
EMU_THUNK_PPI mSecEmuThunkPpi = {
WinPeiAutoScan,
WinFdAddress,
WinThunk
};
VOID
SecPrint (
CHAR8 *Format,
...
)
{
va_list Marker;
UINTN CharCount;
CHAR8 Buffer[0x1000];
va_start (Marker, Format);
_vsnprintf (Buffer, sizeof (Buffer), Format, Marker);
va_end (Marker);
CharCount = strlen (Buffer);
WriteFile (
GetStdHandle (STD_OUTPUT_HANDLE),
Buffer,
(DWORD)CharCount,
(LPDWORD)&CharCount,
NULL
);
}
/*++
Routine Description:
Check to see if an address range is in the EFI GCD memory map.
This is all of GCD for system memory passed to DXE Core. FV
mapping and other device mapped into system memory are not
inlcuded in the check.
Arguments:
Index - Which memory region to use
MemoryBase - Return Base address of memory region
MemorySize - Return size in bytes of the memory region
Returns:
TRUE - Address is in the EFI GCD memory map
FALSE - Address is NOT in memory map
**/
BOOLEAN
EfiSystemMemoryRange (
IN VOID *MemoryAddress
)
{
UINTN Index;
EFI_PHYSICAL_ADDRESS MemoryBase;
MemoryBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryAddress;
for (Index = 0; Index < gSystemMemoryCount; Index++) {
if ((MemoryBase >= gSystemMemory[Index].Memory) &&
(MemoryBase < (gSystemMemory[Index].Memory + gSystemMemory[Index].Size)) ) {
return TRUE;
}
}
return FALSE;
}
EFI_STATUS
WinNtOpenFile (
IN CHAR16 *FileName, OPTIONAL
IN UINT32 MapSize,
IN DWORD CreationDisposition,
IN OUT VOID **BaseAddress,
OUT UINTN *Length
)
/*++
Routine Description:
Opens and memory maps a file using WinNt services. If *BaseAddress is non zero
the process will try and allocate the memory starting at BaseAddress.
Arguments:
FileName - The name of the file to open and map
MapSize - The amount of the file to map in bytes
CreationDisposition - The flags to pass to CreateFile(). Use to create new files for
memory emulation, and exiting files for firmware volume emulation
BaseAddress - The base address of the mapped file in the user address space.
If *BaseAddress is 0, the new memory region is used.
If *BaseAddress is not 0, the request memory region is used for
the mapping of the file into the process space.
Length - The size of the mapped region in bytes
Returns:
EFI_SUCCESS - The file was opened and mapped.
EFI_NOT_FOUND - FileName was not found in the current directory
EFI_DEVICE_ERROR - An error occured attempting to map the opened file
--*/
{
HANDLE NtFileHandle;
HANDLE NtMapHandle;
VOID *VirtualAddress;
UINTN FileSize;
//
// Use Win API to open/create a file
//
NtFileHandle = INVALID_HANDLE_VALUE;
if (FileName != NULL) {
NtFileHandle = CreateFile (
FileName,
GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
FILE_SHARE_READ,
NULL,
CreationDisposition,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (NtFileHandle == INVALID_HANDLE_VALUE) {
return EFI_NOT_FOUND;
}
}
//
// Map the open file into a memory range
//
NtMapHandle = CreateFileMapping (
NtFileHandle,
NULL,
PAGE_EXECUTE_READWRITE,
0,
MapSize,
NULL
);
if (NtMapHandle == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Get the virtual address (address in the emulator) of the mapped file
//
VirtualAddress = MapViewOfFileEx (
NtMapHandle,
FILE_MAP_EXECUTE | FILE_MAP_ALL_ACCESS,
0,
0,
MapSize,
*BaseAddress
);
if (VirtualAddress == NULL) {
return EFI_DEVICE_ERROR;
}
if (MapSize == 0) {
//
// Seek to the end of the file to figure out the true file size.
//
FileSize = SetFilePointer (
NtFileHandle,
0,
NULL,
FILE_END
);
if (FileSize == -1) {
return EFI_DEVICE_ERROR;
}
*Length = FileSize;
} else {
*Length = MapSize;
}
*BaseAddress = VirtualAddress;
return EFI_SUCCESS;
}
INTN
EFIAPI
main (
IN INTN Argc,
IN CHAR8 **Argv,
IN CHAR8 **Envp
)
/*++
Routine Description:
Main entry point to SEC for WinNt. This is a Windows program
Arguments:
Argc - Number of command line arguments
Argv - Array of command line argument strings
Envp - Array of environment variable strings
Returns:
0 - Normal exit
1 - Abnormal exit
--*/
{
EFI_STATUS Status;
HANDLE Token;
TOKEN_PRIVILEGES TokenPrivileges;
VOID *TemporaryRam;
UINT32 TemporaryRamSize;
VOID *EmuMagicPage;
UINTN Index;
UINTN Index1;
CHAR16 *FileName;
CHAR16 *FileNamePtr;
BOOLEAN Done;
EFI_PEI_FILE_HANDLE FileHandle;
VOID *SecFile;
CHAR16 *MemorySizeStr;
CHAR16 *FirmwareVolumesStr;
UINT32 ProcessAffinityMask;
UINT32 SystemAffinityMask;
INT32 LowBit;
//
// Enable the privilege so that RTC driver can successfully run SetTime()
//
OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token);
if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) {
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0);
}
MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize);
FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume);
SecPrint ("\nEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n");
//
// Determine the first thread available to this process.
//
if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) {
LowBit = (INT32)LowBitSet32 (ProcessAffinityMask);
if (LowBit != -1) {
//
// Force the system to bind the process to a single thread to work
// around odd semaphore type crashes.
//
SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit));
}
}
//
// Make some Windows calls to Set the process to the highest priority in the
// idle class. We need this to have good performance.
//
SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
SecInitializeThunk ();
//
// PPIs pased into PEI_CORE
//
AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi);
//
// Allocate space for gSystemMemory Array
//
gSystemMemoryCount = CountSeparatorsInString (MemorySizeStr, '!') + 1;
gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));
if (gSystemMemory == NULL) {
SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", MemorySizeStr);
exit (1);
}
//
// Allocate space for gSystemMemory Array
//
gFdInfoCount = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1;
gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO));
if (gFdInfo == NULL) {
SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", FirmwareVolumesStr);
exit (1);
}
//
// Setup Boot Mode.
//
SecPrint (" BootMode 0x%02x\n", PcdGet32 (PcdEmuBootMode));
//
// Allocate 128K memory to emulate temp memory for PEI.
// on a real platform this would be SRAM, or using the cache as RAM.
// Set TemporaryRam to zero so WinNtOpenFile will allocate a new mapping
//
TemporaryRamSize = TEMPORARY_RAM_SIZE;
TemporaryRam = VirtualAlloc (NULL, (SIZE_T) (TemporaryRamSize), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (TemporaryRam == NULL) {
SecPrint ("ERROR : Can not allocate enough space for SecStack\n");
exit (1);
}
SetMemN (TemporaryRam, TemporaryRamSize, PcdGet32 (PcdInitValueInTempStack));
SecPrint (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n",
TemporaryRamSize / SIZE_1KB,
TemporaryRam
);
//
// If enabled use the magic page to communicate between modules
// This replaces the PI PeiServicesTable pointer mechanism that
// deos not work in the emulator. It also allows the removal of
// writable globals from SEC, PEI_CORE (libraries), PEIMs
//
EmuMagicPage = (VOID *)(UINTN)(FixedPcdGet64 (PcdPeiServicesTablePage) & MAX_UINTN);
if (EmuMagicPage != NULL) {
UINT64 Size;
Status = WinNtOpenFile (
NULL,
SIZE_4KB,
0,
&EmuMagicPage,
&Size
);
if (EFI_ERROR (Status)) {
SecPrint ("ERROR : Could not allocate PeiServicesTablePage @ %p\n", EmuMagicPage);
return EFI_DEVICE_ERROR;
}
}
//
// Open All the firmware volumes and remember the info in the gFdInfo global
// Meanwhile, find the SEC Core.
//
FileNamePtr = AllocateCopyPool (StrSize (FirmwareVolumesStr), FirmwareVolumesStr);
if (FileNamePtr == NULL) {
SecPrint ("ERROR : Can not allocate memory for firmware volume string\n");
exit (1);
}
for (Done = FALSE, Index = 0, SecFile = NULL; !Done; Index++) {
FileName = FileNamePtr;
for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)
;
if (FileNamePtr[Index1] == 0) {
Done = TRUE;
} else {
FileNamePtr[Index1] = '\0';
FileNamePtr = &FileNamePtr[Index1 + 1];
}
//
// Open the FD and remember where it got mapped into our processes address space
//
Status = WinNtOpenFile (
FileName,
0,
OPEN_EXISTING,
&gFdInfo[Index].Address,
&gFdInfo[Index].Size
);
if (EFI_ERROR (Status)) {
SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X). Exiting.\n", FileName, Status);
exit (1);
}
SecPrint (" FD loaded from %S\n", FileName);
if (SecFile == NULL) {
//
// Assume the beginning of the FD is an FV and look for the SEC Core.
// Load the first one we find.
//
FileHandle = NULL;
Status = PeiServicesFfsFindNextFile (
EFI_FV_FILETYPE_SECURITY_CORE,
(EFI_PEI_FV_HANDLE)gFdInfo[Index].Address,
&FileHandle
);
if (!EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile);
if (!EFI_ERROR (Status)) {
SecPrint (" contains SEC Core");
}
}
}
SecPrint ("\n");
}
//
// Calculate memory regions and store the information in the gSystemMemory
// global for later use. The autosizing code will use this data to
// map this memory into the SEC process memory space.
//
for (Index = 0, Done = FALSE; !Done; Index++) {
//
// Save the size of the memory and make a Unicode filename SystemMemory00, ...
//
gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * SIZE_1MB;
//
// Find the next region
//
for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)
;
if (MemorySizeStr[Index1] == 0) {
Done = TRUE;
}
MemorySizeStr = MemorySizeStr + Index1 + 1;
}
SecPrint ("\n");
//
// Hand off to SEC Core
//
SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile);
//
// If we get here, then the SEC Core returned. This is an error as SEC should
// always hand off to PEI Core and then on to DXE Core.
//
SecPrint ("ERROR : SEC returned\n");
exit (1);
}
VOID
SecLoadSecCore (
IN UINTN TemporaryRam,
IN UINTN TemporaryRamSize,
IN VOID *BootFirmwareVolumeBase,
IN UINTN BootFirmwareVolumeSize,
IN VOID *SecCorePe32File
)
/*++
Routine Description:
This is the service to load the SEC Core from the Firmware Volume
Arguments:
TemporaryRam - Memory to use for SEC.
TemporaryRamSize - Size of Memory to use for SEC
BootFirmwareVolumeBase - Start of the Boot FV
SecCorePe32File - SEC Core PE32
Returns:
Success means control is transfered and thus we should never return
--*/
{
EFI_STATUS Status;
VOID *TopOfStack;
VOID *SecCoreEntryPoint;
EFI_SEC_PEI_HAND_OFF *SecCoreData;
UINTN SecStackSize;
//
// Compute Top Of Memory for Stack and PEI Core Allocations
//
SecStackSize = TemporaryRamSize >> 1;
//
// |-----------| <---- TemporaryRamBase + TemporaryRamSize
// | Heap |
// | |
// |-----------| <---- StackBase / PeiTemporaryMemoryBase
// | |
// | Stack |
// |-----------| <---- TemporaryRamBase
//
TopOfStack = (VOID *)(TemporaryRam + SecStackSize);
//
// Reservet space for storing PeiCore's parament in stack.
//
TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT);
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
//
// Bind this information into the SEC hand-off state
//
SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN)TopOfStack;
SecCoreData->DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
SecCoreData->BootFirmwareVolumeBase = BootFirmwareVolumeBase;
SecCoreData->BootFirmwareVolumeSize = BootFirmwareVolumeSize;
SecCoreData->TemporaryRamBase = (VOID*)TemporaryRam;
SecCoreData->TemporaryRamSize = TemporaryRamSize;
SecCoreData->StackBase = SecCoreData->TemporaryRamBase;
SecCoreData->StackSize = SecStackSize;
SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + SecStackSize);
SecCoreData->PeiTemporaryRamSize = TemporaryRamSize - SecStackSize;
//
// Load the PEI Core from a Firmware Volume
//
Status = SecPeCoffGetEntryPoint (
SecCorePe32File,
&SecCoreEntryPoint
);
if (EFI_ERROR (Status)) {
return ;
}
//
// Transfer control to the SEC Core
//
SwitchStack (
(SWITCH_STACK_ENTRY_POINT)SecCoreEntryPoint,
SecCoreData,
GetThunkPpiList (),
TopOfStack
);
//
// If we get here, then the SEC Core returned. This is an error
//
return ;
}
RETURN_STATUS
EFIAPI
SecPeCoffGetEntryPoint (
IN VOID *Pe32Data,
IN OUT VOID **EntryPoint
)
{
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Allocate space in NT (not emulator) memory with ReadWrite and Execute attribute.
// Extra space is for alignment
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (ImageContext.ImageAddress == 0) {
return EFI_OUT_OF_RESOURCES;
}
//
// Align buffer on section boundary
//
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
*EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
SecImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
Arguments:
FileHandle - The handle to the PE/COFF file
FileOffset - The offset, in bytes, into the file to read
ReadSize - The number of bytes to read from the file starting at FileOffset
Buffer - A pointer to the buffer to read the data into.
Returns:
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
--*/
{
CHAR8 *Destination8;
CHAR8 *Source8;
UINTN Length;
Destination8 = Buffer;
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
Length = *ReadSize;
while (Length--) {
*(Destination8++) = *(Source8++);
}
return EFI_SUCCESS;
}
CHAR16 *
AsciiToUnicode (
IN CHAR8 *Ascii,
IN UINTN *StrLen OPTIONAL
)
/*++
Routine Description:
Convert the passed in Ascii string to Unicode.
Optionally return the length of the strings.
Arguments:
Ascii - Ascii string to convert
StrLen - Length of string
Returns:
Pointer to malloc'ed Unicode version of Ascii
--*/
{
UINTN Index;
CHAR16 *Unicode;
//
// Allocate a buffer for unicode string
//
for (Index = 0; Ascii[Index] != '\0'; Index++)
;
Unicode = malloc ((Index + 1) * sizeof (CHAR16));
if (Unicode == NULL) {
return NULL;
}
for (Index = 0; Ascii[Index] != '\0'; Index++) {
Unicode[Index] = (CHAR16) Ascii[Index];
}
Unicode[Index] = '\0';
if (StrLen != NULL) {
*StrLen = Index;
}
return Unicode;
}
UINTN
CountSeparatorsInString (
IN CONST CHAR16 *String,
IN CHAR16 Separator
)
/*++
Routine Description:
Count the number of separators in String
Arguments:
String - String to process
Separator - Item to count
Returns:
Number of Separator in String
--*/
{
UINTN Count;
for (Count = 0; *String != '\0'; String++) {
if (*String == Separator) {
Count++;
}
}
return Count;
}
VOID
EFIAPI
PeCoffLoaderRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
VOID *DllEntryPoint;
CHAR16 *DllFileName;
HMODULE Library;
UINTN Index;
ASSERT (ImageContext != NULL);
//
// If we load our own PE COFF images the Windows debugger can not source
// level debug our code. If a valid PDB pointer exists usw it to load
// the *.dll file as a library using Windows* APIs. This allows
// source level debug. The image is still loaded and relocated
// in the Framework memory space like on a real system (by the code above),
// but the entry point points into the DLL loaded by the code bellow.
//
DllEntryPoint = NULL;
//
// Load the DLL if it's not an EBC image.
//
if ((ImageContext->PdbPointer != NULL) &&
(ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) {
//
// Convert filename from ASCII to Unicode
//
DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index);
//
// Check that we have a valid filename
//
if (Index < 5 || DllFileName[Index - 4] != '.') {
free (DllFileName);
//
// Never return an error if PeCoffLoaderRelocateImage() succeeded.
// The image will run, but we just can't source level debug. If we
// return an error the image will not run.
//
return;
}
//
// Replace .PDB with .DLL on the filename
//
DllFileName[Index - 3] = 'D';
DllFileName[Index - 2] = 'L';
DllFileName[Index - 1] = 'L';
//
// Load the .DLL file into the user process's address space for source
// level debug
//
Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);
if (Library != NULL) {
//
// InitializeDriver is the entry point we put in all our EFI DLL's. The
// DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() suppresses the
// normal DLL entry point of DllMain, and prevents other modules that are
// referenced in side the DllFileName from being loaded. There is no error
// checking as the we can point to the PE32 image loaded by Tiano. This
// step is only needed for source level debugging
//
DllEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver");
}
if ((Library != NULL) && (DllEntryPoint != NULL)) {
ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;
SecPrint ("LoadLibraryEx (%S,\n NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName);
} else {
SecPrint ("WARNING: No source level debug %S. \n", DllFileName);
}
free (DllFileName);
}
}
VOID
EFIAPI
PeCoffLoaderUnloadImageExtraAction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
ASSERT (ImageContext != NULL);
}
VOID
_ModuleEntryPoint (
VOID
)
{
}

View File

@ -0,0 +1,200 @@
/**@file
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
WinHost.h
Abstract:
Include file for Windows Host
**/
#ifndef _HOST_H_
#define _HOST_H_
#include <stdio.h>
#include <time.h>
#include "WinInclude.h"
#include <PiPei.h>
#include <IndustryStandard/PeImage.h>
#include <Ppi/EmuThunk.h>
#include <Protocol/EmuThunk.h>
#include <Library/BaseLib.h>
#include <Library/PeCoffLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ThunkPpiList.h>
#include <Library/ThunkProtocolList.h>
#include <Library/PcdLib.h>
#include <Library/PrintLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeCoffExtraActionLib.h>
#define TEMPORARY_RAM_SIZE 0x20000
typedef struct {
VOID *Address;
UINTN Size;
} NT_FD_INFO;
typedef struct {
EFI_PHYSICAL_ADDRESS Memory;
UINT64 Size;
} NT_SYSTEM_MEMORY;
RETURN_STATUS
EFIAPI
SecPeCoffGetEntryPoint (
IN VOID *Pe32Data,
IN OUT VOID **EntryPoint
);
VOID
SecLoadSecCore (
IN UINTN TemporaryRam,
IN UINTN TemporaryRamSize,
IN VOID *BootFirmwareVolumeBase,
IN UINTN BootFirmwareVolumeSize,
IN VOID *SecCorePe32File
)
/*++
Routine Description:
This is the service to load the SEC Core from the Firmware Volume
Arguments:
TemporaryRam - Memory to use for SEC.
TemporaryRamSize - Size of Memory to use for SEC
BootFirmwareVolumeBase - Start of the Boot FV
SecCorePe32File - SEC Core PE32
Returns:
Success means control is transfered and thus we should never return
--*/
;
EFI_STATUS
EFIAPI
SecWinNtFdAddress (
IN UINTN Index,
IN OUT EFI_PHYSICAL_ADDRESS *FdBase,
IN OUT UINT64 *FdSize
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Index - TODO: add argument description
FdBase - TODO: add argument description
FdSize - TODO: add argument description
Returns:
TODO: add return values
--*/
;
EFI_STATUS
EFIAPI
SecImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
TODO: Add function description
Arguments:
FileHandle - TODO: add argument description
FileOffset - TODO: add argument description
ReadSize - TODO: add argument description
Buffer - TODO: add argument description
Returns:
TODO: add return values
--*/
;
CHAR16 *
AsciiToUnicode (
IN CHAR8 *Ascii,
IN UINTN *StrLen OPTIONAL
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Ascii - TODO: add argument description
StrLen - TODO: add argument description
Returns:
TODO: add return values
--*/
;
UINTN
CountSeparatorsInString (
IN CONST CHAR16 *String,
IN CHAR16 Separator
)
/*++
Routine Description:
TODO: Add function description
Arguments:
String - TODO: add argument description
Separator - TODO: add argument description
Returns:
TODO: add return values
--*/
;
BOOLEAN
EfiSystemMemoryRange (
IN VOID *MemoryAddress
);
VOID
SecInitializeThunk (
VOID
);
extern EMU_THUNK_PROTOCOL gEmuThunkProtocol;
#endif

View File

@ -0,0 +1,88 @@
## @file
# Entry Point of Win Emulator
#
# Main executable file of Win Emulator that loads Sec core after initialization finished.
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = WinHost
FILE_GUID = 62E8F833-2B0A-4C19-A966-63C180588BE7
MODULE_TYPE = USER_DEFINED
VERSION_STRING = 1.0
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
WinMemoryAllocationLib.c
WinThunk.c
WinHost.h
WinHost.c
WinInclude.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmulatorPkg/EmulatorPkg.dec
[LibraryClasses]
DebugLib
PcdLib
PrintLib
BaseMemoryLib
BaseLib
PeCoffLib
ThunkPpiList
ThunkProtocolList
PpiListLib
PeiServicesLib
[Ppis]
gEmuThunkPpiGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack
gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode
gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume
gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize
gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress
gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage
[BuildOptions]
*_*_*_DLINK_FLAGS == /out:"$(BIN_DIR)\$(BASE_NAME).exe" /base:0x10000000 /pdb:"$(BIN_DIR)\$(BASE_NAME).pdb"
:*_*_*_CC_FLAGS == /nologo /W4 /WX /Gy /c /D UNICODE /Od /Oy- /FIAutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
*_*_*_PP_FLAGS == /nologo /E /TC /FIAutoGen.h
MSFT:*_*_IA32_DLINK_FLAGS = /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib
MSFT:*_VS2015_IA32_DLINK_FLAGS = /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib vcruntimed.lib ucrtd.lib
MSFT:*_VS2015x86_IA32_DLINK_FLAGS = /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib vcruntimed.lib ucrtd.lib
MSFT:*_VS2017_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib
MSFT:*_*_IA32_ASM_FLAGS == /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
MSFT:*_*_IA32_ASMLINK_FLAGS == /link /nologo /tiny
MSFT:*_*_X64_DLINK_FLAGS = /LIBPATH:"$(VCINSTALLDIR)\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib
MSFT:*_VS2015_X64_DLINK_FLAGS = /LIBPATH:"$(VCINSTALLDIR)\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib
MSFT:*_VS2015x86_X64_DLINK_FLAGS = /LIBPATH:"$(VCINSTALLDIR)\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib
MSFT:*_VS2017_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib
MSFT:*_*_X64_ASM_FLAGS == /nologo /W3 /WX /c /Cx /Zd /W0 /Zi
MSFT:*_*_X64_ASMLINK_FLAGS == /link /nologo
INTEL:*_*_IA32_DLINK_FLAGS = /LIBPATH:"C:\Program Files\Intel\Compiler\C++\9.1\IA32\Lib" /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib
INTEL:*_*_IA32_ASM_FLAGS == /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
INTEL:*_*_IA32_ASMLINK_FLAGS == /link /nologo /tiny

View File

@ -0,0 +1,75 @@
/**@file
Public include file for the WinNt Library
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __WIN_NT_INCLUDE_H__
#define __WIN_NT_INCLUDE_H__
//
// Win32 include files do not compile clean with /W4, so we use the warning
// pragma to suppress the warnings for Win32 only. This way our code can stil
// compile at /W4 (highest warning level) with /WX (warnings cause build
// errors).
//
#pragma warning(disable : 4115)
#pragma warning(disable : 4201)
#pragma warning(disable : 4028)
#pragma warning(disable : 4133)
#define GUID _WINNT_DUP_GUID_____
#define _LIST_ENTRY _WINNT_DUP_LIST_ENTRY_FORWARD
#define LIST_ENTRY _WINNT_DUP_LIST_ENTRY
#if defined (MDE_CPU_IA32) && (_MSC_VER < 1800)
#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement
#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement
#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64
#endif
#undef UNALIGNED
#undef CONST
#undef VOID
#undef DEBUG_EVENT
// WQBugBug: This typedef is to make "windows.h" buildable.
// It should be removed after the root cause why
// size_t is undefined when go into the line below is found.
#if defined (MDE_CPU_IA32)
typedef UINT32 size_t ;
#endif
#include "windows.h"
#undef GUID
#undef _LIST_ENTRY
#undef LIST_ENTRY
#undef InterlockedIncrement
#undef InterlockedDecrement
#undef InterlockedCompareExchange64
#undef InterlockedCompareExchangePointer
#undef CreateEventEx
#define VOID void
//
// Prevent collisions with Windows API name macros that deal with Unicode/Not issues
//
#undef LoadImage
#undef CreateEvent
#undef FAR
//
// Set the warnings back on as the EFI code must be /W4.
//
#pragma warning(default : 4115)
#pragma warning(default : 4201)
#endif

View File

@ -0,0 +1,178 @@
/*++ @file
Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Base.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <stdlib.h>
/**
Allocates a buffer of type EfiBootServicesData.
Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
@param AllocationSize The number of bytes to allocate.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
EFIAPI
AllocatePool (
IN UINTN AllocationSize
)
{
return (VOID*) malloc (AllocationSize);
}
/**
Allocates and zeros a buffer of type EfiBootServicesData.
Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
request, then NULL is returned.
@param AllocationSize The number of bytes to allocate and zero.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
EFIAPI
AllocateZeroPool (
IN UINTN AllocationSize
)
{
VOID *Buffer;
Buffer = AllocatePool (AllocationSize);
if (Buffer == NULL) {
return NULL;
}
ZeroMem (Buffer, AllocationSize);
return Buffer;
}
/**
Reallocates a buffer of type EfiBootServicesData.
Allocates and zeros the number bytes specified by NewSize from memory of type
EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
OldBuffer is freed. A pointer to the newly allocated buffer is returned.
If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
enough memory remaining to satisfy the request, then NULL is returned.
If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
@param OldSize The size, in bytes, of OldBuffer.
@param NewSize The size, in bytes, of the buffer to reallocate.
@param OldBuffer The buffer to copy to the allocated buffer. This is an optional
parameter that may be NULL.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
EFIAPI
ReallocatePool (
IN UINTN OldSize,
IN UINTN NewSize,
IN VOID *OldBuffer OPTIONAL
)
{
VOID *NewBuffer;
NewBuffer = AllocatePool (NewSize);
if (NewBuffer == NULL) {
return NULL;
}
if (OldBuffer != NULL) {
if (OldSize > 0) {
CopyMem (NewBuffer, OldBuffer, OldSize);
}
FreePool (OldBuffer);
}
return NewBuffer;
}
/**
Copies a buffer to an allocated buffer of type EfiBootServicesData.
Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
is not enough memory remaining to satisfy the request, then NULL is returned.
If Buffer is NULL, then ASSERT().
If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
@param AllocationSize The number of bytes to allocate and zero.
@param Buffer The buffer to copy to the allocated buffer.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
EFIAPI
AllocateCopyPool (
IN UINTN AllocationSize,
IN CONST VOID *Buffer
)
{
VOID *Memory;
Memory = AllocatePool (AllocationSize);
if (Memory != NULL) {
Memory = CopyMem (Memory, Buffer, AllocationSize);
}
return Memory;
}
/**
Frees a buffer that was previously allocated with one of the pool allocation functions in the
Memory Allocation Library.
Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
pool allocation services of the Memory Allocation Library. If it is not possible to free pool
resources, then this function will perform no actions.
If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
then ASSERT().
@param Buffer Pointer to the buffer to free.
**/
VOID
EFIAPI
FreePool (
IN VOID *Buffer
)
{
free ((void *) Buffer);
}

View File

@ -0,0 +1,228 @@
/**@file
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
WinNtThunk.c
Abstract:
Since the SEC is the only windows program in our emulation we
must use a Tiano mechanism to export Win32 APIs to other modules.
This is the role of the EFI_WIN_NT_THUNK_PROTOCOL.
The mWinNtThunkTable exists so that a change to EFI_WIN_NT_THUNK_PROTOCOL
will cause an error in initializing the array if all the member functions
are not added. It looks like adding a element to end and not initializing
it may cause the table to be initaliized with the members at the end being
set to zero. This is bad as jumping to zero will case the NT32 to crash.
All the member functions in mWinNtThunkTable are Win32
API calls, so please reference Microsoft documentation.
gWinNt is a a public exported global that contains the initialized
data.
**/
#include "WinHost.h"
UINTN
SecWriteStdErr (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return 0;
}
EFI_STATUS
SecConfigStdIn (
VOID
)
{
return EFI_SUCCESS;
}
UINTN
SecWriteStdOut (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return 0;
}
BOOLEAN
SecPollStdIn (
VOID
)
{
return FALSE;
}
UINTN
SecReadStdIn (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return 0;
}
VOID *
SecAlloc (
IN UINTN Size
)
{
return malloc ((size_t)Size);
}
BOOLEAN
SecFree (
IN VOID *Ptr
)
{
if (EfiSystemMemoryRange (Ptr)) {
// If an address range is in the EFI memory map it was alloced via EFI.
// So don't free those ranges and let the caller know.
return FALSE;
}
free (Ptr);
return TRUE;
}
VOID
SecSetTimer (
IN UINT64 TimerPeriod,
IN EMU_SET_TIMER_CALLBACK Callback
)
{
}
VOID
SecInitializeThunk (
VOID
)
{
}
VOID
SecEnableInterrupt (
VOID
)
{
}
VOID
SecDisableInterrupt (
VOID
)
{
}
UINT64
SecQueryPerformanceFrequency (
VOID
)
{
// Hard code to nanoseconds
return 1000000000ULL;
}
UINT64
SecQueryPerformanceCounter (
VOID
)
{
return 0;
}
VOID
SecSleep (
IN UINT64 Nanoseconds
)
{
Sleep ((DWORD)DivU64x32 (Nanoseconds, 1000000));
}
VOID
SecCpuSleep (
VOID
)
{
Sleep (1);
}
VOID
SecExit (
UINTN Status
)
{
exit ((int)Status);
}
VOID
SecGetTime (
OUT EFI_TIME *Time,
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
)
{
}
EFI_STATUS
SecSetTime (
IN EFI_TIME *Time
)
{
return EFI_SUCCESS;
}
EMU_THUNK_PROTOCOL gEmuThunkProtocol = {
SecWriteStdErr,
SecConfigStdIn,
SecWriteStdOut,
SecReadStdIn,
SecPollStdIn,
SecAlloc,
NULL,
SecFree,
SecPeCoffGetEntryPoint,
PeCoffLoaderRelocateImageExtraAction,
PeCoffLoaderUnloadImageExtraAction,
SecEnableInterrupt,
SecDisableInterrupt,
SecQueryPerformanceFrequency,
SecQueryPerformanceCounter,
SecSleep,
SecCpuSleep,
SecExit,
SecGetTime,
SecSetTime,
SecSetTimer,
GetNextThunkProtocol
};
#pragma warning(default : 4996)
#pragma warning(default : 4232)