⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesystem.c

📁 EFI(Extensible Firmware Interface)是下一代BIOS
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************
Copyright (c) 2005.12 Lenovo Corporation
All rights reserved.

Module Name:
    FileSystem.c    

Abstract:
	文件系统的操作系列函数

Author: WangZhe
Revision History

********************************************************/

#include "FileSystem.h"
#include "kwTools.h"
//#include <shell.h>

//INT32 FilePathLevel;//文件路径深度,为0时只可以看到驱动器


//列出文件系统
void ListFileSystem(struct _FileMgrControl *this)
{
    EFI_STATUS              Status;
    EFI_HANDLE              *HandleBuffer;
    EFI_FILE_IO_INTERFACE   *Vol;
    UINTN                   i,NoHandles;
    CHAR16 					MapName[MAX_FILEPATH_LENGTH];
    CHAR16 					LabelName[MAX_FILEPATH_LENGTH];
    FSITEM 					*fsitem;
    EFI_FILE_HANDLE RootFs;

    NoHandles = 0;
    HandleBuffer = NULL;
    Status = LibLocateHandle(ByProtocol,
                             &FileSystemProtocol,
                             NULL,
                             &NoHandles,
                             &HandleBuffer
                             );
    if (EFI_ERROR(Status)) 
    {
        Print(L"Can not get the array of FileSystemProtocol handles\n");
		return ;
    }
    for(i=0;i<NoHandles;i++) 
    {
    	ZeroMem(MapName, sizeof(CHAR16)*MAX_FILEPATH_LENGTH);
    	ZeroMem(LabelName, sizeof(CHAR16)*MAX_FILEPATH_LENGTH);
    	Status = GetMapName(HandleBuffer[i], MapName,LabelName, MAX_FILEPATH_LENGTH);
    	if (!EFI_ERROR(Status))
    	{
			Status = BS->HandleProtocol (HandleBuffer[i], 
						&FileSystemProtocol,
              			(VOID*)&Vol);    
	    	if (!EFI_ERROR(Status))
	    	{			
				Status = Vol->OpenVolume (Vol, &RootFs);
		    	if (!EFI_ERROR(Status))
		    	{			
			    	fsitem = (FSITEM*)MEM_ALLOC(sizeof(FSITEM));
			    	fsitem->Signature = EFI_FSITEM_SIGNATURE;
			    	StrCpy(fsitem->FSName, MapName);
			    	StrCpy(fsitem->FSLabel, LabelName);
			    	fsitem->RootFs = RootFs;
			    	
			    	InsertTailList(&this->FileSystemList,&fsitem->LinkFS);			    
		    	}
	    	}
    	}
    }
    if (NoHandles>0)
    	FreePool(HandleBuffer);
}

//清空文件系统列表
void ClearFSList(struct _FileMgrControl *this)
{
    LIST_ENTRY      *Link;
	FSITEM *Prot;

    for (Link = this->FileSystemList.Flink; Link != &this->FileSystemList; )
    {
	    Prot = CR (Link, FSITEM, LinkFS, EFI_FSITEM_SIGNATURE);
	    Link = Link->Flink;

  	    Prot->RootFs->Flush(Prot->RootFs);
		Prot->RootFs->Close(Prot->RootFs);
        
        RemoveEntryList (&Prot->LinkFS);
        FreePool(Prot);
    }
}

//情况目录文件列表
void ClearFileList(struct _FileMgrControl *this)
{
    LIST_ENTRY      *Link;
	FILEITEM *Prot;

	//去除当前目录中存在的文件列表指针
    for (Link = this->DirFileList.Flink; Link != &this->DirFileList; )
    {
	    Prot = CR (Link, FILEITEM, LinkFile, EFI_FILEITEM_SIGNATURE);
	    Link = Link->Flink;
        RemoveEntryList (&Prot->LinkFile);
        FreePool(Prot);
    }
}

void ClearFilePathList(struct _FileMgrControl *this)
{
    LIST_ENTRY      *Link;
	FILEITEM *Prot;

	//从当前目录去除所有的目录文件指针
    for (Link = this->DirFilePathList.Flink; Link != &this->DirFilePathList; Link = Link->Flink)
    {
	    Prot = CR (Link, FILEITEM, LinkFile, EFI_FILEITEM_SIGNATURE);
	    Link = Link->Flink;
        RemoveEntryList (&Prot->LinkFile);
        FreePool(Prot);
    }
}

void OpenSubDir(struct _FileMgrControl *this,CHAR16 *SubDirName)
{
	INT32 nSel;
	UINT32 *signature=NULL;
//	nSel = this->m_ContentList.Find(&(this->m_ContentList),SubDirName);
	nSel = FindDirectory(&(this->m_ContentList),SubDirName);
	if(nSel==-1)return;
	signature = (UINT32*)this->m_ContentList.GetItemSignature(&(this->m_ContentList), nSel);
	
	if (signature == NULL) 
	{
		if (IsListEmpty(&this->DirFilePathList))
		{	
			//是根目录
			this->CurRootFs = NULL;
			DisplayFileSystem(this);
			this->FilePathLevel=0;
		}
		else
		{
			DisplayParentDir(this);
			this->FilePathLevel--;
		}
			
	}
	if (*signature == EFI_FSITEM_SIGNATURE)
	{
		DisplayFileRootDir(this, nSel);
		this->FilePathLevel++;
	}
	if (*signature == EFI_FILEITEM_SIGNATURE)
	{
		DisplayFileDir(this, nSel);
		this->FilePathLevel++;
	}
}


void DisplayFileSystem(struct _FileMgrControl *this)
{
    LIST_ENTRY      *Link;
	FSITEM *Prot;
	CHAR16 buf[MAX_FILEPATH_LENGTH];

	this->m_ContentList.Clear(&this->m_ContentList);

    for (Link = this->FileSystemList.Flink; Link != &this->FileSystemList; Link = Link->Flink)
    {
	    Prot = CR (Link, FSITEM, LinkFS, EFI_FSITEM_SIGNATURE);
		ZeroMem(buf, MAX_FILEPATH_LENGTH);
		//SPrint(buf, MAX_FILEPATH_LENGTH, L"[%s]", Prot->FSLabel);
		SPrint(buf, MAX_FILEPATH_LENGTH, L"%s", Prot->FSLabel);
		this->m_ContentList.AddItem(&this->m_ContentList, buf, (UINT32)Prot,DISKDRIVER);
    }
}

void DisplayFileRootDir(struct _FileMgrControl *this, INTN nSel)
{
    LIST_ENTRY      *Link;
	FSITEM *Prot;
	FILEITEM *FileProt;
	CHAR16 buf[MAX_FILEPATH_LENGTH];
	INT32	kind;

	//得到当前的FS ITEM
	Prot = (FSITEM *)this->m_ContentList.GetItemParam(&this->m_ContentList, nSel);

	ClearFilePathList(this);
	this->CurRootFs = Prot->RootFs;
	ListDirFile(this, Prot->RootFs, L"");
	
	//往LISTBOX中填写数据
	this->m_ContentList.Clear(&this->m_ContentList);

	//this->m_ContentList.AddItem(&this->m_ContentList, L"[..]", 0,PARENT_DIRECTORY);
	this->m_ContentList.AddItem(&this->m_ContentList, L"..", 0,PARENT_DIRECTORY);
    for (Link = this->DirFileList.Flink; Link != &this->DirFileList; Link = Link->Flink)
    {
	    FileProt = CR (Link, FILEITEM, LinkFile, EFI_FILEITEM_SIGNATURE);
		ZeroMem(buf, MAX_FILEPATH_LENGTH);
		if (FileProt->bDirectory)
		{
			//SPrint(buf, MAX_FILEPATH_LENGTH, L"[%s]", FileProt->FileName);
			SPrint(buf, MAX_FILEPATH_LENGTH, L"%s", FileProt->FileName);
			kind = FILE_DIRECTORY;
		}
		else
		{
			SPrint(buf, MAX_FILEPATH_LENGTH, L"%s", FileProt->FileName);
			kind = FILE_NORMAL;
		}
		this->m_ContentList.AddItem(&this->m_ContentList, buf, (UINT32)FileProt,kind);
    }

}

void DisplayFileDir(struct _FileMgrControl *this, INTN nSel)
{
    LIST_ENTRY      *Link;
	FILEITEM *FileProt;
	CHAR16 buf[MAX_FILEPATH_LENGTH];
	INT32	kind;

	//得到当前的FS ITEM
	FileProt = (FILEITEM *)this->m_ContentList.GetItemParam(&this->m_ContentList, nSel);

	if (!FileProt->bDirectory)
	{
		return;
	}

	//!!这里必须使用buf作为中间转接,因为在ListDirFile里面,
	//将会把所有的FileProt全部释放内存,故参数会变得无效.澹
	StrCpy(buf, FileProt->FileName);
	ListDirFile(this, this->CurRootFs, buf);	
	
	//往LISTBOX中填写数据
	this->m_ContentList.Clear(&this->m_ContentList);

//	this->m_ContentList.AddItem(&this->m_ContentList, L"[..]", 0,PARENT_DIRECTORY);
	this->m_ContentList.AddItem(&this->m_ContentList, L"..", 0,PARENT_DIRECTORY);
    for (Link = this->DirFileList.Flink; Link != &this->DirFileList; Link = Link->Flink)
    {
	    FileProt = CR (Link, FILEITEM, LinkFile, EFI_FILEITEM_SIGNATURE);
		ZeroMem(buf, MAX_FILEPATH_LENGTH);
		if (FileProt->bDirectory)
		{
			//SPrint(buf, MAX_FILEPATH_LENGTH, L"[%s]", FileProt->FileName);
			SPrint(buf, MAX_FILEPATH_LENGTH, L"%s", FileProt->FileName);
			kind = FILE_DIRECTORY;
		}
		else
		{
			SPrint(buf, MAX_FILEPATH_LENGTH, L"%s", FileProt->FileName);
			kind = FILE_NORMAL;
		}
		this->m_ContentList.AddItem(&this->m_ContentList, buf, (UINT32)FileProt,kind);
    }
}

void DisplayParentDir(struct _FileMgrControl *this)
{
    LIST_ENTRY      *Link;
	FILEITEM *FileProt;
	CHAR16 buf[MAX_FILEPATH_LENGTH];
	INT32 kind;

	//得到上级目录的所有文件列表
	ListDirFile(this, this->CurRootFs,L"..");

	//往LISTBOX中填写数据
	this->m_ContentList.Clear(&this->m_ContentList);

	//this->m_ContentList.AddItem(&this->m_ContentList, L"[..]", 0,PARENT_DIRECTORY);
	this->m_ContentList.AddItem(&this->m_ContentList, L"..", 0,PARENT_DIRECTORY);
    for (Link = this->DirFileList.Flink; Link != &this->DirFileList; Link = Link->Flink)
    {
	    FileProt = CR (Link, FILEITEM, LinkFile, EFI_FILEITEM_SIGNATURE);
		ZeroMem(buf, MAX_FILEPATH_LENGTH);
		if (FileProt->bDirectory)
		{
			//SPrint(buf, MAX_FILEPATH_LENGTH, L"[%s]", FileProt->FileName);
			SPrint(buf, MAX_FILEPATH_LENGTH, L"%s", FileProt->FileName);
			kind = FILE_DIRECTORY;
		}
		else
		{
			SPrint(buf, MAX_FILEPATH_LENGTH, L"%s", FileProt->FileName);
			kind = FILE_NORMAL;
		}
		this->m_ContentList.AddItem(&this->m_ContentList, buf, (UINT32)FileProt,kind);
    }
}


//得到MAP的文件系统的名字
EFI_STATUS GetMapName(EFI_HANDLE Handle, 
	OUT CHAR16* MapName, 
	OUT CHAR16* LabelName, 
	IN INTN MapNameLen)
{
    CHAR16              *Name;
    CHAR16              *Data;
    UINTN               BufferSize;
    UINTN               NameSize, DataSize;
    EFI_GUID            Id;
    UINT32              Attributes;
    EFI_HANDLE       MapHandle;
    EFI_DEVICE_PATH  *DevicePath;
    EFI_STATUS Status;
    static EFI_GUID MapId    =  DEVICE_PATH_MAPPING_ID;
    UINT8   Type,SubType;
    BOOLEAN bUsbDisk=FALSE;
  
	//先测试是否是可移动磁盘
    Status = BS->HandleProtocol (Handle, 
                  &DevicePathProtocol, 
                  (VOID*)&DevicePath);
	

    if (EFI_ERROR(Status) || DevicePath==NULL) {
           Print(L"Can not get a DevicePath handle for HandleBuffer\n");
		   return EFI_NO_MAPPING;
    }        

    Type = (UINT8)DevicePathType (DevicePath);
	SubType = DevicePathSubType (DevicePath);

	if ( Type == MESSAGING_DEVICE_PATH && SubType == MSG_USB_CLASS_DP) 
	{
		//发现可移动磁盘
		bUsbDisk = TRUE;
	}
	
    BufferSize = 1024;
    Name = MEM_ALLOC (BufferSize);
    Data = MEM_ALLOC (BufferSize);

    for (; ;) 
    {
        NameSize = BufferSize;
        Status = RT->GetNextVariableName (&NameSize, Name, &Id);
        if (EFI_ERROR(Status)) {
        	Print (L"error status %r\n\r", Status);
            break;
        }

       if (CompareGuid (&Id, &MapId) == 0) {
	       DataSize = BufferSize;
	       Status = RT->GetVariable (Name, &Id, &Attributes, &DataSize, Data);
		   DevicePath = (EFI_DEVICE_PATH *)Data;

	       Status = BS->LocateDevicePath(&DevicePathProtocol,&DevicePath,&MapHandle);
	       if (!EFI_ERROR(Status) && MapHandle!=NULL) {
	            if (MapHandle == Handle) {
				  	if (StrLen(Name) < (UINTN)MapNameLen)
				  	{
			  			SPrint(MapName, MapNameLen,L"%s", Name);
				  		if (!bUsbDisk)			  		
				  			SPrint(LabelName, MapNameLen,L"%s:", Name);
				  		else
				  		{
				  			SPrint(LabelName, MapNameLen,L"可移动磁盘(%s:)", Name);
				  		}
					  	FreePool (Data);
				    	FreePool (Name);
    	            	return EFI_SUCCESS;                
				  	}
	            }
	       }
       }
    }

	StrCpy(MapName, L"");
    FreePool (Name);
    FreePool (Data);
    return EFI_NO_MAPPING;
}

void ListDirFile(struct _FileMgrControl *this, EFI_FILE_HANDLE RootFs, IN CHAR16  *DirName)
{
    EFI_FILE_HANDLE DirHandle = 0;
    EFI_FILE_INFO       *Info=0;
    UINTN               BufSize;
    CHAR16 dirBuf[MAX_FILEPATH_LENGTH];
	EFI_STATUS Status;
    FILEITEM 					*fileitem;

	//是否回到上级目录
	if (StrCmp(DirName, L"..") == 0)
	{
		GoParentDir(this);
		ComposeCurDir(this, dirBuf, MAX_FILEPATH_LENGTH);
	}
	else
	{
		ComposeCurDir(this, dirBuf, MAX_FILEPATH_LENGTH);
		if (StrLen(DirName) >0)
		    StrCat(dirBuf, DirName);
	}
    
    Status = RootFs->Open(RootFs,
           &DirHandle,
           dirBuf,
           EFI_FILE_MODE_READ,
           0);
    
    if (EFI_ERROR(Status))    
    {
    	Print(L"open dir [%s] error:%r!\n\r",dirBuf, Status);
    	return;
    }

   BufSize = SIZE_OF_EFI_FILE_INFO + 1024;
   Info = (EFI_FILE_INFO *)AllocatePool (BufSize);
   if (!Info) 
   {
	    Print (L"ls: Out of memory\n");
	    Status = EFI_OUT_OF_RESOURCES;
	    DirHandle->Close(DirHandle);
	    return ;
   }

   //先清除所有的文件列表
	ClearFileList(this);
//  	Print(L"Insert File Path0 DirName=[%s]\n\r", DirName);
	
    for (;;) 	
    {
		BufSize = SIZE_OF_EFI_FILE_INFO + 1024;
	    Status = DirHandle->Read(DirHandle, &BufSize, Info);

      	if (EFI_ERROR(Status)) 
      	{
		    Print (L"Read Eror:%r (BufSize=%d)\n\r",Status, BufSize);
	        break;
      	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -