📄 disktool.c
字号:
/*****************************************************************
Copyright (c) 2005.11 Lenovo Corporation
Module Name: DiskTool.c
Abstract: provide a series of functions to control DiskIO
Author: Wang Zhe
*******************************************************************/
#include "disktool.h"
#include "FileSystem.h"
#define MAX_FILEPATH_LENGTH 256
#define DEBUG_NAME_SIZE 1050
extern EFI_HANDLE g_ImageHandle;
///////////////////////////////////////////////////////////
//16进制转化为10进制
///////////////////////////////////////////////////////////
UINT32 HextoDec(
UINT8 HighHigh,
UINT8 High,
UINT8 Mid,
UINT8 Low
)
{
UINT32 DecNum;// temp32;
DecNum=0;
DecNum = DecNum | HighHigh;
DecNum = DecNum<<8;
DecNum = DecNum | High;
DecNum = DecNum<<8;
DecNum = DecNum | Mid;
DecNum = DecNum<<8;
DecNum = DecNum | Low;
return DecNum;
}
///////////////////////////////////////////////////////////
//10进制转化为16进制
///////////////////////////////////////////////////////////
void DectoHex(
UINT32 DecNum,
UINT8 *HighHigh,
UINT8 *High,
UINT8 *Mid,
UINT8 *Low
)
{
*HighHigh = (UINT8)((DecNum & 0x0f000000)>>24);
*High = (UINT8)((DecNum & 0x00ff0000)>>16);
*Mid = (UINT8)((DecNum & 0x0000ff00)>>8);
*Low = (UINT8)(DecNum & 0x000000ff);
}
///////////////////////////////////////////////////////////
//磁盘块读取函数,单位是扇区
//输入: 存放读出内容的buf
// 从哪个扇区开始读出
// 需要读出的长度
///////////////////////////////////////////////////////////
EFI_STATUS DiskBlockIO_ReadBlock(UINT8 *BlockBuffer, //存放读出内容的buf
INT32 StartSector, //从哪个扇区开始读出
INT32 SectorNum)//需要读出的长度
{
EFI_STATUS Status;
CHAR16 *DevicePathAsString;
EFI_DEVICE_PATH *DevicePath;
INT32 i,j,t;
INT32 Size;
UINT8 *MBRBuffer = NULL;
INT32 NoHandles;
EFI_HANDLE *HandleBuffer;
EFI_BLOCK_IO *BlkIo;
EFI_BLOCK_IO_MEDIA *Media;
UINT32 MediaId;
ATAIDE_Device m_AtaIDEDevice;
if((StartSector<0)||(SectorNum<=0))
{
Print(L"Sector parameter error!\n");
return EFI_INVALID_PARAMETER;
}
//初始化IDE结构
m_AtaIDEDevice.PrimaryMaster[0]=ATAIDE_NULL;
m_AtaIDEDevice.PrimaryMaster[1]=-1;
m_AtaIDEDevice.PrimarySlave[0]=ATAIDE_NULL;
m_AtaIDEDevice.PrimarySlave[1]=-1;
m_AtaIDEDevice.SecondaryMaster[0]=ATAIDE_NULL;
m_AtaIDEDevice.SecondaryMaster[1]=-1;
m_AtaIDEDevice.SecondarySlave[0]=ATAIDE_NULL;
m_AtaIDEDevice.SecondarySlave[1]=-1;
NoHandles = 0;
HandleBuffer = NULL;
Status = LibLocateHandle(ByProtocol,
&BlockIoProtocol,
NULL,
&NoHandles,
&HandleBuffer
);
if (EFI_ERROR(Status)) {
Print(L"Can not get the array of BLOCK_IO handles\n");
return EFI_ABORTED;
//BS->Exit(g_ImageHandle,EFI_SUCCESS,0,NULL);
}
//
// Read the first block from each BLOCK_IO device and display it
//
//Print (L"BlockIo Number = %d.", NoHandles);
//
// Get the DEVICE_PATH Protocol Interface to the device
//
/////////////////////////////////////////////////////////////////////
//找到硬盘的主设备handle
for(i=0;i<NoHandles;i++)
{
Status = BS->HandleProtocol (HandleBuffer[i],
&DevicePathProtocol,
(VOID*)&DevicePath
);
if (EFI_ERROR(Status) || DevicePath==NULL) {
Print(L"Can not get a DevicePath handle for HandleBuffer[0]\n");
return EFI_ABORTED;
//BS->Exit(g_ImageHandle,EFI_SUCCESS,0,NULL);
}
//
// Get the BLOCK_IO Protocol Interface to the device
//
Status = BS->HandleProtocol (HandleBuffer[i],
&BlockIoProtocol,
(VOID*)&BlkIo
);
if (EFI_ERROR(Status) || BlkIo==NULL) {
Print(L"Handle does not support the BLOCK_IO protocol\n");
return EFI_ABORTED;
//BS->Exit(g_ImageHandle,EFI_SUCCESS,0,NULL);
}
DevicePathAsString = DevicePathToStr(DevicePath);
///////////////////////////////////////////////////////////
//检查blk,找到硬盘的主handle
if (DevicePathAsString== NULL)
{
Print(L"Device Path is NULL!\n");
return EFI_ABORTED;
//BS->Exit(g_ImageHandle,EFI_SUCCESS,0,NULL);
}
if (MetaiMatch(DevicePathAsString, L"*Ata(Primary,Master)*"))
{
if(MetaiMatch(DevicePathAsString, L"*HD(Part*"))//是一个硬盘分区
{
m_AtaIDEDevice.PrimaryMaster[0]=ATAIDE_HARDDISK;
}
else if(MetaiMatch(DevicePathAsString, L"*CDROM*"))//是一个光驱分区
{
m_AtaIDEDevice.PrimaryMaster[0]=ATAIDE_CDROM;
}
else//是一个块主设备
{
m_AtaIDEDevice.PrimaryMaster[1]=i;
}
}
else if (MetaiMatch(DevicePathAsString, L"*Ata(Primary,Slave)*"))
{
if(MetaiMatch(DevicePathAsString, L"*HD(Part*"))//是一个硬盘分区
{
m_AtaIDEDevice.PrimarySlave[0]=ATAIDE_HARDDISK;
}
else if(MetaiMatch(DevicePathAsString, L"*CDROM*"))//是一个光驱分区
{
m_AtaIDEDevice.PrimarySlave[0]=ATAIDE_CDROM;
}
else//是一个块主设备
{
m_AtaIDEDevice.PrimarySlave[1]=i;
}
}
else if (MetaiMatch(DevicePathAsString, L"*Ata(Secondary,Master)*"))
{
if(MetaiMatch(DevicePathAsString, L"*HD(Part*"))//是一个硬盘分区
{
m_AtaIDEDevice.SecondaryMaster[0]=ATAIDE_HARDDISK;
}
else if(MetaiMatch(DevicePathAsString, L"*CDROM*"))//是一个光驱分区
{
m_AtaIDEDevice.SecondaryMaster[0]=ATAIDE_CDROM;
}
else//是一个块主设备
{
m_AtaIDEDevice.SecondaryMaster[1]=i;
}
}
else if (MetaiMatch(DevicePathAsString, L"*Ata(Secondary,Slave)*"))
{
if(MetaiMatch(DevicePathAsString, L"*HD(Part*"))//是一个硬盘分区
{
m_AtaIDEDevice.SecondarySlave[0]=ATAIDE_HARDDISK;
}
else if(MetaiMatch(DevicePathAsString, L"*CDROM*"))//是一个光驱分区
{
m_AtaIDEDevice.SecondarySlave[0]=ATAIDE_CDROM;
}
else//是一个块主设备
{
m_AtaIDEDevice.SecondarySlave[1]=i;
}
}
///////////////////////////////////////////////////////////
}
//然后我们搜索刚才建立的IDE表,找到第一个硬盘
if(m_AtaIDEDevice.PrimaryMaster[0]==ATAIDE_HARDDISK)
i= m_AtaIDEDevice.PrimaryMaster[1];
else if(m_AtaIDEDevice.PrimarySlave[0]==ATAIDE_HARDDISK)
i= m_AtaIDEDevice.PrimarySlave[1];
else if(m_AtaIDEDevice.SecondaryMaster[0]==ATAIDE_HARDDISK)
i= m_AtaIDEDevice.SecondaryMaster[1];
else if(m_AtaIDEDevice.SecondarySlave[0]==ATAIDE_HARDDISK)
i= m_AtaIDEDevice.SecondarySlave[1];
else i=-1;//找不到硬盘
if(i!=-1)//找得到硬盘分区时
{
Status = BS->HandleProtocol (HandleBuffer[i], &DevicePathProtocol, (VOID*)&DevicePath);
if (EFI_ERROR(Status) || DevicePath==NULL) {
Print(L"Can not get a DevicePath handle for HandleBuffer[0]\n");
return EFI_ABORTED;
//BS->Exit(g_ImageHandle,EFI_SUCCESS,0,NULL);
}
Status = BS->HandleProtocol (HandleBuffer[i],&BlockIoProtocol,(VOID*)&BlkIo);
if (EFI_ERROR(Status) || BlkIo==NULL) {
Print(L"Handle does not support the BLOCK_IO protocol\n");
return EFI_ABORTED;
}
Media = BlkIo->Media;
}
else//硬盘没有分区,要一个个的试验
{
//PrimaryMaster上有主设备且并非确认的光驱
if((m_AtaIDEDevice.PrimaryMaster[1]!=-1)
&&(m_AtaIDEDevice.PrimaryMaster[0]!=ATAIDE_CDROM))
{
i=m_AtaIDEDevice.PrimaryMaster[1];
Status = BS->HandleProtocol (HandleBuffer[i],&BlockIoProtocol,(VOID*)&BlkIo);
if (EFI_ERROR(Status) || BlkIo==NULL) {
Print(L"Handle does not support the BLOCK_IO protocol\n");
return EFI_ABORTED;
}
Media = BlkIo->Media;//如果可以获得介质,说明这是硬盘
//因为此时的光驱里是没有光盘的
if(Media!=NULL)goto GETDISK;
}
//PrimarySlave上有主设备且并非确认的光驱
if((m_AtaIDEDevice.PrimarySlave[1]!=-1)
&&(m_AtaIDEDevice.PrimarySlave[0]!=ATAIDE_CDROM))
{
i=m_AtaIDEDevice.PrimarySlave[1];
Status = BS->HandleProtocol (HandleBuffer[i],&BlockIoProtocol,(VOID*)&BlkIo);
if (EFI_ERROR(Status) || BlkIo==NULL) {
Print(L"Handle does not support the BLOCK_IO protocol\n");
return EFI_ABORTED;
}
Media = BlkIo->Media;//如果可以获得介质,说明这是硬盘
//因为此时的光驱里是没有光盘的
if(Media!=NULL)goto GETDISK;
}
//SecondaryMaster上有主设备且并非确认的光驱
if((m_AtaIDEDevice.SecondaryMaster[1]!=-1)
&&(m_AtaIDEDevice.SecondaryMaster[0]!=ATAIDE_CDROM))
{
i=m_AtaIDEDevice.SecondaryMaster[1];
Status = BS->HandleProtocol (HandleBuffer[i],&BlockIoProtocol,(VOID*)&BlkIo);
if (EFI_ERROR(Status) || BlkIo==NULL) {
Print(L"Handle does not support the BLOCK_IO protocol\n");
return EFI_ABORTED;
}
Media = BlkIo->Media;//如果可以获得介质,说明这是硬盘
//因为此时的光驱里是没有光盘的
if(Media!=NULL)goto GETDISK;
}
//SecondarySlave上有主设备且并非确认的光驱
if((m_AtaIDEDevice.SecondarySlave[1]!=-1)
&&(m_AtaIDEDevice.SecondarySlave[0]!=ATAIDE_CDROM))
{
i=m_AtaIDEDevice.SecondarySlave[1];
Status = BS->HandleProtocol (HandleBuffer[i],&BlockIoProtocol,(VOID*)&BlkIo);
if (EFI_ERROR(Status) || BlkIo==NULL) {
Print(L"Handle does not support the BLOCK_IO protocol\n");
return EFI_ABORTED;
}
Media = BlkIo->Media;//如果可以获得介质,说明这是硬盘
//因为此时的光驱里是没有光盘的
if(Media!=NULL)goto GETDISK;
}
FreePool(HandleBuffer);//根本就没有硬盘
return EFI_NOT_FOUND;
}
////////////////////////////////////////////////////////////////
//非可移动设备,非只读设备,否则error
GETDISK: if(!(Media->RemovableMedia) && !(Media->ReadOnly))
{
//Print (L"Read HardDisk BlockSize = %d, LastBlock =%d \n", Media->BlockSize, Media->LastBlock);
//============================================================
//设置磁盘的读准备
Size = (Media->BlockSize); //Only read 1 block = 512byte, used to restore MBR
BS->AllocatePool(EfiLoaderData,
Size,
&MBRBuffer
);
if (MBRBuffer == NULL) {
Print(L"Can not allocate a buffer for the Image file \n");
FreePool(DevicePathAsString);
return EFI_ABORTED;
//BS->Exit(g_ImageHandle,EFI_SUCCESS,0,NULL);
}
MediaId = Media->MediaId;
//============================================================
//下面才开始真正的读写
for(i=StartSector,j=0;i<StartSector+SectorNum;i++,j+=512)
{
Status = BlkIo->ReadBlocks(BlkIo,
MediaId,
(EFI_LBA)i,
Size,
MBRBuffer);
if(EFI_ERROR(Status)) Print (L" Read 512 bytes from HD Error\n");
//向buffer中写入
for(t=0;t<512;t++)
BlockBuffer[j+t] = MBRBuffer[t];
}
//============================================================
// Close /////////////////////////////////////////
//
if (MBRBuffer!=NULL) FreePool(MBRBuffer);
//Print (L"Free MBRBuffer success\n");
}
//
// Free the resources allocated from pool.
//
FreePool(HandleBuffer);
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -