/**************************************************************************** * maker.c, for DOS. * * Written by, Sohail Qayum Malik #include #include #include "maker.h" _S16 status = 0; _U16 count; void * bootSector; void * FAT; void * rootDir; _U16 FATEntries = 0; _U16 reservedClusters = 0; _U16 usedClusters = 0; _U16 freeClusters = 0; _U16 badClusters = 0; _U16 linkClusters = 0; _U16 link = 0; _U16 blockFileHandle; _U16 numberOf3ByteFATEntries; _U16 soni_reg_cx; /* CH = CYLINDER, CL = SECTOR */ _U16 soni_reg_dx; /* DH = HEAD, DL = DRIVE */ void fileName(char *); void main(int argc, void ** argv){ _U32 chschs; for(count=0; count 1){ for(count=1; count 0 ){ arguments[LINK] = 1; link = atoi(argv[count + 1]); } } if(strcmp(argv[count], "--RDL") == 0 || strcmp(argv[count], "--rdl") == 0 ) arguments[RDL] = 1; if(strcmp(argv[count], "--drive") == 0){ if( ( (argc - 1) - count) <= 0 ){ arguments[DRIVE] = 1; } else{ switch( *((char *)*(argv + count + 1)) ){ case 'a': case 'A': arguments[DRIVE] = 1; break; case 'b': case 'B': arguments[DRIVE] = 2; break; default: arguments[DRIVE] = 1; break; } } } if(strcmp(argv[count], "--help") == 0) arguments[HELP] = 1; } } if(arguments[HELP] == 1){ printf("--drive [a | b]\n"); printf("--scanfat [link]\n"); printf("--rdl | --RDL\n"); printf("Written by, soni.malik@gmail.com\n"); return; } if(arguments[DRIVE] == 0) arguments[DRIVE] = 1; bootSector = (void *)malloc(510); if(bootSector == NULL){ printf("Dude, I'm unable to allocate memory!\n"); return; } /* Read the boot sector SERVICE:SECTORS to read, AH:AL CYLINDER:SECTOR to start from, CH:CL HEAD:DRIVE, DH:DL */ status = accessSectors((void far *)bootSector, 0x0201, 0x0001, (0x0000 + arguments[DRIVE] - 1)); if( (status & 0xff00) != 0 ){ printf("Read error "); numberToAscii(status >> 8 & 0x00ff); printf("\n"); return; } /* Lets go and check the media type, it is important to know this. The function readFatEntries expects an argument which is total number of 3 byte entries in the FAT table. Each 3 byte entry hold two 12 bit value. Each 12 bit value is a pointer to next FAT entry. */ switch(MEDIA_DESCRIPTOR_TYPE){ case 0xf0: numberOf3ByteFATEntries = (80 * NUMBER_OF_HEADS * SECTORS_PER_TRACK - (NUMBER_OF_DIRECTORY_ENTRIES * DIRECTORY_ENTRY_SIZE)/BYTES_PER_SECTOR - FAT_COPIES * SECTORS_PER_FAT )/2; break; } /* allocate memory for the FAT */ FAT = (void *)malloc(FAT_COPIES * SECTORS_PER_FAT * BYTES_PER_SECTOR); if(FAT == NULL){ printf("I'm unable to allocate memory for the FAT.\n"); return; } /* Lets go and read the FAT.... */ soni_reg_dx = (0x0000 + arguments[DRIVE] - 1); /* DH = HEAD, DL = DRIVE */ soni_reg_cx = 0x0002; /* CH = CYLINDER, CL = SECTOR */ printf("Reading FAT...."); for(count=0; count> 8 & 0x00ff); printf("\n"); return; } printf("\xdb"); CHS(); } /* Lets see if FAT are Okhey. */ if( (*((_U32 *)FAT) & 0x00ffffff) != 0x00fffff0 ){ printf("\nFAT magic string error.... "); numberToAscii( *((_U16 *)FAT) ); printf("\n"); return; } if(FAT_COPIES == 2) if( (*((_U32 *)FAT) & 0x00ffffff) != (*( (_U32 *) ((_U8 *)FAT + 4608) ) & 0x00ffffff) ){ printf("\nDude, your FAT is wrong dude.\n"); return; } /* Lets allocate memory for the directory. */ /* allocate memory for the FAT */ rootDir = (void *)malloc(NUMBER_OF_DIRECTORY_ENTRIES * DIRECTORY_ENTRY_SIZE ); if(rootDir == NULL){ printf("I'm unable to allocate memory for the root directory.\n"); return; } /* Lets go and read the directory */ /*soni_reg_cx+=1;*/ printf("\nReading Root Directory...."); for(count=0; count> 8 & 0x00ff); printf("\n"); return; } printf("\xDB"); CHS(); } if(arguments[RDL] == 1){ printf("\n\nRoot directory listing.\n"); directoryList(rootDir ,NUMBER_OF_DIRECTORY_ENTRIES); } if(arguments[FAT_SCAN] == 1){ printf("\n\nFat scan.\n"); if(arguments[LINK] == 1){ if( (blockFileHandle = open("block.bin", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, S_IREAD | S_IWRITE)) < 0 ){ printf("Unable to open block.bin .\n"); return; } chschs = makeCHS(link, FAT_COPIES * SECTORS_PER_FAT + (NUMBER_OF_DIRECTORY_ENTRIES * DIRECTORY_ENTRY_SIZE)/BYTES_PER_SECTOR ); if( write(blockFileHandle, ((_U16 *)&chschs + 1), 2) < 0 ){ printf("Unable to write the file\n"); return; } if( write(blockFileHandle, ((_U8 *)&chschs + 1), 1) < 0 ){ printf("Unable to write the file\n"); return; } link = link * 1.5; readFATEntries((void far *)FAT, numberOf3ByteFATEntries, link); } else readFATEntries((void far *)FAT, numberOf3ByteFATEntries, 0); printf("\n\nTotal Clusters = %d, Used Clusters = %d, Free Clusters = %d, Reserved Clusters = %d, Bad Clusters = %d, LinkCluster = %d.",FATEntries, usedClusters, freeClusters, reservedClusters, badClusters, linkClusters); } if(arguments[LINK] == 1) close(blockFileHandle); } void evaluateFATEntry(_U16 link){ _U32 chschs; if(FATEntries < numberOf3ByteFATEntries * 2 - 1 ){ FATEntries++; switch(link){ case 0x0000: /*printf("F");*/ printf("\xb2"); freeClusters++; break; case 0x0ff0: case 0x0ff1: case 0x0ff2: case 0x0ff3: case 0x0ff4: case 0x0ff5: case 0x0ff6: printf("\xdd"); reservedClusters++; break; case 0x0ff7: /*B*/ printf("\xb0"); badClusters++; break; default: switch(flag){ case 1: chschs = makeCHS(link, FAT_COPIES * SECTORS_PER_FAT + (NUMBER_OF_DIRECTORY_ENTRIES * DIRECTORY_ENTRY_SIZE)/BYTES_PER_SECTOR); if( write(blockFileHandle, ((_U16 *)&chschs + 1), 2) < 0 ){ printf("Unable to write the file\n"); return; } if( write(blockFileHandle, ((_U8 *)&chschs + 1), 1) < 0 ){ printf("Unable to write the file\n"); return; } /*chsArray[linkClusters + 1] = chschs;*/ printf("\xdb"); /*printf("<%.4x,",link); printf("%.8lx>",chschs);*/ flag = link * 1.5; linkClusters++; break; default: /*printf("U");*/ printf("\xb1"); break; } usedClusters++; break; } } } void directoryList(struct directory near * rootDir, _U16 entries){ _U16 count; for(count=0; countlink); printf(" Size = %.8ld ",(rootDir + count)->size); fileName((rootDir + count)->name); printf("\n"); } } void fileName(char * name){ _U16 count; _U16 localCount =0; _U16 nullName = 0; for(count=0; count<11; count++){ if(name[count] != ' ' && name[count] != 0){ printf("%c", name[count]); localCount++; } if(name[count] == ' ' || name[count] == 0){ localCount++; nullName++; } if(localCount == 8 && nullName != 8){ if(name[localCount] != ' ') printf("."); } } } void CHS(void){ /* See if we have read the last sector of the current track. */ if( (soni_reg_cx & 0x00ff) == SECTORS_PER_TRACK ){ /* Since we have read the last sector, the next sector to read will be the first sector. Keep the cylinder as it is, make the sector 0 and then in the next statement make it 1. */ soni_reg_cx = (soni_reg_cx & 0xff00); soni_reg_cx+=1; /* Since we just read the last sector of the head 0 or 1 so now we have to either change the head to 0 or 1, depending upon the current value of the head and then if the head is changed from 1 to 0 the cylinder should also be incremented by 1. */ /* See if the head is 0, if it is make it 1. */ if( (soni_reg_dx & 0xff00) == 0 ){ soni_reg_dx = (soni_reg_dx & 0x00ff); soni_reg_dx+=0x0100; } /* No the head is not 0, it is 1, so now the cylinder should also be incremented. Now first make the head 0 and then increment the cylinder. */ else{ soni_reg_dx = (soni_reg_dx & 0x00ff); soni_reg_cx+=0x0100; } } /* No we have not read the last sector, so simply increment the sector count. */ else soni_reg_cx+=1; }