📄 filesystem.c
字号:
/*******************************************************
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 + -