/** Check whether a reset is needed, and finish the reset reminder feature. If a reset is needed, Popup a menu to notice user, and finish the feature according to the user selection. **/ VOID EFIAPI SetupResetReminder ( VOID ) { EFI_INPUT_KEY Key; CHAR16 *StringBuffer1; CHAR16 *StringBuffer2; // //check any reset required change is applied? if yes, reset system // if (IsResetRequired ()) { StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer1 != NULL); StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer2 != NULL); StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now."); StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset"); // // Popup a menu to notice user // do { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); FreePool (StringBuffer1); FreePool (StringBuffer2); gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); } }
/** Verify the new identity policy in the current implementation. The same credential provider can't appear twice in one identity policy. @param[in] NewGuid Points to the credential provider guid. @retval TRUE The NewGuid was found in the identity policy. @retval FALSE The NewGuid was not found. **/ BOOLEAN ProviderAlreadyInPolicy ( IN EFI_GUID *NewGuid ) { UINTN Offset; EFI_USER_INFO_IDENTITY_POLICY *Identity; EFI_INPUT_KEY Key; Offset = 0; while (Offset < mUserInfo.NewIdentityPolicyLen) { Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset); if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) { if (CompareGuid (NewGuid, (EFI_GUID *) (Identity + 1))) { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"This Credential Provider Are Already Used!", L"", L"Press Any Key to Continue ...", NULL ); return TRUE; } } Offset += Identity->Length; } return FALSE; }
/** This function processes the results of changes in configuration. @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param[in] Action Specifies the type of action taken by the browser. @param[in] QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. @param[in] Type The type of value for the question. @param[in] Value A pointer to the data being sent to the original exporting driver. @param[out] ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. **/ EFI_STATUS EFIAPI Tcg2Callback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { EFI_INPUT_KEY Key; if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) { return EFI_INVALID_PARAMETER; } if (Action == EFI_BROWSER_ACTION_CHANGING) { if (QuestionId == KEY_TPM_DEVICE_INTERFACE) { EFI_STATUS Status; Status = SetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress), Value->u8); if (EFI_ERROR (Status)) { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Error: Fail to set PTP interface!", NULL ); return EFI_DEVICE_ERROR; } } } if (Action == EFI_BROWSER_ACTION_CHANGED) { if (QuestionId == KEY_TPM_DEVICE) { return EFI_SUCCESS; } if (QuestionId == KEY_TPM2_OPERATION) { return SaveTcg2PpRequest (Value->u8); } if (QuestionId == KEY_TPM2_OPERATION_PARAMETER) { return SaveTcg2PpRequestParameter (Value->u32); } if ((QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) { SaveTcg2PCRBanksRequest (QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0, Value->b); } } return EFI_UNSUPPORTED; }
/** Check whether a reset is needed, and finish the reset reminder feature. If a reset is needed, Popup a menu to notice user, and finish the feature according to the user selection. **/ VOID EFIAPI SetupResetReminder ( VOID ) { EFI_INPUT_KEY Key; CHAR16 *StringBuffer1; CHAR16 *StringBuffer2; // //check any reset required change is applied? if yes, reset system // if (IsResetReminderFeatureEnable ()) { if (IsResetRequired ()) { StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer1 != NULL); StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer2 != NULL); StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? "); StrCpy (StringBuffer2, L"Enter (YES) / Esc (NO)"); // // Popup a menu to notice user // do { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); FreePool (StringBuffer1); FreePool (StringBuffer2); // // If the user hits the YES Response key, reset // if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) { gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); } gST->ConOut->ClearScreen (gST->ConOut); } } }
/** Check whether a reset is needed,if reset is needed, Popup a menu to notice user. **/ VOID BmSetupResetReminder ( VOID ) { EFI_INPUT_KEY Key; CHAR16 *StringBuffer1; CHAR16 *StringBuffer2; EFI_STATUS Status; EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2; // // Use BrowserEx2 protocol to check whether reset is required. // Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2); // //check any reset required change is applied? if yes, reset system // if (!EFI_ERROR(Status) && FormBrowserEx2->IsResetRequired ()) { StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer1 != NULL); StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer2 != NULL); StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now."); StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset"); // // Popup a menu to notice user // do { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); FreePool (StringBuffer1); FreePool (StringBuffer2); gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); } }
/** This function is called to provide results data to the driver. This data consists of a unique key that is used to identify which data is either being passed back or being asked for. @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param[in] Action Specifies the type of action taken by the browser. @param[in] QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. The format of the data tends to vary based on the opcode that enerated the callback. @param[in] Type The type of value for the question. @param[in] Value A pointer to the data being sent to the original exporting driver. @param[out] ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.Currently not implemented. @retval EFI_INVALID_PARAMETERS Passing in wrong parameter. @retval Others Other errors as indicated. **/ EFI_STATUS EFIAPI Ip4FormCallback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { IP4_CONFIG_INSTANCE *Ip4ConfigInstance; CHAR8 Ip4String[IP4_STR_MAX_SIZE]; IP4_CONFIG_IFR_NVDATA *IfrFormNvData; EFI_IP_ADDRESS HostIp; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS Gateway; EFI_STATUS Status; EFI_INPUT_KEY Key; Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This); IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA)); if (IfrFormNvData == NULL) { return EFI_OUT_OF_RESOURCES; } // // Retrive uncommitted data from Browser // if (!HiiGetBrowserData (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) { FreePool (IfrFormNvData); return EFI_NOT_FOUND; } Status = EFI_SUCCESS; switch (QuestionId) { case KEY_ENABLE: if (IfrFormNvData->Configure == 0) { Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = FALSE; } else { Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = TRUE; } break; case KEY_DHCP_ENABLE: if (IfrFormNvData->DhcpEnable == 0) { Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = FALSE; } else { Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = TRUE; } break; case KEY_LOCAL_IP: UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String); Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4); if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); Status = EFI_INVALID_PARAMETER; } else { CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, &HostIp.v4, sizeof (HostIp.v4)); } break; case KEY_SUBNET_MASK: UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String); Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4); if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL); Status = EFI_INVALID_PARAMETER; } else { CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4)); } break; case KEY_GATE_WAY: UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String); Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4); if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL); Status = EFI_INVALID_PARAMETER; } else { CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, &Gateway.v4, sizeof (Gateway.v4)); } break; case KEY_SAVE_CHANGES: Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (Ip4ConfigInstance); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; break; default: break; } if (!EFI_ERROR (Status)) { // // Pass changed uncommitted data back to Form Browser // HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL); } FreePool (IfrFormNvData); return Status; }
/** Convert the IFR data into the network configuration data and set the IP configure parameters for the NIC. @param[in, out] Ip4ConfigInstance The IP4Config instance. @retval EFI_SUCCESS The configure parameter for this NIC was set successfully. @retval EFI_ALREADY_STARTED There is a pending auto configuration. @retval EFI_NOT_FOUND No auto configure parameter is found. **/ EFI_STATUS Ip4ConfigConvertIfrNvDataToDeviceConfigData ( IN OUT IP4_CONFIG_INSTANCE *Ip4ConfigInstance ) { EFI_STATUS Status; EFI_IP_ADDRESS HostIp; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS Gateway; EFI_INPUT_KEY Key; NIC_IP4_CONFIG_INFO *NicInfo; EFI_IP_ADDRESS Ip; if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured) { // // Clear the variable // ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo, sizeof (IP4_SETTING_INFO)); Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE); if (Status == EFI_NOT_FOUND) { return EFI_SUCCESS; } return Status; } NicInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE)); ASSERT (NicInfo != NULL); NicInfo->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (NicInfo + 1); if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled) { CopyMem (&HostIp.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (HostIp.v4)); CopyMem (&SubnetMask.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (SubnetMask.v4)); CopyMem (&Gateway.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (Gateway.v4)); if (!NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); return EFI_INVALID_PARAMETER; } if (EFI_IP4_EQUAL (&SubnetMask, &mZeroIp4Addr)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL); return EFI_INVALID_PARAMETER; } if ((Gateway.Addr[0] != 0)) { if (SubnetMask.Addr[0] == 0) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL); return EFI_INVALID_PARAMETER; } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL); return EFI_INVALID_PARAMETER; } } NicInfo->Source = IP4_CONFIG_SOURCE_STATIC; NicInfo->Ip4Info.RouteTableSize = 2; CopyMem (&NicInfo->Ip4Info.StationAddress, &HostIp.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&NicInfo->Ip4Info.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); Ip.Addr[0] = HostIp.Addr[0] & SubnetMask.Addr[0]; CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&NicInfo->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS)); } else { NicInfo->Source = IP4_CONFIG_SOURCE_DHCP; ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (EFI_IPv4_ADDRESS)); ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (EFI_IPv4_ADDRESS)); } NicInfo->Perment = TRUE; CopyMem (&NicInfo->NicAddr, &Ip4ConfigInstance->NicAddr, sizeof (NIC_ADDR)); return EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE); }
/** Convert the IFR data into the network configuration data and set the IP configure parameters for the NIC. @param[in] IfrFormNvData The IFR NV data. @param[in, out] Instance The IP4 config2 instance. @retval EFI_SUCCESS The configure parameter for this NIC was set successfully. @retval EFI_INVALID_PARAMETER The address information for setting is invalid. @retval Others Other errors as indicated. **/ EFI_STATUS Ip4Config2ConvertIfrNvDataToConfigNvData ( IN IP4_CONFIG2_IFR_NVDATA *IfrFormNvData, IN OUT IP4_CONFIG2_INSTANCE *Instance ) { EFI_STATUS Status; EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2; IP4_CONFIG2_NVDATA *Ip4NvData; EFI_IP_ADDRESS StationAddress; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS Gateway; IP4_ADDR Ip; EFI_IPv4_ADDRESS *DnsAddress; UINTN DnsCount; UINTN Index; EFI_EVENT TimeoutEvent; EFI_EVENT SetAddressEvent; BOOLEAN IsAddressOk; UINTN DataSize; EFI_INPUT_KEY Key; Status = EFI_SUCCESS; Ip4Cfg2 = &Instance->Ip4Config2; Ip4NvData = &Instance->Ip4NvData; DnsCount = 0; DnsAddress = NULL; TimeoutEvent = NULL; SetAddressEvent = NULL; if (Instance == NULL || IfrFormNvData == NULL) { return EFI_INVALID_PARAMETER; } if (IfrFormNvData->Configure != TRUE) { return EFI_SUCCESS; } if (IfrFormNvData->DhcpEnable == TRUE) { Ip4NvData->Policy = Ip4Config2PolicyDhcp; Status = Ip4Cfg2->SetData ( Ip4Cfg2, Ip4Config2DataTypePolicy, sizeof (EFI_IP4_CONFIG2_POLICY), &Ip4NvData->Policy ); if (EFI_ERROR(Status)) { return Status; } } else { // // Get Ip4NvData from IfrFormNvData if it is valid. // Ip4NvData->Policy = Ip4Config2PolicyStatic; Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4); if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL); return EFI_INVALID_PARAMETER; } Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4); if (EFI_ERROR (Status) || (SubnetMask.Addr[0] != 0 && !NetIp4IsUnicast (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0]))) || !Ip4StationAddressValid (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0]))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); return EFI_INVALID_PARAMETER; } Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4); if (EFI_ERROR (Status) || (Gateway.Addr[0] != 0 && SubnetMask.Addr[0] != 0 && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (SubnetMask.Addr[0])))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL); return EFI_INVALID_PARAMETER; } Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount); if (!EFI_ERROR (Status) && DnsCount > 0) { for (Index = 0; Index < DnsCount; Index ++) { CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR)); if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); FreePool(DnsAddress); return EFI_INVALID_PARAMETER; } } } else { if (EFI_ERROR (Status)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); } } if (Ip4NvData->ManualAddress != NULL) { FreePool(Ip4NvData->ManualAddress); } Ip4NvData->ManualAddressCount = 1; Ip4NvData->ManualAddress = AllocateZeroPool(sizeof(EFI_IP4_CONFIG2_MANUAL_ADDRESS)); if (Ip4NvData->ManualAddress == NULL) { if (DnsAddress != NULL) { FreePool(DnsAddress); } return EFI_OUT_OF_RESOURCES; } CopyMem(&Ip4NvData->ManualAddress->Address, &StationAddress.v4, sizeof(EFI_IPv4_ADDRESS)); CopyMem(&Ip4NvData->ManualAddress->SubnetMask, &SubnetMask.v4, sizeof(EFI_IPv4_ADDRESS)); if (Ip4NvData->GatewayAddress != NULL) { FreePool(Ip4NvData->GatewayAddress); } Ip4NvData->GatewayAddressCount = 1; Ip4NvData->GatewayAddress = AllocateZeroPool(sizeof(EFI_IPv4_ADDRESS)); if (Ip4NvData->GatewayAddress == NULL) { if (DnsAddress != NULL) { FreePool(DnsAddress); } return EFI_OUT_OF_RESOURCES; } CopyMem(Ip4NvData->GatewayAddress, &Gateway.v4, sizeof(EFI_IPv4_ADDRESS)); if (Ip4NvData->DnsAddress != NULL) { FreePool(Ip4NvData->DnsAddress); } Ip4NvData->DnsAddressCount = (UINT32) DnsCount; Ip4NvData->DnsAddress = DnsAddress; // // Setting Ip4NvData. // Status = Ip4Cfg2->SetData ( Ip4Cfg2, Ip4Config2DataTypePolicy, sizeof (EFI_IP4_CONFIG2_POLICY), &Ip4NvData->Policy ); if (EFI_ERROR(Status)) { return Status; } // // Create events & timers for asynchronous settings. // Status = gBS->CreateEvent ( EVT_TIMER, TPL_CALLBACK, NULL, NULL, &TimeoutEvent ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, Ip4Config2ManualAddressNotify, &IsAddressOk, &SetAddressEvent ); if (EFI_ERROR (Status)) { goto Exit; } IsAddressOk = FALSE; Status = Ip4Cfg2->RegisterDataNotify ( Ip4Cfg2, Ip4Config2DataTypeManualAddress, SetAddressEvent ); if (EFI_ERROR (Status)) { goto Exit; } // // Set ManualAddress. // DataSize = Ip4NvData->ManualAddressCount * sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS); Status = Ip4Cfg2->SetData ( Ip4Cfg2, Ip4Config2DataTypeManualAddress, DataSize, (VOID *) Ip4NvData->ManualAddress ); if (Status == EFI_NOT_READY) { gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000); while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) { if (IsAddressOk) { Status = EFI_SUCCESS; break; } } } Ip4Cfg2->UnregisterDataNotify ( Ip4Cfg2, Ip4Config2DataTypeManualAddress, SetAddressEvent ); if (EFI_ERROR (Status)) { goto Exit; } // // Set gateway. // DataSize = Ip4NvData->GatewayAddressCount * sizeof (EFI_IPv4_ADDRESS); Status = Ip4Cfg2->SetData ( Ip4Cfg2, Ip4Config2DataTypeGateway, DataSize, Ip4NvData->GatewayAddress ); if (EFI_ERROR (Status)) { goto Exit; } // // Set DNS addresses. // if (Ip4NvData->DnsAddressCount > 0 && Ip4NvData->DnsAddress != NULL) { DataSize = Ip4NvData->DnsAddressCount * sizeof (EFI_IPv4_ADDRESS); Status = Ip4Cfg2->SetData ( Ip4Cfg2, Ip4Config2DataTypeDnsServer, DataSize, Ip4NvData->DnsAddress ); if (EFI_ERROR (Status)) { goto Exit; } } } Exit: if (SetAddressEvent != NULL) { gBS->CloseEvent (SetAddressEvent); } if (TimeoutEvent != NULL) { gBS->CloseEvent (TimeoutEvent); } return Status; }
/** This function is called to provide results data to the driver. This data consists of a unique key that is used to identify which data is either being passed back or being asked for. @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param[in] Action Specifies the type of action taken by the browser. @param[in] QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. The format of the data tends to vary based on the opcode that enerated the callback. @param[in] Type The type of value for the question. @param[in] Value A pointer to the data being sent to the original exporting driver. @param[out] ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.Currently not implemented. @retval EFI_INVALID_PARAMETERS Passing in wrong parameter. @retval Others Other errors as indicated. **/ EFI_STATUS EFIAPI Ip4FormCallback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { EFI_STATUS Status; IP4_CONFIG2_INSTANCE *Instance; IP4_CONFIG2_IFR_NVDATA *IfrFormNvData; IP4_FORM_CALLBACK_INFO *Private; EFI_IP_ADDRESS StationAddress; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS Gateway; IP4_ADDR Ip; EFI_IPv4_ADDRESS *DnsAddress; UINTN DnsCount; UINTN Index; EFI_INPUT_KEY Key; IfrFormNvData = NULL; DnsCount = 0; DnsAddress = NULL; if (Action == EFI_BROWSER_ACTION_CHANGED) { Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This); Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private); IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA)); if (IfrFormNvData == NULL) { return EFI_OUT_OF_RESOURCES; } // // Retrieve uncommitted data from Browser // if (!HiiGetBrowserData (&gIp4Config2NvDataGuid, mIp4Config2StorageName, sizeof (IP4_CONFIG2_IFR_NVDATA), (UINT8 *) IfrFormNvData)) { FreePool (IfrFormNvData); return EFI_NOT_FOUND; } Status = EFI_SUCCESS; switch (QuestionId) { case KEY_LOCAL_IP: Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4); if (EFI_ERROR (Status) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress.Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress.Addr[0]))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); Status = EFI_INVALID_PARAMETER; } break; case KEY_SUBNET_MASK: Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4); if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL); Status = EFI_INVALID_PARAMETER; } break; case KEY_GATE_WAY: Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4); if (EFI_ERROR (Status) || IP4_IS_LOCAL_BROADCAST(NTOHL(Gateway.Addr[0]))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL); Status = EFI_INVALID_PARAMETER; } break; case KEY_DNS: Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount); if (!EFI_ERROR (Status) && DnsCount > 0) { for (Index = 0; Index < DnsCount; Index ++) { CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR)); if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); Status = EFI_INVALID_PARAMETER; break; } } } else { if (EFI_ERROR (Status)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); } } if(DnsAddress != NULL) { FreePool(DnsAddress); } break; case KEY_SAVE_CHANGES: Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Instance); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; break; default: break; } FreePool (IfrFormNvData); return Status; } // // All other action return unsupported. // return EFI_UNSUPPORTED; }
/** Check if disk is locked, show popup window and ask for password if it is @param[in] Dev The device which need to be unlock. **/ VOID OpalDriverRequestPassword ( OPAL_DRIVER_DEVICE *Dev ) { UINT8 Count; BOOLEAN IsEnabled; CHAR8 *Password; UINT32 PasswordLen; TCG_RESULT Ret; EFI_INPUT_KEY Key; OPAL_SESSION Session; BOOLEAN PressEsc; BOOLEAN Locked; if (Dev == NULL) { return; } Count = 0; IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature); if (IsEnabled) { ZeroMem(&Session, sizeof(Session)); Session.Sscp = Dev->OpalDisk.Sscp; Session.MediaId = Dev->OpalDisk.MediaId; Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; Locked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature); while (Count < MAX_PASSWORD_TRY_COUNT) { Password = OpalDriverPopUpHddPassword (Dev, &PressEsc); if (PressEsc) { if (Locked) { // // Current device in the lock status and // User not input password and press ESC, // keep device in lock status and continue boot. // do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Press ENTER to skip password, Press ESC to input password", NULL ); } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { gST->ConOut->ClearScreen(gST->ConOut); // // Keep lock and continue boot. // return; } else { // // Let user input password again. // continue; } } else { // // Current device in the unlock status and // User not input password and press ESC, // Shutdown the device. // do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Press ENTER to shutdown, Press ESC to input password", NULL ); } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); } else { // // Let user input password again. // continue; } } } if (Password == NULL) { Count ++; continue; } PasswordLen = (UINT32) AsciiStrLen(Password); if (Locked) { Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath); } else { Ret = OpalSupportLock(&Session, Password, PasswordLen, Dev->OpalDevicePath); if (Ret == TcgResultSuccess) { Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath); } } if (Password != NULL) { ZeroMem (Password, PasswordLen); FreePool (Password); } if (Ret == TcgResultSuccess) { break; } Count++; do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid password.", L"Press ENTER to retry", NULL ); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); } if (Count >= MAX_PASSWORD_TRY_COUNT) { do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Opal password retry count exceeds the limit. Must shutdown!", L"Press ENTER to shutdown", NULL ); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); } } }
/** This function processes changes in user profile configuration. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Action Specifies the type of action taken by the browser. @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. @param Type The type of value for the question. @param Value A pointer to the data being sent to the original exporting driver. @param ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval Others Fail to handle the action. **/ EFI_STATUS EFIAPI UserProfileManagerCallback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { EFI_STATUS Status; EFI_INPUT_KEY Key; UINT32 CurrentAccessRight; CHAR16 *QuestionStr; CHAR16 *PromptStr; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; EFI_USER_PROFILE_HANDLE CurrentUser; Status = EFI_SUCCESS; switch (Action) { case EFI_BROWSER_ACTION_FORM_OPEN: { // // Update user manage Form when user manage Form is opened. // This will be done only in FORM_OPEN CallBack of question with QUESTIONID_USER_MANAGE from user manage Form. // if (QuestionId != QUESTIONID_USER_MANAGE) { return EFI_SUCCESS; } // // Get current user // CurrentUser = NULL; mUserManager->Current (mUserManager, &CurrentUser); if (CurrentUser == NULL) { DEBUG ((DEBUG_ERROR, "Error: current user does not exist!\n")); return EFI_NOT_READY; } // // Get current user's right information. // Status = GetAccessRight (&CurrentAccessRight); if (EFI_ERROR (Status)) { CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF; } // // Init credential provider information. // Status = InitProviderInfo (); if (EFI_ERROR (Status)) { return Status; } // // Initialize the container for dynamic opcodes. // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode. // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_USER_MANAGE_FUNC; EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_END; // // Add user profile option. // if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) || (CurrentAccessRight == EFI_USER_INFO_ACCESS_ENROLL_OTHERS) ) { HiiCreateActionOpCode ( StartOpCodeHandle, // Container for dynamic created opcodes KEY_ADD_USER, // Question ID STRING_TOKEN (STR_ADD_USER_TITLE), // Prompt text STRING_TOKEN (STR_ADD_USER_HELP), // Help text EFI_IFR_FLAG_CALLBACK, // Question flag 0 // Action String ID ); } // // Add modify user profile option. // HiiCreateGotoOpCode ( StartOpCodeHandle, // Container for dynamic created opcodes FORMID_MODIFY_USER, // Target Form ID STRING_TOKEN (STR_MODIFY_USER_TITLE), // Prompt text STRING_TOKEN (STR_MODIFY_USER_HELP), // Help text EFI_IFR_FLAG_CALLBACK, // Question flag KEY_MODIFY_USER // Question ID ); // // Add delete user profile option // if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) { HiiCreateGotoOpCode ( StartOpCodeHandle, // Container for dynamic created opcodes FORMID_DEL_USER, // Target Form ID STRING_TOKEN (STR_DELETE_USER_TITLE), // Prompt text STRING_TOKEN (STR_DELETE_USER_HELP), // Help text EFI_IFR_FLAG_CALLBACK, // Question flag KEY_DEL_USER // Question ID ); } HiiUpdateForm ( mCallbackInfo->HiiHandle, // HII handle &gUserProfileManagerGuid, // Formset GUID FORMID_USER_MANAGE, // Form ID StartOpCodeHandle, // Label for where to insert opcodes EndOpCodeHandle // Replace data ); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); return EFI_SUCCESS; } break; case EFI_BROWSER_ACTION_FORM_CLOSE: Status = EFI_SUCCESS; break; case EFI_BROWSER_ACTION_CHANGED: { // // Handle the request from form. // if ((Value == NULL) || (ActionRequest == NULL)) { return EFI_INVALID_PARAMETER; } // // Judge first 2 bits. // switch (QuestionId & KEY_FIRST_FORM_MASK) { // // Add user profile operation. // case KEY_ADD_USER: CallAddUser (); break; // // Delete user profile operation. // case KEY_DEL_USER: // // Judge next 2 bits. // switch (QuestionId & KEY_SECOND_FORM_MASK) { // // Delete specified user profile. // case KEY_SELECT_USER: DeleteUser ((UINT8) QuestionId); // // Update select user form after delete a user. // SelectUserToDelete (); break; default: break; } break; // // Modify user profile operation. // case KEY_MODIFY_USER: // // Judge next 2 bits. // switch (QuestionId & KEY_SECOND_FORM_MASK) { // // Enter user profile information form. // case KEY_SELECT_USER: // // Judge next 3 bits. // switch (QuestionId & KEY_MODIFY_INFO_MASK) { // // Modify user name. // case KEY_MODIFY_NAME: ModifyUserName (); // // Update username in parent form. // SelectUserToModify (); break; // // Modify identity policy. // case KEY_MODIFY_IP: // // Judge next 3 bits // switch (QuestionId & KEY_MODIFY_IP_MASK) { // // Change credential provider option. // case KEY_MODIFY_PROV: mProviderChoice = Value->u8; break; // // Change logical connector. // case KEY_MODIFY_CONN: mConncetLogical = Value->u8; break; // // Save option. // case KEY_ADD_IP_OP: AddIdentityPolicyItem (); break; // // Return to user profile information form. // case KEY_IP_RETURN_UIF: SaveIdentityPolicy (); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; break; default: break; } break; // // Modify access policy. // case KEY_MODIFY_AP: // // Judge next 3 bits. // switch (QuestionId & KEY_MODIFY_AP_MASK) { // // Change access right choice. // case KEY_MODIFY_RIGHT: mAccessInfo.AccessRight = Value->u8; break; // // Change setup choice. // case KEY_MODIFY_SETUP: mAccessInfo.AccessSetup= Value->u8; break; // // Change boot order choice. // case KEY_MODIFY_BOOT: mAccessInfo.AccessBootOrder = Value->u32; break; // // Return to user profile information form. // case KEY_AP_RETURN_UIF: SaveAccessPolicy (); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; break; default: break; } break; default: break; } break; // // Access policy device path modified. // case KEY_MODIFY_AP_DP: // // Judge next 2 bits. // switch (QuestionId & KEY_MODIFY_DP_MASK) { // // Load permit device path modified. // case KEY_LOAD_PERMIT_MODIFY: QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_FORBID_LIST)); PromptStr = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE)); CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, QuestionStr, L"", PromptStr, NULL ); FreePool (QuestionStr); FreePool (PromptStr); if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) { break; } AddToForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1))); DisplayLoadPermit (); break; // // Load forbid device path modified. // case KEY_LOAD_FORBID_MODIFY: QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_PERMIT_LIST)); PromptStr = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE)); CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, QuestionStr, L"", PromptStr, NULL ); FreePool (QuestionStr); FreePool (PromptStr); if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) { break; } DeleteFromForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1))); DisplayLoadForbid (); break; // // Connect permit device path modified. // case KEY_CONNECT_PERMIT_MODIFY: break; // // Connect forbid device path modified. // case KEY_CONNECT_FORBID_MODIFY: break; default: break; } break; default: break; } break; default: break; } } break; case EFI_BROWSER_ACTION_CHANGING: { // // Handle the request from form. // if (Value == NULL) { return EFI_INVALID_PARAMETER; } // // Judge first 2 bits. // switch (QuestionId & KEY_FIRST_FORM_MASK) { // // Delete user profile operation. // case KEY_DEL_USER: // // Judge next 2 bits. // switch (QuestionId & KEY_SECOND_FORM_MASK) { // // Enter delete user profile form. // case KEY_ENTER_NEXT_FORM: SelectUserToDelete (); break; default: break; } break; // // Modify user profile operation. // case KEY_MODIFY_USER: // // Judge next 2 bits. // switch (QuestionId & KEY_SECOND_FORM_MASK) { // // Enter modify user profile form. // case KEY_ENTER_NEXT_FORM: SelectUserToModify (); break; // // Enter user profile information form. // case KEY_SELECT_USER: // // Judge next 3 bits. // switch (QuestionId & KEY_MODIFY_INFO_MASK) { // // Display user information form. // case KEY_ENTER_NEXT_FORM: ModifyUserInfo ((UINT8) QuestionId); break; // // Modify identity policy. // case KEY_MODIFY_IP: // // Judge next 3 bits // switch (QuestionId & KEY_MODIFY_IP_MASK) { // // Display identity policy modify form. // case KEY_ENTER_NEXT_FORM: ModifyIdentityPolicy (); break; default: break; } break; // // Modify access policy. // case KEY_MODIFY_AP: // // Judge next 3 bits. // switch (QuestionId & KEY_MODIFY_AP_MASK) { // // Display access policy modify form. // case KEY_ENTER_NEXT_FORM: ModidyAccessPolicy (); break; // // Load device path form. // case KEY_MODIFY_LOAD: // // Judge next 2 bits. // switch (QuestionId & KEY_DISPLAY_DP_MASK) { // // Permit load device path. // case KEY_PERMIT_MODIFY: DisplayLoadPermit (); break; // // Forbid load device path. // case KEY_FORBID_MODIFY: DisplayLoadForbid (); break; default: break; } break; // // Connect device path form. // case KEY_MODIFY_CONNECT: // // Judge next 2 bits. // switch (QuestionId & KEY_DISPLAY_DP_MASK) { // // Permit connect device path. // case KEY_PERMIT_MODIFY: DisplayConnectPermit (); break; // // Forbid connect device path. // case KEY_FORBID_MODIFY: DisplayConnectForbid (); break; default: break; } break; default: break; } break; default: break; } break; default: break; } break; default: break; } } break; default: // // All other action return unsupported. // Status = EFI_UNSUPPORTED; break; } return Status; }
EFI_STATUS ReadString ( IN UI_MENU_OPTION *MenuOption, IN CHAR16 *Prompt, OUT CHAR16 *StringPtr ) /*++ Routine Description: Get string or password input from user. Arguments: MenuOption - Pointer to the current input menu. Prompt - The prompt string shown on popup window. StringPtr - Destination for use input string. Returns: EFI_SUCCESS - If string input is read successfully EFI_DEVICE_ERROR - If operation fails --*/ { EFI_STATUS Status; EFI_INPUT_KEY Key; CHAR16 NullCharacter; UINTN ScreenSize; CHAR16 Space[2]; CHAR16 KeyPad[2]; CHAR16 *TempString; CHAR16 *BufferedString; UINTN Index; UINTN Count; UINTN Start; UINTN Top; UINTN DimensionsWidth; UINTN DimensionsHeight; BOOLEAN CursorVisible; UINTN Minimum; UINTN Maximum; FORM_BROWSER_STATEMENT *Question; BOOLEAN IsPassword; DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn; DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow; NullCharacter = CHAR_NULL; ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16); Space[0] = L' '; Space[1] = CHAR_NULL; Question = MenuOption->ThisTag; Minimum = (UINTN) Question->Minimum; Maximum = (UINTN) Question->Maximum; if (Question->Operand == EFI_IFR_PASSWORD_OP) { IsPassword = TRUE; } else { IsPassword = FALSE; } TempString = EfiLibAllocateZeroPool ((Maximum + 1)* sizeof (CHAR16)); ASSERT (TempString); if (ScreenSize < (Maximum + 1)) { ScreenSize = Maximum + 1; } if ((ScreenSize + 2) > DimensionsWidth) { ScreenSize = DimensionsWidth - 2; } BufferedString = EfiLibAllocateZeroPool (ScreenSize * 2); ASSERT (BufferedString); Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1; Top = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1; // // Display prompt for string // CreatePopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); CursorVisible = gST->ConOut->Mode->CursorVisible; gST->ConOut->EnableCursor (gST->ConOut, TRUE); do { Status = WaitForKeyStroke (&Key); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); switch (Key.UnicodeChar) { case CHAR_NULL: switch (Key.ScanCode) { case SCAN_LEFT: break; case SCAN_RIGHT: break; case SCAN_ESC: gBS->FreePool (TempString); gBS->FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; default: break; } break; case CHAR_CARRIAGE_RETURN: if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) { gBS->FreePool (TempString); gBS->FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_SUCCESS; } else { // // Simply create a popup to tell the user that they had typed in too few characters. // To save code space, we can then treat this as an error and return back to the menu. // do { CreateDialog (4, TRUE, 0, NULL, &Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); gBS->FreePool (TempString); gBS->FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; } break; case CHAR_BACKSPACE: if (StringPtr[0] != CHAR_NULL) { for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) { TempString[Index] = StringPtr[Index]; } // // Effectively truncate string by 1 character // TempString[Index - 1] = CHAR_NULL; EfiStrCpy (StringPtr, TempString); } default: // // If it is the beginning of the string, don't worry about checking maximum limits // if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { StrnCpy (StringPtr, &Key.UnicodeChar, 1); StrnCpy (TempString, &Key.UnicodeChar, 1); } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) { KeyPad[0] = Key.UnicodeChar; KeyPad[1] = CHAR_NULL; EfiStrCat (StringPtr, KeyPad); EfiStrCat (TempString, KeyPad); } // // If the width of the input string is now larger than the screen, we nee to // adjust the index to start printing portions of the string // SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); PrintStringAt (Start + 1, Top + 3, BufferedString); if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; } else { Index = 0; } if (IsPassword) { gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); } for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { BufferedString[Count] = StringPtr[Index]; if (IsPassword) { PrintChar (L'*'); } } if (!IsPassword) { PrintStringAt (Start + 1, Top + 3, BufferedString); } break; } gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3); } while (TRUE); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return Status; }
/** Add a new user profile into the user profile database. **/ VOID CallAddUser ( VOID ) { EFI_STATUS Status; EFI_INPUT_KEY Key; EFI_USER_PROFILE_HANDLE User; UINTN UserNameLen; CHAR16 UserName[USER_NAME_LENGTH]; CHAR16 *QuestionStr; CHAR16 *PromptStr; QuestionStr = NULL; PromptStr = NULL; // // Get user name to add. // UserNameLen = sizeof (UserName); Status = GetUserNameInput (&UserNameLen, UserName); if (EFI_ERROR (Status)) { if (Status != EFI_ABORTED) { QuestionStr = GetStringById (STRING_TOKEN (STR_GET_USERNAME_FAILED)); PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); goto Done; } return ; } // // Create a new user profile. // User = NULL; Status = mUserManager->Create (mUserManager, &User); if (EFI_ERROR (Status)) { QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_FAILED)); PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); } else { // // Add default user information. // Status = SetUserName (User, UserNameLen, UserName); if (EFI_ERROR (Status)) { QuestionStr = GetStringById (STRING_TOKEN (STR_USER_ALREADY_EXISTED)); PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); goto Done; } SetCreateDate (User); SetIdentityPolicy (User); SetAccessPolicy (User); QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_SUCCESS)); PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); } Done: CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, QuestionStr, L"", PromptStr, NULL ); FreePool (QuestionStr); FreePool (PromptStr); }
/** Get user name from the popup windows. @param[in, out] UserNameLen On entry, point to UserName buffer lengh, in bytes. On exit, point to input user name length, in bytes. @param[out] UserName The buffer to hold the input user name. @retval EFI_ABORTED It is given up by pressing 'ESC' key. @retval EFI_NOT_READY Not a valid input at all. @retval EFI_SUCCESS Get a user name successfully. **/ EFI_STATUS GetUserNameInput ( IN OUT UINTN *UserNameLen, OUT CHAR16 *UserName ) { EFI_INPUT_KEY Key; UINTN NameLen; CHAR16 Name[USER_NAME_LENGTH]; NameLen = 0; while (TRUE) { Name[NameLen] = L'_'; Name[NameLen + 1] = L'\0'; CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Input User Name", L"---------------------", Name, NULL ); // // Check key. // if (Key.ScanCode == SCAN_NULL) { if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { // // Add the null terminator. // Name[NameLen] = 0; NameLen++; break; } else if ((Key.UnicodeChar == CHAR_NULL) || (Key.UnicodeChar == CHAR_TAB) || (Key.UnicodeChar == CHAR_LINEFEED) ) { continue; } else { if (Key.UnicodeChar == CHAR_BACKSPACE) { if (NameLen > 0) { NameLen--; } } else { Name[NameLen] = Key.UnicodeChar; NameLen++; if (NameLen + 1 == USER_NAME_LENGTH) { // // Add the null terminator. // Name[NameLen] = 0; NameLen++; break; } } } } if (Key.ScanCode == SCAN_ESC) { return EFI_ABORTED; } } if (NameLen <= 1) { return EFI_NOT_READY; } if (*UserNameLen < NameLen * sizeof (CHAR16)) { return EFI_NOT_READY; } *UserNameLen = NameLen * sizeof (CHAR16); CopyMem (UserName, Name, *UserNameLen); return EFI_SUCCESS; }
/** Check whether the identity policy is valid. @param[in] PolicyInfo Point to the identity policy. @param[in] PolicyInfoLen The policy length. @retval TRUE The policy is a valid identity policy. @retval FALSE The policy is not a valid identity policy. **/ BOOLEAN CheckNewIdentityPolicy ( IN UINT8 *PolicyInfo, IN UINTN PolicyInfoLen ) { EFI_USER_INFO_IDENTITY_POLICY *Identity; EFI_INPUT_KEY Key; UINTN Offset; UINT32 OpCode; // // Check policy expression. // OpCode = EFI_USER_INFO_IDENTITY_FALSE; Offset = 0; while (Offset < PolicyInfoLen) { // // Check identification policy according to type // Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (PolicyInfo + Offset); switch (Identity->Type) { case EFI_USER_INFO_IDENTITY_TRUE: break; case EFI_USER_INFO_IDENTITY_OR: if (OpCode == EFI_USER_INFO_IDENTITY_AND) { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Identity Policy, Mixed Connector Unsupport!", L"", L"Press Any Key to Continue ...", NULL ); return FALSE; } OpCode = EFI_USER_INFO_IDENTITY_OR; break; case EFI_USER_INFO_IDENTITY_AND: if (OpCode == EFI_USER_INFO_IDENTITY_OR) { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Identity Policy, Mixed Connector Unsupport!", L"", L"Press Any Key to Continue ...", NULL ); return FALSE; } OpCode = EFI_USER_INFO_IDENTITY_AND; break; case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER: break; default: CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Unsupport parameter", L"", L"Press Any Key to Continue ...", NULL ); return FALSE; } Offset += Identity->Length; } return TRUE; }
/** Delete the user specified by UserIndex in user profile database. @param[in] UserIndex The index of user in the user name list to be deleted. **/ VOID DeleteUser ( IN UINT8 UserIndex ) { EFI_STATUS Status; EFI_USER_PROFILE_HANDLE User; EFI_INPUT_KEY Key; EFI_USER_INFO_HANDLE UserInfo; EFI_USER_INFO *Info; UINTN InfoSize; // // Find specified user profile and delete it. // User = NULL; Status = mUserManager->GetNext (mUserManager, &User); if (EFI_ERROR (Status)) { goto Done; } while (UserIndex > 1) { Status = mUserManager->GetNext (mUserManager, &User); if (EFI_ERROR (Status)) { goto Done; } UserIndex--; } if (UserIndex == 1) { // // Get the identification policy. // Status = FindInfoByType (User, EFI_USER_INFO_IDENTITY_POLICY_RECORD, &UserInfo); if (EFI_ERROR (Status)) { goto Done; } InfoSize = 0; Info = NULL; Status = mUserManager->GetInfo (mUserManager, User, UserInfo, Info, &InfoSize); if (Status == EFI_BUFFER_TOO_SMALL) { Info = AllocateZeroPool (InfoSize); if (Info == NULL) { goto Done; } Status = mUserManager->GetInfo (mUserManager, User, UserInfo, Info, &InfoSize); } // // Delete the user on the credential providers by its identification policy. // ASSERT (Info != NULL); DeleteCredentialFromProviders ((UINT8 *)(Info + 1), Info->InfoSize - sizeof (EFI_USER_INFO), User); FreePool (Info); Status = mUserManager->Delete (mUserManager, User); if (EFI_ERROR (Status)) { goto Done; } CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Delete User Succeed!", L"", L"Please Press Any Key to Continue ...", NULL ); return ; } Done: CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Delete User Failed!", L"", L"Please Press Any Key to Continue ...", NULL ); }
/** Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.CallBack to EFI_FORM_CALLBACK_PROTOCOL.Callback. Therefor, the framework HII module willl do no porting and work with a UEFI HII SetupBrowser. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Action Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x. @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. The format of the data tends to vary based on the opcode that generated the callback. @param Type The type of value for the question. See EFI_IFR_TYPE_x in EFI_IFR_ONE_OF_OPTION. @param Value A pointer to the data being sent to the original exporting driver. The type is specified by Type. Type EFI_IFR_TYPE_VALUE is defined in EFI_IFR_ONE_OF_OPTION. @param ActionRequest On return, points to the action requested by the callback function. Type EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form Browser Protocol. @retval EFI_UNSUPPORTED If the Framework HII module does not register Callback although it specify the opcode under focuse to be INTERRACTIVE. @retval EFI_SUCCESS The callback complete successfully. @retval !EFI_SUCCESS The error code returned by EFI_FORM_CALLBACK_PROTOCOL.Callback. **/ EFI_STATUS EFIAPI ThunkCallback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { EFI_STATUS Status; CONFIG_ACCESS_PRIVATE *ConfigAccess; EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol; EFI_HII_CALLBACK_PACKET *Packet; EFI_IFR_DATA_ARRAY *Data; EFI_IFR_DATA_ENTRY *DataEntry; UINT16 KeyValue; ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry; EFI_HANDLE NotifyHandle; EFI_INPUT_KEY Key; BOOLEAN NvMapAllocated; if (Action == EFI_BROWSER_ACTION_CHANGING) { ASSERT (This != NULL); ASSERT (Value != NULL); ASSERT (ActionRequest != NULL); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This); FormCallbackProtocol = ConfigAccess->FormCallbackProtocol; if (FormCallbackProtocol == NULL) { ASSERT (FALSE); return EFI_UNSUPPORTED; } // // Check if the QuestionId match a OneOfOption. // OneOfOptionMapEntry = GetOneOfOptionMapEntry (ConfigAccess->ThunkContext, QuestionId, Type, Value); if (OneOfOptionMapEntry == NULL) { // // This is not a One-Of-Option opcode. QuestionId is the KeyValue // KeyValue = QuestionId; } else { // // Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax. // KeyValue = OneOfOptionMapEntry->FwKey; } // // Build the EFI_IFR_DATA_ARRAY // Data = CreateIfrDataArray (ConfigAccess, QuestionId, Type, Value, &NvMapAllocated); Status = mHiiDatabase->RegisterPackageNotify ( mHiiDatabase, EFI_HII_PACKAGE_FORMS, NULL, FormUpdateNotify, EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, &NotifyHandle ); // //Call the Framework Callback function. // Packet = NULL; Status = FormCallbackProtocol->Callback ( FormCallbackProtocol, KeyValue, Data, &Packet ); SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId); // // Callback require browser to perform action // if (EFI_ERROR (Status)) { if (Packet != NULL) { do { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, Packet->String, NULL); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); } // // Error Code in Status is discarded. // } else { if (Packet != NULL) { if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) { DataEntry = (EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (EFI_IFR_DATA_ARRAY)); if ((DataEntry->Flags & EXIT_REQUIRED) == EXIT_REQUIRED) { *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } if ((DataEntry->Flags & SAVE_REQUIRED) == SAVE_REQUIRED) { Status = ConfigAccess->ConfigAccessProtocol.RouteConfig ( &ConfigAccess->ConfigAccessProtocol, NULL, NULL ); } } FreePool (Packet); } } // // Unregister notify for Form package update // Status = mHiiDatabase->UnregisterPackageNotify ( mHiiDatabase, NotifyHandle ); // // UEFI SetupBrowser behaves differently with Framework SetupBrowser when call back function // update any forms in HII database. UEFI SetupBrowser will re-parse the displaying form package and load // the values from variable storages. Framework SetupBrowser will only re-parse the displaying form packages. // To make sure customer's previous changes is saved and the changing question behaves as expected, we // issue a EFI_BROWSER_ACTION_REQUEST_SUBMIT to ask UEFI SetupBrowser to save the changes proceed to re-parse // the form and load all the variable storages. // if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) { mHiiPackageListUpdated= FALSE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; } else { if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS || ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) { *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } } // // Clean up. // DestroyIfrDataArray (Data, NvMapAllocated); return Status; } // // All other action return unsupported. // return EFI_UNSUPPORTED; }
/** Get password input from the popup windows, and unlock the device. @param[in] Dev The device which need to be unlock. @param[out] PressEsc Whether user escape function through Press ESC. @retval Password string if success. NULL if failed. **/ CHAR8 * OpalDriverPopUpHddPassword ( IN OPAL_DRIVER_DEVICE *Dev, OUT BOOLEAN *PressEsc ) { EFI_INPUT_KEY InputKey; UINTN InputLength; CHAR16 Mask[MAX_PASSWORD_SIZE + 1]; CHAR16 Unicode[MAX_PASSWORD_SIZE + 1]; CHAR8 *Ascii; CHAR16 *PopUpString; UINTN StrLength; ZeroMem(Unicode, sizeof(Unicode)); ZeroMem(Mask, sizeof(Mask)); StrLength = StrLen(Dev->Name16); PopUpString = (CHAR16*) AllocateZeroPool ((8 + StrLength) * 2); *PressEsc = FALSE; if (Dev->Name16 == NULL) { UnicodeSPrint(PopUpString, StrLen(L"Unlock Disk") + 1, L"Unlock Disk"); } else { UnicodeSPrint(PopUpString, StrLen(L"Unlock ") + StrLength + 1, L"Unlock %s", Dev->Name16); } gST->ConOut->ClearScreen(gST->ConOut); InputLength = 0; while (TRUE) { Mask[InputLength] = L'_'; CreatePopUp( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &InputKey, PopUpString, L"---------------------", Mask, NULL ); // // Check key. // if (InputKey.ScanCode == SCAN_NULL) { // // password finished // if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) { // // Add the null terminator. // Unicode[InputLength] = 0; InputLength++; break; } else if ((InputKey.UnicodeChar == CHAR_NULL) || (InputKey.UnicodeChar == CHAR_TAB) || (InputKey.UnicodeChar == CHAR_LINEFEED) ) { continue; } else { // // delete last key entered // if (InputKey.UnicodeChar == CHAR_BACKSPACE) { if (InputLength > 0) { Unicode[InputLength] = 0; Mask[InputLength] = 0; InputLength--; } } else { // // add Next key entry // Unicode[InputLength] = InputKey.UnicodeChar; Mask[InputLength] = L'*'; InputLength++; if (InputLength == MAX_PASSWORD_SIZE) { // // Add the null terminator. // Unicode[InputLength] = 0; Mask[InputLength] = 0; break; } } } } // // exit on ESC // if (InputKey.ScanCode == SCAN_ESC) { *PressEsc = TRUE; break; } } gST->ConOut->ClearScreen(gST->ConOut); if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) { return NULL; } Ascii = AllocateZeroPool (MAX_PASSWORD_SIZE + 1); if (Ascii == NULL) { return NULL; } UnicodeStrToAsciiStrS (Unicode, Ascii, MAX_PASSWORD_SIZE + 1); ZeroMem (Unicode, sizeof (Unicode)); return Ascii; }