📄 hdinfo.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 + -