📄 disktool.c
字号:
///////////////////////////////////////////////////////////
//磁盘块写入函数,单位是扇区
//输入: 含有写入内容的buf
// 从哪个扇区开始写入
// 需要写入的长度
///////////////////////////////////////////////////////////
EFI_STATUS DiskBlockIO_WriteBlock(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"Wirte HardDisk BlockSize = %d, LastBlock =%d \n", Media->BlockSize, Media->LastBlock);
//============================================================
//设置磁盘的读准备
// read LastBlock-(EFI_LBA)0 block form floppy
//Size = (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)
{
//从buffer 中读出
for(t=0;t<512;t++)
MBRBuffer[t]=BlockBuffer[j+t];
Status = BlkIo->WriteBlocks(BlkIo,
MediaId,
(EFI_LBA)i,
Size,
MBRBuffer);
if(EFI_ERROR(Status)) Print (L" Wirte 512 bytes to HD Error\n");
}
//============================================================
// Close /////////////////////////////////////////
//
if (MBRBuffer!=NULL) FreePool(MBRBuffer);
// Print (L"Free MBRBuffer success\n");
}
//
// Free the resources allocated from pool.
//
FreePool(HandleBuffer);
return EFI_SUCCESS;
}
//////////////////////////////////////////////////////////
//获得第一个IDE硬盘的BLk块号没有返回-1
//优先级如下:
// Primary,Master
// Primary,Slave
// Secondary,Master
// Secondary,Slave
//参数IsPartID=FALSE 说明是寻找硬盘的主blk,否则是第一个分区的blk
///////////////////////////////////////////////////////////
INT32 GetFirstIDEHardDiskBlkID(BOOLEAN IsPartID)
{
EFI_STATUS Status;
EFI_GUID Guid;
UINT32 Attributes;
CHAR16 Name[DEBUG_NAME_SIZE/2];
UINTN NameSize;
CHAR16 DataOld[DEBUG_NAME_SIZE/2];
UINTN DataSize;
// UINTN Size;
CHAR16 *DevicePathAsString=NULL;
ATAIDE_Device m_AtaIDEDevice;
INT32 BLKID=-1;
Status = EFI_UNSUPPORTED;
//初始化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;
Name[0] = 0x0;
do
{
NameSize = DEBUG_NAME_SIZE;
Status = RT->GetNextVariableName (&NameSize, Name, &Guid);
if (!EFI_ERROR(Status)){
DataSize = DEBUG_NAME_SIZE;
Status = RT->GetVariable (Name, &Guid, &Attributes, &DataSize, DataOld);
if((!EFI_ERROR (Status))
&&((BLKID=BlkStrToBlkID(Name))!=-1))
{
DevicePathAsString = DevicePathToStr(DataOld);
Print(L"***** %s,%s\n",Name,DevicePathAsString);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -