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 [ ] [<-|/>|h>\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); } }