STATIC EFI_STATUS EFIAPI QemuRamfbGraphicsOutputQueryMode ( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber, OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info ) { EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo; if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= mQemuRamfbMode.MaxMode) { return EFI_INVALID_PARAMETER; } ModeInfo = &mQemuRamfbModeInfo[ModeNumber]; *Info = AllocateCopyPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), ModeInfo); if (*Info == NULL) { return EFI_OUT_OF_RESOURCES; } *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); return EFI_SUCCESS; }
/** Extract filename from device path. The returned buffer is allocated using AllocateCopyPool. The caller is responsible for freeing the allocated buffer using FreePool(). @param DevicePath Device path. @return A new allocated string that represents the file name. **/ CHAR16 * ExtractFileNameFromDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { CHAR16 *String; CHAR16 *MatchString; CHAR16 *LastMatch; CHAR16 *FileName; UINTN Length; ASSERT(DevicePath != NULL); String = UiDevicePathToStr(DevicePath); MatchString = String; LastMatch = String; while(MatchString != NULL){ LastMatch = MatchString + 1; MatchString = StrStr(LastMatch,L"\\"); } Length = StrLen(LastMatch); FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch); *(FileName + Length) = 0; FreePool(String); return FileName; }
CHAR8* AsciiStrDup ( IN CONST CHAR8* Str ) { return AllocateCopyPool (AsciiStrSize (Str), Str); }
/** Returns the current state information for the adapter. This function returns information of type InformationType from the adapter. If an adapter does not support the requested informational type, then EFI_UNSUPPORTED is returned. @param[in] This A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance. @param[in] InformationType A pointer to an EFI_GUID that defines the contents of InformationBlock. @param[out] InformationBlock The service returns a pointer to the buffer with the InformationBlock structure which contains details about the data specific to InformationType. @param[out] InformationBlockSize The driver returns the size of the InformationBlock in bytes. @retval EFI_SUCCESS The InformationType information was retrieved. @retval EFI_UNSUPPORTED The InformationType is not known. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER InformationBlock is NULL. @retval EFI_INVALID_PARAMETER InformationBlockSize is NULL. **/ EFI_STATUS EFIAPI HstiAipGetInfo ( IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, IN EFI_GUID *InformationType, OUT VOID **InformationBlock, OUT UINTN *InformationBlockSize ) { HSTI_AIP_PRIVATE_DATA *HstiAip; if ((This == NULL) || (InformationBlock == NULL) || (InformationBlockSize == NULL)) { return EFI_INVALID_PARAMETER; } if (!CompareGuid (InformationType, &gAdapterInfoPlatformSecurityGuid)) { return EFI_UNSUPPORTED; } HstiAip = HSTI_AIP_PRIVATE_DATA_FROM_THIS(This); *InformationBlock = AllocateCopyPool (HstiAip->HstiSize, HstiAip->Hsti); if (*InformationBlock == NULL) { return EFI_OUT_OF_RESOURCES; } *InformationBlockSize = HstiAip->HstiSize; return EFI_SUCCESS; }
EFI_STATUS SemihostFsEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; Status = EFI_NOT_FOUND; if (SemihostConnectionSupported ()) { mSemihostFsLabel = AllocateCopyPool (StrSize (DEFAULT_SEMIHOST_FS_LABEL), DEFAULT_SEMIHOST_FS_LABEL); if (mSemihostFsLabel == NULL) { return EFI_OUT_OF_RESOURCES; } Status = gBS->InstallMultipleProtocolInterfaces ( &gInstallHandle, &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs, &gEfiDevicePathProtocolGuid, &gDevicePath, NULL ); if (EFI_ERROR(Status)) { FreePool (mSemihostFsLabel); } } return Status; }
CHAR16* UnicodeStrDup ( IN CONST CHAR16* Str ) { return AllocateCopyPool (StrSize (Str), Str); }
/** Boot a file selected by user at File Expoloer of BMM. @param FileContext The file context data, which contains the device path of the file to be boot from. @retval EFI_SUCCESS The function completed successfull. @return Other value if the boot from the file fails. **/ EFI_STATUS BootThisFile ( IN BM_FILE_CONTEXT *FileContext ) { EFI_STATUS Status; UINTN ExitDataSize; CHAR16 *ExitData; BDS_COMMON_OPTION *Option; Option = (BDS_COMMON_OPTION *) AllocatePool (sizeof (BDS_COMMON_OPTION)); ASSERT (Option != NULL); Option->Description = (CHAR16 *) AllocateCopyPool (StrSize (FileContext->FileName), FileContext->FileName); Option->DevicePath = FileContext->DevicePath; Option->LoadOptionsSize = 0; Option->LoadOptions = NULL; // // Since current no boot from removable media directly is allowed */ // gST->ConOut->ClearScreen (gST->ConOut); ExitDataSize = 0; Status = BdsLibBootViaBootOption (Option, Option->DevicePath, &ExitDataSize, &ExitData); return Status; }
/** Copy register table from ACPI NVS memory into SMRAM. @param[in] DestinationRegisterTableList Points to destination register table. @param[in] SourceRegisterTableList Points to source register table. @param[in] NumberOfCpus Number of CPUs. **/ VOID CopyRegisterTable ( IN CPU_REGISTER_TABLE *DestinationRegisterTableList, IN CPU_REGISTER_TABLE *SourceRegisterTableList, IN UINT32 NumberOfCpus ) { UINTN Index; UINTN Index1; CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry; CopyMem (DestinationRegisterTableList, SourceRegisterTableList, NumberOfCpus * sizeof (CPU_REGISTER_TABLE)); for (Index = 0; Index < NumberOfCpus; Index++) { if (DestinationRegisterTableList[Index].AllocatedSize != 0) { RegisterTableEntry = AllocateCopyPool ( DestinationRegisterTableList[Index].AllocatedSize, (VOID *)(UINTN)SourceRegisterTableList[Index].RegisterTableEntry ); ASSERT (RegisterTableEntry != NULL); DestinationRegisterTableList[Index].RegisterTableEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTableEntry; // // Go though all MSRs in register table to initialize MSR spin lock // for (Index1 = 0; Index1 < DestinationRegisterTableList[Index].TableLength; Index1++, RegisterTableEntry++) { if ((RegisterTableEntry->RegisterType == Msr) && (RegisterTableEntry->ValidBitLength < 64)) { // // Initialize MSR spin lock only for those MSRs need bit field writing // InitMsrSpinLockByIndex (RegisterTableEntry->Index); } } } } }
EFIAPI GetManFileName( IN CONST CHAR16 *ManFileName ) { CHAR16 *Buffer; if (ManFileName == NULL) { return (NULL); } // // Fix the file name // if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) { Buffer = AllocateCopyPool(StrSize(ManFileName), ManFileName); } else { Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16)); if (Buffer != NULL) { StrnCpyS( Buffer, (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), ManFileName, StrLen(ManFileName) ); StrnCatS( Buffer, (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), L".man", 4 ); } } return (Buffer); }
/** This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name. If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward compatibility support. @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved. @return A pointer to the Unicode string to return. This Unicode string is the name of the controller specified by ControllerHandle and ChildHandle. **/ CHAR16 * DriverHealthManagerGetDriverName ( IN EFI_HANDLE DriverBindingHandle ) { EFI_STATUS Status; CHAR16 *DriverName; // // Get driver name from UEFI 2.0 Component Name 2 protocol interface. // Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentName2ProtocolGuid, DriverBindingHandle, &DriverName); if (EFI_ERROR (Status)) { // // If it fails to get the driver name from Component Name protocol interface, we should fall back on // EFI 1.1 Component Name protocol interface. // Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentNameProtocolGuid, DriverBindingHandle, &DriverName); } if (!EFI_ERROR (Status)) { return AllocateCopyPool (StrSize (DriverName), DriverName); } else { return ConvertDevicePathToText (DevicePathFromHandle (DriverBindingHandle), FALSE, TRUE); } }
/** Check whether current FileName point to a valid Efi Image File. @param FileName File need to be checked. @retval TRUE Is Efi Image @retval FALSE Not a valid Efi Image **/ BOOLEAN LibIsSupportedFileType ( IN UINT16 *FileName ) { CHAR16 *InputFileType; CHAR16 *TmpStr; BOOLEAN IsSupported; if (gFileExplorerPrivate.FileType == NULL) { return TRUE; } InputFileType = LibGetTypeFromName (FileName); // // If the file not has *.* style, always return TRUE. // if (InputFileType == NULL) { return TRUE; } TmpStr = AllocateCopyPool (StrSize (InputFileType), InputFileType); ASSERT(TmpStr != NULL); LibToLowerString(TmpStr); IsSupported = (StrStr (gFileExplorerPrivate.FileType, TmpStr) == NULL ? FALSE : TRUE); FreePool (TmpStr); return IsSupported; }
/** Cleans off all the quotes in the string. @param[in] OriginalString pointer to the string to be cleaned. @param[out] CleanString The new string with all quotes removed. Memory allocated in the function and free by caller. @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS ShellLevel2StripQuotes ( IN CONST CHAR16 *OriginalString, OUT CHAR16 **CleanString ) { CHAR16 *Walker; if (OriginalString == NULL || CleanString == NULL) { return EFI_INVALID_PARAMETER; } *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString); if (*CleanString == NULL) { return EFI_OUT_OF_RESOURCES; } for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL ; Walker++) { if (*Walker == L'\"') { CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0])); } } return EFI_SUCCESS; }
EFI_STATUS EFIAPI EfiBootManagerRegisterContinueKeyOption ( IN UINT32 Modifier, ... ) { EFI_STATUS Status; EFI_BOOT_MANAGER_KEY_OPTION KeyOption; VA_LIST Args; if (mContinueKeyOption != NULL) { return EFI_ALREADY_STARTED; } ZeroMem (&KeyOption, sizeof (EFI_BOOT_MANAGER_KEY_OPTION)); VA_START (Args, Modifier); Status = InitializeKeyFields (Modifier, Args, &KeyOption); VA_END (Args); if (!EFI_ERROR (Status)) { mContinueKeyOption = AllocateCopyPool (sizeof (EFI_BOOT_MANAGER_KEY_OPTION), &KeyOption); ASSERT (mContinueKeyOption != NULL); if (mHotkeyServiceStarted) { ProcessKeyOption (mContinueKeyOption); } } return Status; }
/** Used to allocate and build a device path node for an SD card on the SD controller. The BuildDevicePath() function allocates and builds a single device node for the SD card specified by Slot. If the SD card specified by Slot is not present on the SD controller, then EFI_NOT_FOUND is returned. If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned. Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are initialized to describe the SD card specified by Slot, and EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_SD_MMMC_PASS_THRU_PROTOCOL instance. @param[in] Slot Specifies the slot number of the SD card for which a device path node is to be allocated and built. @param[in,out] DevicePath A pointer to a single device path node that describes the SD card specified by Slot. This function is responsible for allocating the buffer DevicePath with the boot service AllocatePool(). It is the caller's responsibility to free DevicePath when the caller is finished with DevicePath. @retval EFI_SUCCESS The device path node that describes the SD card specified by Slot was allocated and returned in DevicePath. @retval EFI_NOT_FOUND The SD card specified by Slot does not exist on the SD controller. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate DevicePath. **/ EFI_STATUS EFIAPI SdMmcPassThruBuildDevicePath ( IN EFI_SD_MMC_PASS_THRU_PROTOCOL *This, IN UINT8 Slot, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ) { SD_MMC_HC_PRIVATE_DATA *Private; SD_DEVICE_PATH *SdNode; EMMC_DEVICE_PATH *EmmcNode; if ((This == NULL) || (DevicePath == NULL) || (Slot >= SD_MMC_HC_MAX_SLOT)) { return EFI_INVALID_PARAMETER; } Private = SD_MMC_HC_PRIVATE_FROM_THIS (This); if ((!Private->Slot[Slot].Enable) || (!Private->Slot[Slot].MediaPresent)) { return EFI_NOT_FOUND; } if (Private->Slot[Slot].CardType == SdCardType) { SdNode = AllocateCopyPool (sizeof (SD_DEVICE_PATH), &mSdDpTemplate); if (SdNode == NULL) { return EFI_OUT_OF_RESOURCES; } SdNode->SlotNumber = Slot; *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) SdNode; } else if (Private->Slot[Slot].CardType == EmmcCardType) { EmmcNode = AllocateCopyPool (sizeof (EMMC_DEVICE_PATH), &mEmmcDpTemplate); if (EmmcNode == NULL) { return EFI_OUT_OF_RESOURCES; } EmmcNode->SlotNumber = Slot; *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) EmmcNode; } else { // // Currently we only support SD and EMMC two device nodes. // return EFI_NOT_FOUND; } return EFI_SUCCESS; }
/** Get PCD name. @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName. If FALSE, need to get the full PCD name. @param[in] Database PCD database. @param[in] TokenNumber The PCD token number. @return The TokenSpaceCName or full PCD name. **/ CHAR8 * GetPcdName ( IN BOOLEAN OnlyTokenSpaceName, IN PEI_PCD_DATABASE *Database, IN UINTN TokenNumber ) { UINT8 *StringTable; UINTN NameSize; PCD_NAME_INDEX *PcdNameIndex; CHAR8 *TokenSpaceName; CHAR8 *PcdName; CHAR8 *Name; // // Return NULL when PCD name table is absent. // if (Database->PcdNameTableOffset == 0) { return NULL; } // // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. // We have to decrement TokenNumber by 1 to make it usable // as the array index. // TokenNumber--; StringTable = (UINT8 *) Database + Database->StringTableOffset; // // Get the PCD name index. // PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber; TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex]; PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex]; if (OnlyTokenSpaceName) { // // Only need to get the TokenSpaceCName. // Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName); } else { // // Need to get the full PCD name. // NameSize = AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName); Name = AllocateZeroPool (NameSize); ASSERT (Name != NULL); // // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name. // AsciiStrCatS (Name, NameSize, TokenSpaceName); Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.'; AsciiStrCatS (Name, NameSize, PcdName); } return Name; }
/** Save question id and prompt id to the mac device list. If the same mac address has saved yet, no need to add more. @param MacAddrString Mac address string. @retval EFI_SUCCESS Add the item is successful. @return Other values if failed to Add the item. **/ BOOLEAN AddIdToMacDeviceList ( IN EFI_STRING MacAddrString ) { MENU_INFO_ITEM *TempDeviceList; UINTN Index; EFI_STRING StoredString; EFI_STRING_ID PromptId; EFI_HII_HANDLE HiiHandle; HiiHandle = gDeviceManagerPrivate.HiiHandle; TempDeviceList = NULL; for (Index = 0; Index < mMacDeviceList.CurListLen; Index ++) { StoredString = HiiGetString (HiiHandle, mMacDeviceList.NodeList[Index].PromptId, NULL); if (StoredString == NULL) { return FALSE; } // // Already has save the same mac address to the list. // if (StrCmp (MacAddrString, StoredString) == 0) { return FALSE; } } PromptId = HiiSetString(HiiHandle, 0, MacAddrString, NULL); // // If not in the list, save it. // if (mMacDeviceList.MaxListLen > mMacDeviceList.CurListLen + 1) { mMacDeviceList.NodeList[mMacDeviceList.CurListLen].PromptId = PromptId; mMacDeviceList.NodeList[mMacDeviceList.CurListLen].QuestionId = (EFI_QUESTION_ID) (mMacDeviceList.CurListLen + NETWORK_DEVICE_LIST_KEY_OFFSET); } else { mMacDeviceList.MaxListLen += MAX_MAC_ADDRESS_NODE_LIST_LEN; if (mMacDeviceList.CurListLen != 0) { TempDeviceList = (MENU_INFO_ITEM *)AllocateCopyPool (sizeof (MENU_INFO_ITEM) * mMacDeviceList.MaxListLen, (VOID *)mMacDeviceList.NodeList); } else { TempDeviceList = (MENU_INFO_ITEM *)AllocatePool (sizeof (MENU_INFO_ITEM) * mMacDeviceList.MaxListLen); } if (TempDeviceList == NULL) { return FALSE; } TempDeviceList[mMacDeviceList.CurListLen].PromptId = PromptId; TempDeviceList[mMacDeviceList.CurListLen].QuestionId = (EFI_QUESTION_ID) (mMacDeviceList.CurListLen + NETWORK_DEVICE_LIST_KEY_OFFSET); if (mMacDeviceList.CurListLen > 0) { FreePool(mMacDeviceList.NodeList); } mMacDeviceList.NodeList = TempDeviceList; } mMacDeviceList.CurListLen ++; return TRUE; }
/** Set information about a file or a file system. @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle the information is for. @param[in] InformationType The type identifier for the information being set : EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or EFI_FILE_SYSTEM_VOLUME_LABEL_ID @param[in] BufferSize The size, in bytes, of Buffer. @param[in] Buffer A pointer to the data buffer to write. The type of the data inside the buffer is indicated by InformationType. @retval EFI_SUCCESS The information was set. @retval EFI_UNSUPPORTED The InformationType is not known. @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed. @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY Attribute. @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file is a read-only file or has been opened in read-only mode and an attempt is being made to modify a field other than Attribute. @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a file that is already present. @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only attribute. @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by the data inside the buffer. @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request failed. @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. **/ EFI_STATUS FileSetInfo ( IN EFI_FILE *This, IN EFI_GUID *InformationType, IN UINTN BufferSize, IN VOID *Buffer ) { SEMIHOST_FCB *Fcb; EFI_FILE_INFO *Info; EFI_FILE_SYSTEM_INFO *SystemInfo; CHAR16 *VolumeLabel; if ((This == NULL) || (InformationType == NULL) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } Fcb = SEMIHOST_FCB_FROM_THIS (This); if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { Info = Buffer; if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) { return EFI_INVALID_PARAMETER; } if (BufferSize < Info->Size) { return EFI_BAD_BUFFER_SIZE; } return SetFileInfo (Fcb, Info); } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { SystemInfo = Buffer; if (SystemInfo->Size < (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) { return EFI_INVALID_PARAMETER; } if (BufferSize < SystemInfo->Size) { return EFI_BAD_BUFFER_SIZE; } Buffer = SystemInfo->VolumeLabel; if (StrSize (Buffer) > 0) { VolumeLabel = AllocateCopyPool (StrSize (Buffer), Buffer); if (VolumeLabel != NULL) { FreePool (mSemihostFsLabel); mSemihostFsLabel = VolumeLabel; return EFI_SUCCESS; } else { return EFI_OUT_OF_RESOURCES; } } else { return EFI_INVALID_PARAMETER; } } else if (!CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { return EFI_UNSUPPORTED; } else { return EFI_UNSUPPORTED; } }
/** This function installs a EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered by a module using Framework HII Protocol Interfaces. UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so that Setup Utility can load the Buffer Storage using this protocol. @param Packages The Package List. @param ThunkContext The Thunk Context. @retval EFI_SUCCESS The Config Access Protocol is installed successfully. @retval EFI_OUT_RESOURCE There is not enough memory. **/ EFI_STATUS InstallDefaultConfigAccessProtocol ( IN CONST EFI_HII_PACKAGES *Packages, IN OUT HII_THUNK_CONTEXT *ThunkContext ) { EFI_STATUS Status; CONFIG_ACCESS_PRIVATE *ConfigAccessInstance; HII_VENDOR_DEVICE_PATH *HiiVendorPath; ASSERT (ThunkContext->IfrPackageCount != 0); ConfigAccessInstance = AllocateCopyPool ( sizeof (CONFIG_ACCESS_PRIVATE), &gConfigAccessPrivateTempate ); ASSERT (ConfigAccessInstance != NULL); // // Use memory address as unique ID to distinguish from different device paths // This function may be called multi times by the framework HII driver. // HiiVendorPath = AllocateCopyPool ( sizeof (HII_VENDOR_DEVICE_PATH), &mUefiHiiVendorDevicePath ); ASSERT (HiiVendorPath != NULL); HiiVendorPath->Node.UniqueId = (UINT64) ((UINTN) HiiVendorPath); Status = gBS->InstallMultipleProtocolInterfaces ( &ThunkContext->UefiHiiDriverHandle, &gEfiDevicePathProtocolGuid, HiiVendorPath, &gEfiHiiConfigAccessProtocolGuid, &ConfigAccessInstance->ConfigAccessProtocol, NULL ); ASSERT_EFI_ERROR (Status); ConfigAccessInstance->ThunkContext = ThunkContext; return EFI_SUCCESS; }
/** Starts a device controller or a bus controller. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle The handle of the controller to start. This handle must support a protocol interface that supplies an I/O abstraction to the driver. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This parameter is ignored by device drivers, and is optional for bus drivers. For a bus driver, if this parameter is NULL, then handles for all the children of Controller are created by this driver. If this parameter is not NULL and the first Device Path Node is not the End of Device Path Node, then only the handle for the child device specified by the first Device Path Node of RemainingDevicePath is created by this driver. If the first Device Path Node of RemainingDevicePath is the End of Device Path Node, no child handle is created by this driver. @retval EFI_SUCCESS The device was started. @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval Others The driver failded to start the device. **/ EFI_STATUS EFIAPI IsaBusDriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; ISA_BUS_PRIVATE_DATA *Private; Status = gBS->OpenProtocol ( Controller, &gEfiIsaHcProtocolGuid, (VOID **) &mIsaBusPrivateTemplate.IsaHc, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { gBS->CloseProtocol ( Controller, &gEfiIsaHcProtocolGuid, This->DriverBindingHandle, Controller ); return Status; } Private = AllocateCopyPool (sizeof (mIsaBusPrivateTemplate), &mIsaBusPrivateTemplate); ASSERT (Private != NULL); Private->IsaHcHandle = Controller; Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiIsaHcServiceBindingProtocolGuid, &Private->ServiceBinding, NULL ); ASSERT_EFI_ERROR (Status); return Status; }
/** Extract drive string and path string from FullPath. The caller must be free Drive and Path. @param[in] FullPath A path to be extracted. @param[out] Drive Buffer to save drive identifier. @param[out] Path Buffer to save path. @retval EFI_SUCCESS Success. @retval EFI_OUT_OF_RESOUCES A memory allocation failed. **/ EFI_STATUS ExtractDriveAndPath ( IN CONST CHAR16 *FullPath, OUT CHAR16 **Drive, OUT CHAR16 **Path ) { CHAR16 *Splitter; ASSERT (FullPath != NULL); Splitter = StrStr (FullPath, L":"); if (Splitter == NULL) { *Drive = NULL; *Path = AllocateCopyPool (StrSize (FullPath), FullPath); if (*Path == NULL) { return EFI_OUT_OF_RESOURCES; } } else { if (*(Splitter + 1) == CHAR_NULL) { *Drive = AllocateCopyPool (StrSize (FullPath), FullPath); *Path = NULL; if (*Drive == NULL) { return EFI_OUT_OF_RESOURCES; } } else { *Drive = AllocateCopyPool ((Splitter - FullPath + 2) * sizeof(CHAR16), FullPath); if (*Drive == NULL) { return EFI_OUT_OF_RESOURCES; } (*Drive)[Splitter - FullPath + 1] = CHAR_NULL; *Path = AllocateCopyPool (StrSize (Splitter + 1), Splitter + 1); if (*Path == NULL) { FreePool (*Drive); return EFI_OUT_OF_RESOURCES; } } } return EFI_SUCCESS; }
/** Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB. These console show up on the remote system running GDB **/ VOID GdbInitializeSerialConsole ( VOID ) { EFI_STATUS Status; GDB_SERIAL_DEV *StdOutSerialDev; GDB_SERIAL_DEV *StdErrSerialDev; // Use the template to make a copy of the Serial Console private data structure. StdOutSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate); ASSERT (StdOutSerialDev != NULL); // Fixup pointer after the copy StdOutSerialDev->SerialIo.Mode = &StdOutSerialDev->SerialMode; StdErrSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate); ASSERT (StdErrSerialDev != NULL); // Fixup pointer and modify stuff that is different for StdError StdErrSerialDev->SerialIo.Mode = &StdErrSerialDev->SerialMode; StdErrSerialDev->DevicePath.Index = 1; StdErrSerialDev->OutFileDescriptor = GDB_STDERR; // Make a new handle with Serial IO protocol and its device path on it. Status = gBS->InstallMultipleProtocolInterfaces ( &StdOutSerialDev->Handle, &gEfiSerialIoProtocolGuid, &StdOutSerialDev->SerialIo, &gEfiDevicePathProtocolGuid, &StdOutSerialDev->DevicePath, NULL ); ASSERT_EFI_ERROR (Status); // Make a new handle with Serial IO protocol and its device path on it. Status = gBS->InstallMultipleProtocolInterfaces ( &StdErrSerialDev->Handle, &gEfiSerialIoProtocolGuid, &StdErrSerialDev->SerialIo, &gEfiDevicePathProtocolGuid, &StdErrSerialDev->DevicePath, NULL ); ASSERT_EFI_ERROR (Status); }
/** Return the boot description for the controller based on the type. @param Handle Controller handle. @return The description string. **/ CHAR16 * BmGetMiscDescription ( IN EFI_HANDLE Handle ) { EFI_STATUS Status; CHAR16 *Description; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; switch (BmDevicePathType (DevicePathFromHandle (Handle))) { case BmAcpiFloppyBoot: Description = L"Floppy"; break; case BmMessageAtapiBoot: case BmMessageSataBoot: Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); ASSERT_EFI_ERROR (Status); // // Assume a removable SATA device should be the DVD/CD device // Description = BlockIo->Media->RemovableMedia ? L"DVD/CDROM" : L"Hard Drive"; break; case BmMessageUsbBoot: Description = L"USB Device"; break; case BmMessageScsiBoot: Description = L"SCSI Device"; break; case BmHardwareDeviceBoot: Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); if (!EFI_ERROR (Status)) { Description = BlockIo->Media->RemovableMedia ? L"Removable Disk" : L"Hard Drive"; } else { Description = L"Misc Device"; } break; default: Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **) &Fs); if (!EFI_ERROR (Status)) { Description = L"Non-Block Boot Device"; } else { Description = L"Misc Device"; } break; } return AllocateCopyPool (StrSize (Description), Description); }
/** Initialize a PCI_ROOT_BRIDGE structure. @param[in] Supports Supported attributes. @param[in] Attributes Initial attributes. @param[in] AllocAttributes Allocation attributes. @param[in] RootBusNumber The bus number to store in RootBus. @param[in] MaxSubBusNumber The inclusive maximum bus number that can be assigned to any subordinate bus found behind any PCI bridge hanging off this root bus. The caller is repsonsible for ensuring that RootBusNumber <= MaxSubBusNumber. If RootBusNumber equals MaxSubBusNumber, then the root bus has no room for subordinate buses. @param[in] Io IO aperture. @param[in] Mem MMIO aperture. @param[in] MemAbove4G MMIO aperture above 4G. @param[in] PMem Prefetchable MMIO aperture. @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the caller) that should be filled in by this function. @retval EFI_SUCCESS Initialization successful. A device path consisting of an ACPI device path node, with UID = RootBusNumber, has been allocated and linked into RootBus. @retval EFI_OUT_OF_RESOURCES Memory allocation failed. **/ EFI_STATUS InitRootBridge ( IN UINT64 Supports, IN UINT64 Attributes, IN UINT64 AllocAttributes, IN UINT8 RootBusNumber, IN UINT8 MaxSubBusNumber, IN PCI_ROOT_BRIDGE_APERTURE *Io, IN PCI_ROOT_BRIDGE_APERTURE *Mem, IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, IN PCI_ROOT_BRIDGE_APERTURE *PMem, IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G, OUT PCI_ROOT_BRIDGE *RootBus ) { CB_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath; // // Be safe if other fields are added to PCI_ROOT_BRIDGE later. // ZeroMem (RootBus, sizeof *RootBus); RootBus->Segment = 0; RootBus->Supports = Supports; RootBus->Attributes = Attributes; RootBus->DmaAbove4G = FALSE; RootBus->AllocationAttributes = AllocAttributes; RootBus->Bus.Base = RootBusNumber; RootBus->Bus.Limit = MaxSubBusNumber; CopyMem (&RootBus->Io, Io, sizeof (*Io)); CopyMem (&RootBus->Mem, Mem, sizeof (*Mem)); CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G)); CopyMem (&RootBus->PMem, PMem, sizeof (*PMem)); CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G)); RootBus->NoExtendedConfigSpace = FALSE; DevicePath = AllocateCopyPool (sizeof (mRootBridgeDevicePathTemplate), &mRootBridgeDevicePathTemplate); if (DevicePath == NULL) { DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); return EFI_OUT_OF_RESOURCES; } DevicePath->AcpiDevicePath.UID = RootBusNumber; RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath; DEBUG ((EFI_D_INFO, "%a: populated root bus %d, with room for %d subordinate bus(es)\n", __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber)); return EFI_SUCCESS; }
/** Caller provided function to be invoked at the end of DebugPortInitialize(). Refer to the description for DebugPortInitialize() for more details. @param[in] Context The first input argument of DebugPortInitialize(). @param[in] DebugPortHandle Debug port handle created by Debug Communication Library. **/ VOID EFIAPI InitializeDebugAgentPhase2 ( IN VOID *Context, IN DEBUG_PORT_HANDLE DebugPortHandle ) { DEBUG_AGENT_PHASE2_CONTEXT *Phase2Context; UINT64 *MailboxLocation; DEBUG_AGENT_MAILBOX *Mailbox; EFI_SEC_PEI_HAND_OFF *SecCoreData; UINT16 BufferSize; UINT64 NewDebugPortHandle; Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context; MailboxLocation = GetLocationSavedMailboxPointerInIdtEntry (); Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation); BufferSize = PcdGet16(PcdDebugPortHandleBufferSize); if (Phase2Context->InitFlag == DEBUG_AGENT_INIT_PEI && BufferSize != 0) { NewDebugPortHandle = (UINT64)(UINTN)AllocateCopyPool (BufferSize, DebugPortHandle); } else { NewDebugPortHandle = (UINT64)(UINTN)DebugPortHandle; } UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, NewDebugPortHandle); // // Trigger one software interrupt to inform HOST // TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE); if (Phase2Context->InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) { // // If Temporary RAM region is below 128 MB, then send message to // host to disable low memory filtering. // SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context; if ((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB && IsHostAttached ()) { SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1); TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); } // // Enable Debug Timer interrupt // SaveAndSetDebugTimerInterrupt (TRUE); // // Enable CPU interrupts so debug timer interrupts can be delivered // EnableInterrupts (); // // Call continuation function if it is not NULL. // Phase2Context->Function (Phase2Context->Context); } }
STATIC EFI_STATUS SupportedDevicePathsInit ( VOID ) { EFI_STATUS Status; CHAR16* DevicePathListStr; CHAR16* DevicePathStr; CHAR16* NextDevicePathStr; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH_PROTOCOL *Instance; Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); ASSERT_EFI_ERROR (Status); // Initialize Variable DevicePathListStr = (CHAR16*)PcdGetPtr (PcdBootMonFsSupportedDevicePaths); mBootMonFsSupportedDevicePaths = NULL; // Extract the Device Path instances from the multi-device path string while ((DevicePathListStr != NULL) && (DevicePathListStr[0] != L'\0')) { NextDevicePathStr = StrStr (DevicePathListStr, L";"); if (NextDevicePathStr == NULL) { DevicePathStr = DevicePathListStr; DevicePathListStr = NULL; } else { DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DevicePathListStr + 1) * sizeof (CHAR16), DevicePathListStr); if (DevicePathStr == NULL) { return EFI_OUT_OF_RESOURCES; } *(DevicePathStr + (NextDevicePathStr - DevicePathListStr)) = L'\0'; DevicePathListStr = NextDevicePathStr; if (DevicePathListStr[0] == L';') { DevicePathListStr++; } } Instance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr); ASSERT (Instance != NULL); mBootMonFsSupportedDevicePaths = AppendDevicePathInstance (mBootMonFsSupportedDevicePaths, Instance); if (NextDevicePathStr != NULL) { FreePool (DevicePathStr); } FreePool (Instance); } if (mBootMonFsSupportedDevicePaths == NULL) { return EFI_UNSUPPORTED; } else { return EFI_SUCCESS; } }
/** The constructor function. @retval EFI_SUCCESS The constructor successfully . **/ EFI_STATUS EFIAPI EdkiiSystemCapsuleLibConstructor ( VOID ) { mImageFmpInfoSize = PcdGetSize(PcdEdkiiSystemFirmwareImageDescriptor); mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, PcdGetPtr(PcdEdkiiSystemFirmwareImageDescriptor)); ASSERT(mImageFmpInfo != NULL); CopyGuid(&mEdkiiSystemFirmwareFileGuid, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid)); return EFI_SUCCESS; }
EFIAPI GetExecuatableFileName ( IN CONST CHAR16 *NameString ) { CHAR16 *Buffer; CHAR16 *SuffixStr; if (NameString == NULL) { return (NULL); } // // Fix the file name // if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".efi"), L".efi", StrLen(L".efi"))==0) { Buffer = AllocateCopyPool(StrSize(NameString), NameString); } else if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".man"), L".man", StrLen(L".man"))==0) { Buffer = AllocateCopyPool(StrSize(NameString), NameString); if (Buffer != NULL) { SuffixStr = Buffer+StrLen(Buffer)-StrLen(L".man"); StrnCpyS (SuffixStr, StrSize(L".man")/sizeof(CHAR16), L".efi", StrLen(L".efi")); } } else { Buffer = AllocateZeroPool(StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16)); if (Buffer != NULL) { StrnCpyS( Buffer, (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16), NameString, StrLen(NameString) ); StrnCatS( Buffer, (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16), L".efi", StrLen(L".efi") ); } } return (Buffer); }
/** Returns a list of ACPI resource descriptors that detail the special resource configuration requirements for an incompatible PCI device. Prior to bus enumeration, the PCI bus driver will look for the presence of the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL. Only one instance of this protocol can be present in the system. For each PCI device that the PCI bus driver discovers, the PCI bus driver calls this function with the device's vendor ID, device ID, revision ID, subsystem vendor ID, and subsystem device ID. If the VendorId, DeviceId, RevisionId, SubsystemVendorId, or SubsystemDeviceId value is set to (UINTN)-1, that field will be ignored. The ID values that are not (UINTN)-1 will be used to identify the current device. This function will only return EFI_SUCCESS. However, if the device is an incompatible PCI device, a list of ACPI resource descriptors will be returned in Configuration. Otherwise, NULL will be returned in Configuration instead. The PCI bus driver does not need to allocate memory for Configuration. However, it is the PCI bus driver's responsibility to free it. The PCI bus driver then can configure this device with the information that is derived from this list of resource nodes, rather than the result of BAR probing. Only the following two resource descriptor types from the ACPI Specification may be used to describe the incompatible PCI device resource requirements: - QWORD Address Space Descriptor (ACPI 2.0, section 6.4.3.5.1; also ACPI 3.0) - End Tag (ACPI 2.0, section 6.4.2.8; also ACPI 3.0) The QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD Address Space Descriptors, followed by an End Tag. See the ACPI Specification for details on the field values. @param[in] This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance. @param[in] VendorId A unique ID to identify the manufacturer of the PCI device. See the Conventional PCI Specification 3.0 for details. @param[in] DeviceId A unique ID to identify the particular PCI device. See the Conventional PCI Specification 3.0 for details. @param[in] RevisionId A PCI device-specific revision identifier. See the Conventional PCI Specification 3.0 for details. @param[in] SubsystemVendorId Specifies the subsystem vendor ID. See the Conventional PCI Specification 3.0 for details. @param[in] SubsystemDeviceId Specifies the subsystem device ID. See the Conventional PCI Specification 3.0 for details. @param[out] Configuration A list of ACPI resource descriptors that detail the configuration requirement. @retval EFI_SUCCESS The function always returns EFI_SUCCESS. **/ STATIC EFI_STATUS EFIAPI CheckDevice ( IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This, IN UINTN VendorId, IN UINTN DeviceId, IN UINTN RevisionId, IN UINTN SubsystemVendorId, IN UINTN SubsystemDeviceId, OUT VOID **Configuration ) { mCheckDeviceCalled = TRUE; // // Unlike the general description of this protocol member suggests, there is // nothing incompatible about the PCI devices that we'll match here. We'll // match all PCI devices, and generate exactly one QWORD Address Space // Descriptor for each. That descriptor will instruct the PCI Bus UEFI_DRIVER // not to degrade 64-bit MMIO BARs for the device, even if a PCI option ROM // BAR is present on the device. // // The concern captured in the PCI Bus UEFI_DRIVER is that a legacy BIOS boot // (via a CSM) could dispatch a legacy option ROM on the device, which might // have trouble with MMIO BARs that have been allocated outside of the 32-bit // address space. But, if we don't support legacy option ROMs at all, then // this problem cannot arise. // if (mLegacyBiosInstalled) { // // Don't interfere with resource degradation. // *Configuration = NULL; return EFI_SUCCESS; } // // This member function is mis-specified actually: it is supposed to allocate // memory, but as specified, it could not return an error status. Thankfully, // the edk2 PCI Bus UEFI_DRIVER actually handles error codes; see the // UpdatePciInfo() function. // *Configuration = AllocateCopyPool (sizeof mConfiguration, &mConfiguration); if (*Configuration == NULL) { DEBUG ((EFI_D_WARN, "%a: 64-bit MMIO BARs may be degraded for PCI 0x%04x:0x%04x (rev %d)\n", __FUNCTION__, (UINT32)VendorId, (UINT32)DeviceId, (UINT8)RevisionId)); return EFI_OUT_OF_RESOURCES; } return EFI_SUCCESS; }
/** Initialize a load option. @param Option Pointer to the load option to be initialized. @param OptionNumber Option number of the load option. @param OptionType Type of the load option. @param Attributes Attributes of the load option. @param Description Description of the load option. @param FilePath Device path of the load option. @param OptionalData Optional data of the load option. @param OptionalDataSize Size of the optional data of the load option. @retval EFI_SUCCESS The load option was initialized successfully. @retval EFI_INVALID_PARAMETER Option, Description or FilePath is NULL. **/ EFI_STATUS EFIAPI EfiBootManagerInitializeLoadOption ( IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN OptionNumber, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType, IN UINT32 Attributes, IN CHAR16 *Description, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN UINT8 *OptionalData, OPTIONAL IN UINT32 OptionalDataSize ) { if ((Option == NULL) || (Description == NULL) || (FilePath == NULL)) { return EFI_INVALID_PARAMETER; } if (((OptionalData != NULL) && (OptionalDataSize == 0)) || ((OptionalData == NULL) && (OptionalDataSize != 0))) { return EFI_INVALID_PARAMETER; } if ((UINT32) OptionType >= LoadOptionTypeMax) { return EFI_INVALID_PARAMETER; } ZeroMem (Option, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION)); Option->OptionNumber = OptionNumber; Option->OptionType = OptionType; Option->Attributes = Attributes; Option->Description = AllocateCopyPool (StrSize (Description), Description); Option->FilePath = DuplicateDevicePath (FilePath); if (OptionalData != NULL) { Option->OptionalData = AllocateCopyPool (OptionalDataSize, OptionalData); Option->OptionalDataSize = OptionalDataSize; } return EFI_SUCCESS; }
/** Split a string with specified separator and save the substring to a list. @param[in] String The pointer of the input string. @param[in] Separator The specified separator. @return The pointer of headnode of ARG_LIST. **/ ARG_LIST * SplitStrToList ( IN CONST CHAR16 *String, IN CHAR16 Separator ) { CHAR16 *Str; CHAR16 *ArgStr; ARG_LIST *ArgList; ARG_LIST *ArgNode; if (String == NULL || *String == L'\0') { return NULL; } // // Copy the CONST string to a local copy. // Str = AllocateCopyPool (StrSize (String), String); ASSERT (Str != NULL); ArgStr = Str; // // init a node for the list head. // ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST)); ASSERT (ArgNode != NULL); ArgList = ArgNode; // // Split the local copy and save in the list node. // while (*Str != L'\0') { if (*Str == Separator) { *Str = L'\0'; ArgNode->Arg = ArgStr; ArgStr = Str + 1; ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST)); ASSERT (ArgNode->Next != NULL); ArgNode = ArgNode->Next; } Str++; } ArgNode->Arg = ArgStr; ArgNode->Next = NULL; return ArgList; }