www.pudn.com > CLONE.rar > CLONE.C


#include  
#include  
#include  
#include  
#define _TC_ 1 
#ifndef _TC_ 
struct REGPACK { 
   unsigned  r_ax, r_bx, r_cx, r_dx; 
   unsigned  r_bp, r_si, r_di; 
   unsigned  r_ds, r_es, r_flags; 
}; 
#endif 
char READ  = 0x02; 
char WRITE = 0x02; 
#define MAX_SECTOR_NUMBER 100 
#define BYTE unsigned char 
#define WORD unsigned int 
#define DWORD unsigned long 
#define SectorEnd  0xAA55 
#define DEFAULT_DISK 0x80 
typedef struct BootRecord{ 
	unsigned char Go2BootCode[3]; 
	unsigned char OEMNameVersion[8]; 
	WORD BytesPerSector; 
	BYTE SectorsPerCluster; /* must be power of 2 */ 
	WORD ReservedSectors; 
	BYTE CopiesOfFAT; 
	WORD MaxNumberOfRootEntries; 
	WORD TotalSectors; 
	BYTE MediaType; 
	WORD SectorsInFAT; 
	WORD SectorsPerTrack; 
	WORD HiddenSectors; 
}BR; 
typedef struct PartionTable{ 
	BYTE BootTAG; /*Boot TAG */ 
	BYTE StartHead; /*Starting Head*/ 
	unsigned StartSector:6; 
	unsigned StartCylinder_H2:2; 
	unsigned StartCylinder_L8:8; 
	BYTE SystemID; 
	BYTE EndHead; 
	unsigned EndSector:6; 
	unsigned EndCylinder_H2:2; 
	unsigned EndCylinder_L8:8; 
	DWORD RelativeSectors; 
	DWORD TotalSectors; 
}PT; 
typedef struct MainBootRecord{ 
	unsigned char Dummy[0x1B0]; 
	WORD blank[7]; 
	PT PT1; 
	PT PT2; 
	PT PT3; 
	PT PT4; 
	WORD ENDTAG; 
}MBR; 
char Version[]="Composed by Kuang Yujun, Bupt. 2001/08/17"; 
#define DISK 0x13 
#define _BYTE_ 0x100 
int ReadSector(unsigned char *buffer, 
	BYTE Sectors, DWORD Cylinder, BYTE Header, BYTE Sector, BYTE Driver) 
{ 
	struct REGPACK REGs; 
	REGs.r_es=FP_SEG(buffer); 
	REGs.r_bx=FP_OFF(buffer); 
	REGs.r_ax=READ*_BYTE_+Sectors%_BYTE_; 
	REGs.r_flags=0; 
	REGs.r_cx=(Cylinder%_BYTE_)*_BYTE_+((Cylinder/_BYTE_)%0x04)*0x40+Sector%0x40; 
	REGs.r_dx=(Header%_BYTE_)*_BYTE_+Driver%_BYTE_; 
	intr(DISK, ®s); 
	if(REGs.r_flags & 1) 
		return(-(int)REGs.r_ax/_BYTE_); 
	else 
		return(Sectors%_BYTE_); 
} 
int WriteSector(unsigned char *buffer_d, 
	BYTE Sectors_d, DWORD Cylinder_d, BYTE Header_d, BYTE Sector_d, BYTE Driver_d) 
{ 
	struct REGPACK REGs_d; 
	REGs_d.r_es=FP_SEG(buffer_d); 
	REGs_d.r_bx=FP_OFF(buffer_d); 
	REGs_d.r_ax=WRITE*_BYTE_+Sectors_d%_BYTE_; 
	REGs_d.r_flags=0; 
	REGs_d.r_cx=(Cylinder_d%_BYTE_)*_BYTE_+((Cylinder_d/_BYTE_)%0x04)*0x40+Sector_d%0x40; 
	REGs_d.r_dx=(Header_d%_BYTE_)*_BYTE_+Driver_d%_BYTE_; 
	intr(DISK, ®s_d); 
	if(REGs_d.r_flags & 1) 
		return(-(int)REGs_d.r_ax/_BYTE_); 
	else 
		return(Sectors_d%_BYTE_); 
} 
int ReadDiskPara(BYTE Driver,BYTE *TYPE,WORD *MaxCylinder,BYTE *MaxSector,WORD *MaxHead, BYTE *Drivers) 
{ 
	struct REGPACK REGs; 
	REGs.r_ax = 0x0800; 
	REGs.r_bx = 0x0000; 
	REGs.r_dx = Driver%_BYTE_; 
	intr(DISK, ®s); 
	if(REGs.r_flags & 1) 
		return(-1); 
	else{ 
		*TYPE = (BYTE)(REGs.r_bx&0xFF); 
		*MaxCylinder = ((REGs.r_cx%_BYTE_)/0x40)*_BYTE_+REGs.r_cx/_BYTE_; 
		*MaxHead = REGs.r_dx/_BYTE_; 
		*MaxSector = REGs.r_cx%0x40; 
		*Drivers = REGs.r_dx%_BYTE_; 
		return(*MaxCylinder); 
	} 
} 
unsigned char GetHardDriveIndex(char* driveName) 
{ 
	unsigned char HardDrive; 
	switch(driveName[0]){ 
		case 'A': case 'a': HardDrive = 0x00; break; 
		case 'B': case 'b': HardDrive = 0x01; break; 
		case '1': case 'C': case 'c': HardDrive = 0x80; break; 
		case '2': case 'D': case 'd': HardDrive = 0x81; break; 
		case '3': case 'E': case 'e': HardDrive = 0x82; break; 
		case '4': case 'F': case 'f': HardDrive = 0x83; break; 
		default:{ 
			fprintf(stdout, "\n\tPANIC: not valid diskname given.\n"); 
			exit(-1); 
		}break; 
	} 
	return HardDrive; 
} 
char ProgressMark(){ 
	static i; 
	switch(i%8){ 
		case 0: i++; return('-'); 
		case 1: i++; return('-'); 
		case 2: i++; return('\\'); 
		case 3: i++; return('\\'); 
		case 4: i++; return('|'); 
		case 5: i++; return('|'); 
		case 6: i++; return('/'); 
		case 7: i++; return('/'); 
	} 
} 
int main(int argc, char **argv) 
{ 
	MBR MBRs[MAX_SECTOR_NUMBER]; 
	DWORD ii; 
	BYTE type_s=0,type_d=0; 
	BYTE maxSector_s,maxSector_d,drivers, maxBlock = MAX_SECTOR_NUMBER /* in sectors */; 
	BYTE srcHardDrive,dstHardDrive; 
	WORD maxHead_s,maxHead_d, maxCylinder_s,maxCylinder_d; 
	DWORD maxSectors=0; 
	BYTE Sector; WORD Cylinder, Head; 
	char *fileName=NULL; 
	char *dstDriveName; 
	char *srcDriveName; 
	char *blockSize=NULL; 
	FILE *fp; 
/*	char *MSWIN="MSWIN4.1"; 
	char *N1TFS ="NTFS    "; 
	char *BootRecordMSGFormat="\n;At:[%9lu of %9lu]\n;Position:\tHead/Side|Cylinder|Sector|\n[BOOTCODE]\t%9u %8u %6u\n"; 
	char *PartionTableMSGFormat="\n;PartionTable:[%10lu of %10lu]\n;Position:\tHead/Side|Cylinder|Sector|\n[PARTION]\t%9u %8u %6u\n;     |ID|A|sHead|sCylind|sSec|eHead|eCylind|eSec|RelativeSectors|TotalSectors|\n"; 
*/	char *HelpMessage="CLONE: Copy a disk content to another disk.\n\n"\ 
				"Usage:\tCLONE [] [<-|/>\n"\ 
				"\t-l\tSpecify \n"\ 
				"\t-s\tSpecify \n"\ 
				"\t-d\tSpecify \n"\ 
				"\t-n\tSpecify  (<= 100)\n"\ 
				"\t/write\tTo confirm copy, otherwise, just for simulation.\n" 
				"\t-?/h\tShow this help message\n   Shareware for free distribution and evaluation.\n   Composed by Kuang Yujun, Bupt (KuangYujun@263.net), and Modified by TongXiaopeng.\n  "; 
	char Message[256]; 
 
	if(argc==1){ 
		fprintf(stdout, "%s\nError: No Options given. Press ENTER to exit for another try...", HelpMessage); 
		fflush(stdin);getchar();fflush(stdin); 
		exit(-1); 
	} 
	if(fileName== NULL) fp = stdout; 
	else if((fp=fopen(fileName, "wt")) == NULL) fp = stdout; 
	for((int)ii=1; (int)ii MAX_SECTOR_NUMBER) maxBlock = MAX_SECTOR_NUMBER; 
				else maxBlock = tmp; 
			} 
		} 
		maxSectors = (DWORD)maxCylinder_s*maxSector_s*(maxHead_s+1); 
		Head = 0; 
		Cylinder = 0; 
		Sector = 1; 
		for(ii = 0; ii < maxSectors;) 
		{ 
			int jj; 
			gotoxy(1,1); 
			cprintf(";Reading[%c]:(%c)%9lu/%-9lu[Head:%4u/ Cylinder:%5u/ Sector:%2u] by %3d", \ 
				srcDriveName[0], ProgressMark(), ii, maxSectors, Head, Cylinder, Sector, maxBlock); 
			jj=ReadSector((char*)MBRs, maxBlock, Cylinder, Head, Sector,srcHardDrive); 
			if(jj >= 0) 
			{ 
				gotoxy(1,2); 
				cprintf(";Writing[%c]:(%c)%9lu/%-9lu[Head:%4u/ Cylinder:%5u/ Sector:%2u] by %3d", \ 
					dstDriveName[0], ProgressMark(), ii, maxSectors, Head, Cylinder, Sector, maxBlock); 
				jj=WriteSector((char*)MBRs, maxBlock, Cylinder, Head, Sector,dstHardDrive); 
				if(jj < 0){ 
					fprintf(stdout, "\n\n\n\n;Disk Access Failure:[Code %02X]------Sectors Skipped.\n", -jj); 
				} 
			} 
			else{ 
				fprintf(stdout, "\n\n\n\n;Disk Access Failure:[Code %02X]------Sectors Skipped.\n", -jj); 
			} 
			if(kbhit()){ 
				int key; 
				if((key = getch()) == 0){ 
					key = getch(); 
				} 
				else{ 
					if(key == 0x1B){ 
						puttext(1,1,80,25,ScreenBuffer); 
						gotoxy(x,y); 
						exit(-1); 
					} 
				} 
			} 
			ii += maxBlock; 
			Sector = ii%maxSector_s+1; 
			Head = (ii/maxSector_s)%(maxHead_s+1); 
			Cylinder = (ii/maxSector_s/(maxHead_s+1))%maxCylinder_s; 
		} 
		if(fp != stdout) fclose(fp); 
		puttext(1,1,80,25,ScreenBuffer); 
		gotoxy(x,y); 
	} 
	else{ 
		fprintf(fp, "Disk Parametert not compatible. Abort operation.\n"); 
		exit(-1); 
	} 
}