VOID * EfiLibAllocateZeroPool ( IN UINTN AllocationSize ) /*++ Routine Description: Allocate BootServicesData pool and zero it. Arguments: AllocationSize - The size to allocate Returns: Pointer of the buffer allocated. --*/ { VOID *Memory; Memory = EfiLibAllocatePool (AllocationSize); if (Memory != NULL) { gBS->SetMem (Memory, AllocationSize, 0); } return Memory; }
EFI_STATUS ValidateDataFromHiiHandle ( IN EFI_HII_HANDLE HiiHandle, OUT BOOLEAN *Results ) /*++ Routine Description: Validate that the data associated with the HiiHandle in NVRAM is within the reasonable parameters for that FormSet. Values for strings and passwords are not verified due to their not having the equivalent of valid range settings. Arguments: HiiHandle - Handle of the HII database entry to query Results - If return Status is EFI_SUCCESS, Results provides valid data TRUE = NVRAM Data is within parameters FALSE = NVRAM Data is NOT within parameters Returns: EFI_OUT_OF_RESOURCES - No enough buffer to allocate EFI_SUCCESS - Data successfully validated --*/ { EFI_STATUS Status; EFI_HII_PROTOCOL *Hii; EFI_GUID Guid; UINT8 *RawData; UINT8 *OldData; UINTN RawDataLength; UINT8 *VariableData; UINTN Index; UINTN Temp; UINTN SizeOfNvStore; UINTN CachedStart; BOOLEAN GotMatch; RawDataLength = DEFAULT_FORM_BUFFER_SIZE; SizeOfNvStore = 0; CachedStart = 0; GotMatch = FALSE; *Results = TRUE; Status = GetHiiInterface (&Hii); if (EFI_ERROR (Status)) { return Status; } // // Allocate space for retrieval of IFR data // RawData = EfiLibAllocateZeroPool (RawDataLength); if (RawData == NULL) { return EFI_OUT_OF_RESOURCES; } // // Get all the forms associated with this HiiHandle // Status = Hii->GetForms (Hii, HiiHandle, 0, &RawDataLength, RawData); if (EFI_ERROR (Status)) { gBS->FreePool (RawData); // // Allocate space for retrieval of IFR data // RawData = EfiLibAllocateZeroPool (RawDataLength); if (RawData == NULL) { return EFI_OUT_OF_RESOURCES; } // // Get all the forms associated with this HiiHandle // Status = Hii->GetForms (Hii, HiiHandle, 0, &RawDataLength, RawData); } OldData = RawData; // // Point RawData to the beginning of the form data // RawData = (UINT8 *) ((UINTN) RawData + sizeof (EFI_HII_PACK_HEADER)); for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) { if (RawData[Index] == EFI_IFR_FORM_SET_OP) { EfiCopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID)); break; } Index = RawData[Index + 1] + Index; } for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) { switch (RawData[Index]) { case EFI_IFR_FORM_SET_OP: break; case EFI_IFR_ONE_OF_OP: case EFI_IFR_CHECKBOX_OP: case EFI_IFR_NUMERIC_OP: case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: case EFI_IFR_PASSWORD_OP: case EFI_IFR_STRING_OP: // // Remember, multiple op-codes may reference the same item, so let's keep a running // marker of what the highest QuestionId that wasn't zero length. This will accurately // maintain the Size of the NvStore // if (((EFI_IFR_ONE_OF *) &RawData[Index])->Width != 0) { Temp = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width; if (SizeOfNvStore < Temp) { SizeOfNvStore = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width; } } } Index = RawData[Index + 1] + Index; } // // Allocate memory for our File Form Tags // VariableData = EfiLibAllocateZeroPool (SizeOfNvStore); if (VariableData == NULL) { return EFI_OUT_OF_RESOURCES; } Status = gRT->GetVariable ( L"Setup", &Guid, NULL, &SizeOfNvStore, (VOID *) VariableData ); if (EFI_ERROR (Status)) { // // If there is a variable that exists already and it is larger than what we calculated the // storage needs to be, we must assume the variable size from GetVariable is correct and not // allow the truncation of the variable. It is very possible that the user who created the IFR // we are cracking is not referring to a variable that was in a previous map, however we cannot // allow it's truncation. // if (Status == EFI_BUFFER_TOO_SMALL) { // // Free the buffer that was allocated that was too small // gBS->FreePool (VariableData); VariableData = EfiLibAllocatePool (SizeOfNvStore); if (VariableData == NULL) { return EFI_OUT_OF_RESOURCES; } Status = gRT->GetVariable ( L"Setup", &Guid, NULL, &SizeOfNvStore, (VOID *) VariableData ); } } // // Walk through the form and see that the variable data it refers to is ok. // This allows for the possibility of stale (obsoleted) data in the variable // can be overlooked without causing an error // for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) { switch (RawData[Index]) { case EFI_IFR_ONE_OF_OP: // // A one_of has no data, its the option that does - cache the storage Id // CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId; break; case EFI_IFR_ONE_OF_OPTION_OP: // // A one_of_option can be any value // if (VariableData[CachedStart] == ((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value) { GotMatch = TRUE; } break; case EFI_IFR_END_ONE_OF_OP: // // At this point lets make sure that the data value in the NVRAM matches one of the options // if (!GotMatch) { *Results = FALSE; return EFI_SUCCESS; } break; case EFI_IFR_CHECKBOX_OP: // // A checkbox is a boolean, so 0 and 1 are valid // Remember, QuestionId corresponds to the offset location of the data in the variable // if (VariableData[((EFI_IFR_CHECK_BOX *) &RawData[Index])->QuestionId] > 1) { *Results = FALSE; return EFI_SUCCESS; } break; case EFI_IFR_NUMERIC_OP: if ((VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] < ((EFI_IFR_NUMERIC *)&RawData[Index])->Minimum) || (VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] > ((EFI_IFR_NUMERIC *)&RawData[Index])->Maximum)) { *Results = FALSE; return EFI_SUCCESS; } break; } Index = RawData[Index + 1] + Index; } // // Free our temporary repository of form data // gBS->FreePool (OldData); gBS->FreePool (VariableData); return EFI_SUCCESS; }
EFI_HII_HANDLE FindHiiHandle ( IN OUT EFI_HII_PROTOCOL **HiiProtocol, OPTIONAL IN EFI_GUID *Guid ) /*++ Routine Description: Finds HII handle for given pack GUID previously registered with the HII. Arguments: HiiProtocol - pointer to pointer to HII protocol interface. If NULL, the interface will be found but not returned. If it points to NULL, the interface will be found and written back to the pointer that is pointed to. Guid - The GUID of the pack that registered with the HII. Returns: Handle to the HII pack previously registered by the memory driver. --*/ { EFI_STATUS Status; EFI_HII_HANDLE *HiiHandleBuffer; EFI_HII_HANDLE HiiHandle; UINT16 HiiHandleBufferLength; UINT32 NumberOfHiiHandles; EFI_GUID HiiGuid; EFI_HII_PROTOCOL *HiiProt; UINT32 Index; UINT16 Length; HiiHandle = 0; if ((HiiProtocol != NULL) && (*HiiProtocol != NULL)) { // // The protocol has been passed in // HiiProt = *HiiProtocol; } else { gBS->LocateProtocol ( &gEfiHiiProtocolGuid, NULL, (VOID **) &HiiProt ); if (HiiProt == NULL) { return HiiHandle; } if (HiiProtocol != NULL) { // // Return back the HII protocol for the caller as promissed // *HiiProtocol = HiiProt; } } // // Allocate buffer // HiiHandleBufferLength = 10; HiiHandleBuffer = EfiLibAllocatePool (HiiHandleBufferLength); ASSERT (HiiHandleBuffer != NULL); // // Get the Handles of the packages that were registered with Hii // Status = HiiProt->FindHandles ( HiiProt, &HiiHandleBufferLength, HiiHandleBuffer ); // // Get a bigger bugffer if this one is to small, and try again // if (Status == EFI_BUFFER_TOO_SMALL) { gBS->FreePool (HiiHandleBuffer); HiiHandleBuffer = EfiLibAllocatePool (HiiHandleBufferLength); ASSERT (HiiHandleBuffer != NULL); Status = HiiProt->FindHandles ( HiiProt, &HiiHandleBufferLength, HiiHandleBuffer ); } if (EFI_ERROR (Status)) { goto lbl_exit; } NumberOfHiiHandles = HiiHandleBufferLength / sizeof (EFI_HII_HANDLE); // // Iterate Hii handles and look for the one that matches our Guid // for (Index = 0; Index < NumberOfHiiHandles; Index++) { Length = 0; ExtractDataFromHiiHandle (HiiHandleBuffer[Index], &Length, NULL, &HiiGuid); if (EfiCompareGuid (&HiiGuid, Guid)) { HiiHandle = HiiHandleBuffer[Index]; break; } } lbl_exit: gBS->FreePool (HiiHandleBuffer); return HiiHandle; }
EFI_STATUS ConvertBmpToGopBlt ( IN VOID *BmpImage, IN UINTN BmpImageSize, IN OUT VOID **GopBlt, IN OUT UINTN *GopBltSize, OUT UINTN *PixelHeight, OUT UINTN *PixelWidth ) /*++ Routine Description: Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt buffer is passed in it will be used if it is big enough. Arguments: BmpImage - Pointer to BMP file BmpImageSize - Number of bytes in BmpImage GopBlt - Buffer containing GOP version of BmpImage. GopBltSize - Size of GopBlt in bytes. PixelHeight - Height of GopBlt/BmpImage in pixels PixelWidth - Width of GopBlt/BmpImage in pixels Returns: EFI_SUCCESS - GopBlt and GopBltSize are returned. EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image EFI_BUFFER_TOO_SMALL - The passed in GopBlt buffer is not big enough. GopBltSize will contain the required size. EFI_OUT_OF_RESOURCES - No enough buffer to allocate --*/ { UINT8 *Image; UINT8 *ImageHeader; BMP_IMAGE_HEADER *BmpHeader; BMP_COLOR_MAP *BmpColorMap; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; UINT64 BltBufferSize; UINTN Index; UINTN Height; UINTN Width; UINTN ImageIndex; BOOLEAN IsAllocated; BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { return EFI_UNSUPPORTED; } if (BmpHeader->CompressionType != 0) { return EFI_UNSUPPORTED; } // // Calculate Color Map offset in the image. // Image = BmpImage; BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); // // Calculate graphics image data address in the image // Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset; ImageHeader = Image; BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight); // // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow // if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), NULL)) { return EFI_UNSUPPORTED; } BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); IsAllocated = FALSE; if (*GopBlt == NULL) { *GopBltSize = (UINTN) BltBufferSize; *GopBlt = EfiLibAllocatePool (*GopBltSize); IsAllocated = TRUE; if (*GopBlt == NULL) { return EFI_OUT_OF_RESOURCES; } } else { if (*GopBltSize < (UINTN) BltBufferSize) { *GopBltSize = (UINTN) BltBufferSize; return EFI_BUFFER_TOO_SMALL; } } *PixelWidth = BmpHeader->PixelWidth; *PixelHeight = BmpHeader->PixelHeight; // // Convert image from BMP to Blt buffer format // BltBuffer = *GopBlt; for (Height = 0; Height < BmpHeader->PixelHeight; Height++) { Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth]; for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) { switch (BmpHeader->BitPerPixel) { case 1: // // Convert 1bit BMP to 24-bit color // for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) { Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red; Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green; Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue; Blt++; Width++; } Blt --; Width --; break; case 4: // // Convert BMP Palette to 24-bit color // Index = (*Image) >> 4; Blt->Red = BmpColorMap[Index].Red; Blt->Green = BmpColorMap[Index].Green; Blt->Blue = BmpColorMap[Index].Blue; if (Width < (BmpHeader->PixelWidth - 1)) { Blt++; Width++; Index = (*Image) & 0x0f; Blt->Red = BmpColorMap[Index].Red; Blt->Green = BmpColorMap[Index].Green; Blt->Blue = BmpColorMap[Index].Blue; } break; case 8: // // Convert BMP Palette to 24-bit color // Blt->Red = BmpColorMap[*Image].Red; Blt->Green = BmpColorMap[*Image].Green; Blt->Blue = BmpColorMap[*Image].Blue; break; case 24: Blt->Blue = *Image++; Blt->Green = *Image++; Blt->Red = *Image; break; default: if (IsAllocated) { gBS->FreePool (*GopBlt); *GopBlt = NULL; } return EFI_UNSUPPORTED; break; }; } ImageIndex = (UINTN) (Image - ImageHeader); if ((ImageIndex % 4) != 0) { // // Bmp Image starts each row on a 32-bit boundary! // Image = Image + (4 - (ImageIndex % 4)); } } return EFI_SUCCESS; }
EFI_STATUS prepareTapeTest(int initTestFileMarkCnt, int initTestBlockMarkCnt) { EFI_STATUS status; char *buffer=NULL; UINTN bufferSize = MAX_TAPE_BUFFER_SIZE; EFI_INPUT_KEY Key; int index, ii; buffer = (char *)EfiLibAllocatePool(bufferSize); // 1.0 check input parameters if((buffer==NULL) || (gTapeIoProtocol==NULL)) status = EFI_INVALID_PARAMETER; else status = EFI_SUCCESS; if(status == EFI_SUCCESS) { Print (L"\r\n Tape IO protocol Test will lose all data on the Tape? (Y/N)"); status = gtST->ConIn->ReadKeyStroke (gtST->ConIn, &Key); while(status == EFI_NOT_READY){ status = gtST->ConIn->ReadKeyStroke(gtST->ConIn, &Key); if((status == EFI_SUCCESS) && (Key.UnicodeChar != 'Y') && (Key.UnicodeChar != 'y') && (Key.UnicodeChar != 'N') && (Key.UnicodeChar != 'n')) { // check for a valid key Print (L"\r\n Invalid selection ......................... enter (Y/N)"); status = EFI_NOT_READY; } } if((Key.UnicodeChar == 'Y') || (Key.UnicodeChar == 'y')) { Print (L"\r\n Preparing tape ... "); for(index=0; index<(int)bufferSize; index++) buffer[index] = (char)index; // Note: the returned status has not check after calling TapeIoProtocol() // reset tape driver status = gTapeIoProtocol->TapeReset(gTapeIoProtocol, 1); Print (L"\r\n Reset tape ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") ); if(status != EFI_SUCCESS) goto prepareTapeTestEnd; // goto tape begin status = gTapeIoProtocol->TapeRewind(gTapeIoProtocol); Print (L"\r\n Rewind tape I ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") ); if(status != EFI_SUCCESS) goto prepareTapeTestEnd; // write some data and FileMark initTestFileMarkCnt = (initTestFileMarkCnt<TAPE_IO_TEST_FILEMARK_CNT) ? TAPE_IO_TEST_FILEMARK_CNT : initTestFileMarkCnt; for(index=0; index<initTestFileMarkCnt; index++) { Print (L"\r\n Write tape(%d, %d) ... ", index+1, initTestBlockMarkCnt); for(ii=0; ii<initTestBlockMarkCnt; ii++) { bufferSize = MAX_TAPE_BUFFER_SIZE; status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer); Print (L"%s", ((status == EFI_SUCCESS) ? L"." : L"Fail!") ); if(status != EFI_SUCCESS) goto prepareTapeTestEnd; } status = gTapeIoProtocol->TapeWriteFM(gTapeIoProtocol, 1); Print (L" %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") ); if(status != EFI_SUCCESS) goto prepareTapeTestEnd; } // write some other FileMark status = gTapeIoProtocol->TapeWriteFM(gTapeIoProtocol, 10); Print (L"\r\n WriteFM II ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") ); // goto tape begin status = gTapeIoProtocol->TapeRewind(gTapeIoProtocol); Print (L"\r\n Rewind tape II ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") ); if(status != EFI_SUCCESS) goto prepareTapeTestEnd; } } prepareTapeTestEnd: if(buffer!=NULL) gBS->FreePool(buffer); logMsg(gTapeBBTestMainAssertionGuid02E, "EFI_TAPE_IO_PROTOCOL Test", "prepare for tape testing", status, EFI_SUCCESS ); Print (L"\r\n prepareTapeTest Completed.\r\n"); return status; }
EFI_STATUS BBTestTapeFunctionWrite ( IN EFI_BB_TEST_PROTOCOL *_This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STATUS status; char *buffer=NULL; UINTN bufferSize = MAX_TAPE_BUFFER_SIZE; getStandardLibInterface(SupportHandle); // // Enter a function. It is put at the entry point of a function LogEnterFunction( LoggingLib, L"BBTestTapeFunctionWrite", L"%a:%d : EnterFunction", __FILE__, (UINTN)__LINE__ ); buffer = (char *)EfiLibAllocatePool(bufferSize); // 2.0 check input parameters gTapeIoProtocol = (EFI_TAPE_IO_PROTOCOL *)ClientInterface; if((buffer==NULL)||(_This==NULL) || (LoggingLib==NULL) || (gTapeIoProtocol==NULL)) status = EFI_INVALID_PARAMETER; else status = EFI_SUCCESS; logMsg(gTapeBBTestMainAssertionGuid008, "EFI_TAPE_IO_PROTOCOL write test", "check input parameters", status, EFI_SUCCESS ); if(status != EFI_SUCCESS) goto BBTestTapeFunctionWriteEnd; // 2.1 TapeWrite with valid parameters status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer); logMsg(gTapeBBTestMainAssertionGuid009, "EFI_TAPE_IO_PROTOCOL.TapeWrite", "with valid parameters", status, EFI_SUCCESS ); switch(status) { case EFI_SUCCESS: case EFI_END_OF_MEDIA: break; case EFI_NO_MEDIA: case EFI_MEDIA_CHANGED: case EFI_DEVICE_ERROR: case EFI_INVALID_PARAMETER: case EFI_NOT_READY: case EFI_TIMEOUT: case EFI_WRITE_PROTECTED: case EFI_UNSUPPORTED: default: goto BBTestTapeFunctionWriteEnd; break; } // 2.2.1 TapeWrite with invalid parameters bufferSize = MAX_TAPE_BUFFER_SIZE; status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, NULL); logMsg(gTapeBBTestMainAssertionGuid00A, "EFI_TAPE_IO_PROTOCOL.TapeWrite(Buffer=NULL)", "with invalid parameters", status, EFI_INVALID_PARAMETER ); // 2.2.2 TapeWrite with invalid parameters bufferSize = MAX_TAPE_BUFFER_SIZE; status = gTapeIoProtocol->TapeWrite(NULL, &bufferSize, buffer); logMsg(gTapeBBTestMainAssertionGuid00B, "EFI_TAPE_IO_PROTOCOL.TapeWrite", "with invalid parameters(EFI_TAPE_IO_PROTOCOL=NULL)", status, EFI_INVALID_PARAMETER ); // 2.3.1 TapeWrite with invalid parameters bufferSize = 0; status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, NULL); logMsg(gTapeBBTestMainAssertionGuid00C, "EFI_TAPE_IO_PROTOCOL.TapeWrite", "with invalid parameters(bufferSize=0,buffer=NULL)", status, EFI_INVALID_PARAMETER ); // 2.3.2 TapeWrite with valid parameters bufferSize = 0; status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer); logMsg(gTapeBBTestMainAssertionGuid00E, "EFI_TAPE_IO_PROTOCOL.TapeWrite", "with valid parameters(bufferSize=0,buffer!=NULL)", status, EFI_SUCCESS ); #if 0 // 2.4 do TapeWrite with valid parameters until not EFI_SUCCESS while(status==EFI_SUCCESS) { bufferSize = MAX_TAPE_BUFFER_SIZE; status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer); } logMsg(gTapeBBTestMainAssertionGuid00D, "EFI_TAPE_IO_PROTOCOL.TapeWrite", "do with valid parameters until not EFI_SUCCESS", status, EFI_SUCCESS ); #endif BBTestTapeFunctionWriteEnd: if(buffer!=NULL) gBS->FreePool(buffer); // // Exit a function. It is put at the exit point of a function LogExitFunction( LoggingLib, L"BBTestTapeFunctionWrite", L"%a:%d : ExitFunction", __FILE__, (UINTN)__LINE__ ); return EFI_SUCCESS; }
EFI_STATUS BBTestTapeFunctionRead( IN EFI_BB_TEST_PROTOCOL *_This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STATUS status; char *buffer=NULL; UINTN bufferSize = MAX_TAPE_BUFFER_SIZE; UINTN index; getStandardLibInterface(SupportHandle); // // Enter a function. It is put at the entry point of a function LogEnterFunction( LoggingLib, L"BBTestTapeFunctionRead", L"%a:%d : EnterFunction", __FILE__, (UINTN)__LINE__ ); buffer = (char *)EfiLibAllocatePool(bufferSize); // 1.0 check input parameters gTapeIoProtocol = (EFI_TAPE_IO_PROTOCOL *)ClientInterface; if((buffer==NULL)||(_This==NULL) || (LoggingLib==NULL) || (gTapeIoProtocol==NULL)) status = EFI_INVALID_PARAMETER; else status = EFI_SUCCESS; logMsg(gTapeBBTestMainAssertionGuid001, "EFI_TAPE_IO_PROTOCOL read test", "check input parameters", status, EFI_SUCCESS ); if(status != EFI_SUCCESS) goto BBTestTapeFunctionReadEnd; // 1.0.1 prepare Reading data prepareTapeTest(TAPE_IO_TEST_FILEMARK_CNT, TAPE_IO_TEST_BLOCKMARK_CNT); if(status != EFI_SUCCESS) goto BBTestTapeFunctionReadEnd; // 1.1 TapeRead with valid parameters status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, buffer); logMsg(gTapeBBTestMainAssertionGuid002, "EFI_TAPE_IO_PROTOCOL.TapeRead", "with valid parameters", status, EFI_SUCCESS ); switch(status) { case EFI_SUCCESS: case EFI_END_OF_FILE: // 1.1.1 verify reading data ... for(index=0; index<bufferSize; index++) if(buffer[index]!=(char)(index&0xff)) break; logMsg(gTapeBBTestMainAssertionGuid02F, "EFI_TAPE_IO_PROTOCOL.TapeRead", "verify reading data", ((index==bufferSize)?EFI_SUCCESS:EFI_LOAD_ERROR), EFI_SUCCESS ); break; case EFI_NO_MEDIA: case EFI_MEDIA_CHANGED: case EFI_DEVICE_ERROR: case EFI_INVALID_PARAMETER: case EFI_NOT_READY: case EFI_TIMEOUT: default: goto BBTestTapeFunctionReadEnd; break; } // 1.2.1 TapeRead with invalid parameters status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, NULL); logMsg(gTapeBBTestMainAssertionGuid003, "EFI_TAPE_IO_PROTOCOL.TapeRead", "with invalid parameters(Buffer=NULL)", status, EFI_INVALID_PARAMETER ); // 1.2.2 TapeRead with invalid parameters status = gTapeIoProtocol->TapeRead(NULL, &bufferSize, buffer); logMsg(gTapeBBTestMainAssertionGuid004, "EFI_TAPE_IO_PROTOCOL.TapeRead", "with invalid parameters(EFI_TAPE_IO_PROTOCOL=NULL)", status, EFI_INVALID_PARAMETER ); // 1.3.1 TapeRead with valid parameters bufferSize = 0; status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, NULL); logMsg(gTapeBBTestMainAssertionGuid005, "EFI_TAPE_IO_PROTOCOL.TapeRead", "with valid parameters(bufferSize=0,buffer=NULL)", status, EFI_SUCCESS ); // 1.3.2 TapeRead with valid parameters bufferSize = 0; status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, buffer); logMsg(gTapeBBTestMainAssertionGuid007, "EFI_TAPE_IO_PROTOCOL.TapeRead", "with valid parameters(bufferSize=0,buffer!=NULL)", status, EFI_SUCCESS ); #if 0 // 1.4 do TapeRead with valid parameters until not EFI_SUCCESS while(status==EFI_SUCCESS) { bufferSize = MAX_TAPE_BUFFER_SIZE; status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, buffer); } logMsg(gTapeBBTestMainAssertionGuid006, "EFI_TAPE_IO_PROTOCOL.TapeRead", "do with valid parameters until not EFI_SUCCESS", status, EFI_SUCCESS ); #endif BBTestTapeFunctionReadEnd: if(buffer!=NULL) gBS->FreePool(buffer); // // Exit a function. It is put at the exit point of a function LogExitFunction( LoggingLib, L"BBTestTapeFunctionRead", L"%a:%d : ExitFunction", __FILE__, (UINTN)__LINE__ ); return EFI_SUCCESS; }
VOID ProcessHelpString ( IN CHAR16 *StringPtr, OUT CHAR16 **FormattedString, IN UINTN RowCount ) /*++ Routine Description: Process the help string: Split StringPtr to several lines of strings stored in FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth. Arguments: StringPtr - The entire help string. MenuOption - The MenuOption for this Question. RowCount - TRUE: if Question is selected. OptionString - Pointer of the Option String to be displayed. Returns: None. --*/ { CONST UINTN BlockWidth = (UINTN) gHelpBlockWidth - 1; UINTN AllocateSize; // // [PrevCurrIndex, CurrIndex) forms a range of a screen-line // UINTN CurrIndex; UINTN PrevCurrIndex; UINTN LineCount; UINTN VirtualLineCount; // // GlyphOffset stores glyph width of current screen-line // UINTN GlyphOffset; // // GlyphWidth equals to 2 if we meet width directive // UINTN GlyphWidth; // // during scanning, we remember the position of last space character // in case that if next word cannot put in current line, we could restore back to the position // of last space character // while we should also remmeber the glyph width of the last space character for restoring // UINTN LastSpaceIndex; UINTN LastSpaceGlyphWidth; // // every time we begin to form a new screen-line, we should remember glyph width of single character // of last line // UINTN LineStartGlyphWidth; UINTN *IndexArray; UINTN *OldIndexArray; // // every three elements of IndexArray form a screen-line of string:[ IndexArray[i*3], IndexArray[i*3+1] ) // IndexArray[i*3+2] stores the initial glyph width of single character. to save this is because we want // to bring the width directive of the last line to current screen-line. // e.g.: "\wideabcde ... fghi", if "fghi" also has width directive but is splitted to the next screen-line // different from that of "\wideabcde", we should remember the width directive. // AllocateSize = 0x20; IndexArray = EfiLibAllocatePool (AllocateSize * sizeof (UINTN) * 3); if (*FormattedString != NULL) { gBS->FreePool (*FormattedString); *FormattedString = NULL; } for (PrevCurrIndex = 0, CurrIndex = 0, LineCount = 0, LastSpaceIndex = 0, IndexArray[0] = 0, GlyphWidth = 1, GlyphOffset = 0, LastSpaceGlyphWidth = 1, LineStartGlyphWidth = 1; (StringPtr[CurrIndex] != CHAR_NULL); CurrIndex ++) { if (LineCount == AllocateSize) { AllocateSize += 0x10; OldIndexArray = IndexArray; IndexArray = EfiLibAllocatePool (AllocateSize * sizeof (UINTN) * 3); EfiCopyMem (IndexArray, OldIndexArray, LineCount * sizeof (UINTN) * 3); gBS->FreePool (OldIndexArray); } switch (StringPtr[CurrIndex]) { case NARROW_CHAR: case WIDE_CHAR: GlyphWidth = ((StringPtr[CurrIndex] == WIDE_CHAR) ? 2 : 1); if (CurrIndex == 0) { LineStartGlyphWidth = GlyphWidth; } break; // // char is '\n' // "\r\n" isn't handled here, handled by case CHAR_CARRIAGE_RETURN // case CHAR_LINEFEED: // // Store a range of string as a line // IndexArray[LineCount*3] = PrevCurrIndex; IndexArray[LineCount*3+1] = CurrIndex; IndexArray[LineCount*3+2] = LineStartGlyphWidth; LineCount ++; // // Reset offset and save begin position of line // GlyphOffset = 0; LineStartGlyphWidth = GlyphWidth; PrevCurrIndex = CurrIndex + 1; break; // // char is '\r' // "\r\n" and "\r" both are handled here // case CHAR_CARRIAGE_RETURN: if (StringPtr[CurrIndex + 1] == CHAR_LINEFEED) { // // next char is '\n' // IndexArray[LineCount*3] = PrevCurrIndex; IndexArray[LineCount*3+1] = CurrIndex; IndexArray[LineCount*3+2] = LineStartGlyphWidth; LineCount ++; CurrIndex ++; } GlyphOffset = 0; LineStartGlyphWidth = GlyphWidth; PrevCurrIndex = CurrIndex + 1; break; // // char is space or other char // default: GlyphOffset += GlyphWidth; if (GlyphOffset >= BlockWidth) { if (LastSpaceIndex > PrevCurrIndex) { // // LastSpaceIndex points to space inside current screen-line, // restore to LastSpaceIndex // (Otherwise the word is too long to fit one screen-line, just cut it) // CurrIndex = LastSpaceIndex; GlyphWidth = LastSpaceGlyphWidth; } else if (GlyphOffset > BlockWidth) { // // the word is too long to fit one screen-line and we don't get the chance // of GlyphOffset == BlockWidth because GlyphWidth = 2 // CurrIndex --; } IndexArray[LineCount*3] = PrevCurrIndex; IndexArray[LineCount*3+1] = CurrIndex + 1; IndexArray[LineCount*3+2] = LineStartGlyphWidth; LineStartGlyphWidth = GlyphWidth; LineCount ++; // // Reset offset and save begin position of line // GlyphOffset = 0; PrevCurrIndex = CurrIndex + 1; } // // LastSpaceIndex: remember position of last space // if (StringPtr[CurrIndex] == CHAR_SPACE) { LastSpaceIndex = CurrIndex; LastSpaceGlyphWidth = GlyphWidth; } break; } } if (GlyphOffset > 0) { IndexArray[LineCount*3] = PrevCurrIndex; IndexArray[LineCount*3+1] = CurrIndex; IndexArray[LineCount*3+2] = GlyphWidth; LineCount ++; } if (LineCount == 0) { // // in case we meet null string // IndexArray[0] = 0; IndexArray[1] = 1; // // we assume null string's glyph width is 1 // IndexArray[1] = 1; LineCount ++; } VirtualLineCount = RowCount * (LineCount / RowCount + (LineCount % RowCount > 0)); *FormattedString = EfiLibAllocateZeroPool (VirtualLineCount * (BlockWidth + 1) * sizeof (CHAR16) * 2); for (CurrIndex = 0; CurrIndex < LineCount; CurrIndex ++) { *(*FormattedString + CurrIndex * 2 * (BlockWidth + 1)) = (IndexArray[CurrIndex*3+2] == 2) ? WIDE_CHAR : NARROW_CHAR; StrnCpy ( *FormattedString + CurrIndex * 2 * (BlockWidth + 1) + 1, StringPtr + IndexArray[CurrIndex*3], IndexArray[CurrIndex*3+1]-IndexArray[CurrIndex*3] ); } gBS->FreePool (IndexArray); }
EFI_STATUS EFIAPI FdcControllerDriverStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) /*++ Routine Description: Arguments: Returns: --*/ // GC_TODO: This - add argument and description to function comment // GC_TODO: Controller - add argument and description to function comment // GC_TODO: RemainingDevicePath - add argument and description to function comment { EFI_STATUS Status; FDC_BLK_IO_DEV *FdcDev; EFI_INTERFACE_DEFINITION_FOR_ISA_IO *IsaIo; UINTN Index; EFI_LIST_ENTRY *List; BOOLEAN Found; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; FdcDev = NULL; IsaIo = NULL; // // Open the device path protocol // Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &ParentDevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Report enable progress code // ReportStatusCodeWithDevicePath ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE, 0, &gEfiCallerIdGuid, ParentDevicePath ); // // Open the ISA I/O Protocol // Status = gBS->OpenProtocol ( Controller, EFI_ISA_IO_PROTOCOL_VERSION, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto Done; } // // Allocate the Floppy Disk Controller's Device structure // FdcDev = EfiLibAllocateZeroPool (sizeof (FDC_BLK_IO_DEV)); if (FdcDev == NULL) { goto Done; } // // Initialize the Floppy Disk Controller's Device structure // FdcDev->Signature = FDC_BLK_IO_DEV_SIGNATURE; FdcDev->Handle = Controller; FdcDev->IsaIo = IsaIo; FdcDev->Disk = IsaIo->ResourceList->Device.UID; FdcDev->Cache = NULL; FdcDev->Event = NULL; FdcDev->ControllerState = NULL; FdcDev->DevicePath = ParentDevicePath; ADD_FLOPPY_NAME (FdcDev); // // Look up the base address of the Floppy Disk Controller // for (Index = 0; FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) { if (FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) { FdcDev->BaseAddress = (UINT16) FdcDev->IsaIo->ResourceList->ResourceItem[Index].StartRange; } } // // Maintain the list of controller list // Found = FALSE; List = gControllerHead.ForwardLink; while (List != &gControllerHead) { FdcDev->ControllerState = FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List); if (FdcDev->BaseAddress == FdcDev->ControllerState->BaseAddress) { Found = TRUE; break; } List = List->ForwardLink; } if (!Found) { // // The Controller is new // FdcDev->ControllerState = EfiLibAllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT)); if (FdcDev->ControllerState == NULL) { goto Done; } FdcDev->ControllerState->Signature = FLOPPY_CONTROLLER_CONTEXT_SIGNATURE; FdcDev->ControllerState->FddResetPerformed = FALSE; FdcDev->ControllerState->NeedRecalibrate = FALSE; FdcDev->ControllerState->BaseAddress = FdcDev->BaseAddress; FdcDev->ControllerState->NumberOfDrive = 0; InsertTailList (&gControllerHead, &FdcDev->ControllerState->Link); } // // Create a timer event for each Floppd Disk Controller. // This timer event is used to control the motor on and off // Status = gBS->CreateEvent ( EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_NOTIFY, FddTimerProc, FdcDev, &FdcDev->Event ); if (EFI_ERROR (Status)) { goto Done; } // // Reset the Floppy Disk Controller // if (!FdcDev->ControllerState->FddResetPerformed) { FdcDev->ControllerState->FddResetPerformed = TRUE; FdcDev->ControllerState->FddResetStatus = FddReset (FdcDev); } if (EFI_ERROR (FdcDev->ControllerState->FddResetStatus)) { Status = EFI_DEVICE_ERROR; goto Done; } ReportStatusCodeWithDevicePath ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT, 0, &gEfiCallerIdGuid, ParentDevicePath ); // // Discover the Floppy Drive // Status = DiscoverFddDevice (FdcDev); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; goto Done; } // // Install protocol interfaces for the serial device. // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiBlockIoProtocolGuid, &FdcDev->BlkIo, NULL ); FdcDev->ControllerState->NumberOfDrive++; Done: if (EFI_ERROR (Status)) { ReportStatusCodeWithDevicePath ( EFI_ERROR_CODE | EFI_ERROR_MINOR, EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR, 0, &gEfiCallerIdGuid, ParentDevicePath ); // // Close the device path protocol // gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); // // Close the ISA I/O Protocol // if (IsaIo != NULL) { gBS->CloseProtocol ( Controller, EFI_ISA_IO_PROTOCOL_VERSION, This->DriverBindingHandle, Controller ); } // // If a Floppy Disk Controller Device structure was allocated, then free it // if (FdcDev != NULL) { if (FdcDev->Event != NULL) { // // Close the event for turning the motor off // gBS->CloseEvent (FdcDev->Event); } EfiLibFreeUnicodeStringTable (FdcDev->ControllerNameTable); gBS->FreePool (FdcDev); } } return Status; }
EFI_STATUS PartitionInstallElToritoChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) /*++ Routine Description: Install child handles if the Handle supports El Torito format. Arguments: This - Calling context. Handle - Parent Handle DiskIo - Parent DiskIo interface BlockIo - Parent BlockIo interface DevicePath - Parent Device Path Returns: EFI_SUCCESS - some child handle(s) was added EFI_MEDIA_CHANGED - Media changed Detected !EFI_SUCCESS - no child handle was added --*/ { EFI_STATUS Status; UINT32 VolDescriptorLba; UINT32 Lba; EFI_BLOCK_IO_MEDIA *Media; CDROM_VOLUME_DESCRIPTOR *VolDescriptor; ELTORITO_CATALOG *Catalog; UINTN Check; UINTN Index; UINTN BootEntry; UINTN MaxIndex; UINT16 *CheckBuffer; CDROM_DEVICE_PATH CdDev; UINT32 SubBlockSize; UINT32 SectorCount; EFI_STATUS Found; UINTN Dummy; UINT32 VolSpaceSize; Found = EFI_NOT_FOUND; Media = BlockIo->Media; VolSpaceSize = 0; // // CD_ROM has the fixed block size as 2048 bytes // if (Media->BlockSize != 2048) { return EFI_NOT_FOUND; } VolDescriptor = EfiLibAllocatePool ((UINTN) Media->BlockSize); if (VolDescriptor == NULL) { return EFI_NOT_FOUND; } Catalog = (ELTORITO_CATALOG *) VolDescriptor; // // the ISO-9660 volume descriptor starts at 32k on the media // and CD_ROM has the fixed block size as 2048 bytes, so... // // // ((16*2048) / Media->BlockSize) - 1; // VolDescriptorLba = 15; // // Loop: handle one volume descriptor per time // while (TRUE) { VolDescriptorLba += 1; if (VolDescriptorLba > Media->LastBlock) { // // We are pointing past the end of the device so exit // break; } Status = DiskIo->ReadDisk ( DiskIo, Media->MediaId, MultU64x32 (VolDescriptorLba, Media->BlockSize), Media->BlockSize, VolDescriptor ); if (EFI_ERROR (Status)) { Found = Status; break; } // // Check for valid volume descriptor signature // if (VolDescriptor->Type == CDVOL_TYPE_END || EfiCompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0 ) { // // end of Volume descriptor list // break; } // // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte, // the 32-bit numerical values is stored in Both-byte orders // if (VolDescriptor->Type == CDVOL_TYPE_CODED) { VolSpaceSize = VolDescriptor->VolSpaceSize[0]; } // // Is it an El Torito volume descriptor? // if (EfiCompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) { continue; } // // Read in the boot El Torito boot catalog // Lba = UNPACK_INT32 (VolDescriptor->EltCatalog); if (Lba > Media->LastBlock) { continue; } Status = DiskIo->ReadDisk ( DiskIo, Media->MediaId, MultU64x32 (Lba, Media->BlockSize), Media->BlockSize, Catalog ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status)); continue; } // // We don't care too much about the Catalog header's contents, but we do want // to make sure it looks like a Catalog header // if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) { DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header IDs not correct\n")); continue; } Check = 0; CheckBuffer = (UINT16 *) Catalog; for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) { Check += CheckBuffer[Index]; } if (Check & 0xFFFF) { DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n")); continue; } MaxIndex = Media->BlockSize / sizeof (ELTORITO_CATALOG); for (Index = 1, BootEntry = 1; Index < MaxIndex; Index += 1) { // // Next entry // Catalog += 1; // // Check this entry // if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) { continue; } SubBlockSize = 512; SectorCount = Catalog->Boot.SectorCount; switch (Catalog->Boot.MediaType) { case ELTORITO_NO_EMULATION: SubBlockSize = Media->BlockSize; break; case ELTORITO_HARD_DISK: break; case ELTORITO_12_DISKETTE: SectorCount = 0x50 * 0x02 * 0x0F; break; case ELTORITO_14_DISKETTE: SectorCount = 0x50 * 0x02 * 0x12; break; case ELTORITO_28_DISKETTE: SectorCount = 0x50 * 0x02 * 0x24; break; default: DEBUG ((EFI_D_INIT, "EltCheckDevice: unsupported El Torito boot media type %x\n", Catalog->Boot.MediaType)); SectorCount = 0; SubBlockSize = Media->BlockSize; break; } // // Create child device handle // CdDev.Header.Type = MEDIA_DEVICE_PATH; CdDev.Header.SubType = MEDIA_CDROM_DP; SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev)); if (Index == 1) { // // This is the initial/default entry // BootEntry = 0; } CdDev.BootEntry = (UINT32) BootEntry; BootEntry++; CdDev.PartitionStart = Catalog->Boot.Lba; if (SectorCount < 2) { // //When the SectorCount < 2, set the Partition as the whole CD. // CdDev.PartitionSize = (VolSpaceSize > Media->LastBlock + 1) ? (UINT32)(Media->LastBlock - Catalog->Boot.Lba + 1) : (UINT32)(VolSpaceSize - Catalog->Boot.Lba); } else { CdDev.PartitionSize = DivU64x32 ( MultU64x32 (SectorCount, SubBlockSize) + Media->BlockSize - 1, Media->BlockSize, &Dummy ); } Status = PartitionInstallChildHandle ( This, Handle, DiskIo, BlockIo, DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &CdDev, Catalog->Boot.Lba, Catalog->Boot.Lba + CdDev.PartitionSize - 1, SubBlockSize, FALSE ); if (!EFI_ERROR (Status)) { Found = EFI_SUCCESS; } } } gBS->FreePool (VolDescriptor); return Found; }
EFI_STATUS IfrCatenate ( IN FORM_BROWSER_FORMSET *FormSet, OUT EFI_HII_VALUE *Result ) /*++ Routine Description: Evaluate opcode EFI_IFR_CATENATE. Arguments: FormSet - Formset which contains this opcode. Result - Evaluation result for this opcode. Returns: EFI_SUCCESS - Opcode evaluation success. Other - Opcode evaluation failed. --*/ { EFI_STATUS Status; EFI_HII_VALUE Value; CHAR16 *String[2]; UINTN Index; CHAR16 *StringPtr; // // String[0] - The second string // String[1] - The first string // String[0] = NULL; String[1] = NULL; StringPtr = NULL; Status = EFI_SUCCESS; for (Index = 0; Index < 2; Index++) { Status = PopExpression (&Value); if (EFI_ERROR (Status)) { goto Done; } if (Value.Type != EFI_IFR_TYPE_STRING) { Status = EFI_UNSUPPORTED; goto Done; } String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle); if (String== NULL) { Status = EFI_NOT_FOUND; goto Done; } } StringPtr= EfiLibAllocatePool (EfiStrSize (String[1]) + EfiStrSize (String[0])); ASSERT (StringPtr != NULL); EfiStrCpy (StringPtr, String[1]); EfiStrCat (StringPtr, String[0]); Result->Type = EFI_IFR_TYPE_STRING; Result->Value.string = NewString (StringPtr, FormSet->HiiHandle); Done: EfiLibSafeFreePool (String[0]); EfiLibSafeFreePool (String[1]); EfiLibSafeFreePool (StringPtr); return Status; }
STATIC EFI_STATUS GrowStack ( IN OUT EFI_HII_VALUE **Stack, IN OUT EFI_HII_VALUE **StackPtr, IN OUT EFI_HII_VALUE **StackEnd ) /*++ Routine Description: Grow size of the stack Arguments: Stack - On input: old stack; On output: new stack StackPtr - On input: old stack pointer; On output: new stack pointer StackEnd - On input: old stack end; On output: new stack end Returns: EFI_SUCCESS - Grow stack success. EFI_OUT_OF_RESOURCES - No enough memory for stack space. --*/ { UINTN Size; EFI_HII_VALUE *NewStack; Size = EXPRESSION_STACK_SIZE_INCREMENT; if (*StackPtr != NULL) { Size = Size + (*StackEnd - *Stack); } NewStack = EfiLibAllocatePool (Size * sizeof (EFI_HII_VALUE)); if (NewStack == NULL) { return EFI_OUT_OF_RESOURCES; } if (*StackPtr != NULL) { // // Copy from Old Stack to the New Stack // EfiCopyMem ( NewStack, *Stack, (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE) ); // // Free The Old Stack // gBS->FreePool (*Stack); } // // Make the Stack pointer point to the old data in the new stack // *StackPtr = NewStack + (*StackPtr - *Stack); *Stack = NewStack; *StackEnd = NewStack + Size; return EFI_SUCCESS; }
EFI_STATUS EfiLibAddUnicodeString ( IN CHAR8 *Language, IN CHAR8 *SupportedLanguages, IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable, IN CHAR16 *UnicodeString ) /*++ Routine Description: Add an translation to the dictionary if this language if supported. Arguments: Language - The name of language to translate to SupportedLanguages - Supported languages set UnicodeStringTable - Translation dictionary UnicodeString - The corresponding string for the language to be translated to Returns: EFI_INVALID_PARAMETER - Invalid parameter EFI_UNSUPPORTED - System not supported this language EFI_ALREADY_STARTED - Already has a translation item of this language EFI_OUT_OF_RESOURCES - No enough buffer to be allocated EFI_SUCCESS - String successfully translated --*/ { UINTN NumberOfEntries; EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable; EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable; UINTN UnicodeStringLength; // // Make sure the parameter are valid // if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) { return EFI_INVALID_PARAMETER; } // // If there are no supported languages, then a Unicode String can not be added // if (SupportedLanguages == NULL) { return EFI_UNSUPPORTED; } // // If the Unicode String is empty, then a Unicode String can not be added // if (UnicodeString[0] == 0) { return EFI_INVALID_PARAMETER; } // // Make sure Language is a member of SupportedLanguages // while (*SupportedLanguages != 0) { if (EfiLibCompareLanguage (Language, SupportedLanguages)) { // // Determine the size of the Unicode String Table by looking for a NULL Language entry // NumberOfEntries = 0; if (*UnicodeStringTable != NULL) { OldUnicodeStringTable = *UnicodeStringTable; while (OldUnicodeStringTable->Language != NULL) { if (EfiLibCompareLanguage (Language, OldUnicodeStringTable->Language)) { return EFI_ALREADY_STARTED; } OldUnicodeStringTable++; NumberOfEntries++; } } // // Allocate space for a new Unicode String Table. It must hold the current number of // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table // marker // NewUnicodeStringTable = EfiLibAllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE)); if (NewUnicodeStringTable == NULL) { return EFI_OUT_OF_RESOURCES; } // // If the current Unicode String Table contains any entries, then copy them to the // newly allocated Unicode String Table. // if (*UnicodeStringTable != NULL) { EfiCopyMem ( NewUnicodeStringTable, *UnicodeStringTable, NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE) ); } // // Allocate space for a copy of the Language specifier // NewUnicodeStringTable[NumberOfEntries].Language = EfiLibAllocateCopyPool (EfiAsciiStrLen(Language) + 1, Language); if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) { gBS->FreePool (NewUnicodeStringTable); return EFI_OUT_OF_RESOURCES; } // // Compute the length of the Unicode String // for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++) ; // // Allocate space for a copy of the Unicode String // NewUnicodeStringTable[NumberOfEntries].UnicodeString = EfiLibAllocateCopyPool ( (UnicodeStringLength + 1) * sizeof (CHAR16), UnicodeString ); if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) { gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language); gBS->FreePool (NewUnicodeStringTable); return EFI_OUT_OF_RESOURCES; } // // Mark the end of the Unicode String Table // NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL; NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL; // // Free the old Unicode String Table // if (*UnicodeStringTable != NULL) { gBS->FreePool (*UnicodeStringTable); } // // Point UnicodeStringTable at the newly allocated Unicode String Table // *UnicodeStringTable = NewUnicodeStringTable; return EFI_SUCCESS; } SupportedLanguages = NextSupportedLanguage(SupportedLanguages); } return EFI_UNSUPPORTED; }
EFI_STATUS FtwReclaimWorkSpace ( IN EFI_FTW_LITE_DEVICE *FtwLiteDevice, IN BOOLEAN PreserveRecord ) /*++ Routine Description: Reclaim the work space on the working block. Arguments: FtwLiteDevice - Point to private data of FTW driver PreserveRecord - Whether to preserve the working record is needed Returns: EFI_SUCCESS - The function completed successfully EFI_OUT_OF_RESOURCES - Allocate memory error EFI_ABORTED - The function could not complete successfully --*/ { EFI_STATUS Status; UINT8 *TempBuffer; UINTN TempBufferSize; UINT8 *Ptr; UINTN Length; UINTN Index; UINTN SpareBufferSize; UINT8 *SpareBuffer; EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader; EFI_FTW_LITE_RECORD *Record; DEBUG ((EFI_D_FTW_LITE, "FtwLite: start to reclaim work space\n")); // // Read all original data from working block to a memory buffer // TempBufferSize = FtwLiteDevice->SpareAreaLength; Status = gBS->AllocatePool ( EfiBootServicesData, TempBufferSize, &TempBuffer ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } EfiZeroMem (TempBuffer, TempBufferSize); Ptr = TempBuffer; for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { Length = FtwLiteDevice->SizeOfSpareBlock; Status = FtwLiteDevice->FtwFvBlock->Read ( FtwLiteDevice->FtwFvBlock, FtwLiteDevice->FtwWorkBlockLba + Index, 0, &Length, Ptr ); if (EFI_ERROR (Status)) { gBS->FreePool (TempBuffer); return EFI_ABORTED; } Ptr += Length; } // // Clean up the workspace, remove all the completed records. // Ptr = TempBuffer + ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) * FtwLiteDevice->SizeOfSpareBlock + FtwLiteDevice->FtwWorkSpaceBase; // // Clear the content of buffer that will save the new work space data // EfiSetMem (Ptr, FtwLiteDevice->FtwWorkSpaceSize, FTW_ERASED_BYTE); // // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer // EfiCopyMem ( Ptr, FtwLiteDevice->FtwWorkSpaceHeader, sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER) ); if (PreserveRecord) { // // Get the last record // Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); Record = FtwLiteDevice->FtwLastRecord; if (!EFI_ERROR (Status) && Record != NULL && Record->WriteAllocated == FTW_VALID_STATE && Record->WriteCompleted != FTW_VALID_STATE) { EfiCopyMem ( (UINT8 *) Ptr + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), Record, WRITE_TOTAL_SIZE ); } } EfiCopyMem ( FtwLiteDevice->FtwWorkSpace, Ptr, FtwLiteDevice->FtwWorkSpaceSize ); Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord); // // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID // WorkingBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr; WorkingBlockHeader->WorkingBlockValid = FTW_INVALID_STATE; WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE; // // Try to keep the content of spare block // Save spare block into a spare backup memory buffer (Sparebuffer) // SpareBufferSize = FtwLiteDevice->SpareAreaLength; SpareBuffer = EfiLibAllocatePool (SpareBufferSize); if (SpareBuffer == NULL) { gBS->FreePool (TempBuffer); return EFI_OUT_OF_RESOURCES; } Ptr = SpareBuffer; for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { Length = FtwLiteDevice->SizeOfSpareBlock; Status = FtwLiteDevice->FtwBackupFvb->Read ( FtwLiteDevice->FtwBackupFvb, FtwLiteDevice->FtwSpareLba + Index, 0, &Length, Ptr ); if (EFI_ERROR (Status)) { gBS->FreePool (TempBuffer); gBS->FreePool (SpareBuffer); return EFI_ABORTED; } Ptr += Length; } // // Write the memory buffer to spare block // Status = FtwEraseSpareBlock (FtwLiteDevice); Ptr = TempBuffer; for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { Length = FtwLiteDevice->SizeOfSpareBlock; Status = FtwLiteDevice->FtwBackupFvb->Write ( FtwLiteDevice->FtwBackupFvb, FtwLiteDevice->FtwSpareLba + Index, 0, &Length, Ptr ); if (EFI_ERROR (Status)) { gBS->FreePool (TempBuffer); gBS->FreePool (SpareBuffer); return EFI_ABORTED; } Ptr += Length; } // // Free TempBuffer // gBS->FreePool (TempBuffer); // // Write the spare block to working block // Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice); if (EFI_ERROR (Status)) { gBS->FreePool (SpareBuffer); return Status; } // // Restore spare backup buffer into spare block , if no failure happened during FtwWrite. // Status = FtwEraseSpareBlock (FtwLiteDevice); Ptr = SpareBuffer; for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) { Length = FtwLiteDevice->SizeOfSpareBlock; Status = FtwLiteDevice->FtwBackupFvb->Write ( FtwLiteDevice->FtwBackupFvb, FtwLiteDevice->FtwSpareLba + Index, 0, &Length, Ptr ); if (EFI_ERROR (Status)) { gBS->FreePool (SpareBuffer); return EFI_ABORTED; } Ptr += Length; } gBS->FreePool (SpareBuffer); DEBUG ((EFI_D_FTW_LITE, "FtwLite: reclaim work space success\n")); return EFI_SUCCESS; }