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

📄 disktool.c

📁 EFI(Extensible Firmware Interface)是下一代BIOS
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************
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 + -