misc.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 411 行
C
411 行
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
misc.c
Abstract:
Miscellaneous support routines for EFI emulation.
--*/
#include "ntemul.h"
#define EFI_RTC_NAME L"RTC"
#define EFI_ALARM_NAME L"ALARM"
#define EFI_ALARM_ENABLE_NAME L"ALARMEN"
//
// BugBug - get this from the platform time code. Need to find a common declaration point.
//
#define EFI_RTC_GUID \
{ 0xe4329f89, 0x546b, 0x11d4, 0x9a, 0x39, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }
EFI_GUID EfiRtcGuid = EFI_RTC_GUID;
VOID
PlSystemTimeToEfiTime (
IN SYSTEMTIME *SystemTime,
OUT EFI_TIME *Time
)
{
TIME_ZONE_INFORMATION TimeZone;
GetTimeZoneInformation (&TimeZone);
Time->Year = (UINT16) SystemTime->wYear;
Time->Month = (UINT8) SystemTime->wMonth;
Time->Day = (UINT8) SystemTime->wDay;
Time->Hour = (UINT8) SystemTime->wHour;
Time->Minute = (UINT8) SystemTime->wMinute;
Time->Second = (UINT8) SystemTime->wSecond;
Time->Nanosecond = (UINT32) SystemTime->wMilliseconds * 1000000;
Time->TimeZone = (INT16) TimeZone.Bias;
if (TimeZone.StandardDate.wMonth) {
Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;
}
}
VOID
PlEfiTimeToSystemTime (
IN EFI_TIME *Time,
OUT SYSTEMTIME *SystemTime
)
{
SystemTime->wYear = Time->Year;
SystemTime->wMonth = Time->Month;
SystemTime->wDay = Time->Day;
SystemTime->wHour = Time->Hour;
SystemTime->wMinute = Time->Minute;
SystemTime->wSecond = Time->Second;
SystemTime->wMilliseconds = Time->Nanosecond / 1000000;
}
EFI_STATUS
PlGetTime (
IN EFI_TIME *Time,
IN EFI_TIME_CAPABILITIES *Cap OPTIONAL
)
// Provide the EFI get time function
{
SYSTEMTIME SystemTime;
UINTN BufferSize;
EFI_STATUS Status;
if (Time == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (Time, sizeof(EFI_TIME));
GetSystemTime (&SystemTime);
PlSystemTimeToEfiTime (&SystemTime, Time);
Time->Nanosecond = 0;
BufferSize = sizeof(INT16) + sizeof(UINT8);
Status = RT->GetVariable (
EFI_RTC_NAME,
&EfiRtcGuid,
NULL,
&BufferSize,
&Time->TimeZone
);
if (Cap) {
ZeroMem (Cap, sizeof(EFI_TIME_CAPABILITIES));
Cap->Resolution = 1; // 1 hertz
Cap->Accuracy = 50000000; // 50 ppm
Cap->SetsToZero = FALSE;
}
return EFI_SUCCESS;
}
EFI_STATUS
PlTimeFieldsValid (
IN EFI_TIME *Time
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
if (Time->Year < 1998 || Time->Year > 2099) {
Status = EFI_INVALID_PARAMETER;
}
if (Time->Month < 1 || Time->Month > 12) {
Status = EFI_INVALID_PARAMETER;
}
if (Time->Day < 1) {
Status = EFI_INVALID_PARAMETER;
}
else {
if (Time->Month == 2) {
if ((Time->Year % 4 == 0 && Time->Year % 100 != 0) || Time->Year % 400 == 0) {
// Leap year
if (Time->Day > 29) {
Status = EFI_INVALID_PARAMETER;
}
}
else if (Time->Day > 28) {
Status = EFI_INVALID_PARAMETER;
}
}
// 0x15AA is a bit mask, with the nth bit set if its corresponding month has 31 days.
else if (Time->Day > (((1 << Time->Month) & 0x15AA) ? 31 : 30)) {
Status = EFI_INVALID_PARAMETER;
}
}
if (Time->Hour > 23) {
Status = EFI_INVALID_PARAMETER;
}
if (Time->Minute > 59) {
Status = EFI_INVALID_PARAMETER;
}
if (Time->Second > 59) {
Status = EFI_INVALID_PARAMETER;
}
if (Time->Nanosecond > 999999999) {
Status = EFI_INVALID_PARAMETER;
}
if (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE ||
(Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) {
Status = EFI_INVALID_PARAMETER;
}
if (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) {
Status = EFI_INVALID_PARAMETER;
}
if (EFI_ERROR(Status)) {
DEBUG((D_ERROR,"RTC : Invalid time/date field parameter\n"));
}
return Status;
}
EFI_STATUS
PlSetTime (
IN EFI_TIME *Time
)
// Provide the EFI set time function
{
SYSTEMTIME SystemTime;
EFI_STATUS Status;
Status = PlTimeFieldsValid (Time);
if (EFI_ERROR(Status)) {
return Status;
}
PlEfiTimeToSystemTime (Time, &SystemTime);
SetSystemTime (&SystemTime);
Status = RT->SetVariable (
EFI_RTC_NAME,
&EfiRtcGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof(INT16) + sizeof(UINT8),
&Time->TimeZone
);
return EFI_SUCCESS;
}
EFI_STATUS
PlSetWakeupTime (
IN BOOLEAN Enable,
IN EFI_TIME *Time
)
{
EFI_STATUS Status;
Status = PlTimeFieldsValid (Time);
if (EFI_ERROR(Status)) {
return Status;
}
Status = RT->SetVariable (
EFI_ALARM_NAME,
&EfiRtcGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof(EFI_TIME),
Time
);
Status = RT->SetVariable (
EFI_ALARM_ENABLE_NAME,
&EfiRtcGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof(BOOLEAN),
&Enable
);
return Status;
}
EFI_STATUS
PlGetWakeupTime (
OUT BOOLEAN *Enabled,
OUT BOOLEAN *Pending,
OUT EFI_TIME *Time
)
{
EFI_STATUS Status;
UINTN BufferSize;
EFI_TIME CurrentTime;
UINT32 Current;
UINT32 Wakeup;
if (Enabled == NULL || Pending == NULL || Time == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem(Time,sizeof(Time));
BufferSize = sizeof (EFI_TIME);
Status = RT->GetVariable (
EFI_ALARM_NAME,
&EfiRtcGuid,
NULL,
&BufferSize,
Time
);
*Enabled = FALSE;
BufferSize = sizeof (BOOLEAN);
Status = RT->GetVariable (
EFI_ALARM_ENABLE_NAME,
&EfiRtcGuid,
NULL,
&BufferSize,
Enabled
);
*Pending = FALSE;
if (!*Enabled) {
return EFI_SUCCESS;
}
Status = PlGetTime(&CurrentTime,NULL);
Current = (CurrentTime.Year << 16) | (CurrentTime.Month << 8) | (CurrentTime.Day);
Wakeup = (Time->Year << 16) | (Time->Month << 8) | (Time->Day);
if (Current < Wakeup) {
return EFI_SUCCESS;
}
if (Current > Wakeup) {
*Pending = TRUE;
return EFI_SUCCESS;
}
Current = (CurrentTime.Hour << 16) | (CurrentTime.Minute << 8) | (CurrentTime.Second);
Wakeup = (Time->Hour << 16) | (Time->Minute << 8) | (Time->Second);
if (Current < Wakeup) {
return EFI_SUCCESS;
}
*Pending = TRUE;
return EFI_SUCCESS;
}
#define MAX_FILE_NAME_LENGTH 280
EFI_STATUS
WinNtLoadAsDll (
IN CHAR8 *PdbFileName,
IN VOID **ImageEntryPoint
)
/*++
Routine Description:
Loads the .DLL file is present when a PE/COFF file is loaded. This provides source level
debugging for drivers that have cooresponding .DLL files on the local system.
Arguments:
PdbFileName - The name of the .PDB file. This was found from the PE/COFF
file's debug directory entry.
ImageEntryPoint - A pointer to the DLL entry point of the .DLL file was loaded.
Returns:
EFI_SUCCESS - The .DLL file was loaded, and the DLL entry point is returned in ImageEntryPoint
EFI_NOT_FOUND - The .DLL file could not be found
EFI_UNSUPPORTED - The .DLL file was loaded, but the entry point to the .DLL file could not
determined.
--*/
{
CHAR16 DllFileName[MAX_FILE_NAME_LENGTH];
HMODULE Library;
UINTN Index;
*ImageEntryPoint = NULL;
//
// Convert filename from ASCII to Unicode
//
for (Index = 0;Index < MAX_FILE_NAME_LENGTH && PdbFileName[Index] != 0; Index++) {
DllFileName[Index] = PdbFileName[Index];
}
DllFileName[Index] = 0;
//
// Check that we have a valid filename
//
if (Index < 5 ||
Index >= MAX_FILE_NAME_LENGTH ||
DllFileName[Index - 4] != '.') {
return EFI_NOT_FOUND;
}
//
// 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
//
Library = GetModuleHandle(DllFileName);
if(Library != NULL){
FreeLibrary(Library);
}
Library = LoadLibraryEx (
DllFileName,
NULL,
DONT_RESOLVE_DLL_REFERENCES
);
if (Library == NULL) {
return EFI_NOT_FOUND;
}
//
// InitializeDriver is the entry point we put in all our EFI DLL's. The
// DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() supresses the normal
// DLL entry point of DllMain, and prevents other modules that are referenced
// in side the DllFileName from being loaded.
//
*ImageEntryPoint = (VOID *)(UINTN)GetProcAddress (
Library,
"InitializeDriver"
);
if(*ImageEntryPoint == NULL) {
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?