www.pudn.com > DiskIOForC_class.rar > DiskOpt.cpp


// DiskOpt.cpp: implementation of the CDiskOpt class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "DiskIO.h" 
#include "DiskOpt.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CDiskOpt::CDiskOpt() 
{ 
 
} 
 
CDiskOpt::~CDiskOpt() 
{ 
 
} 
int CDiskOpt::WinBiosDisk(unsigned char command, 
				unsigned char drive, 
				unsigned char head, 
				unsigned char track, 
				unsigned char sector, 
				unsigned char nsectors, 
				void *buffer) 
{ 
	HANDLE hd; 
	DWORD dw; 
 
	//int13 寄存器参数块 
	typedef struct tagPackage 
	{ 
		void  *buffer;            //  ebx 寄存器 
 
		unsigned char  drive;     //  edx 寄存器 
		unsigned char  head;      //  
		unsigned short edx_high;  //    
 
		unsigned char  sector;    //  ecx 寄存器 
		unsigned char  track;     // 
		unsigned short ecx_high;  // 
 
		unsigned char  number;    // eax 寄存器 
		unsigned char  option;    // 
		unsigned short eax_high;  // 
 
		unsigned int   edi;       // edi 寄存器 
 
		unsigned int   esi; 
		unsigned int   eflag; 
	} PK; 
 
	PK pk; 
	memset(&pk,0,sizeof PK); 
	pk.buffer=buffer; 
	pk.drive=drive; 
	pk.head=head; 
	pk.sector=sector; 
	pk.track=track; 
	pk.option=command; 
	pk.number=nsectors; 
 
	if(command==0x18)	 
		pk.edi=(int)buffer; 
	hd=CreateFile("\\\\.\\vWin32", 
		GENERIC_READ,FILE_SHARE_READ, 
		NULL,OPEN_EXISTING,NULL, 
		NULL); 
	if(hd==NULL) 
		return 1; 
 
	DeviceIoControl(hd,4,&pk,0x1c,&pk,0x1c,&dw,NULL); 
 
	if(command==0x8) 
		memcpy(buffer,(unsigned char *)pk.edi,11); 
	CloseHandle(hd); 
	return pk.option; 
} 
int CDiskOpt::WinReadDisk(unsigned char drive, 
				unsigned char sector, 
				unsigned char nsectors, 
				void *buffer) 
{ 
	HANDLE hd; 
	DWORD dw; 
	struct PARA  
	{ 
		unsigned int start_sector; 
		unsigned short number; 
		void *buffer; 
	}para; 
  
	typedef struct tagPackage 
	{ 
		DWORD ebx; 
		DWORD edx; 
		DWORD ecx; 
		DWORD eax; 
		DWORD edi; 
		DWORD esi; 
		DWORD eflag; 
	} REGPACK; 
 
	REGPACK pk; 
	para.start_sector=sector; 
	para.number=nsectors; 
	para.buffer=buffer; 
	memset(&pk,0,sizeof REGPACK); 
	memset(¶,0,sizeof (struct PARA)); 
	pk.eax=0x7305; 
	pk.ecx=0xffff; 
	pk.edx=drive+1; 
	pk.esi=0; 
	pk.ebx=(DWORD)¶ 
 
	hd=CreateFile("\\\\.\\vWin32", 
		GENERIC_READ, 
		FILE_SHARE_READ, 
		NULL, 
		OPEN_EXISTING, 
		NULL, 
		NULL); 
	if(hd==NULL) 
		return 1; 
	DeviceIoControl(hd,6,&pk,0x1c,&pk,0x1c,&dw,NULL); 
	CloseHandle(hd); 
	return pk.eflag; 
} 
 
int CDiskOpt::MakeSector(unsigned char drive, 
			   unsigned char head, 
			   unsigned char track, 
			   unsigned char sector, 
			   unsigned char *buffer) 
{ 
	int i,ret,retry; 
	unsigned char ctemp[513],cmd[3]={5,3,2}; 
	for(i=0;i<3;i++) 
	{ 
		retry=5; 
		while(retry)  
 		{ 
			  if(i==0) 
			  { 
				  ctemp[0]=track; 
				  ctemp[1]=head; 
				  ctemp[2]=sector; 
				  ctemp[3]=2; 
				} 
				else if(i==1) 
					memcpy(ctemp,buffer,512); 
				ret=WinBiosDisk(cmd[i],drive,head,track,sector,1,ctemp); 
				if(ret==0)break; 
				else if(ret==0x3)return ret; 
				WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,ctemp); //重置磁头 
				retry--;	  
		} 
		if(!retry)return ret; 
	} 
	ret=memcmp(ctemp,buffer,512); 
	if(ret) 
		return 0xffff; 
	else 
		return 0; 
} 
 
int CDiskOpt::ReadSector(unsigned char drive, 
			   unsigned char head, 
			   unsigned char track, 
			   unsigned char sector, 
			   unsigned char *buffer) 
{ 
	int i,retry=5; 
	while(retry)  
	{ 
		i=WinBiosDisk(2,drive,head,track,sector,1,buffer); 
		if(i==0)break; 
		WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,buffer); //重置磁头 
		retry--; 
	} 
	return i; 
} 
 
int CDiskOpt::WriteSector(unsigned char drive, 
				unsigned char head, 
				unsigned char track, 
				unsigned char sector, 
				unsigned char *buffer) 
{ 
	int i,retry=5; 
	char *buffer1; 
	buffer1=new char[8196]; 
	while(retry)  
	{ 
		i=WinBiosDisk(3,drive,head,track,sector,1,buffer); 
		if(i==0)break; 
		WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,buffer1); //重置磁头 
		retry--; 
	} 
	delete []buffer1; 
	return i; 
} 
 
void CDiskOpt::ErrMsg(int iCode, LPSTR buffer) 
{ 
	switch(iCode) 
	{ 
	case 0: 
			wsprintf(buffer,"操作成功!"); 
		break; 
	case 1: 
		wsprintf(buffer,"无效的操作!"); 
		break; 
	case 2: 
		wsprintf(buffer,"地址标记没有找到!");    
		break; 
	case 3: 
		wsprintf(buffer,"磁盘被写保护!"); 
		break; 
	case 4: 
		wsprintf(buffer,"扇区没有找到!"); 
		break; 
	case 6: 
		wsprintf(buffer,"磁盘被更换!"); 
		break; 
	case 0xa: 
		wsprintf(buffer,"发现坏扇区!"); 
		break; 
	case 0x80: 
		wsprintf(buffer,"磁盘没有准备好"); 
		break; 
	case 0xfffc: 
		wsprintf(buffer,"打开动态链接库 BIOS.DLL 失败!"); 
		break; 
	case 0xfffd: 
		wsprintf(buffer,"BIOS.DLL 没有 export 函数 "); 
		break; 
	case 0xffff: 
		wsprintf(buffer,"数据错误!"); 
		break; 
	default: 
		wsprintf(buffer,"错误代码: 0x%X",iCode); 
		break; 
	} 
 
}