home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / dos / lread10.exe / READDISK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-23  |  5.4 KB  |  223 lines

  1. /* If we are under DOS, install the first half of the file.
  2.  * Otherwise, install the second half.
  3.  **************************************************************/
  4.  
  5. #ifdef __TURBOC__
  6.  
  7. /* Read DOS */
  8. /* by Jason Hunter
  9.  * April, 1995
  10. */
  11.  
  12. /* This file's primary purpose is to give DOS the ability to read
  13.  * a set of bytes from the Linux partition.  It has to look at the
  14.  * partition table and find where the Linux partition is and what
  15.  * the drive's parameters look like so it can convert a ulong
  16.  * representative of a logical byte number in the partition to
  17.  * a track #, sector #, head assignment, and offset in that sector.
  18.  * It's in essence a DOS version of Linux's lseek off /dev/hda4.
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <bios.h>
  23. #include <dos.h>
  24. #include <stdlib.h>
  25. #include <conio.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <fcntl.h>
  29. #include <string.h>
  30.  
  31. #define DEBUG 0  /* true==1 */
  32.  
  33. /* globals */
  34. int HEADS;
  35. int SECTORS;
  36. long start;
  37. long num_sect;
  38.  
  39.  
  40. void convert(unsigned long x, int *head, int *track, int *sector, int *offset)
  41. {
  42.   unsigned long logicsect;
  43.   unsigned long absolsect;
  44.  
  45.   logicsect = x / 512;
  46.   absolsect = logicsect+start;
  47.   *track = (absolsect / (SECTORS*HEADS));  /* if we had to % we'd fall off */
  48.   *head = (absolsect / SECTORS) % HEADS;
  49.   *sector = (absolsect % SECTORS) +1;
  50.   *offset = x % 512;
  51.  
  52.   if (DEBUG)
  53.   {
  54.     printf ("Beginning at sect=%ld...\n",start);
  55.     printf ("byte=%4ld logic: %-4ld absol: %-4ld head: %-2d track: %-3d sect: %-4d  offset: %-d\n",
  56.                 x,logicsect,absolsect,*head,*track,*sector,*offset);
  57.   }
  58.  
  59.   if (absolsect > start+num_sect)
  60.   {
  61.     fprintf(stderr,"You cannot access ABOVE the Linux partition.\n");
  62.     exit(-1);
  63.   }
  64. }
  65.  
  66.  
  67. void examine_drive(void)
  68. {
  69.   int rc;
  70.   int i,j,k;
  71.   char buf[512];
  72.   int run[16];
  73.  
  74.   int boot, head, sect, cyl;
  75.   int first_head, first_sect, first_cyl;
  76.   int end_head, end_sect, end_cyl;
  77.   int system;
  78.  
  79.   if (DEBUG)
  80.     printf ("\n\n------------------\n");
  81.  
  82.   /* read the partition table from the first hard drive */
  83.   rc = biosdisk (2, 128, 0, 0, 1, 1, buf);
  84.   if (DEBUG)
  85.     printf ("rc is %d\n",rc);
  86.  
  87.   /* For fun, tell what's the OEM for the table */
  88.   if (DEBUG)
  89.     printf ("\nOEM:\n%c%c%c%c\n",buf[2],buf[3],buf[4],buf[5]);
  90.  
  91.   /* scan through the four entries looking for Linux */
  92.   j=1;
  93.  
  94.   for (k=0;k<4;k++)
  95.   {
  96.     for (i=0;i<16;i++)
  97.     {
  98.       run[i] = (int) buf[446+(k*16)+i];
  99.       if (run[i] < 0)
  100.         run[i] = run[i] - 0xff00;
  101.       if (DEBUG)
  102.       {
  103.         printf("%x, ",run[i]);
  104.         if (!(j % 16)) printf ("\n\n");
  105.         j++;
  106.       }
  107.     }
  108.     if (run[4] == 0x83) break;   /* we found the Linux partition */
  109.   }
  110.  
  111.   /* If you never found Linux... */
  112.   if (k==4)  /* error!! */
  113.   {
  114.     fprintf(stderr,"Could not find Linux partition\n");
  115.     exit (-1);
  116.   }
  117.  
  118.   boot=run[0];
  119.   first_head=run[1];
  120.   first_sect=run[2];
  121.   first_cyl=run[3];
  122.  
  123.   first_cyl += (first_sect / 64)*256;  /* add top 2 bits of first_sect */
  124.   first_sect = first_sect % 192;       /* and remove them from first_sect */
  125.  
  126.   system=run[4];
  127.  
  128.   end_head=run[5];
  129.   end_sect=run[6];
  130.   end_cyl=run[7];
  131.  
  132.   end_cyl += (end_sect / 64)*256;      /* add top 2 bits of end_sect */
  133.   end_sect = end_sect % 192;           /* and remove them from end_sect */
  134.  
  135.   start = (long) run[11];
  136.   start = start*256 + run[10];
  137.   start = start*256 + run[9];
  138.   start = start*256 + run[8];
  139.   num_sect = (long) run[15];
  140.   num_sect = num_sect*256 + run[14];
  141.   num_sect = num_sect*256 + run[13];
  142.   num_sect = num_sect*256 + run[12];
  143.  
  144.   HEADS = end_head+1;
  145.   SECTORS = start/(first_cyl*HEADS);
  146.  
  147.   /* Brag about the results */
  148.   if (DEBUG)
  149.   {
  150.     printf ("\n      THE DRIVE HAS:\n");
  151.     printf ("    number of heads: %d\n",HEADS);
  152.     printf ("  number of sectors: %d\n",SECTORS);
  153.     printf ("\n   LINUX ITSELF HAS:\n");
  154.     printf ("     boot indicator: %xh\n",boot);
  155.     printf ("     beginning head: %d\n",first_head);
  156.     printf ("   beginning sector: %d\n",first_sect);
  157.     printf (" beginning cylinder: %d\n",first_cyl);
  158.     printf ("   system indicator: %xh\n",system);
  159.     printf ("        ending head: %d\n",end_head);
  160.     printf ("      ending sector: %d\n",end_sect);
  161.     printf ("    ending cylinder: %d\n",end_cyl);
  162.     printf ("relative start sect: %ld\n",start);
  163.     printf ("  number of sectors: %ld\n",num_sect);
  164.   }
  165.  
  166. }
  167.  
  168.  
  169. int readdisk( char *buf, unsigned long loc, size_t size )
  170. {
  171.   int head,cyl,sect,offset;
  172.   int i,rc;
  173.   char temp[20480];           /* when this gets big, it tromps data */
  174.  
  175.   convert (loc,&head,&cyl,§,&offset);
  176.  
  177.   rc = biosdisk (2, 128, head,cyl,sect,(size/512)+2,temp);
  178.  
  179.   if (DEBUG)
  180.     printf ("rc is %d\n",rc);
  181.  
  182.   memcpy(buf,temp+offset,size);  /* no ending NULL */
  183.  
  184.   if (rc==0)
  185.     return size;
  186.   else
  187.     return 0;
  188. }
  189.  
  190.  
  191.  
  192.  
  193. /* If we're under Linux (for testing) include the following */
  194.  
  195. #else
  196.  
  197.  
  198. /* Read Linux */
  199. /* Written by Dave Lutz */
  200.  
  201. /* This file is to be used for testing this software under Linux. */
  202.  
  203. #include <stdio.h>
  204. #include <sys/types.h>
  205. #include <sys/stat.h>
  206. #include <fcntl.h>
  207.  
  208. int IN;                /* holds the open input dev */
  209. typedef unsigned char byte;
  210.  
  211. int open_dev( char *name )
  212. {
  213.   return( IN = open( name, O_RDONLY ) ); /* open the file */
  214. }
  215.  
  216. int readdisk( byte *buf, unsigned long loc, size_t size )
  217. {
  218.   lseek( IN, loc, SEEK_SET );
  219.   return( read( IN, buf, size ) );
  220. }
  221.  
  222. #endif
  223.