/** Acquire the string associated with the Index from smbios structure and return it. The caller is responsible for free the string buffer. @param OptionalStrStart The start position to search the string @param Index The index of the string to extract @param String The string that is extracted @retval EFI_SUCCESS The function returns EFI_SUCCESS always. **/ EFI_STATUS GetOptionalStringByIndex ( IN CHAR8 *OptionalStrStart, IN UINT8 Index, OUT CHAR16 **String ) { UINTN StrSize; if (Index == 0) { *String = AllocateZeroPool (sizeof (CHAR16)); return EFI_SUCCESS; } StrSize = 0; do { Index--; OptionalStrStart += StrSize; StrSize = AsciiStrSize (OptionalStrStart); } while (OptionalStrStart[StrSize] != 0 && Index != 0); if ((Index != 0) || (StrSize == 1)) { // // Meet the end of strings set but Index is non-zero, or // Find an empty string // *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING)); } else { *String = AllocatePool (StrSize * sizeof (CHAR16)); AsciiStrToUnicodeStr (OptionalStrStart, *String); } return EFI_SUCCESS; }
/* Normalize a narrow-character path and produce a wide-character path that has forward slashes replaced with backslashes. Backslashes are directory separators in UEFI File Paths. It is the caller's responsibility to eventually free() the returned buffer. @param[in] path A pointer to the narrow-character path to be normalized. @return A pointer to a buffer containing the normalized, wide-character, path. */ wchar_t * NormalizePath( const char *path) { wchar_t *temp; wchar_t *OldPath; wchar_t *NewPath; size_t Length; OldPath = AsciiStrToUnicodeStr(path, gMD->UString); Length = wcslen(OldPath) + 1; NewPath = calloc(Length, sizeof(wchar_t)); if(NewPath != NULL) { temp = NewPath; for( ; *OldPath; ++OldPath) { if(*OldPath == L'/') { *temp = L'\\'; } else { *temp = *OldPath; } ++temp; } } else { errno = ENOMEM; EFIerrno = RETURN_OUT_OF_RESOURCES; } return NewPath; }
/** Allows a program to determine the primary languages that are supported on a given handle. This routine is intended to be used by drivers to query the interface database for supported languages. This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle. @param This A pointer to the EFI_HII_PROTOCOL instance. @param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() in the Packages section. @param LanguageString A string allocated by GetPrimaryLanguages() that contains a list of all primary languages registered on the handle. The routine will not return the three-spaces language identifier used in other functions to indicate non-language-specific strings. @retval EFI_SUCCESS LanguageString was correctly returned. @retval EFI_INVALID_PARAMETER The Handle was unknown. **/ EFI_STATUS EFIAPI HiiGetPrimaryLanguages ( IN EFI_HII_PROTOCOL *This, IN FRAMEWORK_EFI_HII_HANDLE Handle, OUT EFI_STRING *LanguageString ) { HII_THUNK_PRIVATE_DATA *Private; EFI_HII_HANDLE UefiHiiHandle; CHAR8 *LangCodes4646; CHAR16 *UnicodeLangCodes639; CHAR8 *LangCodes639; EFI_STATUS Status; Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle); if (UefiHiiHandle == NULL) { return EFI_INVALID_PARAMETER; } LangCodes4646 = HiiGetSupportedLanguages (UefiHiiHandle); if (LangCodes4646 == NULL) { return EFI_INVALID_PARAMETER; } LangCodes639 = ConvertLanguagesRfc4646ToIso639 (LangCodes4646); if (LangCodes639 == NULL) { Status = EFI_INVALID_PARAMETER; goto Done; } UnicodeLangCodes639 = AllocateZeroPool (AsciiStrSize (LangCodes639) * sizeof (CHAR16)); if (UnicodeLangCodes639 == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } // // The language returned is in RFC 639-2 format. // AsciiStrToUnicodeStr (LangCodes639, UnicodeLangCodes639); *LanguageString = UnicodeLangCodes639; Status = EFI_SUCCESS; Done: FreePool (LangCodes4646); if (LangCodes639 != NULL) { FreePool (LangCodes639); } return Status; }
VOID Ext2DebugDirent (struct dirent *dir) { CHAR16 Name[dir->d_namlen]; AsciiStrToUnicodeStr(dir->d_name, Name); DEBUG ((EFI_D_INFO, "\n============Ext2 direct===================\n")); DEBUG ((EFI_D_INFO, "d_fileno : %d\n", dir->d_fileno)); DEBUG ((EFI_D_INFO, "d_reclen : %d\n", dir->d_reclen)); DEBUG ((EFI_D_INFO, "d_namelen : %d\n", dir->d_namlen)); DEBUG ((EFI_D_INFO, "d_name : %s\n", Name)); }
/** The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are determined by the underlying UEFI Shell implementation. @return The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function. If the specified name cannot be found, a null pointer is returned. **/ char *getenv(const char *name) { const CHAR16 *EfiEnv; char *retval = NULL; (void)AsciiStrToUnicodeStr( name, gMD->UString); EfiEnv = ShellGetEnvironmentVariable(gMD->UString); if(EfiEnv != NULL) { retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv); } return retval; }
VOID Ext2DebugDirect (struct ext2fs_direct *dir) { CHAR16 Name[dir->e2d_namlen+1]; AsciiStrToUnicodeStr(dir->e2d_name, Name); DEBUG ((EFI_D_INFO, "\n============Ext2 direct===================\n")); DEBUG ((EFI_D_INFO, "e2d_ino : %d\n", dir->e2d_ino)); DEBUG ((EFI_D_INFO, "e2d_reclen : %d\n", dir->e2d_reclen)); DEBUG ((EFI_D_INFO, "e2d_namelen : %d\n", dir->e2d_namlen)); DEBUG ((EFI_D_INFO, "e2d_type : %d\n", dir->e2d_type)); DEBUG ((EFI_D_INFO, "e2d_name : %s\n", Name)); }
CHAR16* Ascii2Unicode ( CONST CHAR8* AsciiStr ) { CHAR16* UnicodeStr = AllocatePool((AsciiStrLen (AsciiStr) + 1) * sizeof (CHAR16)); if (UnicodeStr == NULL) { return NULL; } AsciiStrToUnicodeStr(AsciiStr, UnicodeStr); return UnicodeStr; }
/** Get EMMC device model name. @param[in, out] Device The pointer to the EMMC_DEVICE data structure. @param[in] Cid Pointer to EMMC_CID data structure. @retval EFI_SUCCESS The function completed successfully **/ EFI_STATUS GetEmmcModelName ( IN OUT EMMC_DEVICE *Device, IN EMMC_CID *Cid ) { CHAR8 String[EMMC_MODEL_NAME_MAX_LEN]; ZeroMem (String, sizeof (String)); CopyMem (String, &Cid->OemId, sizeof (Cid->OemId)); String[sizeof (Cid->OemId)] = ' '; CopyMem (String + sizeof (Cid->OemId) + 1, Cid->ProductName, sizeof (Cid->ProductName)); String[sizeof (Cid->OemId) + sizeof (Cid->ProductName)] = ' '; CopyMem (String + sizeof (Cid->OemId) + sizeof (Cid->ProductName) + 1, Cid->ProductSerialNumber, sizeof (Cid->ProductSerialNumber)); AsciiStrToUnicodeStr (String, Device->ModelName); return EFI_SUCCESS; }
/** If string is a null pointer, the system function determines whether the host environment has a command processor. If string is not a null pointer, the system function passes the string pointed to by string to that command processor to be executed in a manner which the implementation shall document; this might then cause the program calling system to behave in a non-conforming manner or to terminate. @retval EXIT_FAILURE EFIerrno will contain the EFI status code indicating the cause of failure. @retval EXIT_SUCCESS EFIerrno will contain the EFI status returned by the executed command string. @retval 0 If string is NULL, 0 means a command processor is not available. @retval 1 If string is NULL, 1 means a command processor is available. **/ int system(const char *string) { EFI_STATUS CmdStat; EFI_STATUS OpStat; EFI_HANDLE MyHandle = gImageHandle; if( string == NULL) { return 1; } (void)AsciiStrToUnicodeStr( string, gMD->UString); OpStat = ShellExecute( &MyHandle, gMD->UString, FALSE, NULL, &CmdStat); if(OpStat == RETURN_SUCCESS) { EFIerrno = CmdStat; return EXIT_SUCCESS; } EFIerrno = OpStat; return EXIT_FAILURE; }
EFI_STATUS ArmFastbootPlatformOemCommand ( IN CHAR8 *Command ) { CHAR16 CommandUnicode[65]; AsciiStrToUnicodeStr (Command, CommandUnicode); if (AsciiStrCmp (Command, "Demonstrate") == 0) { DEBUG ((EFI_D_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n")); return EFI_SUCCESS; } else { DEBUG ((EFI_D_ERROR, "VExpress: Unrecognised Fastboot OEM command: %s\n", CommandUnicode )); return EFI_NOT_FOUND; } }
EFI_STATUS EditHIInputAscii ( IN OUT CHAR8 *CmdLine, IN UINTN MaxCmdLine ) { CHAR16* Str; EFI_STATUS Status; Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16)); AsciiStrToUnicodeStr (CmdLine, Str); Status = EditHIInputStr (Str, MaxCmdLine); if (!EFI_ERROR(Status)) { UnicodeStrToAsciiStr (Str, CmdLine); } FreePool (Str); return Status; }
VOID InstallProcessorSmbios ( IN VOID *Smbios ) { SMBIOS_STRUCTURE_POINTER SmbiosTable; CHAR8 *AString; CHAR16 *UString; STRING_REF Token; // // Processor info (TYPE 4) // SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 4, 0); if (SmbiosTable.Raw == NULL) { DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 4 (Processor Info) not found!\n")); return ; } // // Log Smbios Record Type4 // LogSmbiosData(gSmbios,(UINT8*)SmbiosTable.Type4); // // Set ProcessorVersion string // AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type4->ProcessorVersion); UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16)); ASSERT (UString != NULL); AsciiStrToUnicodeStr (AString, UString); Token = HiiSetString (gStringHandle, 0, UString, NULL); if (Token == 0) { gBS->FreePool (UString); return ; } gBS->FreePool (UString); return ; }
VOID InstallMiscSmbios ( IN VOID *Smbios ) { SMBIOS_STRUCTURE_POINTER SmbiosTable; CHAR8 *AString; CHAR16 *UString; STRING_REF Token; // // BIOS information (TYPE 0) // SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 0, 0); if (SmbiosTable.Raw == NULL) { DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 0 (BIOS Information) not found!\n")); return ; } // // Record Type 2 // AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type0->BiosVersion); UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_BIOS_VERSIONE)); ASSERT (UString != NULL); CopyMem (UString, FIRMWARE_BIOS_VERSIONE, sizeof(FIRMWARE_BIOS_VERSIONE)); AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_BIOS_VERSIONE) / sizeof(CHAR16) - 1); Token = HiiSetString (gStringHandle, 0, UString, NULL); if (Token == 0) { gBS->FreePool (UString); return ; } gBS->FreePool (UString); // // Log Smios Type 0 // LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type0); // // System information (TYPE 1) // SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 1, 0); if (SmbiosTable.Raw == NULL) { DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 1 (System Information) not found!\n")); return ; } // // Record Type 3 // AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type1->ProductName); UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_PRODUCT_NAME)); ASSERT (UString != NULL); CopyMem (UString, FIRMWARE_PRODUCT_NAME, sizeof(FIRMWARE_PRODUCT_NAME)); AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_PRODUCT_NAME) / sizeof(CHAR16) - 1); Token = HiiSetString (gStringHandle, 0, UString, NULL); if (Token == 0) { gBS->FreePool (UString); return ; } gBS->FreePool (UString); // // Log Smbios Type 1 // LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type1); return ; }
EFI_STATUS DefineDefaultBootEntries ( VOID ) { BDS_LOAD_OPTION* BdsLoadOption; UINTN Size; EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH* BootDevicePath; UINTN CmdLineSize; UINTN CmdLineAsciiSize; CHAR16* DefaultBootArgument; CHAR8* AsciiDefaultBootArgument; // // If Boot Order does not exist then create a default entry // Size = 0; Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL); if (Status == EFI_NOT_FOUND) { if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) { return EFI_UNSUPPORTED; } Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n")); return Status; } BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)); DEBUG_CODE_BEGIN(); // We convert back to the text representation of the device Path to see if the initial text is correct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE); if (StrCmp ((CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt) != 0) { DEBUG ((EFI_D_ERROR, "Device Path given: '%s' Device Path expected: '%s'\n", (CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt)); ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); } FreePool (DevicePathTxt); DEBUG_CODE_END(); // Create the entry is the Default values are correct if (BootDevicePath != NULL) { // We do not support NULL pointer ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL); // // Logic to handle ASCII or Unicode default parameters // if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') { CmdLineSize = 0; CmdLineAsciiSize = 0; DefaultBootArgument = NULL; AsciiDefaultBootArgument = NULL; } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) { // The command line is a Unicode string DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument); CmdLineSize = StrSize (DefaultBootArgument); // Initialize ASCII variables CmdLineAsciiSize = CmdLineSize / 2; AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize); if (AsciiDefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument); } else { // The command line is a ASCII string AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument); CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument); // Initialize ASCII variables CmdLineSize = CmdLineAsciiSize * 2; DefaultBootArgument = AllocatePool (CmdLineSize); if (DefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument); } BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT, (CHAR16*)PcdGetPtr (PcdDefaultBootDescription), BootDevicePath, (UINT8 *)DefaultBootArgument, // OptionalData CmdLineSize, // OptionalDataSize &BdsLoadOption ); FreePool (BdsLoadOption); if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) { FreePool (AsciiDefaultBootArgument); } else if (DefaultBootArgument != NULL) { FreePool (DefaultBootArgument); } } else { Status = EFI_UNSUPPORTED; } } return Status; }
/** The Request() function queues an HTTP request to this HTTP instance. Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent successfully, or if there is an error, Status in token will be updated and Event will be signaled. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[in] Token Pointer to storage containing HTTP request token. @retval EFI_SUCCESS Outgoing data was processed. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. @retval EFI_UNSUPPORTED The HTTP method is not supported in current implementation. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. Token->Message is NULL. Token->Message->Body is not NULL, Token->Message->BodyLength is non-zero, and Token->Message->Data is NULL, but a previous call to Request()has not been completed successfully. **/ EFI_STATUS EFIAPI EfiHttpRequest ( IN EFI_HTTP_PROTOCOL *This, IN EFI_HTTP_TOKEN *Token ) { EFI_HTTP_MESSAGE *HttpMsg; EFI_HTTP_REQUEST_DATA *Request; VOID *UrlParser; EFI_STATUS Status; CHAR8 *HostName; UINT16 RemotePort; HTTP_PROTOCOL *HttpInstance; BOOLEAN Configure; BOOLEAN ReConfigure; CHAR8 *RequestStr; CHAR8 *Url; CHAR16 *HostNameStr; HTTP_TOKEN_WRAP *Wrap; HTTP_TCP_TOKEN_WRAP *TcpWrap; if ((This == NULL) || (Token == NULL)) { return EFI_INVALID_PARAMETER; } HttpMsg = Token->Message; if ((HttpMsg == NULL) || (HttpMsg->Headers == NULL)) { return EFI_INVALID_PARAMETER; } // // Current implementation does not support POST/PUT method. // If future version supports these two methods, Request could be NULL for a special case that to send large amounts // of data. For this case, the implementation need check whether previous call to Request() has been completed or not. // // Request = HttpMsg->Data.Request; if ((Request == NULL) || (Request->Url == NULL)) { return EFI_INVALID_PARAMETER; } // // Only support GET and HEAD method in current implementation. // if ((Request->Method != HttpMethodGet) && (Request->Method != HttpMethodHead)) { return EFI_UNSUPPORTED; } HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); ASSERT (HttpInstance != NULL); if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) { return EFI_NOT_STARTED; } if (HttpInstance->LocalAddressIsIPv6) { return EFI_UNSUPPORTED; } // // Check whether the token already existed. // if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTokenExist, Token))) { return EFI_ACCESS_DENIED; } Url = NULL; HostName = NULL; Wrap = NULL; HostNameStr = NULL; TcpWrap = NULL; // // Parse the URI of the remote host. // Url = AllocatePool (StrLen (Request->Url) + 1); if (Url == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (Request->Url, Url); UrlParser = NULL; Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser); if (EFI_ERROR (Status)) { goto Error1; } RequestStr = NULL; HostName = NULL; Status = HttpUrlGetHostName (Url, UrlParser, &HostName); if (EFI_ERROR (Status)) { goto Error1; } Status = HttpUrlGetPort (Url, UrlParser, &RemotePort); if (EFI_ERROR (Status)) { RemotePort = HTTP_DEFAULT_PORT; } Configure = TRUE; ReConfigure = TRUE; if (HttpInstance->RemoteHost == NULL && HttpInstance->RemotePort == 0) { // // Request() is called the first time. // ReConfigure = FALSE; } else { if ((HttpInstance->RemotePort == RemotePort) && (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) { // // Host Name and port number of the request URL are the same with previous call to Request(). // Check whether previous TCP packet sent out. // if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) { // // Wrap the HTTP token in HTTP_TOKEN_WRAP // Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); if (Wrap == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } Wrap->HttpToken = Token; Wrap->HttpInstance = HttpInstance; Status = HttpCreateTcp4TxEvent (Wrap); if (EFI_ERROR (Status)) { goto Error1; } Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); if (EFI_ERROR (Status)) { goto Error1; } Wrap->TcpWrap.Method = Request->Method; FreePool (Url); FreePool (HostName); // // Queue the HTTP token and return. // return EFI_SUCCESS; } else { // // Use existing TCP instance to transmit the packet. // Configure = FALSE; ReConfigure = FALSE; } } else { // // Need close existing TCP instance and create a new TCP instance for data transmit. // if (HttpInstance->RemoteHost != NULL) { FreePool (HttpInstance->RemoteHost); HttpInstance->RemoteHost = NULL; } } } if (Configure) { // // Parse Url for IPv4 address, if failed, perform DNS resolution. // Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr); if (EFI_ERROR (Status)) { HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (UINT16)); if (HostNameStr == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } AsciiStrToUnicodeStr (HostName, HostNameStr); Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr); FreePool (HostNameStr); if (EFI_ERROR (Status)) { goto Error1; } } // // Save the RemotePort and RemoteHost. // ASSERT (HttpInstance->RemoteHost == NULL); HttpInstance->RemotePort = RemotePort; HttpInstance->RemoteHost = HostName; HostName = NULL; } if (ReConfigure) { // // The request URL is different from previous calls to Request(), close existing TCP instance. // ASSERT (HttpInstance->Tcp4 != NULL); HttpCloseConnection (HttpInstance); EfiHttpCancel (This, NULL); } // // Wrap the HTTP token in HTTP_TOKEN_WRAP // Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); if (Wrap == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } Wrap->HttpToken = Token; Wrap->HttpInstance = HttpInstance; Wrap->TcpWrap.Method = Request->Method; if (Configure) { // // Configure TCP instance. // Status = HttpConfigureTcp4 (HttpInstance, Wrap); if (EFI_ERROR (Status)) { goto Error1; } // // Connect TCP. // Status = HttpConnectTcp4 (HttpInstance); if (EFI_ERROR (Status)) { goto Error2; } } else { // // For the new HTTP token, create TX TCP token events. // Status = HttpCreateTcp4TxEvent (Wrap); if (EFI_ERROR (Status)) { goto Error1; } } // // Create request message. // RequestStr = HttpGenRequestString (HttpInstance, HttpMsg, Url); if (RequestStr == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error3; } Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); if (EFI_ERROR (Status)) { goto Error4; } FreePool (Url); if (HostName != NULL) { FreePool (HostName); } // // Transmit the request message. // Status = HttpTransmitTcp4 ( HttpInstance, Wrap, (UINT8*) RequestStr, AsciiStrLen (RequestStr) ); if (EFI_ERROR (Status)) { goto Error5; } return EFI_SUCCESS; Error5: NetMapRemoveTail (&HttpInstance->TxTokens, NULL); Error4: if (RequestStr != NULL) { FreePool (RequestStr); } Error3: HttpCloseConnection (HttpInstance); Error2: HttpCloseTcp4ConnCloseEvent (HttpInstance); if (NULL != Wrap->TcpWrap.TxToken.CompletionToken.Event) { gBS->CloseEvent (Wrap->TcpWrap.TxToken.CompletionToken.Event); } Error1: if (Url != NULL) { FreePool (Url); } if (HostName != NULL) { FreePool (HostName); } if (Wrap != NULL) { FreePool (Wrap); } if (UrlParser!= NULL) { HttpUrlFreeParser (UrlParser); } return Status; }
/* Set up TCP Fastboot transport: Configure the network device via DHCP then start waiting for a TCP connection on the Fastboot port. */ EFI_STATUS TcpFastbootTransportStart ( EFI_EVENT ReceiveEvent ) { EFI_STATUS Status; EFI_HANDLE NetDeviceHandle; EFI_HANDLE *HandleBuffer; EFI_IP4_MODE_DATA Ip4ModeData; UINTN NumHandles; UINTN HostnameSize = 256; CHAR8 Hostname[256]; CHAR16 HostnameUnicode[256] = L"<no hostname>"; CHAR16 IpAddrString[16]; UINTN Index; EFI_TCP4_CONFIG_DATA TcpConfigData = { 0x00, // IPv4 Type of Service 255, // IPv4 Time to Live { // AccessPoint: TRUE, // Use default address { {0, 0, 0, 0} }, // IP Address (ignored - use default) { {0, 0, 0, 0} }, // Subnet mask (ignored - use default) FixedPcdGet32 (PcdAndroidFastbootTcpPort), // Station port { {0, 0, 0, 0} }, // Remote address: accept any 0, // Remote Port: accept any FALSE // ActiveFlag: be a "server" }, NULL // Default advanced TCP options }; mReceiveEvent = ReceiveEvent; InitializeListHead (&mPacketListHead); mTextOut->OutputString (mTextOut, L"Initialising TCP Fastboot transport...\r\n"); // // Open a passive TCP instance // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiTcp4ServiceBindingProtocolGuid, NULL, &NumHandles, &HandleBuffer ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Find TCP Service Binding: %r\n", Status)); return Status; } // We just use the first network device NetDeviceHandle = HandleBuffer[0]; Status = gBS->OpenProtocol ( NetDeviceHandle, &gEfiTcp4ServiceBindingProtocolGuid, (VOID **) &mTcpServiceBinding, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Open TCP Service Binding: %r\n", Status)); return Status; } Status = mTcpServiceBinding->CreateChild (mTcpServiceBinding, &mTcpHandle); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TCP ServiceBinding Create: %r\n", Status)); return Status; } Status = gBS->OpenProtocol ( mTcpHandle, &gEfiTcp4ProtocolGuid, (VOID **) &mTcpListener, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Open TCP Protocol: %r\n", Status)); } // // Set up re-usable tokens // for (Index = 0; Index < NUM_RX_TOKENS; Index++) { mRxData[Index].UrgentFlag = FALSE; mRxData[Index].FragmentCount = 1; mReceiveToken[Index].Packet.RxData = &mRxData[Index]; } mTxData.Push = TRUE; mTxData.Urgent = FALSE; mTxData.FragmentCount = 1; mTransmitToken.Packet.TxData = &mTxData; Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, ConnectionAccepted, &mAcceptToken, &mAcceptToken.CompletionToken.Event ); ASSERT_EFI_ERROR (Status); Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, ConnectionClosed, &mCloseToken, &mCloseToken.CompletionToken.Event ); ASSERT_EFI_ERROR (Status); // // Configure the TCP instance // Status = mTcpListener->Configure (mTcpListener, &TcpConfigData); if (Status == EFI_NO_MAPPING) { // Wait until the IP configuration process (probably DHCP) has finished do { Status = mTcpListener->GetModeData (mTcpListener, NULL, NULL, &Ip4ModeData, NULL, NULL ); ASSERT_EFI_ERROR (Status); } while (!Ip4ModeData.IsConfigured); Status = mTcpListener->Configure (mTcpListener, &TcpConfigData); } else if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TCP Configure: %r\n", Status)); return Status; } // // Tell the user our address and hostname // IP4_ADDR_TO_STRING (Ip4ModeData.ConfigData.StationAddress, IpAddrString); // Look up hostname Status = gRT->GetVariable ( L"Hostname", &gEfiHostnameVariableGuid, NULL, &HostnameSize, &Hostname ); if (!EFI_ERROR (Status) && HostnameSize != 0) { AsciiStrToUnicodeStr (Hostname, HostnameUnicode); } // Hostname variable is not null-terminated. Hostname[HostnameSize] = L'\0'; mTextOut->OutputString (mTextOut, L"TCP Fastboot transport configured."); mTextOut->OutputString (mTextOut, L"\r\nIP address: "); mTextOut->OutputString (mTextOut ,IpAddrString); mTextOut->OutputString (mTextOut, L"\r\n"); mTextOut->OutputString (mTextOut, L"\r\nhostname: "); mTextOut->OutputString (mTextOut, HostnameUnicode); mTextOut->OutputString (mTextOut, L"\r\n"); // // Start listening for a connection // Status = mTcpListener->Accept (mTcpListener, &mAcceptToken); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TCP Accept: %r\n", Status)); return Status; } mTextOut->OutputString (mTextOut, L"TCP Fastboot transport initialised.\r\n"); FreePool (HandleBuffer); return EFI_SUCCESS; }
/** Gather and print Handle data. @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. @return Status from a call to gBS->LocateHandle(). **/ EFI_STATUS ProcessHandles( IN BOOLEAN ExcludeFlag ) { MEASUREMENT_RECORD Measurement; UINT64 ElapsedTime; UINT64 Duration; EFI_HANDLE *HandleBuffer; EFI_STRING StringPtr; UINTN Index; UINTN LogEntryKey; UINTN Count; UINTN Size; EFI_HANDLE TempHandle; EFI_STATUS Status; EFI_STRING StringPtrUnknown; StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL); PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER), (StringPtr == NULL) ? StringPtrUnknown : StringPtr); FreePool (StringPtr); FreePool (StringPtrUnknown); Size = 0; HandleBuffer = &TempHandle; Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle); if (Status == EFI_BUFFER_TOO_SMALL) { HandleBuffer = AllocatePool (Size); ASSERT (HandleBuffer != NULL); if (HandleBuffer == NULL) { return Status; } Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer); } if (EFI_ERROR (Status)) { PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status); } else { #if DP_DEBUG == 2 Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0]))); #endif if (mShowId) { PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION2) ); } else { PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION) ); } PrintToken (STRING_TOKEN (STR_DP_DASHES) ); LogEntryKey = 0; Count = 0; while ((LogEntryKey = GetPerformanceMeasurementEx ( LogEntryKey, &Measurement.Handle, &Measurement.Token, &Measurement.Module, &Measurement.StartTimeStamp, &Measurement.EndTimeStamp, &Measurement.Identifier)) != 0) { Count++; Duration = GetDuration (&Measurement); ElapsedTime = DurationInMicroSeconds ( Duration ); if ((ElapsedTime < mInterestThreshold) || (Measurement.EndTimeStamp == 0) || (Measurement.Handle == NULL) || ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0)) ) { // Ignore "uninteresting" or excluded records continue; } mGaugeString[0] = 0; // Empty driver name by default AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken); // See if the Handle is in the HandleBuffer for (Index = 0; Index < (Size / sizeof(HandleBuffer[0])); Index++) { if (Measurement.Handle == HandleBuffer[Index]) { GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString break; } } // Ensure that the argument strings are not too long. mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; mUnicodeToken[11] = 0; if (mGaugeString[0] != 0) { // Display the record if it has a valid handle. if (mShowId) { PrintToken ( STRING_TOKEN (STR_DP_HANDLE_VARS2), Count, // 1 based, Which measurement record is being printed Index + 1, // 1 based, Which handle is being printed mGaugeString, mUnicodeToken, ElapsedTime, Measurement.Identifier ); } else { PrintToken ( STRING_TOKEN (STR_DP_HANDLE_VARS), Count, // 1 based, Which measurement record is being printed Index + 1, // 1 based, Which handle is being printed mGaugeString, mUnicodeToken, ElapsedTime ); } } } } if (HandleBuffer != &TempHandle) { FreePool (HandleBuffer); } return Status; }
/** Add or update a variable in the environment list @param name Address of a zero terminated name string @param value Address of a zero terminated value string @param rewrite TRUE allows overwriting existing values @retval Returns 0 upon success @retval Returns -1 upon failure, sets errno with more information Errors EINVAL - name is NULL or points to a zero length string EALREADY - name already set and rewrite set to FALSE ENODEV - Unable to set non-volatile version of environment variable ENOMEM - Unable to set volatile version of environment variable ENOTSUP - Variable storage not supported **/ int setenv ( register const char * name, register const char * value, int rewrite ) { CONST CHAR16 * HostName; int retval; EFI_STATUS Status; CHAR16 * UName; CHAR16 * UValue; // // Assume failure // retval = -1; // // Validate the inputs // errno = EINVAL; if (( NULL != name ) && ( 0 != *name )) { // // Get the storage locations for the unicode strings // UName = &gMD->UString[0]; UValue = &gMD->UString2[0]; // // Convert the strings // AsciiStrToUnicodeStr ( name, UName ); AsciiStrToUnicodeStr ( value, UValue ); // // Determine if the string is already present // errno = EALREADY; HostName = ShellGetEnvironmentVariable ( UName ); if ( rewrite || ( NULL == HostName )) { // // Support systems that don't have non-volatile memory // errno = ENOMEM; Status = ShellSetEnvironmentVariable ( UName, UValue, TRUE ); if ( EFI_ERROR ( Status )) { if ( EFI_UNSUPPORTED == Status ) { errno = ENOTSUP; } } else { // // Permanently set the environment variable // errno = ENODEV; Status = ShellSetEnvironmentVariable ( UName, UValue, FALSE ); if ( !EFI_ERROR ( Status )) { // // Success // errno = 0; retval = 0; } } } } // // Return the operation status // return retval; }
/** Gather and print ALL Trace Records. Displays all "interesting" Trace measurements in order.<BR> The number of records displayed is controlled by: - records with a duration less than mInterestThreshold microseconds are not displayed. - No more than Limit records are displayed. A Limit of zero will not limit the output. - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not displayed. @pre The mInterestThreshold global variable is set to the shortest duration to be printed. The mGaugeString and mUnicodeToken global arrays are used for temporary string storage. They must not be in use by a calling function. @param[in] Limit The number of records to print. Zero is ALL. @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. **/ VOID DumpAllTrace( IN UINTN Limit, IN BOOLEAN ExcludeFlag ) { MEASUREMENT_RECORD Measurement; UINT64 ElapsedTime; UINT64 Duration; const CHAR16 *IncFlag; UINTN LogEntryKey; UINTN Count; UINTN Index; UINTN TIndex; EFI_HANDLE *HandleBuffer; UINTN Size; EFI_HANDLE TempHandle; EFI_STATUS Status; EFI_STRING StringPtrUnknown; StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL); PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER), (IncFlag == NULL) ? StringPtrUnknown : IncFlag); FreePool (StringPtrUnknown); // Get Handle information // Size = 0; HandleBuffer = &TempHandle; Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle); if (Status == EFI_BUFFER_TOO_SMALL) { HandleBuffer = AllocatePool (Size); ASSERT (HandleBuffer != NULL); if (HandleBuffer == NULL) { return; } Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer); } if (EFI_ERROR (Status)) { PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status); } else { // We have successfully populated the HandleBuffer // Display ALL Measurement Records // Up to Limit lines displayed // Display only records with Elapsed times >= mInterestThreshold // Display driver names in Module field for records with Handles. // if (mShowId) { PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR2) ); PrintToken (STRING_TOKEN (STR_DP_ALL_DASHES2) ); } else { PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR) ); PrintToken (STRING_TOKEN (STR_DP_DASHES) ); } LogEntryKey = 0; Count = 0; Index = 0; while ( WITHIN_LIMIT(Count, Limit) && ((LogEntryKey = GetPerformanceMeasurementEx ( LogEntryKey, &Measurement.Handle, &Measurement.Token, &Measurement.Module, &Measurement.StartTimeStamp, &Measurement.EndTimeStamp, &Measurement.Identifier)) != 0) ) { ++Index; // Count every record. First record is 1. ElapsedTime = 0; SafeFreePool ((VOID *) IncFlag); if (Measurement.EndTimeStamp != 0) { Duration = GetDuration (&Measurement); ElapsedTime = DurationInMicroSeconds ( Duration ); IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL); } else { IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records } if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) || ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0)) ) { // Ignore "uninteresting" or excluded records continue; } ++Count; // Count the number of records printed // If Handle is non-zero, see if we can determine a name for the driver AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); // Use Module by default AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken); if (Measurement.Handle != NULL) { // See if the Handle is in the HandleBuffer for (TIndex = 0; TIndex < (Size / sizeof(HandleBuffer[0])); TIndex++) { if (Measurement.Handle == HandleBuffer[TIndex]) { GetNameFromHandle (HandleBuffer[TIndex]); break; } } } if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) { UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle); } // Ensure that the argument strings are not too long. mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; mUnicodeToken[13] = 0; if (mShowId) { PrintToken( STRING_TOKEN (STR_DP_ALL_VARS2), Index, // 1 based, Which measurement record is being printed IncFlag, Measurement.Handle, mGaugeString, mUnicodeToken, ElapsedTime, Measurement.Identifier ); } else { PrintToken( STRING_TOKEN (STR_DP_ALL_VARS), Index, // 1 based, Which measurement record is being printed IncFlag, Measurement.Handle, mGaugeString, mUnicodeToken, ElapsedTime ); } } } if (HandleBuffer != &TempHandle) { FreePool (HandleBuffer); } SafeFreePool ((VOID *) IncFlag); }
EFI_STATUS ArmFastbootPlatformFlashPartition ( IN CHAR8 *PartitionName, IN UINTN Size, IN VOID *Image ) { EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_DISK_IO_PROTOCOL *DiskIo; UINT32 MediaId; UINTN PartitionSize; FASTBOOT_PARTITION_LIST *Entry; CHAR16 PartitionNameUnicode[60]; BOOLEAN PartitionFound; AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode); PartitionFound = FALSE; Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead)); while (!IsNull (&mPartitionListHead, &Entry->Link)) { // Search the partition list for the partition named by PartitionName if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) { PartitionFound = TRUE; break; } Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link); } if (!PartitionFound) { return EFI_NOT_FOUND; } Status = gBS->OpenProtocol ( Entry->PartitionHandle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Fastboot platform: couldn't open Block IO for flash: %r\n", Status)); return EFI_NOT_FOUND; } // Check image will fit on device PartitionSize = (BlockIo->Media->LastBlock + 1) * BlockIo->Media->BlockSize; if (PartitionSize < Size) { DEBUG ((EFI_D_ERROR, "Partition not big enough.\n")); DEBUG ((EFI_D_ERROR, "Partition Size:\t%d\nImage Size:\t%d\n", PartitionSize, Size)); return EFI_VOLUME_FULL; } MediaId = BlockIo->Media->MediaId; Status = gBS->OpenProtocol ( Entry->PartitionHandle, &gEfiDiskIoProtocolGuid, (VOID **) &DiskIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); ASSERT_EFI_ERROR (Status); Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image); if (EFI_ERROR (Status)) { return Status; } BlockIo->FlushBlocks(BlockIo); return Status; }
EFI_STATUS EFIAPI EblGetCmd ( IN UINTN Argc, IN CHAR8 **Argv ) { EFI_STATUS Status = EFI_INVALID_PARAMETER; UINTN Size; VOID* Value; CHAR8* AsciiVariableName = NULL; CHAR16* VariableName; UINT32 Index; if (Argc == 1) { AsciiPrint("Variable name is missing.\n"); return Status; } for (Index = 1; Index < Argc; Index++) { if (Argv[Index][0] == '-') { AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]); } else { AsciiVariableName = Argv[Index]; } } if (AsciiVariableName == NULL) { AsciiPrint("Variable name is missing.\n"); return Status; } else { VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16)); AsciiStrToUnicodeStr (AsciiVariableName,VariableName); } // Try to get the variable size. Value = NULL; Size = 0; Status = gRT->GetVariable (VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value); if (Status == EFI_NOT_FOUND) { AsciiPrint("Variable name '%s' not found.\n",VariableName); } else if (Status == EFI_BUFFER_TOO_SMALL) { // Get the environment variable value Value = AllocatePool (Size); if (Value == NULL) { return EFI_OUT_OF_RESOURCES; } Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value); if (EFI_ERROR (Status)) { AsciiPrint("Error: '%r'\n",Status); } else { AsciiPrint("%a=%a\n",AsciiVariableName,Value); } FreePool(Value); } else { AsciiPrint("Error: '%r'\n",Status); } FreePool(VariableName); return Status; }
/** Allows a program to determine which secondary languages are supported on a given handle for a given primary language This routine is intended to be used by drivers to query the interface database for supported languages. This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle. @param This A pointer to the EFI_HII_PROTOCOL instance. @param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() in the Packages section. @param PrimaryLanguage Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating the primary language. @param LanguageString A string allocated by GetSecondaryLanguages() containing a list of all secondary languages registered on the handle. The routine will not return the three-spaces language identifier used in other functions to indicate non-language-specific strings, nor will it return the primary language. This function succeeds but returns a NULL LanguageString if there are no secondary languages associated with the input Handle and PrimaryLanguage pair. Type EFI_STRING is defined in String. @retval EFI_SUCCESS LanguageString was correctly returned. @retval EFI_INVALID_PARAMETER The Handle was unknown. **/ EFI_STATUS EFIAPI HiiGetSecondaryLanguages ( IN EFI_HII_PROTOCOL *This, IN FRAMEWORK_EFI_HII_HANDLE Handle, IN CHAR16 *PrimaryLanguage, OUT EFI_STRING *LanguageString ) { HII_THUNK_PRIVATE_DATA *Private; EFI_HII_HANDLE UefiHiiHandle; CHAR8 *PrimaryLang4646; CHAR8 *PrimaryLang639; CHAR8 *SecLangCodes4646; CHAR8 *SecLangCodes639; CHAR16 *UnicodeSecLangCodes639; EFI_STATUS Status; Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); SecLangCodes639 = NULL; SecLangCodes4646 = NULL; PrimaryLang4646 = NULL; UnicodeSecLangCodes639 = NULL; UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle); if (UefiHiiHandle == NULL) { return EFI_INVALID_PARAMETER; } PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1); if (PrimaryLang639 == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639); PrimaryLang4646 = ConvertLanguagesIso639ToRfc4646 (PrimaryLang639); ASSERT_EFI_ERROR (PrimaryLang4646 != NULL); SecLangCodes4646 = HiiGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang4646); if (SecLangCodes4646 == NULL) { Status = EFI_INVALID_PARAMETER; goto Done; } SecLangCodes639 = ConvertLanguagesIso639ToRfc4646 (SecLangCodes4646); if (SecLangCodes639 == NULL) { Status = EFI_INVALID_PARAMETER; goto Done; } UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16)); if (UnicodeSecLangCodes639 == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } // // The language returned is in RFC 4646 format. // *LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639); Status = EFI_SUCCESS; Done: if (PrimaryLang639 != NULL) { FreePool (PrimaryLang639); } if (SecLangCodes639 != NULL) { FreePool (SecLangCodes639); } if (PrimaryLang4646 != NULL) { FreePool (PrimaryLang4646); } if (SecLangCodes4646 != NULL) { FreePool (SecLangCodes4646); } if (UnicodeSecLangCodes639 != NULL) { FreePool (UnicodeSecLangCodes639); } return Status; }
EFI_STATUS DefineDefaultBootEntries ( VOID ) { BDS_LOAD_OPTION* BdsLoadOption; UINTN Size; EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH* BootDevicePath; UINT8* OptionalData; UINTN OptionalDataSize; ARM_BDS_LOADER_ARGUMENTS* BootArguments; ARM_BDS_LOADER_TYPE BootType; EFI_DEVICE_PATH* InitrdPath; UINTN InitrdSize; UINTN CmdLineSize; UINTN CmdLineAsciiSize; CHAR16* DefaultBootArgument; CHAR8* AsciiDefaultBootArgument; // // If Boot Order does not exist then create a default entry // Size = 0; Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL); if (Status == EFI_NOT_FOUND) { if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) { return EFI_UNSUPPORTED; } Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n")); return Status; } BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)); DEBUG_CODE_BEGIN(); // We convert back to the text representation of the device Path to see if the initial text is correct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE); ASSERT (StrCmp ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath), DevicePathTxt) == 0); FreePool (DevicePathTxt); DEBUG_CODE_END(); // Create the entry is the Default values are correct if (BootDevicePath != NULL) { BootType = (ARM_BDS_LOADER_TYPE)PcdGet32 (PcdDefaultBootType); // We do not support NULL pointer ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL); // // Logic to handle ASCII or Unicode default parameters // if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') { CmdLineSize = 0; CmdLineAsciiSize = 0; DefaultBootArgument = NULL; AsciiDefaultBootArgument = NULL; } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) { // The command line is a Unicode string DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument); CmdLineSize = StrSize (DefaultBootArgument); // Initialize ASCII variables CmdLineAsciiSize = CmdLineSize / 2; AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize); if (AsciiDefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument); } else { // The command line is a ASCII string AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument); CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument); // Initialize ASCII variables CmdLineSize = CmdLineAsciiSize * 2; DefaultBootArgument = AllocatePool (CmdLineSize); if (DefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument); } if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { InitrdPath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath)); InitrdSize = GetDevicePathSize (InitrdPath); OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineAsciiSize + InitrdSize; BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize); if (BootArguments == NULL) { return EFI_OUT_OF_RESOURCES; } BootArguments->LinuxArguments.CmdLineSize = CmdLineAsciiSize; BootArguments->LinuxArguments.InitrdSize = InitrdSize; CopyMem ((VOID*)(BootArguments + 1), AsciiDefaultBootArgument, CmdLineAsciiSize); CopyMem ((VOID*)((UINTN)(BootArguments + 1) + CmdLineAsciiSize), InitrdPath, InitrdSize); OptionalData = (UINT8*)BootArguments; } else { OptionalData = (UINT8*)DefaultBootArgument; OptionalDataSize = CmdLineSize; } BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT, (CHAR16*)PcdGetPtr(PcdDefaultBootDescription), BootDevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOption ); FreePool (BdsLoadOption); if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) { FreePool (AsciiDefaultBootArgument); } else if (DefaultBootArgument != NULL) { FreePool (DefaultBootArgument); } } else { Status = EFI_UNSUPPORTED; } } return Status; }
/** Gather and print global data. Strips out incomplete or "Execution Phase" records Only prints records where Handle is NULL Increment TIndex for every record, even skipped ones, so that we have an indication of every measurement record taken. **/ VOID ProcessGlobal( VOID ) { MEASUREMENT_RECORD Measurement; UINT64 Duration; UINT64 ElapsedTime; EFI_STRING StringPtr; UINTN LogEntryKey; UINTN Index; // Index, or number, of the measurement record being processed EFI_STRING StringPtrUnknown; StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL); PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER), (StringPtr == NULL) ? StringPtrUnknown: StringPtr); FreePool (StringPtr); FreePool (StringPtrUnknown); if (mShowId) { PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION2)); } else { PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION)); } PrintToken (STRING_TOKEN (STR_DP_DASHES)); Index = 1; LogEntryKey = 0; while ((LogEntryKey = GetPerformanceMeasurementEx ( LogEntryKey, &Measurement.Handle, &Measurement.Token, &Measurement.Module, &Measurement.StartTimeStamp, &Measurement.EndTimeStamp, &Measurement.Identifier)) != 0) { AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken); mGaugeString[25] = 0; mUnicodeToken[31] = 0; if ( ! ( IsPhase( &Measurement) || (Measurement.Handle != NULL) || (Measurement.EndTimeStamp == 0) )) { Duration = GetDuration (&Measurement); ElapsedTime = DurationInMicroSeconds ( Duration ); if (ElapsedTime >= mInterestThreshold) { if (mShowId) { PrintToken ( STRING_TOKEN (STR_DP_GLOBAL_VARS2), Index, mGaugeString, mUnicodeToken, ElapsedTime, Measurement.Identifier ); } else { PrintToken ( STRING_TOKEN (STR_DP_GLOBAL_VARS), Index, mGaugeString, mUnicodeToken, ElapsedTime ); } } } Index++; } }
/** Initialize HII information for the FrontPage @param InitializeHiiData TRUE if HII elements need to be initialized. @retval EFI_SUCCESS The operation is successful. @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed. **/ EFI_STATUS InitializeFrontPage ( IN BOOLEAN InitializeHiiData ) { EFI_STATUS Status; CHAR8 *LangCode; CHAR8 *Lang; CHAR8 *CurrentLang; UINTN OptionCount; CHAR16 *StringBuffer; EFI_HII_HANDLE HiiHandle; VOID *OptionsOpCodeHandle; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; EFI_HII_STRING_PROTOCOL *HiiString; UINTN StringSize; Lang = NULL; StringBuffer = NULL; if (InitializeHiiData) { // // Initialize the Device Manager // InitializeDeviceManager (); // // Initialize the Device Manager // InitializeBootManager (); gCallbackKey = 0; // // Locate Hii relative protocols // Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2); if (EFI_ERROR (Status)) { return Status; } // // Install Device Path Protocol and Config Access protocol to driver handle // Status = gBS->InstallMultipleProtocolInterfaces ( &gFrontPagePrivate.DriverHandle, &gEfiDevicePathProtocolGuid, &mFrontPageHiiVendorDevicePath, &gEfiHiiConfigAccessProtocolGuid, &gFrontPagePrivate.ConfigAccess, NULL ); ASSERT_EFI_ERROR (Status); // // Publish our HII data // gFrontPagePrivate.HiiHandle = HiiAddPackages ( &gFrontPageFormSetGuid, gFrontPagePrivate.DriverHandle, FrontPageVfrBin, BdsDxeStrings, NULL ); if (gFrontPagePrivate.HiiHandle == NULL) { return EFI_OUT_OF_RESOURCES; } } // // Init OpCode Handle and Allocate space for creation of UpdateData Buffer // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (OptionsOpCodeHandle != NULL); // // Create Hii Extend Label OpCode as the start 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_SELECT_LANGUAGE; // // Create Hii Extend Label OpCode as the end opcode // 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; // // Collect the languages from what our current Language support is based on our VFR // HiiHandle = gFrontPagePrivate.HiiHandle; GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL); // // Get Support language list from variable. // if (mLanguageString == NULL){ GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&mLanguageString, NULL); if (mLanguageString == NULL) { mLanguageString = AllocateCopyPool ( AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)), (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes) ); ASSERT (mLanguageString != NULL); } } if (gFrontPagePrivate.LanguageToken == NULL) { // // Count the language list number. // LangCode = mLanguageString; Lang = AllocatePool (AsciiStrSize (mLanguageString)); ASSERT (Lang != NULL); OptionCount = 0; while (*LangCode != 0) { GetNextLanguage (&LangCode, Lang); OptionCount ++; } // // Allocate extra 1 as the end tag. // gFrontPagePrivate.LanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID)); ASSERT (gFrontPagePrivate.LanguageToken != NULL); Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString); ASSERT_EFI_ERROR (Status); LangCode = mLanguageString; OptionCount = 0; while (*LangCode != 0) { GetNextLanguage (&LangCode, Lang); StringSize = 0; Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL); if (Status == EFI_BUFFER_TOO_SMALL) { StringBuffer = AllocateZeroPool (StringSize); ASSERT (StringBuffer != NULL); Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL); ASSERT_EFI_ERROR (Status); } if (EFI_ERROR (Status)) { StringBuffer = AllocatePool (AsciiStrSize (Lang) * sizeof (CHAR16)); ASSERT (StringBuffer != NULL); AsciiStrToUnicodeStr (Lang, StringBuffer); } ASSERT (StringBuffer != NULL); gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL); FreePool (StringBuffer); OptionCount++; } } ASSERT (gFrontPagePrivate.LanguageToken != NULL); LangCode = mLanguageString; OptionCount = 0; if (Lang == NULL) { Lang = AllocatePool (AsciiStrSize (mLanguageString)); ASSERT (Lang != NULL); } while (*LangCode != 0) { GetNextLanguage (&LangCode, Lang); if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) { HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, gFrontPagePrivate.LanguageToken[OptionCount], EFI_IFR_OPTION_DEFAULT, EFI_IFR_NUMERIC_SIZE_1, (UINT8) OptionCount ); } else { HiiCreateOneOfOptionOpCode ( OptionsOpCodeHandle, gFrontPagePrivate.LanguageToken[OptionCount], 0, EFI_IFR_NUMERIC_SIZE_1, (UINT8) OptionCount ); } OptionCount++; } if (CurrentLang != NULL) { FreePool (CurrentLang); } FreePool (Lang); HiiCreateOneOfOpCode ( StartOpCodeHandle, FRONT_PAGE_KEY_LANGUAGE, 0, 0, STRING_TOKEN (STR_LANGUAGE_SELECT), STRING_TOKEN (STR_LANGUAGE_SELECT_HELP), EFI_IFR_FLAG_CALLBACK, EFI_IFR_NUMERIC_SIZE_1, OptionsOpCodeHandle, NULL ); Status = HiiUpdateForm ( HiiHandle, &gFrontPageFormSetGuid, FRONT_PAGE_FORM_ID, StartOpCodeHandle, // LABEL_SELECT_LANGUAGE EndOpCodeHandle // LABEL_END ); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); HiiFreeOpCodeHandle (OptionsOpCodeHandle); return Status; }
/** Perform a dir on a device. The device must support Simple File System Protocol or the FV protocol. Argv[0] - "dir" Argv[1] - Device Name:path. Path is optional Argv[2] - Optional filename to match on. A leading * means match substring Argv[3] - Optional FV file type dir fs1:\efi ; perform a dir on fs1: device in the efi directory dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but only print out files that contain the string *.efi dir fv1:\ ; perform a dir on fv1: device in the efi directory NOTE: fv devices do not contain subdirs dir fv1:\ * PEIM ; will match all files of type PEIM @param Argc Number of command arguments in Argv @param Argv Array of strings that represent the parsed command line. Argv[0] is the command name @return EFI_SUCCESS **/ EFI_STATUS EblDirCmd ( IN UINTN Argc, IN CHAR8 **Argv ) { EFI_STATUS Status; EFI_OPEN_FILE *File; EFI_FILE_INFO *DirInfo; UINTN ReadSize; UINTN CurrentRow; CHAR16 *MatchSubString; EFI_STATUS GetNextFileStatus; UINTN Key; EFI_FV_FILETYPE SearchType; EFI_FV_FILETYPE Type; EFI_FV_FILE_ATTRIBUTES Attributes; UINTN Size; EFI_GUID NameGuid; EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; UINT32 AuthenticationStatus; VOID *Section; UINTN SectionSize; EFI_FV_FILETYPE Index; UINTN Length; UINTN BestMatchCount; CHAR16 UnicodeFileName[MAX_CMD_LINE]; CHAR8 *Path; CHAR8 *TypeStr; UINTN TotalSize; if (Argc <= 1) { Path = EfiGetCwd (); if (Path == NULL) { return EFI_SUCCESS; } } else { Path = Argv[1]; } File = EfiOpen (Path, EFI_FILE_MODE_READ, 0); if (File == NULL) { return EFI_SUCCESS; } if (File->Type == EfiOpenFirmwareVolume) { // FV Dir SearchType = EFI_FV_FILETYPE_ALL; UnicodeFileName[0] = '\0'; MatchSubString = &UnicodeFileName[0]; if (Argc > 2) { AsciiStrToUnicodeStr (Argv[2], UnicodeFileName); if (UnicodeFileName[0] == '*') { // Handle *Name substring matching MatchSubString = &UnicodeFileName[1]; } // Handle file type matchs if (Argc > 3) { // match a specific file type, always last argument Length = AsciiStrLen (Argv[3]); for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) { if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) { // exact match SearchType = Index; break; } if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) { // partial match, so keep looking to make sure there is only one partial match BestMatchCount++; SearchType = Index; } } if (BestMatchCount > 1) { SearchType = EFI_FV_FILETYPE_ALL; } } } TotalSize = 0; Fv = File->Fv; Key = 0; CurrentRow = 0; do { Type = SearchType; GetNextFileStatus = Fv->GetNextFile ( Fv, &Key, &Type, &NameGuid, &Attributes, &Size ); if (!EFI_ERROR (GetNextFileStatus)) { TotalSize += Size; // Calculate size of entire file Section = NULL; Size = 0; Status = Fv->ReadFile ( Fv, &NameGuid, Section, &Size, &Type, &Attributes, &AuthenticationStatus ); if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) { // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid Size = 0; } TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN"; // read the UI seciton to do a name match. Section = NULL; Status = Fv->ReadSection ( Fv, &NameGuid, EFI_SECTION_USER_INTERFACE, 0, &Section, &SectionSize, &AuthenticationStatus ); if (!EFI_ERROR (Status)) { if (StrStr (Section, MatchSubString) != NULL) { AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section); if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) { break; } } FreePool (Section); } else { if (*MatchSubString == '\0') { AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid); if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) { break; } } } } } while (!EFI_ERROR (GetNextFileStatus)); if (SearchType == EFI_FV_FILETYPE_ALL) { AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize); } } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) { // Simple File System DIR if (File->FsFileInfo == NULL) { return EFI_SUCCESS; } if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) { return EFI_SUCCESS; } // Handle *Name substring matching MatchSubString = NULL; UnicodeFileName[0] = '\0'; if (Argc > 2) { AsciiStrToUnicodeStr (Argv[2], UnicodeFileName); if (UnicodeFileName[0] == '*') { MatchSubString = &UnicodeFileName[1]; } } File->FsFileHandle->SetPosition (File->FsFileHandle, 0); for (CurrentRow = 0;;) { // First read gets the size DirInfo = NULL; ReadSize = 0; Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo); if (Status == EFI_BUFFER_TOO_SMALL) { // Allocate the buffer for the real read DirInfo = AllocatePool (ReadSize); if (DirInfo == NULL) { goto Done; } // Read the data Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo); if ((EFI_ERROR (Status)) || (ReadSize == 0)) { break; } } else { break; } if (MatchSubString != NULL) { if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) { // does not match *name argument, so skip continue; } } else if (UnicodeFileName[0] != '\0') { // is not an exact match for name argument, so skip if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) { continue; } } if (DirInfo->Attribute & EFI_FILE_DIRECTORY) { AsciiPrint (" <DIR> %s\n", &DirInfo->FileName[0]); } else { AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]); } if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) { break; } FreePool (DirInfo); } Done: if (DirInfo != NULL) { FreePool (DirInfo); } } EfiClose (File); return EFI_SUCCESS; }
EFI_STATUS EFIAPI EblSetCmd ( IN UINTN Argc, IN CHAR8 **Argv ) { EFI_STATUS Status = EFI_INVALID_PARAMETER; CHAR8* AsciiVariableSetting = NULL; CHAR8* AsciiVariableName; CHAR8* AsciiValue; UINT32 AsciiValueLength; CHAR16* VariableName; UINT32 Index; UINT32 EscapedQuotes = 0; BOOLEAN Volatile = FALSE; if (Argc == 1) { AsciiPrint("Variable name is missing.\n"); return Status; } for (Index = 1; Index < Argc; Index++) { if (AsciiStrCmp(Argv[Index],"-v") == 0) { Volatile = 0; } else if (Argv[Index][0] == '-') { AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]); } else { AsciiVariableSetting = Argv[Index]; } } if (AsciiVariableSetting == NULL) { AsciiPrint("Variable name is missing.\n"); return Status; } // Check if it is a valid variable setting AsciiValue = AsciiStrStr (AsciiVariableSetting,"="); if (AsciiValue == NULL) { // // There is no value. It means this variable will be deleted // // Convert VariableName into Unicode VariableName = AllocatePool((AsciiStrLen (AsciiVariableSetting) + 1) * sizeof (CHAR16)); AsciiStrToUnicodeStr (AsciiVariableSetting,VariableName); Status = gRT->SetVariable ( VariableName, &gEfiGlobalVariableGuid, ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL ); if (!EFI_ERROR(Status)) { AsciiPrint("Variable '%s' deleted\n",VariableName); } else { AsciiPrint("Variable setting is incorrect. It should be VariableName=Value\n"); } return Status; } AsciiValue[0] = '\0'; AsciiVariableName = AsciiVariableSetting; AsciiValue++; // Clean AsciiValue from quote if (AsciiValue[0] == '"') { AsciiValue++; } AsciiValueLength = AsciiStrLen (AsciiValue); if ((AsciiValue[AsciiValueLength-2] != '\\') && (AsciiValue[AsciiValueLength-1] == '"')) { AsciiValue[AsciiValueLength-1] = '\0'; } // Clean AsciiValue from escaped quotes for (Index = 0; Index < AsciiValueLength; Index++) { if ((Index > 0) && (AsciiValue[Index-1] == '\\') && (AsciiValue[Index] == '"')) { EscapedQuotes++; } AsciiValue[Index-EscapedQuotes] = AsciiValue[Index]; } // Fill the end of the value with '\0' for (Index = 0; Index < EscapedQuotes; Index++) { AsciiValue[AsciiValueLength-1-Index] = '\0'; } // Convert VariableName into Unicode VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16)); AsciiStrToUnicodeStr (AsciiVariableName,VariableName); Status = gRT->SetVariable ( VariableName, &gEfiGlobalVariableGuid, ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, AsciiStrLen (AsciiValue)+1, AsciiValue ); if (!EFI_ERROR(Status)) { AsciiPrint("'%a'='%a'\n",AsciiVariableName,AsciiValue); } return Status; }
/** Internal work function to fill in EFI_OPEN_FILE information for the Fs and BlkIo @param File Open file handle @param FileName Name of file after device stripped off **/ EFI_STATUS EblFileDevicePath ( IN OUT EFI_OPEN_FILE *File, IN CHAR8 *FileName, IN CONST UINT64 OpenMode ) { EFI_STATUS Status; UINTN Size; FILEPATH_DEVICE_PATH *FilePath; EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; CHAR16 UnicodeFileName[MAX_PATHNAME]; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; EFI_FILE_HANDLE Root; if ( *FileName != 0 ) { AsciiStrToUnicodeStr (FileName, UnicodeFileName); } else { AsciiStrToUnicodeStr ("\\", UnicodeFileName); } Size = StrSize (UnicodeFileName); FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL)); if (FileDevicePath != NULL) { FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath; FilePath->Header.Type = MEDIA_DEVICE_PATH; FilePath->Header.SubType = MEDIA_FILEPATH_DP; CopyMem (&FilePath->PathName, UnicodeFileName, Size); SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header)); if (File->EfiHandle != NULL) { File->DevicePath = DevicePathFromHandle (File->EfiHandle); } File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath); FreePool (FileDevicePath); } Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo); if (!EFI_ERROR (Status)) { File->FsBlockIoMedia = BlkIo->Media; File->FsBlockIo = BlkIo; // If we are not opening the device this will get over written with file info File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize); } if (File->Type == EfiOpenFileSystem) { Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs); if (!EFI_ERROR (Status)) { Status = Fs->OpenVolume (Fs, &Root); if (!EFI_ERROR (Status)) { // Get information about the volume Size = 0; Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo); if (Status == EFI_BUFFER_TOO_SMALL) { File->FsInfo = AllocatePool (Size); Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo); } // Get information about the file Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0); if (!EFI_ERROR (Status)) { Size = 0; Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL); if (Status == EFI_BUFFER_TOO_SMALL) { File->FsFileInfo = AllocatePool (Size); Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo); if (!EFI_ERROR (Status)) { File->Size = (UINTN)File->FsFileInfo->FileSize; File->MaxPosition = (UINT64)File->Size; } } } Root->Close (Root); } } } else if (File->Type == EfiOpenBlockIo) { File->Size = (UINTN)File->MaxPosition; } return Status; }
/** Try to get the controller's ATA/ATAPI description. @param Handle Controller handle. @return The description string. **/ CHAR16 * BmGetDescriptionFromDiskInfo ( IN EFI_HANDLE Handle ) { UINTN Index; EFI_STATUS Status; EFI_DISK_INFO_PROTOCOL *DiskInfo; UINT32 BufferSize; EFI_ATAPI_IDENTIFY_DATA IdentifyData; EFI_SCSI_INQUIRY_DATA InquiryData; CHAR16 *Description; UINTN Length; CONST UINTN ModelNameLength = 40; CONST UINTN SerialNumberLength = 20; CHAR8 *StrPtr; UINT8 Temp; Description = NULL; Status = gBS->HandleProtocol ( Handle, &gEfiDiskInfoProtocolGuid, (VOID **) &DiskInfo ); if (EFI_ERROR (Status)) { return NULL; } if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoAhciInterfaceGuid) || CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid)) { BufferSize = sizeof (EFI_ATAPI_IDENTIFY_DATA); Status = DiskInfo->Identify ( DiskInfo, &IdentifyData, &BufferSize ); if (!EFI_ERROR (Status)) { Description = AllocateZeroPool ((ModelNameLength + SerialNumberLength + 2) * sizeof (CHAR16)); ASSERT (Description != NULL); for (Index = 0; Index + 1 < ModelNameLength; Index += 2) { Description[Index] = (CHAR16) IdentifyData.ModelName[Index + 1]; Description[Index + 1] = (CHAR16) IdentifyData.ModelName[Index]; } Length = Index; Description[Length++] = L' '; for (Index = 0; Index + 1 < SerialNumberLength; Index += 2) { Description[Length + Index] = (CHAR16) IdentifyData.SerialNo[Index + 1]; Description[Length + Index + 1] = (CHAR16) IdentifyData.SerialNo[Index]; } Length += Index; Description[Length++] = L'\0'; ASSERT (Length == ModelNameLength + SerialNumberLength + 2); BmEliminateExtraSpaces (Description); } } else if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoScsiInterfaceGuid)) { BufferSize = sizeof (EFI_SCSI_INQUIRY_DATA); Status = DiskInfo->Inquiry ( DiskInfo, &InquiryData, &BufferSize ); if (!EFI_ERROR (Status)) { Description = AllocateZeroPool ((VENDOR_IDENTIFICATION_LENGTH + PRODUCT_IDENTIFICATION_LENGTH + 2) * sizeof (CHAR16)); ASSERT (Description != NULL); // // Per SCSI spec, EFI_SCSI_INQUIRY_DATA.Reserved_5_95[3 - 10] save the Verdor identification // EFI_SCSI_INQUIRY_DATA.Reserved_5_95[11 - 26] save the product identification, // Here combine the vendor identification and product identification to the description. // StrPtr = (CHAR8 *) (&InquiryData.Reserved_5_95[VENDOR_IDENTIFICATION_OFFSET]); Temp = StrPtr[VENDOR_IDENTIFICATION_LENGTH]; StrPtr[VENDOR_IDENTIFICATION_LENGTH] = '\0'; AsciiStrToUnicodeStr (StrPtr, Description); StrPtr[VENDOR_IDENTIFICATION_LENGTH] = Temp; // // Add one space at the middle of vendor information and product information. // Description[VENDOR_IDENTIFICATION_LENGTH] = L' '; StrPtr = (CHAR8 *) (&InquiryData.Reserved_5_95[PRODUCT_IDENTIFICATION_OFFSET]); StrPtr[PRODUCT_IDENTIFICATION_LENGTH] = '\0'; AsciiStrToUnicodeStr (StrPtr, Description + VENDOR_IDENTIFICATION_LENGTH + 1); BmEliminateExtraSpaces (Description); } } return Description; }
/** The Request() function queues an HTTP request to this HTTP instance. Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent successfully, or if there is an error, Status in token will be updated and Event will be signaled. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[in] Token Pointer to storage containing HTTP request token. @retval EFI_SUCCESS Outgoing data was processed. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. @retval EFI_UNSUPPORTED The HTTP method is not supported in current implementation. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. Token is NULL. Token->Message is NULL. Token->Message->Body is not NULL, Token->Message->BodyLength is non-zero, and Token->Message->Data is NULL, but a previous call to Request()has not been completed successfully. **/ EFI_STATUS EFIAPI EfiHttpRequest ( IN EFI_HTTP_PROTOCOL *This, IN EFI_HTTP_TOKEN *Token ) { EFI_HTTP_MESSAGE *HttpMsg; EFI_HTTP_REQUEST_DATA *Request; VOID *UrlParser; EFI_STATUS Status; CHAR8 *HostName; UINT16 RemotePort; HTTP_PROTOCOL *HttpInstance; BOOLEAN Configure; BOOLEAN ReConfigure; CHAR8 *RequestMsg; CHAR8 *Url; UINTN UrlLen; CHAR16 *HostNameStr; HTTP_TOKEN_WRAP *Wrap; CHAR8 *FileUrl; UINTN RequestMsgSize; // // Initializations // Url = NULL; HostName = NULL; RequestMsg = NULL; HostNameStr = NULL; Wrap = NULL; FileUrl = NULL; if ((This == NULL) || (Token == NULL)) { return EFI_INVALID_PARAMETER; } HttpMsg = Token->Message; if (HttpMsg == NULL) { return EFI_INVALID_PARAMETER; } Request = HttpMsg->Data.Request; // // Only support GET, HEAD, PUT and POST method in current implementation. // if ((Request != NULL) && (Request->Method != HttpMethodGet) && (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost)) { return EFI_UNSUPPORTED; } HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); ASSERT (HttpInstance != NULL); // // Capture the method into HttpInstance. // if (Request != NULL) { HttpInstance->Method = Request->Method; } if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) { return EFI_NOT_STARTED; } if (Request == NULL) { // // Request would be NULL only for PUT/POST operation (in the current implementation) // if ((HttpInstance->Method != HttpMethodPut) && (HttpInstance->Method != HttpMethodPost)) { return EFI_INVALID_PARAMETER; } // // For PUT/POST, we need to have the TCP already configured. Bail out if it is not! // if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED) { return EFI_INVALID_PARAMETER; } // // We need to have the Message Body for sending the HTTP message across in these cases. // if (HttpMsg->Body == NULL || HttpMsg->BodyLength == 0) { return EFI_INVALID_PARAMETER; } // // Use existing TCP instance to transmit the packet. // Configure = FALSE; ReConfigure = FALSE; } else { // // Check whether the token already existed. // if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTokenExist, Token))) { return EFI_ACCESS_DENIED; } // // Parse the URI of the remote host. // Url = HttpInstance->Url; UrlLen = StrLen (Request->Url) + 1; if (UrlLen > HTTP_URL_BUFFER_LEN) { Url = AllocateZeroPool (UrlLen); if (Url == NULL) { return EFI_OUT_OF_RESOURCES; } FreePool (HttpInstance->Url); HttpInstance->Url = Url; } UnicodeStrToAsciiStr (Request->Url, Url); UrlParser = NULL; Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser); if (EFI_ERROR (Status)) { goto Error1; } HostName = NULL; Status = HttpUrlGetHostName (Url, UrlParser, &HostName); if (EFI_ERROR (Status)) { goto Error1; } Status = HttpUrlGetPort (Url, UrlParser, &RemotePort); if (EFI_ERROR (Status)) { RemotePort = HTTP_DEFAULT_PORT; } // // If Configure is TRUE, it indicates the first time to call Request(); // If ReConfigure is TRUE, it indicates the request URL is not same // with the previous call to Request(); // Configure = TRUE; ReConfigure = TRUE; if (HttpInstance->RemoteHost == NULL) { // // Request() is called the first time. // ReConfigure = FALSE; } else { if ((HttpInstance->RemotePort == RemotePort) && (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) { // // Host Name and port number of the request URL are the same with previous call to Request(). // Check whether previous TCP packet sent out. // if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) { // // Wrap the HTTP token in HTTP_TOKEN_WRAP // Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); if (Wrap == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } Wrap->HttpToken = Token; Wrap->HttpInstance = HttpInstance; Status = HttpCreateTcpTxEvent (Wrap); if (EFI_ERROR (Status)) { goto Error1; } Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); if (EFI_ERROR (Status)) { goto Error1; } Wrap->TcpWrap.Method = Request->Method; FreePool (HostName); // // Queue the HTTP token and return. // return EFI_SUCCESS; } else { // // Use existing TCP instance to transmit the packet. // Configure = FALSE; ReConfigure = FALSE; } } else { // // Need close existing TCP instance and create a new TCP instance for data transmit. // if (HttpInstance->RemoteHost != NULL) { FreePool (HttpInstance->RemoteHost); HttpInstance->RemoteHost = NULL; HttpInstance->RemotePort = 0; } } } } if (Configure) { // // Parse Url for IPv4 or IPv6 address, if failed, perform DNS resolution. // if (!HttpInstance->LocalAddressIsIPv6) { Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr); } else { Status = HttpUrlGetIp6 (Url, UrlParser, &HttpInstance->RemoteIpv6Addr); } if (EFI_ERROR (Status)) { HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (CHAR16)); if (HostNameStr == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } AsciiStrToUnicodeStr (HostName, HostNameStr); if (!HttpInstance->LocalAddressIsIPv6) { Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr); } else { Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr); } FreePool (HostNameStr); if (EFI_ERROR (Status)) { goto Error1; } } // // Save the RemotePort and RemoteHost. // ASSERT (HttpInstance->RemoteHost == NULL); HttpInstance->RemotePort = RemotePort; HttpInstance->RemoteHost = HostName; HostName = NULL; } if (ReConfigure) { // // The request URL is different from previous calls to Request(), close existing TCP instance. // if (!HttpInstance->LocalAddressIsIPv6) { ASSERT (HttpInstance->Tcp4 != NULL); } else { ASSERT (HttpInstance->Tcp6 != NULL); } HttpCloseConnection (HttpInstance); EfiHttpCancel (This, NULL); } // // Wrap the HTTP token in HTTP_TOKEN_WRAP // Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); if (Wrap == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } Wrap->HttpToken = Token; Wrap->HttpInstance = HttpInstance; if (Request != NULL) { Wrap->TcpWrap.Method = Request->Method; } Status = HttpInitTcp (HttpInstance, Wrap, Configure); if (EFI_ERROR (Status)) { goto Error2; } if (!Configure) { // // For the new HTTP token, create TX TCP token events. // Status = HttpCreateTcpTxEvent (Wrap); if (EFI_ERROR (Status)) { goto Error1; } } // // Create request message. // FileUrl = Url; if (Url != NULL && *FileUrl != '/') { // // Convert the absolute-URI to the absolute-path // while (*FileUrl != ':') { FileUrl++; } if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) { FileUrl += 3; while (*FileUrl != '/') { FileUrl++; } } else { Status = EFI_INVALID_PARAMETER; goto Error3; } } Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize); if (EFI_ERROR (Status)) { goto Error3; } // // Every request we insert a TxToken and a response call would remove the TxToken. // In cases of PUT/POST, after an initial request-response pair, we would do a // continuous request without a response call. So, in such cases, where Request // structure is NULL, we would not insert a TxToken. // if (Request != NULL) { Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); if (EFI_ERROR (Status)) { goto Error4; } } // // Transmit the request message. // Status = HttpTransmitTcp ( HttpInstance, Wrap, (UINT8*) RequestMsg, RequestMsgSize ); if (EFI_ERROR (Status)) { goto Error5; } DispatchDpc (); if (HostName != NULL) { FreePool (HostName); } return EFI_SUCCESS; Error5: // // We would have inserted a TxToken only if Request structure is not NULL. // Hence check before we do a remove in this error case. // if (Request != NULL) { NetMapRemoveTail (&HttpInstance->TxTokens, NULL); } Error4: if (RequestMsg != NULL) { FreePool (RequestMsg); } Error3: HttpCloseConnection (HttpInstance); Error2: HttpCloseTcpConnCloseEvent (HttpInstance); if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) { gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event); Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL; } if (NULL != Wrap->TcpWrap.Tx6Token.CompletionToken.Event) { gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event); Wrap->TcpWrap.Tx6Token.CompletionToken.Event = NULL; } Error1: if (HostName != NULL) { FreePool (HostName); } if (Wrap != NULL) { FreePool (Wrap); } if (UrlParser!= NULL) { HttpUrlFreeParser (UrlParser); } return Status; }