/**
 *  TDS 5.1 - Entry point for GetVariable() and SetVariable() Stress Test.
 *  @param This             A pointer to the EFI_BB_TEST_PROTOCOL instance.
 *  @param ClientInterface  A pointer to the interface to be tested.
 *  @param TestLevel        Test "thoroughness" control.
 *  @param SupportHandle    A handle containing support protocols.
 *  @return EFI_SUCCESS     Successfully.
 *  @return Other value     Something failed.
 */
EFI_STATUS
MultipleStressTest (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{
  EFI_STATUS                          Status;
  EFI_RUNTIME_SERVICES                *RT;
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL  *StandardLib;
  EFI_TEST_RECOVERY_LIBRARY_PROTOCOL  *RecoveryLib;
  EFI_TEST_LOGGING_LIBRARY_PROTOCOL   *LoggingLib;

  //
  // Get test support library interfaces
  //
  Status = GetTestSupportLibrary (
             SupportHandle,
             &StandardLib,
             &RecoveryLib,
             &LoggingLib
             );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  RT = (EFI_RUNTIME_SERVICES *)ClientInterface;

  //
  // Stress test for GetVariable
  //
  Status = MultipleStressTestSub1 (RT, StandardLib, LoggingLib);

  //
  // Stress test for GetNextVariableName
  //
  Status = MultipleStressTestSub2 (RT, StandardLib, LoggingLib);

  //
  // Stress test for SetVariable
  //
  Status = MultipleStressTestSub3 (RT, StandardLib, LoggingLib);

  //
  // Done
  //
  return EFI_SUCCESS;
}
/**
 *  TDS 5.2 - Entry point for Variable Overflow Stress Test.
 *  @param This             A pointer to the EFI_BB_TEST_PROTOCOL instance.
 *  @param ClientInterface  A pointer to the interface to be tested.
 *  @param TestLevel        Test "thoroughness" control.
 *  @param SupportHandle    A handle containing support protocols.
 *  @return EFI_SUCCESS     Successfully.
 *  @return Other value     Something failed.
 */
EFI_STATUS
OverflowStressTest (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{
  EFI_STATUS                          Status;
  EFI_RUNTIME_SERVICES                *RT;
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL  *StandardLib;
  EFI_TEST_RECOVERY_LIBRARY_PROTOCOL  *RecoveryLib;
  EFI_TEST_LOGGING_LIBRARY_PROTOCOL   *LoggingLib;
  UINTN                               RecoveryDataSize;
  UINT8                               *RecoveryData;

  //
  // Get test support library interfaces
  //
  Status = GetTestSupportLibrary (
             SupportHandle,
             &StandardLib,
             &RecoveryLib,
             &LoggingLib
             );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  RT = (EFI_RUNTIME_SERVICES *)ClientInterface;

  //
  // Allocate memory for recovery data
  //
  Status = gtBS->AllocatePool (
                   EfiLoaderData,
                   1024,
                   (VOID **)&RecoveryData
                   );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Read reset record
  //
  RecoveryDataSize = 1024;
  Status = RecoveryLib->ReadResetRecord (
                          RecoveryLib,
                          &RecoveryDataSize,
                          RecoveryData
                          );
  if (!EFI_ERROR(Status) && (RecoveryDataSize > 0)) {
    switch (RecoveryData[0]) {
    case 2:
      goto step2;
    default:
      goto step3;
    }
  }

  //
  // Reclaim test with system reset
  //
step2:
  Status = OverflowStressTestSub1 (RT, StandardLib, RecoveryLib, LoggingLib);


  //
  // Free resources
  //
step3:
  gtBS->FreePool (RecoveryData);

  //
  // Done
  //
  return EFI_SUCCESS;
}
//
// TDS 4.4
//
EFI_STATUS
BBTestSetWakeupTimeInterfaceTest (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib;
  EFI_TEST_RECOVERY_LIBRARY_PROTOCOL   *RecoveryLib;
  EFI_TEST_LOGGING_LIBRARY_PROTOCOL    *LoggingLib;
  EFI_STATUS                           Status;
  EFI_TEST_ASSERTION                   AssertionType;
  UINTN                                Index;
  EFI_TPL                              OldTpl;
  EFI_TIME                             OldTime;
  EFI_TIME                             NewTime;
  BOOLEAN                              Enable;
  BOOLEAN                              Pending;
  UINTN                                RecoveryDataSize;
  UINT8                                *RecoveryData;

  //
  // Get test support library interfaces
  //
  Status = GetTestSupportLibrary (
             SupportHandle,
             &StandardLib,
             &RecoveryLib,
             &LoggingLib
             );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Allocate memory for recovery data
  //
  Status = gtBS->AllocatePool (
                   EfiLoaderData,
                   1024,
                   (VOID **)&RecoveryData
                   );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Read reset record
  //
  RecoveryDataSize = 1024;
  Status = RecoveryLib->ReadResetRecord (
                          RecoveryLib,
                          &RecoveryDataSize,
                          RecoveryData
                          );
  if (!EFI_ERROR(Status) && (RecoveryDataSize > 0)) {
    switch (RecoveryData[0]) {
    case 1:
      goto step1;
    case 2:
      goto step2;
    default:
      goto step3;
    }
  }
  for (Index = 0; Index < TPL_ARRAY_SIZE; Index++) {
    //
    // 4.4.2.1  SetWakeupTime must succeed when set the system wakeup alarm clock
    //
    Status = gtRT->GetTime (
                     &OldTime,
                     NULL
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get time",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
      continue;
    }

    //
    // Change hour
    //
    AddOneHour (&OldTime);
    OldTpl = gtBS->RaiseTPL (TplArray[Index]);
    Status = gtRT->SetWakeupTime (
                     TRUE,
                     &OldTime
                     );
    gtBS->RestoreTPL (OldTpl);
    if (Status == EFI_UNSUPPORTED) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_WARNING,
                     gTestGenericFailureGuid,
                     L"RT.SetWakeupTime - Unsupported",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status
                     );
      return EFI_SUCCESS;
    }
    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   Index==0? \
                   gTimeServicesBBTestFunctionAssertionGuid043: \
                   (Index == 1? \
                    gTimeServicesBBTestFunctionAssertionGuid044: \
                    gTimeServicesBBTestFunctionAssertionGuid045),
                   L"RT.SetWakeupTime - Set wakeup time",
                   L"%a:%d:Status - %r, TPL - %d",
                   __FILE__,
                   (UINTN)__LINE__,
                   Status,
                   TplArray[Index]
                   );
	//
	// Write reset record 
	//
    RecoveryData[0] = 1;
	RecoveryData[1] = (UINT8)(Index);
	gtBS->CopyMem (&RecoveryData[2], &OldTime, sizeof(EFI_TIME));
    RecoveryLib->WriteResetRecord (RecoveryLib, sizeof(EFI_TIME)+2, RecoveryData);
	gtBS->FreePool (RecoveryData);
    //
    // Prompt the user about the cold reset and reset the system
    //
    if (LoggingLib != NULL) {
      LoggingLib->EnterFunction (
                    LoggingLib,
                    L"\r\nSetTime Test",
                    L"System will cold reset after 1 second..."
                    );
    }
    gtBS->Stall (1000000);
    gtRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);

step1:

    //
    // Restore the env
    //
    RecoveryData[0] = 0;
    Index = RecoveryData[1];
    gtBS->CopyMem (&OldTime, &RecoveryData[2], sizeof(EFI_TIME));
	
    Status = gtRT->GetWakeupTime (
                     &Enable,
                     &Pending,
                     &NewTime
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get wakeup time 1",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    } else {
      if (Enable == TRUE) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid046: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid047: \
                      gTimeServicesBBTestFunctionAssertionGuid048),
                     L"RT.SetWakeupTime - Wakeup timer should be enabled",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
      if (Pending == FALSE) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid049: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid050: \
                      gTimeServicesBBTestFunctionAssertionGuid051),
                     L"RT.SetWakeupTime - Timer should not be pending",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
      if ((OldTime.Year != NewTime.Year) || (OldTime.Month != NewTime.Month) || (OldTime.Day != NewTime.Day) || 
  	    (OldTime.Hour != NewTime.Hour) || (OldTime.Minute != NewTime.Minute) || (OldTime.Second != NewTime.Second) ||
  	    (OldTime.TimeZone != NewTime.TimeZone) || (OldTime.Daylight != NewTime.Daylight)) {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid052: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid053: \
                      gTimeServicesBBTestFunctionAssertionGuid054),
                     L"RT.SetWakeupTime - Verify wakeup time after change",
                     L"%a:%d:Status - %r, TPL - %d, YMD-%d,%d,%d,%d,%d,%d, HMS-%d,%d,%d,%d,%d,%d, NDT-%d,%d,%d,%d,%d,%d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index],
                     OldTime.Year, NewTime.Year,
                     OldTime.Month, NewTime.Month,
                     OldTime.Day, NewTime.Day,
                     OldTime.Hour, NewTime.Hour,
                     OldTime.Minute, NewTime.Minute,
                     OldTime.Second, NewTime.Second,
                     OldTime.Nanosecond, NewTime.Nanosecond,
                     OldTime.Daylight, NewTime.Daylight,
                     OldTime.TimeZone, NewTime.TimeZone
                     );
    }

    //
    // 4.4.2.2  SetWakeupTime must succeed when disable the wakeup alarm clock
    //
    OldTpl = gtBS->RaiseTPL (TplArray[Index]);
    Status = gtRT->SetWakeupTime (
                     FALSE,
                     NULL
                     );
    gtBS->RestoreTPL (OldTpl);
    if (Status == EFI_UNSUPPORTED) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_WARNING,
                     gTestGenericFailureGuid,
                     L"RT.SetWakeupTime - Unsupported",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status
                     );
      return EFI_SUCCESS;
    }
    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   Index==0? \
                   gTimeServicesBBTestFunctionAssertionGuid055: \
                   (Index == 1? \
                    gTimeServicesBBTestFunctionAssertionGuid056: \
                    gTimeServicesBBTestFunctionAssertionGuid057),
                   L"RT.SetWakeupTime - Disable wakeup time",
                   L"%a:%d:Status - %r, TPL - %d",
                   __FILE__,
                   (UINTN)__LINE__,
                   Status,
                   TplArray[Index]
                   );
	
	//
	// Write reset record 
	//
    RecoveryData[0] = 2;
	RecoveryData[1] = (UINT8)(Index);
    RecoveryLib->WriteResetRecord (RecoveryLib, 2, RecoveryData);
	gtBS->FreePool (RecoveryData);
    //
    // Prompt the user about the cold reset and reset the system
    //
    if (LoggingLib != NULL) {
      LoggingLib->EnterFunction (
                    LoggingLib,
                    L"\r\nSetTime Test",
                    L"System will cold reset after 1 second..."
                    );
    }
    gtBS->Stall (1000000);
    gtRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
	
step2:
	
    //
    // Restore the env
    //
    RecoveryData[0] = 0;
    Index = RecoveryData[1];
	
    Status = gtRT->GetWakeupTime (
                     &Enable,
                     &Pending,
                     &NewTime
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get wakeup time 2",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    } else {
      if (Enable == FALSE) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid058: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid059: \
                      gTimeServicesBBTestFunctionAssertionGuid060),
                     L"RT.SetWakeupTime - Wakeup timer should be disabled",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    }
  }

step3:
  gtBS->FreePool (RecoveryData);

  return EFI_SUCCESS;
}
//
// TDS 4.2
//
EFI_STATUS
BBTestSetTimeInterfaceTest (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{  
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL  *StandardLib;
  EFI_TEST_RECOVERY_LIBRARY_PROTOCOL  *RecoveryLib;
  EFI_TEST_LOGGING_LIBRARY_PROTOCOL   *LoggingLib;
  EFI_STATUS                          Status;
  EFI_TEST_ASSERTION                  AssertionType;
  UINTN                               Index;
  EFI_TPL                             OldTpl;
  EFI_TIME                            OldTime;
  EFI_TIME                            NewTime;
  EFI_TIME                            Time;
  UINTN                               RecoveryDataSize;
  UINT8                               *RecoveryData;

  //
  // Get test support library interfaces
  //
  Status = GetTestSupportLibrary (
             SupportHandle,
             &StandardLib,
             &RecoveryLib,
             &LoggingLib
             );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Allocate memory for recovery data
  //
  Status = gtBS->AllocatePool (
                   EfiLoaderData,
                   1024,
                   (VOID **)&RecoveryData
                   );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Read reset record
  //
  RecoveryDataSize = 1024;
  Status = RecoveryLib->ReadResetRecord (
                          RecoveryLib,
                          &RecoveryDataSize,
                          RecoveryData
                          );
  if (!EFI_ERROR(Status) && (RecoveryDataSize > 0)) {
    switch (RecoveryData[0]) {
    case 1:
      goto step1;
    case 2:
      goto step2;
    case 3:
      goto step3;
    case 4:
      goto step4;
    default:
      goto step5;
    }
  }

  for (Index = 0; Index < TPL_ARRAY_SIZE; Index++) {
    //
    // 4.2.2.1  SetTime must succeed with valid parameters
    //
    Status = gtRT->GetTime (
                     &OldTime,
                     NULL
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get time",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
      continue;
    }

    //
    // Change year
    // NOTES: The new year must be set as a leap year.
    //
    Time = OldTime;
    if (Time.Year != 2012) {
      Time.Year = 2012;
    } else {
      Time.Year = 2016;
    }
    // skip 2012 12  31 11:59:59 corner case  
    Time.Day = 1;
    
    OldTpl = gtBS->RaiseTPL (TplArray[Index]);
    Status = gtRT->SetTime (
                     &Time
                     );
    gtBS->RestoreTPL (OldTpl);
    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   Index==0? \
                   gTimeServicesBBTestFunctionAssertionGuid013: \
                   (Index == 1? \
                    gTimeServicesBBTestFunctionAssertionGuid014: \
                    gTimeServicesBBTestFunctionAssertionGuid015),
                   L"RT.SetTime - Change year",
                   L"%a:%d:Status - %r, TPL - %d, Year - %d",
                   __FILE__,
                   (UINTN)__LINE__,
                   Status,
                   TplArray[Index],
                   OldTime.Year
                   );

	//
	// Write reset record 
	//
    RecoveryData[0] = 1;
	RecoveryData[1] = (UINT8)(Index);
	gtBS->CopyMem (&RecoveryData[2], &OldTime, sizeof(EFI_TIME));
    RecoveryLib->WriteResetRecord (RecoveryLib, sizeof(EFI_TIME)+2, RecoveryData);
	gtBS->FreePool (RecoveryData);
    //
    // Prompt the user about the cold reset and reset the system
    //
    if (LoggingLib != NULL) {
      LoggingLib->EnterFunction (
                    LoggingLib,
                    L"\r\nSetTime Test",
                    L"System will cold reset after 1 second..."
                    );
    }
    gtBS->Stall (1000000);
    gtRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);

step1:
    //
    // Restore the env
    //
    RecoveryData[0] = 0;
    Index = RecoveryData[1];
    gtBS->CopyMem (&OldTime, &RecoveryData[2], sizeof(EFI_TIME));

	//
	// Call GetTime() to check the result of SetTime()
	//
    Status = gtRT->GetTime (
                     &NewTime,
                     NULL
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get new time 1",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    } else {
      if (((OldTime.Year == 2012) && (NewTime.Year == 2016)) ||
          ((OldTime.Year != 2012) && (NewTime.Year == 2012))) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid016: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid017: \
                      gTimeServicesBBTestFunctionAssertionGuid018),
                     L"RT.SetTime - Verity year after change",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    }

    //
    // Change month
    //
    Time = OldTime;
    if (Time.Month != 1) {
      Time.Month = 1;
    } else {
      Time.Month = 12;
    }
    
    // skip 2012 12  31 11:59:59 corner case  
    Time.Day = 1;
    
    OldTpl = gtBS->RaiseTPL (TplArray[Index]);
    Status = gtRT->SetTime (
                     &Time
                     );
    gtBS->RestoreTPL (OldTpl);
    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   Index==0? \
                   gTimeServicesBBTestFunctionAssertionGuid019: \
                   (Index == 1? \
                    gTimeServicesBBTestFunctionAssertionGuid020: \
                    gTimeServicesBBTestFunctionAssertionGuid021),
                   L"RT.SetTime - Change month",
                   L"%a:%d:Status - %r, TPL - %d",
                   __FILE__,
                   (UINTN)__LINE__,
                   Status,
                   TplArray[Index]
                   );

	//
	// Write reset record 
	//
    RecoveryData[0] = 2;
	RecoveryData[1] = (UINT8)Index;
	gtBS->CopyMem (&RecoveryData[2], &OldTime, sizeof(EFI_TIME));
    RecoveryLib->WriteResetRecord (RecoveryLib, sizeof(EFI_TIME)+2, RecoveryData);
    gtBS->FreePool (RecoveryData);
    //
    // Prompt the user about the cold reset and reset the system
    //
    if (LoggingLib != NULL) {
      LoggingLib->EnterFunction (
                    LoggingLib,
                    L"\r\nSetTime Test",
                    L"System will cold reset after 1 second..."
                    );
    }
    gtBS->Stall (1000000);
    gtRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);


step2:
    //
    // Restore the env
    //
    RecoveryData[0] = 0;
	Index = RecoveryData[1];
    gtBS->CopyMem (&OldTime, &RecoveryData[2], sizeof(EFI_TIME));

	//
	// Call GetTime() to check the result of SetTime()
	//	
    Status = gtRT->GetTime (
                     &NewTime,
                     NULL
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get new time 2",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    } else {
      if (((OldTime.Month == 1) && (NewTime.Month == 12)) ||
          ((OldTime.Month != 1) && (NewTime.Month == 1))) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid022: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid023: \
                      gTimeServicesBBTestFunctionAssertionGuid024),
                     L"RT.SetTime - Verity month after change",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    }

    //
    // Change daylight
    //
    Time = OldTime;
    if (Time.Daylight & EFI_TIME_ADJUST_DAYLIGHT) {
      Time.Daylight &= ~EFI_TIME_ADJUST_DAYLIGHT;
    } else {
      Time.Daylight |= EFI_TIME_ADJUST_DAYLIGHT;
    }
    // reverse EFI_TIME_IN_DAYLIGHT bit
    Time.Daylight ^= EFI_TIME_IN_DAYLIGHT;
   
    OldTpl = gtBS->RaiseTPL (TplArray[Index]);
    Status = gtRT->SetTime (
                     &Time
                     );
    gtBS->RestoreTPL (OldTpl);
    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   Index==0? \
                   gTimeServicesBBTestFunctionAssertionGuid025: \
                   (Index == 1? \
                    gTimeServicesBBTestFunctionAssertionGuid026: \
                    gTimeServicesBBTestFunctionAssertionGuid027),
                   L"RT.SetTime - Change daylight",
                   L"%a:%d:Status - %r, TPL - %d",
                   __FILE__,
                   (UINTN)__LINE__,
                   Status,
                   TplArray[Index]
                   );
	
	//
	// Write reset record 
	//
    RecoveryData[0] = 3;
	RecoveryData[1] = (UINT8)Index;
	gtBS->CopyMem (&RecoveryData[2], &OldTime, sizeof(EFI_TIME));
    RecoveryLib->WriteResetRecord (RecoveryLib, sizeof(EFI_TIME)+2, RecoveryData);
    gtBS->FreePool (RecoveryData);
    //
    // Prompt the user about the cold reset and reset the system
    //
    if (LoggingLib != NULL) {
      LoggingLib->EnterFunction (
                    LoggingLib,
                    L"\r\nSetTime Test",
                    L"System will cold reset after 1 second..."
                    );
    }
    gtBS->Stall (1000000);
    gtRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);

step3:
    //
    // Restore the env
    //
    RecoveryData[0] = 0;
	Index = RecoveryData[1];
    gtBS->CopyMem (&OldTime, &RecoveryData[2], sizeof(EFI_TIME));

	//
	// Call GetTime() to check the result of SetTime()
	//
    Status = gtRT->GetTime (
                     &NewTime,
                     NULL
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get new time 3",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    } else {
      if ((OldTime.Daylight ^ NewTime.Daylight) == (EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid028: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid029: \
                      gTimeServicesBBTestFunctionAssertionGuid030),
                     L"RT.SetTime - Verity daylight after change",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    }

    //
    // Change time zone
    //
    Time = OldTime;
    if (Time.TimeZone != 0) {
      Time.TimeZone = 0;
    } else {
      Time.TimeZone = 1;
    }
    OldTpl = gtBS->RaiseTPL (TplArray[Index]);
    Status = gtRT->SetTime (
                     &Time
                     );
    gtBS->RestoreTPL (OldTpl);
    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   Index==0? \
                   gTimeServicesBBTestFunctionAssertionGuid031: \
                   (Index == 1? \
                    gTimeServicesBBTestFunctionAssertionGuid032: \
                    gTimeServicesBBTestFunctionAssertionGuid033),
                   L"RT.SetTime - Change time zone",
                   L"%a:%d:Status - %r, TPL - %d",
                   __FILE__,
                   (UINTN)__LINE__,
                   Status,
                   TplArray[Index]
                   );

	//
	// Write reset record 
	//
    RecoveryData[0] = 4;
	RecoveryData[1] = (UINT8)Index;
	gtBS->CopyMem (&RecoveryData[2], &OldTime, sizeof(EFI_TIME));
    RecoveryLib->WriteResetRecord (RecoveryLib, sizeof(EFI_TIME)+2, RecoveryData);
    gtBS->FreePool (RecoveryData);
    //
    // Prompt the user about the cold reset and reset the system
    //
    if (LoggingLib != NULL) {
      LoggingLib->EnterFunction (
                    LoggingLib,
                    L"\r\nSetTime Test",
                    L"System will cold reset after 1 second..."
                    );
    }
//	Print (L"System will cold reset after 1 second...");
    gtBS->Stall (1000000);
    gtRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);

step4:
    //
    // Restore the env
    //
    RecoveryData[0] = 0;
	Index = RecoveryData[1];
    gtBS->CopyMem (&OldTime, &RecoveryData[2], sizeof(EFI_TIME));

	//
	// Call GetTime() to check the result of SetTime()
	//
    Status = gtRT->GetTime (
                     &NewTime,
                     NULL
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.GetTime - Get new time 4",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    } else {
      if (((OldTime.TimeZone == 0) && (NewTime.TimeZone == 1)) ||
          ((OldTime.TimeZone != 0) && (NewTime.TimeZone == 0))) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     Index==0? \
                     gTimeServicesBBTestFunctionAssertionGuid034: \
                     (Index == 1? \
                      gTimeServicesBBTestFunctionAssertionGuid035: \
                      gTimeServicesBBTestFunctionAssertionGuid036),
                     L"RT.SetTime - Verity time zone after change",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    }

    //
    // Restore the time
    //
    Status = gtRT->SetTime (
                     &OldTime
                     );
    if (EFI_ERROR(Status)) {
      StandardLib->RecordAssertion (
                     StandardLib,
                     EFI_TEST_ASSERTION_FAILED,
                     gTestGenericFailureGuid,
                     L"RT.SetTime - Restore time",
                     L"%a:%d:Status - %r, TPL - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     TplArray[Index]
                     );
    }
  }

step5:
  gtBS->FreePool (RecoveryData);

  return EFI_SUCCESS;
}
//
//TDS 4.1.1
//
EFI_STATUS
GetInfo_Func (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{
  EFI_STATUS                              Status;
  EFI_DECOMPRESS_PROTOCOL                 *Decompress;
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL      *StandardLib;
  EFI_TEST_PROFILE_LIBRARY_PROTOCOL      *ProfileLib;
  UINT32                                  UncompressedFileSize;
  UINT32                                  CompressedFileSize;
  UINT32                                  DestinationSize;
  UINT32                                  SecondTimeSize;
  UINT32                                  ScratchSize;
  UINT32                                  ScratchSizeOrg;
  UINTN                                   Index;
  VOID                                    *Buffer;
  UINTN                                   BufferSize;
  EFI_TEST_ASSERTION                      AssertionType;
  EFI_INI_FILE_HANDLE                     FileHandle;
  EFI_FILE_HANDLE                         CompressedFHandle;
  UINTN                                   MaxOrder;
  CHAR16                                  *FileName;

  //
  //get tested interface.
  //
  Decompress = (EFI_DECOMPRESS_PROTOCOL *)ClientInterface;

  //
  // Get the test Supported Library Interface
  //
  Status = GetTestSupportLibrary (
             SupportHandle,
             &StandardLib,
             &ProfileLib
             );

  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Get the system device path and file path
  //
  Status = GetSystemData (ProfileLib);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  //open the ini file.
  //
  Status = OpenTestIniFile (ProfileLib, &FileHandle);

  if (EFI_ERROR(Status)) {
    StandardLib->RecordAssertion (
                   StandardLib,
                   EFI_TEST_ASSERTION_WARNING,
                   gTestGenericFailureGuid,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() -no item found for this test case.",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );

    return Status;
  }

  //
  //we initialize this variable because it was taken as UINT32 type, in fact it
  //is UINT64 value in ipf platform.
  //

  MaxOrder = 0;

  Status = FileHandle->GetOrderNum (
                         FileHandle,
                         SECTION_NAME_GETINFO_BASIC_TEST,
                         (UINT32 *)&MaxOrder
                         );

  if (EFI_ERROR(Status)) {
    StandardLib->RecordAssertion (
                   StandardLib,
                   EFI_TEST_ASSERTION_WARNING,
                   gTestGenericFailureGuid,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() -no item found for this test case",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );

    CloseTestIniFile (ProfileLib, FileHandle);
    return Status;
  }

  for (Index = 0; Index < MaxOrder; Index++) {
    //
    //get compressed FileName and Uncompressed File Size.
    //
    Status = GetUncompressedFileSize (
               FileHandle,
               SECTION_NAME_GETINFO_BASIC_TEST,
               Index,
               &UncompressedFileSize
               );

    if (EFI_ERROR(Status)) {
      continue;
    }

    Status = GetCompressedFileName (
               FileHandle,
               SECTION_NAME_GETINFO_BASIC_TEST,
               Index,
               &FileName
               );

    if (EFI_ERROR(Status)) {
      continue;
    }

    //
    //read the Compressed file into memory.
    //
    Status = OpenFileAndGetSize (
               FileName,
               &CompressedFHandle,
               &CompressedFileSize
               );

    if (EFI_ERROR(Status)) {
      Print (L"Can not open the File :%s\r\n", FileName);
      gtBS->FreePool (FileName);
      continue;
    }

    gtBS->FreePool (FileName);

    Buffer = AllocatePool (CompressedFileSize);

    if (Buffer == NULL) {
      CompressedFHandle->Close (CompressedFHandle);
      Print (L"Can not allocate %xh buffer.\r\n", CompressedFileSize);
      continue;
    }

    BufferSize = CompressedFileSize;

    Status = CompressedFHandle->Read (
                                  CompressedFHandle,
                                  &BufferSize,
                                  Buffer
                                  );

    if (EFI_ERROR(Status)) {
      CompressedFHandle->Close (CompressedFHandle);
      Print (L"File Read Error Status %r\r\n", Status);
      gtBS->FreePool (Buffer);
      continue;
    }

    //
    //now verify the check points.
    //
    Status = Decompress->GetInfo (
                           Decompress,
                           Buffer,
                           CompressedFileSize,
                           &DestinationSize,
                           &ScratchSize
                           );

    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gDecompressBBTestFunctionAssertionGuid001,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - return Status should be EFI_SUCCESS",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );

    if (DestinationSize == UncompressedFileSize) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gDecompressBBTestFunctionAssertionGuid002,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - the Destination Size should be equal with the Uncompressed File Size",
                   L"%a:%d:Destination Size - %d, Uncompressed File Size - %d",
                   __FILE__,
                   __LINE__,
                   (UINT32)DestinationSize,
                   (UINT32)UncompressedFileSize
                   );

    //
    //call GetInfo again see if the returned value is the same.
    //
    ScratchSizeOrg = ScratchSize;
    Status = Decompress->GetInfo (
                           Decompress,
                           Buffer,
                           CompressedFileSize,
                           &SecondTimeSize,
                           &ScratchSize
                           );

    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gDecompressBBTestFunctionAssertionGuid003,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - call the second time, return Status should be EFI_SUCCESS",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );
    if (SecondTimeSize == DestinationSize) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gDecompressBBTestFunctionAssertionGuid004,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - two time returned Destination size must be equal",
                   L"%a:%d:First Time - %08x, Second Time- %08x",
                   __FILE__,
                   __LINE__,
                   DestinationSize,
                   SecondTimeSize
                   );

    if (ScratchSize == ScratchSizeOrg) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gDecompressBBTestFunctionAssertionGuid005,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - two time returned Scratch size must be equal",
                   L"%a:%d:First Time - %08x, Second Time- %08x",
                   __FILE__,
                   __LINE__,
                   ScratchSizeOrg,
                   ScratchSize
                   );

    //
    //free the resources
    //
    gtBS->FreePool (Buffer);
    CompressedFHandle->Close (CompressedFHandle);
  }

  CloseTestIniFile (ProfileLib, FileHandle);

  //
  //done successfully
  //
  return EFI_SUCCESS;
}
//
//TDS 4.1.2
//
EFI_STATUS
Decompress_Func (
  IN EFI_BB_TEST_PROTOCOL       *This,
  IN VOID                       *ClientInterface,
  IN EFI_TEST_LEVEL             TestLevel,
  IN EFI_HANDLE                 SupportHandle
  )
{
  EFI_STATUS                              Status;
  EFI_DECOMPRESS_PROTOCOL                 *Decompress;
  EFI_STANDARD_TEST_LIBRARY_PROTOCOL      *StandardLib;
  EFI_TEST_PROFILE_LIBRARY_PROTOCOL      *ProfileLib;
  UINT32                                  UncompressedFileSize;
  UINT32                                  CompressedFileSize;
  UINT32                                  DestinationSize;
  UINT32                                  ScratchSize;
  UINTN                                   Index;
  UINTN                                   SubIndex;
  VOID                                    *CompressedFileBuffer;
  VOID                                    *UncompressedFileBuffer;
  UINT8                                   *DecompressBuffer;
  VOID                                    *ScratchBuffer;
  UINTN                                   BufferSize;
  EFI_TEST_ASSERTION                      AssertionType;
  EFI_INI_FILE_HANDLE                     FileHandle;
  EFI_FILE_HANDLE                         CompressedFHandle;
  EFI_FILE_HANDLE                         UncompressedFHandle;
  UINTN                                   MaxOrder;
  CHAR16                                  *CompressedFileName;
  CHAR16                                  *UncompressedFileName;

  //
  //get tested interface.
  //
  Decompress = (EFI_DECOMPRESS_PROTOCOL *)ClientInterface;

  //
  // Get the test Supported Library Interface
  //
  Status = GetTestSupportLibrary (
             SupportHandle,
             &StandardLib,
             &ProfileLib
             );

  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Get the system device path and file path
  //
  Status = GetSystemData (ProfileLib);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  //open the ini file.
  //
  Status = OpenTestIniFile (ProfileLib, &FileHandle);

  if (EFI_ERROR(Status)) {
    StandardLib->RecordAssertion (
                   StandardLib,
                   EFI_TEST_ASSERTION_WARNING,
                   gTestGenericFailureGuid,
                   L"EFI_DECOMPRESS_PROTOCOL.Decompress() -not found the profile.",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );
    return Status;
  }

  //
  //we initialize this variable because it was taken as UINT32 type, in fact it
  //is UINT64 value in ipf platform.
  //

  MaxOrder = 0;

  Status = FileHandle->GetOrderNum (
                         FileHandle,
                         SECTION_NAME_DECOMPRESS_BASIC_TEST,
                         (UINT32 *)&MaxOrder
                         );

  if (EFI_ERROR(Status)) {
    CloseTestIniFile (ProfileLib, FileHandle);
    StandardLib->RecordAssertion (
                   StandardLib,
                   EFI_TEST_ASSERTION_WARNING,
                   gTestGenericFailureGuid,
                   L"EFI_DECOMPRESS_PROTOCOL.Decompress() -no item found for this test case.",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );
    return Status;
  }

  for (Index = 0; Index < MaxOrder; Index++) {

    CompressedFileBuffer   = NULL;
    UncompressedFileBuffer = NULL;
    DecompressBuffer       = NULL;
    ScratchBuffer          = NULL;

    //
    //get compressed FileName and file size.
    //
    Status = GetCompressedFileName (
               FileHandle,
               SECTION_NAME_DECOMPRESS_BASIC_TEST,
               Index,
               &CompressedFileName
               );

    if (EFI_ERROR(Status)) {
      Print (L"Get CompressedFileName Error\r\n");
      continue;
    }

    Status = GetUncompressedFileName (
               FileHandle,
               SECTION_NAME_DECOMPRESS_BASIC_TEST,
               Index,
               &UncompressedFileName
               );

    if (EFI_ERROR(Status)) {
      gtBS->FreePool (CompressedFileName);
      Print (L"Get UncompressedFileName Error\r\n");
      continue;
    }

    //
    //Open the Compressed file and get file size.
    //
    Status = OpenFileAndGetSize (
               CompressedFileName,
               &CompressedFHandle,
               &CompressedFileSize
               );

    if (EFI_ERROR(Status)) {
      Print (L"Can not open the File :%s\r\n", CompressedFileName);
      gtBS->FreePool (CompressedFileName);
      gtBS->FreePool (UncompressedFileName);
      continue;
    }
    gtBS->FreePool (CompressedFileName);

    //
    //Open the Uncompressed file and get file size.
    //
    Status = OpenFileAndGetSize (
               UncompressedFileName,
               &UncompressedFHandle,
               &UncompressedFileSize
               );

    if (EFI_ERROR(Status)) {
      Print (L"Can not open the File :%s\r\n", UncompressedFileName);
      CompressedFHandle->Close (CompressedFHandle);
      gtBS->FreePool (UncompressedFileName);
      continue;
    }
    gtBS->FreePool (UncompressedFileName);

    //
    //then read the Compressed File into memory.
    //
    CompressedFileBuffer = AllocatePool (CompressedFileSize);

    if (CompressedFileBuffer == NULL) {
      CompressedFHandle->Close (CompressedFHandle);
      UncompressedFHandle->Close (UncompressedFHandle);
      Print (L"Can not allocate %xh buffer.\r\n", CompressedFileSize);
      continue;
    }

    BufferSize = CompressedFileSize;

    Status = CompressedFHandle->Read (
                                  CompressedFHandle,
                                  &BufferSize,
                                  CompressedFileBuffer
                                  );

    CompressedFHandle->Close (CompressedFHandle);

    if (EFI_ERROR(Status)) {
      UncompressedFHandle->Close (UncompressedFHandle);
      Print (L"File Read Error Status %r\r\n", Status);
      gtBS->FreePool (CompressedFileBuffer);
      continue;
    }

    if (UncompressedFileSize == 0) {

      UncompressedFHandle->Close (UncompressedFHandle);

      Status = Decompress->GetInfo (
                             Decompress,
                             CompressedFileBuffer,
                             CompressedFileSize,
                             &DestinationSize,
                             &ScratchSize
                             );

      if (Status == EFI_SUCCESS) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gTestGenericFailureGuid,
                     L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - return Status Should be EFI_SUCCESS",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     __LINE__,
                     Status
                     );

      if (DestinationSize == 0) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gTestGenericFailureGuid,
                     L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - the Destination Size should be equal with the Uncompressed File Size",
                     L"%a:%d:destination Size - %d, Uncompressed File Size - %d",
                     __FILE__,
                     __LINE__,
                     (UINT32)DestinationSize,
                     (UINT32)UncompressedFileSize
                     );


      //
      // Fill the buffer with 0x00, and check whether the buffer is changed later
      //
      DecompressBuffer = AllocateZeroPool (128);

      if (DecompressBuffer == NULL) {
        gtBS->FreePool (CompressedFileBuffer);
        Print (L"Can not allocate %xh buffer.\r\n", 128);
        continue;
      }

      ScratchBuffer = AllocatePool (ScratchSize);

      if (ScratchBuffer == NULL) {
        gtBS->FreePool (CompressedFileBuffer);
        gtBS->FreePool (DecompressBuffer);
        Print (L"Can not allocate %xh buffer.\r\n", ScratchSize);
        continue;
      }

      Status = Decompress->Decompress (
                             Decompress,
                             CompressedFileBuffer,
                             CompressedFileSize,
                             DecompressBuffer,
                             DestinationSize,
                             ScratchBuffer,
                             ScratchSize
                             );

      if (!EFI_ERROR(Status)) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gDecompressBBTestFunctionAssertionGuid007,
                     L"EFI_DECOMPRESS_PROTOCOL.Decompess() - decompress zero file, return Status should be EFI_SUCCESS",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     __LINE__,
                     Status
                     );

      AssertionType = EFI_TEST_ASSERTION_PASSED;

      //
      // Check whether the buffer is changed
      //
      for (SubIndex = 0; SubIndex < 128; SubIndex++) {
        if (DecompressBuffer[SubIndex] != (UINT8)0x00) {
          AssertionType = EFI_TEST_ASSERTION_FAILED;
          break;
        }
      }
      SubIndex = (SubIndex < 127) ? SubIndex : 127;
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gDecompressBBTestFunctionAssertionGuid008,
                     L"EFI_DECOMPRESS_PROTOCOL.Decompess() - Decompressed zero length file, the buffer should not be modified",
                     L"%a:%d:buffer - 0x%02x, expected - 0x00",
                     __FILE__,
                     __LINE__,
                     DecompressBuffer[SubIndex]
                     );

      //
      // Fill the buffer with 0xff, and check whether the buffer is changed later
      //
      for (SubIndex = 0; SubIndex < 128; SubIndex++) {
        DecompressBuffer[SubIndex] = (UINT8)0xff;
      }

      Status = Decompress->Decompress (
                             Decompress,
                             CompressedFileBuffer,
                             CompressedFileSize,
                             DecompressBuffer,
                             DestinationSize,
                             ScratchBuffer,
                             ScratchSize
                             );

      if (!EFI_ERROR(Status)) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gDecompressBBTestFunctionAssertionGuid007,
                     L"EFI_DECOMPRESS_PROTOCOL.Decompess() - decompress zero file, return Status should be EFI_SUCCESS",
                     L"%a:%d:Status - %r",
                     __FILE__,
                     __LINE__,
                     Status
                     );

      AssertionType = EFI_TEST_ASSERTION_PASSED;

      //
      // Check whether the buffer is changed
      //
      for (SubIndex = 0; SubIndex < 128; SubIndex++) {
        if (DecompressBuffer[SubIndex] != (UINT8)0xff) {
          AssertionType = EFI_TEST_ASSERTION_FAILED;
          break;
        }
      }
      SubIndex = (SubIndex < 127) ? SubIndex : 127;
      //
      //record assertion
      //
      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gDecompressBBTestFunctionAssertionGuid008,
                     L"EFI_DECOMPRESS_PROTOCOL.Decompess() - Decompressed zero length file, the buffer should not be modified",
                     L"%a:%d:buffer - 0x%02x, expected - 0xff",
                     __FILE__,
                     __LINE__,
                     DecompressBuffer[SubIndex]
                     );

      //
      //free the resources.
      //
      gtBS->FreePool (CompressedFileBuffer);
      gtBS->FreePool (DecompressBuffer);
      gtBS->FreePool (ScratchBuffer);
      continue;
    }

    //
    //the Uncompressed file is not null so read it into memory.
    //
    UncompressedFileBuffer = AllocatePool (UncompressedFileSize);

    if (UncompressedFileBuffer == NULL) {
      UncompressedFHandle->Close (UncompressedFHandle);
      gtBS->FreePool (CompressedFileBuffer);
      Print (L"Can not alloate %xh buffer.\r\n", UncompressedFileSize);
      continue;
    }

    BufferSize = UncompressedFileSize;

    Status = UncompressedFHandle->Read (
                                    UncompressedFHandle,
                                    &BufferSize,
                                    UncompressedFileBuffer
                                    );

    UncompressedFHandle->Close (UncompressedFHandle);

    if (EFI_ERROR(Status)) {
      gtBS->FreePool (CompressedFileBuffer);
      gtBS->FreePool (UncompressedFileBuffer);
      Print (L"File Read Error Status %r\r\n", Status);
      continue;
    }

    //
    //now verify the check points.
    //

    Status = Decompress->GetInfo (
                           Decompress,
                           CompressedFileBuffer,
                           CompressedFileSize,
                           &DestinationSize,
                           &ScratchSize
                           );

    if (Status == EFI_SUCCESS) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gTestGenericFailureGuid,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - return Status should be EFI_SUCCESS",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );

    if (DestinationSize == UncompressedFileSize) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gTestGenericFailureGuid,
                   L"EFI_DECOMPRESS_PROTOCOL.GetInfo() - the Destination Size should be equal with the Uncompressed File Size",
                   L"%a:%d:destination Size - %d, Uncompressed File Size - %d",
                   __FILE__,
                   __LINE__,
                   (UINT32)DestinationSize,
                   (UINT32)UncompressedFileSize
                   );

    //
    //allocate Decompess buffer and Decompress the compessed data.
    //
    DecompressBuffer = AllocatePool (DestinationSize);
    if (DecompressBuffer == NULL) {
      gtBS->FreePool (CompressedFileBuffer);
      gtBS->FreePool (UncompressedFileBuffer);
      Print (L"Can not allocate %xh buffer.\r\n", DestinationSize);
      continue;
    }

    ScratchBuffer = AllocatePool (ScratchSize);
    if (ScratchBuffer == NULL) {
      gtBS->FreePool (CompressedFileBuffer);
      gtBS->FreePool (UncompressedFileBuffer);
      gtBS->FreePool (DecompressBuffer);
      Print (L"Can not allocate %xh buffer.\r\n", ScratchSize);
      continue;
    }

    Status = Decompress->Decompress (
                           Decompress,
                           CompressedFileBuffer,
                           CompressedFileSize,
                           DecompressBuffer,
                           DestinationSize,
                           ScratchBuffer,
                           ScratchSize
                           );

    if (!EFI_ERROR(Status)) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gDecompressBBTestFunctionAssertionGuid009,
                   L"EFI_DECOMPRESS_PROTOCOL.Decompess() - decompress unzero file, return Status should be EFI_SUCCESS",
                   L"%a:%d:Status - %r",
                   __FILE__,
                   __LINE__,
                   Status
                   );
    if (CompareMem (DecompressBuffer,
                    UncompressedFileBuffer, UncompressedFileSize) == 0) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }
    //
    //record assertion
    //
    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gDecompressBBTestFunctionAssertionGuid010,
                   L"EFI_DECOMPRESS_PROTOCOL.Decompess() - Decompressed data should be equal with Uncompressed data",
                   L"%a:%d",
                   __FILE__,
                   __LINE__
                   );

    //
    //free the resources
    //
    gtBS->FreePool (CompressedFileBuffer);
    gtBS->FreePool (UncompressedFileBuffer);
    gtBS->FreePool (DecompressBuffer);
    gtBS->FreePool (ScratchBuffer);
  }

  CloseTestIniFile (ProfileLib, FileHandle);

  //
  //done successfully
  //
  return EFI_SUCCESS;
}