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

📄 hdinfo.c

📁 DOS下读取硬盘信息,硬盘容量,供应商信息等
💻 C
字号:
#include "ata.h"
#include "global.h"
#include <conio.h>
#include <stdio.h>
#include <io.h>
#include <sys\stat.h>
#include <fcntl.h>
#include "graph.h"

char	DevName[23];
LONG	count;
buffer	info;
//volatile ADDRESS sys_area = (System_data FAR  *)0;

BOOL GetStrValue(char *,char *,char* );
BOOL GetHdInfo();

void puthz(char *,int ,int ,int );
BOOL GetYes(void);
#define ROW 1 //纵坐标放大倍数
#define COL 1 //横坐标放大倍数

BOOL GetFun(int , char* );
#define WRITE 6 
#define CMP   8 

Device			dev[MAX_DEV];
char *channelname[]={
        "Primary    Master: ",
        "Primary    Slave : ",
        "Secondary  Master: ",
        "Secondary  Slave : ",
};

void repinsw(WORD ioport, ADDRESS buffer, WORD count)
{
	WORD	i;
	for(i=0;i<count;i++)
	{
        *((WORD *)buffer+i) = inpw(ioport);
	}
}
void repoutsw(WORD ioport, ADDRESS buffer, WORD count)
{
	WORD	i;
	for(i=0;i<count;i++)
	{
        outpw(ioport,*((WORD *)buffer+i));
	}
}
/**************
void repinsd(WORD ioport, ADDRESS buffer, WORD count)
{
	WORD	i;
	for(i=0;i<count;i++)
	{
		*(buffer+i) = inpd(ioport);
	}
}
void repoutsd(WORD ioport, ADDRESS buffer, WORD count)
{
	WORD	i;
	for(i=0;i<count;i++)
	{
		outpd(ioport,*(buffer+i));
	}
}
****************/
void Delay(int time)
{
	int i;
	for (i=0;i<=time*100;i++)
		;
}

BYTE WaitOnBusy(WORD IoPort2)
{
    BYTE    status;
    LONG   i;

    for (i = 0; i < 0x600; i++) {
        status = GetStatus(IoPort2);

        if ((status & STAT_BSY)||(status & STAT_ERR)) {
            Delay(150);
            continue;
        }
        else
            break;
    }
    return status;
}

BYTE WaitForDrq(WORD IoPort2)
{
    BYTE    status;
    LONG   i;

    for (i = 0; i < 0x600; i++) {
        status = GetStatus(IoPort2);

        if (status & STAT_BSY) {
            Delay(10);
        }
        else if (status & (STAT_DRQ | STAT_ERR))
            break;
        else {
            Delay(10);
        }
    }
    return status;
}

void GetCount()
{
	LONG	Total;
	Total = *((LONG *)((volatile ADDRESS)0 + 0x46c));
	while(Total == *((LONG *)((volatile ADDRESS)0 + 0x46c)))
		Total += 4;
    count = 0;
	while(Total != *((LONG *)((volatile ADDRESS)0 + 0x46c)))
		count++; 
}

void init()
{
	int i;
	for(i=0;i<MAX_DEV;i++)
	{
		memset((void *)(&dev[i]),0,sizeof(Device));
		dev[i].IoPort = (i<2)?0x1f0:0x170;
		dev[i].ContrlPort  = (i<2)?0x3f6:0x376;
		dev[i].Unit = (i%2)?0xb0:0xa0;
		dev[i].channelname = channelname[i];
		dev[i].BigLBA = 0;
		dev[i].m.cap.cap_high = 0;
		dev[i].m.cap.cap_low  = 0;
		dev[i].ISATAPI = 0;
		dev[i].cap = 0;
	}
}

int IssueIdentify(pDevice pDev,BYTE cmd)
{
	WORD IoPort = pDev->IoPort;
    WORD ControlPort = pDev->ContrlPort;
	
	SelectUnit(IoPort,pDev->Unit);
    if(WaitOnBusy(ControlPort) & STAT_BSY) 
        return FALSE;
	IssueCommand(IoPort,cmd);
	if(WaitOnBusy(ControlPort) & (STAT_ERR |STAT_BSY))
        return FALSE;
	if (WaitForDrq(ControlPort) & STAT_DRQ) {
		InPort(IoPort+CommandPort);
		repinsw(IoPort,(ADDRESS)&info, sizeof(buffer));
		return TRUE;
    }else{
		return FALSE;
	}
}

int main(int argc, char *argv[])
{
	WORD		i,j,cyl;
	pDevice		npUT,pDev;
	WORD		IOPort,ControlPort;
	FILE		*stream;
	char		val[4][60];
	char		buf[60];
	char		val1[4][60];
	int			valid[4]={0,};
	int			cap[4]={0,};
	int			err=0,fun=0;
	
	fun = GetFun(argc, argv[1]);
	if(!fun)
		return FALSE;
	if(fun == WRITE)
	{
		if((stream = fopen(argv[2],"a")) == NULL)
			return FALSE;
		init();
		if(!GetHdInfo())
			return FALSE;
		fprintf(stream,"[IDE Device Information]\n");
		for(i=0;i<MAX_DEV;i++)
		{
			if(!dev[i].Status)
                continue;
			fprintf(stream,"IDEAddr(%XH)Num(%d)=Mod(%s);",
				(i<2)?0x1f0:0x170,(i%2),dev[i].Name );
			if(dev[i].ISATAPI )
			{
				fprintf(stream,"Ctl(%s)\n",dev[i].FirmwareRevision );
			}else{
				fprintf(stream,"\n");
				fprintf(stream,"Driver(%d)DiskCapacity=%luMB\n",i,dev[i].cap );
			}
		}
		fclose(stream);
		return TRUE;
	}
	
	init();
	if(!GetHdInfo())
		return FALSE;
	for(i=0;i<MAX_DEV;i++)
	{
		memset(buf,0,sizeof(char)*60);
		memset(val[i],0,sizeof(char)*60);
		memset(val1[i],0,sizeof(char)*60);
		sprintf(buf,"IDEAddr(%XH)Num(%d)\0",(i<2)?0x1f0:0x170,i%2?1:0);
                valid[i] = GetStrValue(argv[2],buf,val[i]);
		memset(buf,0,sizeof(char)*60);
		sprintf(buf,"Driver(%d)DiskCapacity\0",i);
                cap[i] = GetStrValue(argv[2],buf,val1[i]);
	}
	
	for(i=0; i<MAX_DEV; i++)
	{
		if(!valid[i])
			continue;
		memset(buf,0,sizeof(char)*60);
		pDev = npUT = &dev[i];
		if(pDev->Status)
		{
			IOPort = npUT->IoPort ;
			ControlPort = npUT->ContrlPort ;
			sprintf(buf,"Mod(%s);",npUT->Name );
			if(npUT->ISATAPI)
			{
				strcat(buf,"Ctl(");
				strcat(buf,npUT->FirmwareRevision );
				strcat(buf,")\0");
				if(memcmp(buf,val[i],strlen(buf)) != 0)
				{
					_setvideomode(_VRES16COLOR);
					puthz("光驱类型检测失败!",200,30,12);
					puthz("实测类型:",5,110,14);
					_settextposition(8,20);
					_outtext( buf );
					puthz("标配类型:",5,170,14);
					_settextposition(12,20);
					_outtext( val[i]);
					puthz("按“Y”键允许通过,否则按电源键关机。",60,360,14);
					GetYes();
					_setvideomode(_DEFAULTMODE);
					err=1;
					
				}
			}else{
				if(npUT->BestUDMA < 2)
					return 2;
				strcat(buf,"\0");
				if(memcmp(buf,val[i],strlen(buf)) != 0)
				{
					_setvideomode(_VRES16COLOR);
					puthz("硬盘类型检测失败!",200,30,12);
					puthz("实测类型:",5,110,14);
					_settextposition(8,20);
					_outtext( buf );
					puthz("标配类型:",5,170,14);
					_settextposition(12,20);
					_outtext( val[i]);
					puthz("按“Y”键允许通过,否则按电源键关机。",60,360,14);
					GetYes();
					_setvideomode(_DEFAULTMODE);
					err=1;
				}
				memset(buf,0,sizeof(char)*60);
				sprintf(buf,"%luMB\0",npUT->cap );//npUT->m .cap .cap_low/2048);
				if(atoi(buf) != atoi(val1[i]))
				{
					_setvideomode(_VRES16COLOR);
					puthz("硬盘容量检测失败!",200,30,12);
					puthz("实测容量:",5,110,14);
					_settextposition(8,20);
					_outtext( buf );
					puthz("标配容量:",5,170,14);
					_settextposition(12,20);
					_outtext( val1[i]);
					puthz("按“Y”键允许通过,否则按电源键关机。",60,360,14);
					GetYes();
					_setvideomode(_DEFAULTMODE);
					err=1;
				}
			}
		}else{
			_setvideomode(_VRES16COLOR);
			puthz("设备检测失败!",200,30,12);
			puthz("实测类型:无设备连接!",5,110,14);
			puthz("标配类型:",5,170,14);
			_settextposition(12,20);
			_outtext( val[i]);
			puthz("按“Y”键允许通过,否则按电源键关机。",60,360,14);
			GetYes();
			_setvideomode(_DEFAULTMODE);
			err=1;
		}
	}
	if(err)
        return 2;
	
	return TRUE;
}

BOOL GetHdInfo()
{
	LONG		c=0,tmp=0;
	BYTE		stat;
	WORD		i,j,cyl;
	pDevice		npUT;
	WORD		IOPort,ControlPort;
	
	init();
	
	for(i=0;i<MAX_DEV;i++)
	{
		npUT = &dev[i];
		IOPort = npUT->IoPort ;
		ControlPort = npUT->ContrlPort ;
		
		WaitOnBusy(ControlPort);
		for(j=0;j<60;j++)
		{
			SelectUnit(IOPort,npUT->Unit );
			if( InPort(IOPort+DriveHead) == npUT->Unit ){
				break;
			}
		}
		
		OutPort(IOPort+SectorNumber, 0x55);
		OutPort(IOPort+SectorCount, 0);
		if(InPort(IOPort+SectorNumber) != 0x55) 
			goto nodev;
		OutPort(IOPort+SectorNumber, 0xAA);
		if(InPort(IOPort+SectorNumber) != 0xAA)
nodev:
		{
			npUT->Status = 0;
			continue;
		}
		
		if(InPort(IOPort+4) == 0x14 && InPort(IOPort+5) == 0xEB)
			goto is_cdrom;
		
		for(j = 0; j < 20000; j++) {
			stat = InPort(IOPort+StatusPort);
			if(stat & STAT_DWF)
				break;
			if((stat & STAT_BSY) == 0) {
				if((stat & (STAT_DSC|STAT_DRDY)) == (STAT_DSC|STAT_DRDY))
					goto try_disk;
				break;
			}
		}
		
		if((InPort(IOPort+StatusPort) & 0xAE) != 0) 
			goto nodev;
		
try_disk:
		if(InPort(IOPort+4) == 0x14 && InPort(IOPort+5) == 0xEB) 
		{
is_cdrom:
		SelectUnit(IOPort,npUT->Unit);
		OutPort(IOPort+CommandPort, 8);
		Delay(6000);
		SelectUnit(IOPort,npUT->Unit);
		WaitOnBusy(ControlPort);
		if(IssueIdentify(npUT, 0xA1) == 0)
			goto nodev;
		npUT->ISATAPI  = TRUE;
		goto show_info;
		}
		if(IssueIdentify(npUT,WIN_IDENTIFY) == 0)
		{
			if((InPort(IOPort+7) & ~1) == 0x50 ||
				(InPort(IOPort+4) == 0x14 && InPort(IOPort+5) == 0xEB))
				goto is_cdrom;
			goto nodev;
		}
show_info:		
		npUT->Status = TRUE;
		for (cyl=0; cyl<40; cyl++)
			npUT->Name[cyl] = info.IdentifyInfo.ModelNumber[cyl^1] ;
		for (cyl=0; cyl<8; cyl++)
			npUT->FirmwareRevision[cyl] =((char *)(info.IdentifyInfo.FirmwareRevision))[cyl^1] ;
		for(cyl=39; cyl>=0; cyl--)
		{
			if(
				(npUT->Name[cyl] == 0)||
				(npUT->Name[cyl] == 0x20)
				)
			{
				npUT->Name[cyl] = 0;
			}else{
				break;
			}
		}
		for(cyl=7; cyl>=0; cyl--)
		{
			if(
				(npUT->FirmwareRevision[cyl] == 0)||
				(npUT->FirmwareRevision[cyl] == 0x20)
				)
			{
				npUT->FirmwareRevision[cyl] = 0;
			}else{
				break;
			}
		}
		
		if(info.IdentifyInfo.Smart & 0x01)
			npUT->SMART = TRUE;
		npUT->BestUDMA  = 
			(info.IdentifyInfo .UtralDmaMode & 0x40) ? 6 :
		(info.IdentifyInfo .UtralDmaMode & 0x20) ? 5 :
		(info.IdentifyInfo .UtralDmaMode & 0x10) ? 4 :
		(info.IdentifyInfo .UtralDmaMode & 0x8 ) ? 3 :
		(info.IdentifyInfo .UtralDmaMode & 0x4 ) ? 2 :    // ultra DMA Mode 2 
		(info.IdentifyInfo .UtralDmaMode & 0x2 ) ? 1 : 0;   // ultra DMA Mode 1
		npUT->BigLBA = (info.info [84] & 0x40) ? 1:0;
		
		if(npUT->ISATAPI)
			continue;
		SelectUnit(IOPort,(i%2)?0xf0:0xe0);
		if(npUT->BigLBA)
		{
			IssueCommand(IOPort,0x27);
		}else{
			IssueCommand(IOPort,0xf8);
		}
		if(WaitOnBusy(ControlPort) & (STAT_ERR |STAT_BSY))
			return FALSE;
		if(npUT->BigLBA)
		{
			npUT->m .LBA.lba  [0] = inp(IOPort+0x03);
			npUT->m .LBA.lba  [1] = inp(IOPort+0x04);
			npUT->m .LBA.lba  [2] = inp(IOPort+0x05);
			npUT->m .LBA.lba  [3] = inp(IOPort+0x03);
			npUT->m .LBA.lba  [4] = inp(IOPort+0x04);
			npUT->m .LBA.lba  [5] = inp(IOPort+0x05);
		}else{
			npUT->m .LBA.lba  [0] = inp(IOPort+0x03);
			npUT->m .LBA.lba  [1] = inp(IOPort+0x04);
			npUT->m .LBA.lba  [2] = inp(IOPort+0x05);
			npUT->m .LBA.lba  [3] = inp(IOPort+0x06)&0x0f;
		}
/*******************
		c = npUT->m .cap.cap_high <<21;
		tmp = npUT->m .cap .cap_low >>11;
		c&=0xffe00000;
		tmp&=0x1ffff;
		c|=tmp;
		npUT->cap = c;
*******************/
		{
			float cap;
			cap=((float)(npUT->m .cap .cap_low) *512)/((float)1000*1000);
			npUT->cap=(unsigned long)cap+1;
		}
		
	}
	return	TRUE;
}

BOOL GetStrValue(char *filename,char *str,char* value)
{
	int			i,k,isok=0;
	FILE		*stream;
	char		*lpBuffer;
	LONG		len=0;

	stream = fopen(filename,"rb");
	if(stream == NULL)
	{
		printf("Can't open %s\n",filename);
		return FALSE;
	}
	len =  _filelength(stream->_file );
	lpBuffer = (BYTE *)malloc((size_t )len);
	fread(lpBuffer,sizeof(char), (size_t)len,stream);

	for(i=0;i<(len-strlen(str));i++)
	{
		int o=strlen(str);
		if((memcmp((char *)lpBuffer+i,str,strlen(str))==0 )&&
			(
			(*((char *)lpBuffer+i-1) == 20)||
			(*((char *)lpBuffer+i-1) == 0xa)||
			(i == 0)
			)&&
			(
			(*((char *)lpBuffer+i+strlen(str)) == 20)||
			(*((char *)lpBuffer+i+strlen(str)) == 0x3d)
			)
			)
		{
			int m=0;
			for(k=0;k<(len-strlen(str)-i);k++)
			{
				int j=lpBuffer+i+strlen(str)+1+k;
				char x1=*((char *)j);
				char x2=*((char *)j+1);
				if(
					(*((char *)j) == 0x0d)&&
					(*((char *)j+1) == 0x0a)
					)
				{
					isok = 1;
					free(lpBuffer);
					fclose(stream);
					return	TRUE;
				}else{
					value[m]=*((char *)j);
					m++;
				}
			}
		}
	}
	if(isok)
	{
		free(lpBuffer);
		fclose(stream);
		return	TRUE;
	}else{
		free(lpBuffer);
		fclose(stream);
		return	FALSE;
	}
}


void puthz(char *s,int x,int y,int color)
{
	FILE	*hzk;
	char buffer[32]; //buffer用来存储一个汉字
	register m,n,i,j,k;
	unsigned char qh,wh;
	unsigned long offset;
	
	if ((hzk=fopen("hzk16","rb"))==NULL)
		return;

	while(*s)
	{ qh=*(s)-0xa0; //汉字区位码
	wh=*(s+1)-0xa0;
	offset=(94*(qh-1)+(wh-1))*32L;//计算该汉字在字库中偏移量
	fseek(hzk,offset,SEEK_SET);
	fread(buffer,32,1,hzk); //取出汉字32字节的点阵字模存入buffer中(一个汉字)
	_setcolor( color );
	for (i=0;i<16;i++)//将32位字节的点阵按位在屏幕上打印出来(1:打印,0:不打印),显示汉字
		for(n=0;n<ROW;n++)
			for(j=0;j<2;j++)
				for(k=0;k<8;k++)
					for(m=0;m<COL;m++)
						if (((buffer[i*2+j]>>(7-k))&0x1)!=NULL)
							_setpixel(x+8*j*COL+k*COL+m,y+i*ROW+n);
						s+=2; //因为一个汉字内码占用两个字节,所以s必须加2
						x+=30;
	}
	fclose(hzk);
	//getch();
	//closegraph();
}

/////////////////////////////////////////////////////////////////////////////////
// Function GetYesOrNo
// This function get user selection:Y/N
// GetYesOrNo returns TRUE if user press 'y'or'Y', or FALSE if user press 'n'or'N'
//////////////////////////////////////////////////////////////////////////////////
BOOL GetYes(void)
{
//	printf("%s",Message); 
	for(;;){
		fflush(stdin);
		switch(getch()){
		case 'y':
		case 'Y':
			return TRUE;
//		case 'n':
//		case 'N':
//			return FALSE;
		default:
//			printf("Invalid input,please input again.\n");
//			printf("%s",Message); 
			break;
		}
	}
}
	

BOOL GetFun(int argc, char* argv)
{
	if((argc!=3)||(strlen(argv)>2))
	{
verinfo:
	printf("赏屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯籠n");
	printf("

⌨️ 快捷键说明

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