Beispiel #1
0
void emAvFileModel::PlaySolely()
{
	if (GetFileState()!=FS_LOADED) return;
	while (ActiveList->Var && ActiveList->Var!=this) ActiveList->Var->Stop();
	while (ALNext) ALNext->Stop();
	Play();
}
Beispiel #2
0
void emAvFileModel::StreamStateChanged(StreamStateType streamState)
{
	emString str;

	if (streamState==STREAM_ERRORED && GetFileState()==FS_LOADED) {
		str=GetStreamErrorText();
		if (ErrorText!=str) {
			ErrorText=str;
			Signal(InfoSignal);
		}
		if (PlayState!=PS_STOPPED) {
			RemoveFromActiveList();
			PlayState=PS_STOPPED;
			Signal(PlayStateSignal);
		}
		if (PlayPos!=0) {
			PlayPos=0;
			Signal(PlayPosSignal);
		}
		if (!Image.IsEmpty()) {
			Image.Empty();
			Signal(ImageSignal);
		}
		SaveFileState();
	}
}
Beispiel #3
0
/**
  Check if it's a valid FFS file header.

  @param  ErasePolarity  Erase polarity attribute of the firmware volume
  @param  FfsHeader      Points to the FFS file header to be checked
  @param  FileState      FFS file state to be returned

  @retval TRUE           Valid FFS file header
  @retval FALSE          Invalid FFS file header

**/
BOOLEAN
IsValidFfsHeader (
  IN UINT8                ErasePolarity,
  IN EFI_FFS_FILE_HEADER  *FfsHeader,
  OUT EFI_FFS_FILE_STATE  *FileState
  )
{
  *FileState = GetFileState (ErasePolarity, FfsHeader);

  switch (*FileState) {
  case EFI_FILE_HEADER_VALID:
  case EFI_FILE_DATA_VALID:
  case EFI_FILE_MARKED_FOR_UPDATE:
  case EFI_FILE_DELETED:
    //
    // Here we need to verify header checksum
    //
    return VerifyHeaderChecksum (FfsHeader);

  case EFI_FILE_HEADER_CONSTRUCTION:
  case EFI_FILE_HEADER_INVALID:
  default:
    return FALSE;
  }
}
Beispiel #4
0
static WatchedFile* NewWatchedFile(const WCHAR* filePath, const std::function<void()>& onFileChangedCb) {
    bool isManualCheck = PathIsNetworkPath(filePath);
    AutoFreeW dirPath(path::GetDir(filePath));
    WatchedDir* wd = nullptr;
    bool newDir = false;
    if (!isManualCheck) {
        wd = FindExistingWatchedDir(dirPath);
        if (!wd) {
            wd = NewWatchedDir(dirPath);
            if (!wd)
                return nullptr;
            newDir = true;
        }
    }

    WatchedFile* wf = AllocStruct<WatchedFile>();
    wf->filePath = str::Dup(filePath);
    wf->onFileChangedCb = onFileChangedCb;
    wf->watchedDir = wd;
    wf->isManualCheck = isManualCheck;

    ListInsert(&g_watchedFiles, wf);

    if (wf->isManualCheck) {
        GetFileState(filePath, &wf->fileState);
        AwakeWatcherThread();
    } else {
        if (newDir)
            StartMonitoringDirForChanges(wf->watchedDir);
    }

    return wf;
}
Beispiel #5
0
/**
  Check if it's a valid FFS file.
  Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.

  @param  ErasePolarity  Erase polarity attribute of the firmware volume
  @param  FfsHeader      Points to the FFS file to be checked

  @retval TRUE           Valid FFS file
  @retval FALSE          Invalid FFS file

**/
BOOLEAN
IsValidFfsFile (
  IN UINT8                ErasePolarity,
  IN EFI_FFS_FILE_HEADER  *FfsHeader
  )
{
  EFI_FFS_FILE_STATE  FileState;
  UINT8               DataCheckSum;

  FileState = GetFileState (ErasePolarity, FfsHeader);
  switch (FileState) {

  case EFI_FILE_DELETED:
  case EFI_FILE_DATA_VALID:
  case EFI_FILE_MARKED_FOR_UPDATE:
    DataCheckSum = FFS_FIXED_CHECKSUM;
    if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
      if (IS_FFS_FILE2 (FfsHeader)) {
        DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER2));
      } else {
        DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER));
      }
    }
    if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) {
      return TRUE;
    }

  default:
    return FALSE;
  }
}
static WatchedFile *NewWatchedFile(const WCHAR *filePath, FileChangeObserver *observer)
{
    bool isManualCheck = PathIsNetworkPath(filePath);
    ScopedMem<WCHAR> dirPath(path::GetDir(filePath));
    WatchedDir *wd = nullptr;
    bool newDir = false;
    if (!isManualCheck) {
        wd = FindExistingWatchedDir(dirPath);
        if (!wd) {
            wd = NewWatchedDir(dirPath);
            if (!wd)
                return nullptr;
            newDir = true;
        }
    }

    WatchedFile *wf = AllocStruct<WatchedFile>();
    wf->filePath = str::Dup(filePath);
    wf->observer = observer;
    wf->watchedDir = wd;
    wf->isManualCheck = isManualCheck;

    ListInsert(&g_watchedFiles, wf);

    if (wf->isManualCheck) {
        GetFileState(filePath, &wf->fileState);
        AwakeWatcherThread();
    } else {
        if (newDir)
            StartMonitoringDirForChanges(wf->watchedDir);
    }

    return wf;
}
Beispiel #7
0
void emAvFileModel::SetAudioMute(bool audioMute)
{
	if (GetFileState()!=FS_LOADED) return;
	if (AudioMute!=audioMute) {
		AudioMute=audioMute;
		Signal(AdjustmentSignal);
		SetProperty("audio_mute",AudioMute?"on":"off");
	}
}
Beispiel #8
0
static bool FileStateChanged(const WCHAR* filePath, FileState* fs) {
    FileState fsTmp;

    GetFileState(filePath, &fsTmp);
    if (FileStateEq(fs, &fsTmp))
        return false;

    memcpy(fs, &fsTmp, sizeof(*fs));
    return true;
}
Beispiel #9
0
void emAvFileModel::SetAudioVolume(int audioVolume)
{
	if (GetFileState()!=FS_LOADED) return;
	if (audioVolume<0) audioVolume=0;
	if (audioVolume>100) audioVolume=100;
	if (AudioVolume!=audioVolume) {
		AudioVolume=audioVolume;
		Signal(AdjustmentSignal);
		SetProperty("audio_volume",emString::Format("%d",AudioVolume));
	}
	SaveAudioVolume();
}
Beispiel #10
0
void emAvFileModel::SetPlayPos(int playPos)
{
	if (GetFileState()!=FS_LOADED) return;
	if (playPos<0) playPos=0;
	if (playPos>PlayLength) playPos=PlayLength;
	if (PlayPos!=playPos) {
		if (PlayState==PS_STOPPED) Pause();
		PlayPos=playPos;
		Signal(PlayPosSignal);
		SetProperty("pos",emString::Format("%d",PlayPos));
	}
	SaveFileState();
}
Beispiel #11
0
void emAvFileModel::SetPlayState(PlayStateType playState)
{
	if (GetFileState()!=FS_LOADED) return;
	if (PlayState==playState) return;

	PlayState=playState;
	Signal(PlayStateSignal);

	if (PlayState==PS_STOPPED) {
		RemoveFromActiveList();
		CloseStream();
		PlayPos=0;
		Signal(PlayPosSignal);
		Image.Empty();
		Signal(ImageSignal);
	}
	else {
		AddToActiveList();
		if (GetStreamState()!=STREAM_OPENING && GetStreamState()!=STREAM_OPENED) {
			if (!WarningText.IsEmpty() || !ErrorText.IsEmpty()) {
				WarningText.Empty();
				ErrorText.Empty();
				Signal(InfoSignal);
			}
			OpenStream("auto","emAv",GetFilePath());
			SetProperty("audio_volume",emString::Format("%d",AudioVolume));
			SetProperty("audio_mute",AudioMute?"on":"off");
			if (AudioVisu>=0 && AudioVisu<AudioVisus.GetCount()) {
				SetProperty("audio_visu",AudioVisus[AudioVisu].Get());
			}
			SetProperty("pos",emString::Format("%d",PlayPos));
#if 0 // ??? This did not function.
			if (AudioChannel>=0 && AudioChannel<AudioChannels.GetCount()) {
				SetProperty("audio_channel",AudioChannels[AudioChannel].Get());
			}
			if (SpuChannel>=0 && SpuChannel<SpuChannels.GetCount()) {
				SetProperty("spu_channel",SpuChannels[SpuChannel].Get());
			}
#endif
		}
		SetProperty(
			"state",
			PlayState==PS_PAUSED ? "paused" :
			PlayState==PS_SLOW ? "slow" :
			PlayState==PS_FAST ? "fast" :
			"normal"
		);
	}
	SaveFileState();
}
Beispiel #12
0
void emAvFileModel::SetSpuChannel(int spuChannel)
{
	int n;

	if (GetFileState()!=FS_LOADED) return;
	n=SpuChannels.GetCount();
	if (n>0) {
		if (spuChannel<0) spuChannel=0;
		if (spuChannel>=n) spuChannel=n-1;
		if (SpuChannel!=spuChannel) {
			SpuChannel=spuChannel;
			Signal(AdjustmentSignal);
			SetProperty("spu_channel",SpuChannels[spuChannel].Get());
		}
	}
	SaveFileState();
}
Beispiel #13
0
void emAvFileModel::SetAudioChannel(int audioChannel)
{
	int n;

	if (GetFileState()!=FS_LOADED) return;
	n=AudioChannels.GetCount();
	if (n>0) {
		if (audioChannel<0) audioChannel=0;
		if (audioChannel>=n) audioChannel=n-1;
		if (AudioChannel!=audioChannel) {
			AudioChannel=audioChannel;
			Signal(AdjustmentSignal);
			SetProperty("audio_channel",AudioChannels[audioChannel].Get());
		}
	}
	SaveFileState();
}
Beispiel #14
0
void emAvFileModel::SetAudioVisu(int audioVisu)
{
	int n;

	if (GetFileState()!=FS_LOADED) return;
	n=AudioVisus.GetCount();
	if (n>0) {
		if (audioVisu<0) audioVisu=0;
		if (audioVisu>=n) audioVisu=n-1;
		if (AudioVisu!=audioVisu) {
			AudioVisu=audioVisu;
			Signal(AdjustmentSignal);
			SetProperty("audio_visu",AudioVisus[audioVisu].Get());
		}
	}
	SaveAudioVisu();
}
Beispiel #15
0
/**
  Check if an FV is consistent and allocate cache for it.

  @param  FvDevice              A pointer to the FvDevice to be checked.

  @retval EFI_OUT_OF_RESOURCES  No enough buffer could be allocated.
  @retval EFI_SUCCESS           FV is consistent and cache is allocated.
  @retval EFI_VOLUME_CORRUPTED  File system is corrupted.

**/
EFI_STATUS
FvCheck (
  IN OUT FV_DEVICE  *FvDevice
  )
{
  EFI_STATUS                            Status;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;
  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;
  EFI_FIRMWARE_VOLUME_EXT_HEADER        *FwVolExtHeader;
  EFI_FVB_ATTRIBUTES_2                  FvbAttributes;
  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;
  FFS_FILE_LIST_ENTRY                   *FfsFileEntry;
  EFI_FFS_FILE_HEADER                   *FfsHeader;
  UINT8                                 *CacheLocation;
  UINTN                                 LbaOffset;
  UINTN                                 HeaderSize;
  UINTN                                 Index;
  EFI_LBA                               LbaIndex;
  UINTN                                 Size;
  EFI_FFS_FILE_STATE                    FileState;
  UINT8                                 *TopFvAddress;
  UINTN                                 TestLength;
  EFI_PHYSICAL_ADDRESS                  PhysicalAddress;
  BOOLEAN                               FileCached;
  UINTN                                 WholeFileSize;
  EFI_FFS_FILE_HEADER                   *CacheFfsHeader;

  FileCached = FALSE;
  CacheFfsHeader = NULL;

  Fvb = FvDevice->Fvb;
  FwVolHeader = FvDevice->FwVolHeader;

  Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Size is the size of the FV minus the head. We have already allocated
  // the header to check to make sure the volume is valid
  //
  Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);
  if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
    FvDevice->IsMemoryMapped = TRUE;

    Status = Fvb->GetPhysicalAddress (Fvb, &PhysicalAddress);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Don't cache memory mapped FV really.
    //
    FvDevice->CachedFv = (UINT8 *) (UINTN) (PhysicalAddress + FwVolHeader->HeaderLength);
  } else {
    FvDevice->IsMemoryMapped = FALSE;
    FvDevice->CachedFv = AllocatePool (Size);

    if (FvDevice->CachedFv == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  //
  // Remember a pointer to the end fo the CachedFv
  //
  FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;

  if (!FvDevice->IsMemoryMapped) {
    //
    // Copy FV minus header into memory using the block map we have all ready
    // read into memory.
    //
    BlockMap = FwVolHeader->BlockMap;
    CacheLocation = FvDevice->CachedFv;
    LbaIndex = 0;
    LbaOffset = 0;
    HeaderSize = FwVolHeader->HeaderLength;
    while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
      Index = 0;
      Size  = BlockMap->Length;
      if (HeaderSize > 0) {
        //
        // Skip header size
        //
        for (; Index < BlockMap->NumBlocks && HeaderSize >= BlockMap->Length; Index ++) {
          HeaderSize -= BlockMap->Length;
          LbaIndex ++;
        }

        //
        // Check whether FvHeader is crossing the multi block range.
        //
        if (Index >= BlockMap->NumBlocks) {
          BlockMap++;
          continue;
        } else if (HeaderSize > 0) {
          LbaOffset = HeaderSize;
          Size = BlockMap->Length - HeaderSize;
          HeaderSize = 0;
        }
      }
    
      //
      // read the FV data  
      //
      for (; Index < BlockMap->NumBlocks; Index ++) {
        Status = Fvb->Read (Fvb,
                        LbaIndex,
                        LbaOffset,
                        &Size,
                        CacheLocation
                        );

        //
        // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length
        //
        if (EFI_ERROR (Status)) {
          goto Done;
        }

        LbaIndex++;
        CacheLocation += Size;

        //
        // After we skip Fv Header always read from start of block
        //
        LbaOffset = 0;
        Size  = BlockMap->Length;
      }

      BlockMap++;
    }
  }

  //
  // Scan to check the free space & File list
  //
  if ((FvbAttributes & EFI_FVB2_ERASE_POLARITY) != 0) {
    FvDevice->ErasePolarity = 1;
  } else {
    FvDevice->ErasePolarity = 0;
  }


  //
  // go through the whole FV cache, check the consistence of the FV.
  // Make a linked list of all the Ffs file headers
  //
  Status = EFI_SUCCESS;
  InitializeListHead (&FvDevice->FfsFileListHeader);

  //
  // Build FFS list
  //
  if (FwVolHeader->ExtHeaderOffset != 0) {
    //
    // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
    //
    FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) (FvDevice->CachedFv + (FwVolHeader->ExtHeaderOffset - FwVolHeader->HeaderLength));
    FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);
    FfsHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsHeader, 8);
  } else {
    FfsHeader = (EFI_FFS_FILE_HEADER *) (FvDevice->CachedFv);
  }
  TopFvAddress = FvDevice->EndOfCachedFv;
  while (((UINTN) FfsHeader >= (UINTN) FvDevice->CachedFv) && ((UINTN) FfsHeader <= (UINTN) ((UINTN) TopFvAddress - sizeof (EFI_FFS_FILE_HEADER)))) {

    if (FileCached) {
      CoreFreePool (CacheFfsHeader);
      FileCached = FALSE;
    }

    TestLength = TopFvAddress - ((UINT8 *) FfsHeader);
    if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
      TestLength = sizeof (EFI_FFS_FILE_HEADER);
    }

    if (IsBufferErased (FvDevice->ErasePolarity, FfsHeader, TestLength)) {
      //
      // We have found the free space so we are done!
      //
      goto Done;
    }

    if (!IsValidFfsHeader (FvDevice->ErasePolarity, FfsHeader, &FileState)) {
      if ((FileState == EFI_FILE_HEADER_INVALID) ||
          (FileState == EFI_FILE_HEADER_CONSTRUCTION)) {
        if (IS_FFS_FILE2 (FfsHeader)) {
          if (!FvDevice->IsFfs3Fv) {
            DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsHeader->Name));
          }
          FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2));
        } else {
          FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER));
        }
        continue;
      } else {
        //
        // File system is corrputed
        //
        Status = EFI_VOLUME_CORRUPTED;
        goto Done;
      }
    }

    CacheFfsHeader = FfsHeader;
    if ((CacheFfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
      if (FvDevice->IsMemoryMapped) {
        //
        // Memory mapped FV has not been cached.
        // Here is to cache FFS file to memory buffer for following checksum calculating.
        // And then, the cached file buffer can be also used for FvReadFile.
        //
        WholeFileSize = IS_FFS_FILE2 (CacheFfsHeader) ? FFS_FILE2_SIZE (CacheFfsHeader): FFS_FILE_SIZE (CacheFfsHeader);
        CacheFfsHeader = AllocateCopyPool (WholeFileSize, CacheFfsHeader);
        if (CacheFfsHeader == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Done;
        }
        FileCached = TRUE;
      }
    }

    if (!IsValidFfsFile (FvDevice->ErasePolarity, CacheFfsHeader)) {
      //
      // File system is corrupted
      //
      Status = EFI_VOLUME_CORRUPTED;
      goto Done;
    }

    if (IS_FFS_FILE2 (CacheFfsHeader)) {
      ASSERT (FFS_FILE2_SIZE (CacheFfsHeader) > 0x00FFFFFF);
      if (!FvDevice->IsFfs3Fv) {
        DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &CacheFfsHeader->Name));
        FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (CacheFfsHeader));
        //
        // Adjust pointer to the next 8-byte aligned boundry.
        //
        FfsHeader = (EFI_FFS_FILE_HEADER *) (((UINTN) FfsHeader + 7) & ~0x07);
        continue;
      }
    }

    FileState = GetFileState (FvDevice->ErasePolarity, CacheFfsHeader);

    //
    // check for non-deleted file
    //
    if (FileState != EFI_FILE_DELETED) {
      //
      // Create a FFS list entry for each non-deleted file
      //
      FfsFileEntry = AllocateZeroPool (sizeof (FFS_FILE_LIST_ENTRY));
      if (FfsFileEntry == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      FfsFileEntry->FfsHeader = CacheFfsHeader;
      FfsFileEntry->FileCached = FileCached;
      FileCached = FALSE;
      InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);
    }

    if (IS_FFS_FILE2 (CacheFfsHeader)) {
      FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (CacheFfsHeader));
    } else {
      FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE_SIZE (CacheFfsHeader));
    }

    //
    // Adjust pointer to the next 8-byte aligned boundry.
    //
    FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINTN)FfsHeader + 7) & ~0x07);

  }

Done:
  if (EFI_ERROR (Status)) {
    if (FileCached) {
      CoreFreePool (CacheFfsHeader);
      FileCached = FALSE;
    }
    FreeFvDeviceResource (FvDevice);
  }

  return Status;
}
EFI_STATUS
GetFfsFile (
  IN  EFI_FIRMWARE_VOLUME_HEADER           *FwVolHeader,
  IN  EFI_FV_FILETYPE                      FileType,
  OUT EFI_FFS_FILE_HEADER                  **FileHeader
  )
{
  UINT64                                FvLength;
  UINTN                                 FileOffset;
  EFI_FFS_FILE_HEADER                   *FfsFileHeader;
  UINT8                                 ErasePolarity;
  UINT8                                 FileState;
  UINT32                                FileLength;
  UINT32                                FileOccupiedSize;

  ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);

  FvLength = FwVolHeader->FvLength;
  FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
  FileOffset = FwVolHeader->HeaderLength;

  if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
    ErasePolarity = 1;
  } else {
    ErasePolarity = 0;
  }

  while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
    // Get FileState which is the highest bit of the State
    FileState = GetFileState (ErasePolarity, FfsFileHeader);

    switch (FileState) {

    case EFI_FILE_HEADER_INVALID:
      FileOffset += sizeof(EFI_FFS_FILE_HEADER);
      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
      break;

    case EFI_FILE_DATA_VALID:
    case EFI_FILE_MARKED_FOR_UPDATE:
      if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
        ASSERT (FALSE);
        return EFI_NOT_FOUND;
      }

      if (FfsFileHeader->Type == FileType) {
        *FileHeader = FfsFileHeader;
        return EFI_SUCCESS;
      }

      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);

      FileOffset += FileOccupiedSize;
      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
      break;

    case EFI_FILE_DELETED:
      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
      FileOffset += FileOccupiedSize;
      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
      break;

    default:
      return EFI_NOT_FOUND;
    }
  }
  return EFI_NOT_FOUND;
}
Beispiel #17
0
/**
  Check if an FV is consistent and allocate cache for it.

  @param  FvDevice              A pointer to the FvDevice to be checked.

  @retval EFI_OUT_OF_RESOURCES  No enough buffer could be allocated.
  @retval EFI_VOLUME_CORRUPTED  File system is corrupted.
  @retval EFI_SUCCESS           FV is consistent and cache is allocated.

**/
EFI_STATUS
FvCheck (
  IN FV_DEVICE  *FvDevice
  )
{
  EFI_STATUS                          Status;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  EFI_FVB_ATTRIBUTES_2                FvbAttributes;
  EFI_FV_BLOCK_MAP_ENTRY              *BlockMap;
  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;
  EFI_FIRMWARE_VOLUME_EXT_HEADER      *FwVolExtHeader;
  UINT8                               *FwCache;
  LBA_ENTRY                           *LbaEntry;
  FREE_SPACE_ENTRY                    *FreeSpaceEntry;
  FFS_FILE_LIST_ENTRY                 *FfsFileEntry;
  UINT8                               *LbaStart;
  UINTN                               Index;
  EFI_LBA                             LbaIndex;
  UINT8                               *Ptr;
  UINTN                               Size;
  UINT8                               *FreeStart;
  UINTN                               FreeSize;
  UINT8                               ErasePolarity;
  EFI_FFS_FILE_STATE                  FileState;
  UINT8                               *TopFvAddress;
  UINTN                               TestLength;
  EFI_PHYSICAL_ADDRESS                BaseAddress;

  Fvb     = FvDevice->Fvb;

  Status  = Fvb->GetAttributes (Fvb, &FvbAttributes);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  InitializeListHead (&FvDevice->LbaHeader);
  InitializeListHead (&FvDevice->FreeSpaceHeader);
  InitializeListHead (&FvDevice->FfsFileListHeader);

  FwVolHeader = NULL;
  Status = GetFwVolHeader (Fvb, &FwVolHeader);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  ASSERT (FwVolHeader != NULL);

  FvDevice->IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);

  //
  // Double Check firmware volume header here
  //
  if (!VerifyFvHeaderChecksum (FwVolHeader)) {
    FreePool (FwVolHeader);
    return EFI_VOLUME_CORRUPTED;
  }

  BlockMap = FwVolHeader->BlockMap;

  //
  // FwVolHeader->FvLength is the whole FV length including FV header
  //
  FwCache = AllocateZeroPool ((UINTN) FwVolHeader->FvLength);
  if (FwCache == NULL) {
    FreePool (FwVolHeader);
    return EFI_OUT_OF_RESOURCES;
  }

  FvDevice->CachedFv = (EFI_PHYSICAL_ADDRESS) (UINTN) FwCache;

  //
  // Copy to memory
  //
  LbaStart  = FwCache;
  LbaIndex  = 0;
  Ptr       = NULL;

  if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
    //
    // Get volume base address
    //
    Status = Fvb->GetPhysicalAddress (Fvb, &BaseAddress);
    if (EFI_ERROR (Status)) {
      FreePool (FwVolHeader);
      return Status;
    }

    Ptr = (UINT8 *) ((UINTN) BaseAddress);

    DEBUG((EFI_D_INFO, "Fv Base Address is 0x%LX\n", BaseAddress));
  }
  //
  // Copy whole FV into the memory
  //
  while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {

    for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
      LbaEntry = AllocatePool (sizeof (LBA_ENTRY));
      if (LbaEntry == NULL) {
        FreePool (FwVolHeader);
        FreeFvDeviceResource (FvDevice);
        return EFI_OUT_OF_RESOURCES;
      }

      LbaEntry->LbaIndex        = LbaIndex;
      LbaEntry->StartingAddress = LbaStart;
      LbaEntry->BlockLength     = BlockMap->Length;

      //
      // Copy each LBA into memory
      //
      if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {

        CopyMem (LbaStart, Ptr, BlockMap->Length);
        Ptr += BlockMap->Length;

      } else {

        Size = BlockMap->Length;
        Status = Fvb->Read (
                        Fvb,
                        LbaIndex,
                        0,
                        &Size,
                        LbaStart
                        );
        //
        // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length
        //
        if (EFI_ERROR (Status)) {
          FreePool (FwVolHeader);
          FreeFvDeviceResource (FvDevice);
          return Status;
        }

      }

      LbaIndex++;
      LbaStart += BlockMap->Length;

      InsertTailList (&FvDevice->LbaHeader, &LbaEntry->Link);
    }

    BlockMap++;
  }

  FvDevice->FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FwCache;

  //
  // it is not used any more, so free FwVolHeader
  //
  FreePool (FwVolHeader);

  //
  // Scan to check the free space & File list
  //
  if ((FvbAttributes & EFI_FVB2_ERASE_POLARITY) != 0) {
    ErasePolarity = 1;
  } else {
    ErasePolarity = 0;
  }

  FvDevice->ErasePolarity = ErasePolarity;

  //
  // go through the whole FV cache, check the consistence of the FV
  //
  if (FvDevice->FwVolHeader->ExtHeaderOffset != 0) {
    //
    // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
    //
    FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) (UINTN) (FvDevice->CachedFv + FvDevice->FwVolHeader->ExtHeaderOffset);
    Ptr = (UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize;
    Ptr = (UINT8 *) ALIGN_POINTER (Ptr, 8);
  } else {
    Ptr = (UINT8 *) (UINTN) (FvDevice->CachedFv + FvDevice->FwVolHeader->HeaderLength);
  }
  TopFvAddress = (UINT8 *) (UINTN) (FvDevice->CachedFv + FvDevice->FwVolHeader->FvLength);

  //
  // Build FFS list & Free Space List here
  //
  while (Ptr < TopFvAddress) {
    TestLength = TopFvAddress - Ptr;

    if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
      TestLength = sizeof (EFI_FFS_FILE_HEADER);
    }

    if (IsBufferErased (ErasePolarity, Ptr, TestLength)) {
      //
      // We found free space
      //
      FreeStart = Ptr;
      FreeSize  = 0;

      do {
        TestLength = TopFvAddress - Ptr;

        if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
          TestLength = sizeof (EFI_FFS_FILE_HEADER);
        }

        if (!IsBufferErased (ErasePolarity, Ptr, TestLength)) {
          break;
        }

        FreeSize += TestLength;
        Ptr += TestLength;
      } while (Ptr < TopFvAddress);

      FreeSpaceEntry = AllocateZeroPool (sizeof (FREE_SPACE_ENTRY));
      if (FreeSpaceEntry == NULL) {
        FreeFvDeviceResource (FvDevice);
        return EFI_OUT_OF_RESOURCES;
      }
      //
      // Create a Free space entry
      //
      FreeSpaceEntry->StartingAddress = FreeStart;
      FreeSpaceEntry->Length          = FreeSize;
      InsertTailList (&FvDevice->FreeSpaceHeader, &FreeSpaceEntry->Link);
      continue;
    }
    //
    // double check boundry
    //
    if (TestLength < sizeof (EFI_FFS_FILE_HEADER)) {
      break;
    }

    if (!IsValidFFSHeader (
          FvDevice->ErasePolarity,
          (EFI_FFS_FILE_HEADER *) Ptr
          )) {
      FileState = GetFileState (
                    FvDevice->ErasePolarity,
                    (EFI_FFS_FILE_HEADER *) Ptr
                    );
      if ((FileState == EFI_FILE_HEADER_INVALID) || (FileState == EFI_FILE_HEADER_CONSTRUCTION)) {
        if (IS_FFS_FILE2 (Ptr)) {
          if (!FvDevice->IsFfs3Fv) {
            DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name));
          }
          Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER2);
        } else {
          Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER);
        }

        continue;

      } else {
        //
        // File system is corrputed, return
        //
        FreeFvDeviceResource (FvDevice);
        return EFI_VOLUME_CORRUPTED;
      }
    }

    if (IS_FFS_FILE2 (Ptr)) {
      ASSERT (FFS_FILE2_SIZE (Ptr) > 0x00FFFFFF);
      if (!FvDevice->IsFfs3Fv) {
        DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name));
        Ptr = Ptr + FFS_FILE2_SIZE (Ptr);
        //
        // Adjust Ptr to the next 8-byte aligned boundry.
        //
        while (((UINTN) Ptr & 0x07) != 0) {
          Ptr++;
        }
        continue;
      }
    }

    if (IsValidFFSFile (FvDevice, (EFI_FFS_FILE_HEADER *) Ptr)) {
      FileState = GetFileState (
                    FvDevice->ErasePolarity,
                    (EFI_FFS_FILE_HEADER *) Ptr
                    );

      //
      // check for non-deleted file
      //
      if (FileState != EFI_FILE_DELETED) {
        //
        // Create a FFS list entry for each non-deleted file
        //
        FfsFileEntry = AllocateZeroPool (sizeof (FFS_FILE_LIST_ENTRY));
        if (FfsFileEntry == NULL) {
          FreeFvDeviceResource (FvDevice);
          return EFI_OUT_OF_RESOURCES;
        }

        FfsFileEntry->FfsHeader = Ptr;
        InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);
      }

      if (IS_FFS_FILE2 (Ptr)) {
        Ptr = Ptr + FFS_FILE2_SIZE (Ptr);
      } else {
        Ptr = Ptr + FFS_FILE_SIZE (Ptr);
      }

      //
      // Adjust Ptr to the next 8-byte aligned boundry.
      //
      while (((UINTN) Ptr & 0x07) != 0) {
        Ptr++;
      }
    } else {
      //
      // File system is corrupted, return
      //
      FreeFvDeviceResource (FvDevice);
      return EFI_VOLUME_CORRUPTED;
    }
  }

  FvDevice->CurrentFfsFile = NULL;

  return EFI_SUCCESS;
}
Beispiel #18
0
void emAvFileModel::PropertyChanged(const emString & name, const emString & value)
{
	PlayStateType ps;
	double d;
	bool b;
	int i;

	if (name=="type") {
		b=(value=="video");
		if (Video!=b) {
			Video=b;
			Signal(InfoSignal);
		}
	}
	else if (name=="length") {
		i=atoi(value);
		if (i<0) i=0;
		if (PlayLength!=i) {
			PlayLength=i;
			Signal(InfoSignal);
			if (PlayPos>PlayLength) {
				PlayPos=PlayLength;
				Signal(PlayPosSignal);
			}
		}
	}
	else if (name=="aspect") {
		i=atoi(value);
		if (i>0) {
			d=65536.0/i;
			if (Tallness!=d) {
				Tallness=d;
				Signal(ImageSignal);
			}
		}
	}
	else if (name=="info") {
		if (InfoText!=value) {
			InfoText=value;
			Signal(InfoSignal);
		}
	}
	else if (name=="warning") {
		if (WarningText!=value) {
			WarningText=value;
			Signal(InfoSignal);
		}
	}
	else if (name=="audio_visus") {
		if (UpdateStringArray(AudioVisus,value)) {
			Signal(InfoSignal);
			if (AudioVisu>=AudioVisus.GetCount()) {
				AudioVisu=0;
				Signal(AdjustmentSignal);
			}
		}
	}
	else if (name=="audio_channels") {
		if (UpdateStringArray(AudioChannels,value)) {
			Signal(InfoSignal);
			if (AudioChannel>=AudioChannels.GetCount()) {
				AudioChannel=0;
				Signal(AdjustmentSignal);
			}
		}
	}
	else if (name=="spu_channels") {
		if (UpdateStringArray(SpuChannels,value)) {
			Signal(InfoSignal);
			if (SpuChannel>=SpuChannels.GetCount()) {
				SpuChannel=0;
				Signal(AdjustmentSignal);
			}
		}
	}
	else if (name=="state") {
		if (value=="paused") ps=PS_PAUSED;
		else if (value=="normal") ps=PS_NORMAL;
		else if (value=="fast") ps=PS_FAST;
		else if (value=="slow") ps=PS_SLOW;
		else ps=PS_STOPPED;
		if (PlayState!=ps) {
			PlayState=ps;
			Signal(PlayStateSignal);
			if (ps==PS_STOPPED) RemoveFromActiveList();
			else AddToActiveList();
			if (PlayState==PS_STOPPED && GetFileState()==FS_LOADED) {
				CloseStream();
				PlayPos=0;
				Signal(PlayPosSignal);
				Image.Empty();
				Signal(ImageSignal);
			}
		}
	}
	else if (name=="pos") {
		i=atoi(value);
		if (i<0) i=0;
		if (i>PlayLength) i=PlayLength;
		if (PlayPos!=i) {
			PlayPos=i;
			Signal(PlayPosSignal);
			if (GetStreamState()==STREAM_OPENED) SaveFileState();
		}
	}
	else if (name=="audio_volume") {
		i=atoi(value);
		if (i<0) i=0;
		if (i>100) i=100;
		if (AudioVolume!=i) {
			AudioVolume=i;
			Signal(AdjustmentSignal);
		}
	}
	else if (name=="audio_mute") {
		b=(value=="on");
		if (AudioMute!=b) {
			AudioMute=b;
			Signal(AdjustmentSignal);
		}
	}
	else if (name=="audio_visu") {
		for (i=AudioVisus.GetCount()-1; i>=0; i--) {
			if (AudioVisus[i]==value) break;
		}
		if (i>=0 && AudioVisu!=i) {
			AudioVisu=i;
			Signal(AdjustmentSignal);
		}
	}
	else if (name=="audio_channel") {
		for (i=AudioChannels.GetCount()-1; i>=0; i--) {
			if (AudioChannels[i]==value) break;
		}
		if (i>=0 && AudioChannel!=i) {
			AudioChannel=i;
			Signal(AdjustmentSignal);
		}
	}
	else if (name=="spu_channel") {
		for (i=SpuChannels.GetCount()-1; i>=0; i--) {
			if (SpuChannels[i]==value) break;
		}
		if (i>=0 && SpuChannel!=i) {
			SpuChannel=i;
			Signal(AdjustmentSignal);
		}
	}
	else {
		emDLog(
			"emAvFileModel::PropertyChanged: Unsupported property name \"%s\".",
			name.Get()
		);
	}
}