/[scripts]/trunk/isobar.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/isobar.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 114 - (hide annotations)
Sun May 3 16:35:58 2009 UTC (14 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 6424 byte(s)
boot floppy image extractor described at
http://www.thinkwiki.org/wiki/BIOS_update_without_optical_disk

1 dpavlin 114 /*
2     * isobar.c: ISO Boot Archive Remover.
3     *
4     * Jason Hood, 6, 8 & 9 March, 2005.
5     *
6     * Extract the boot image (or code if no emulation) from a bootable CD-ROM
7     * (or an image of one).
8     *
9     * Adapted from the program by David Brinkman.
10     *
11     * v1.01, 30 May, 2005:
12     * always include Image Size in display.
13     *
14     * v1.02, 5 & 6 June, 2005:
15     * Win32 port.
16     *
17     * v1.03, 10 Nov, 2007:
18     * Linux port by newhren <colimit@gmail.com>
19     *
20     * Todo: possibly replace the boot image in a CD image;
21     * recognise boot sections;
22     * ignore non-bootable CDs (are there any?).
23     *
24     * http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf
25     * http://www.geocities.com/jadoxa/shsucdx/omibar32.zip
26     * http://adoxa.110mb.com/shsucdx/omibar32.zip
27     * http://colimit.googlepages.com/isobar.c
28     *
29     */
30    
31     #define PVERS "1.03"
32     #define PDATE "10 Nov, 2007"
33    
34     #include <stdio.h>
35     #include <stdlib.h>
36     #include <string.h>
37     #include <fcntl.h>
38     #include <stdint.h>
39     #include <unistd.h>
40     #include <sys/stat.h>
41    
42     typedef uint8_t BYTE;
43     typedef uint16_t WORD;
44     typedef uint32_t DWORD;
45     typedef unsigned int UINT;
46    
47     #define MAX 32
48     #define OFLAG O_CREAT | O_WRONLY | O_TRUNC
49     #define OMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
50    
51     char * buf;
52     DWORD offset = 0, imgsize;
53     int fdin;
54    
55     int CDRead( UINT SectorCount, DWORD StartSector )
56     {
57     return (pread(fdin, buf, SectorCount << 11, StartSector << 11) == SectorCount << 11); // Sector size = 0x800
58     }
59    
60     const char* platform[] = { "80x86",
61     "Power PC",
62     "Mac" };
63    
64     const char* boot_type[] = { "no emulation",
65     "1.2 meg floppy",
66     "1.44 meg floppy",
67     "2.88 meg floppy",
68     "hard disk" };
69    
70     enum
71     {
72     E_OK, // No problems
73     E_OPT, // Unknown/invalid option
74     E_MEM, // Not enough memory
75     E_NOCD, // Not a CD drive, MSCDEX/SHSUCDX not installed,
76     // unknown CD format or no CD present
77     E_CREATE, // Unable to create image file
78     E_ABORTED // Read/write error
79     };
80    
81    
82     void usage( void )
83     {
84     puts(
85    
86     "ISOBAR, Version "PVERS" ("PDATE"). Freeware.\n"
87     "\n"
88     "Extract the boot image (or code) from .ISO image of a bootable CD-ROM.\n"
89     "\n"
90     "isobar [-o file] iso-file\n"
91     "\n"
92     "-o file Write the boot image (or code) to the specified filename\n"
93     " (without this, just boot information is displayed).\n"
94     "iso-file An image of a bootable CD-ROM.\n"
95    
96     );
97    
98     exit( E_OK );
99     }
100    
101    
102     int main( int argc, char* argv[] )
103     {
104     int i;
105     int fdout = 0;
106     char *outfile = NULL, *isofile = NULL;
107     DWORD bootfound;
108     int type;
109     DWORD n;
110     UINT len, w;
111    
112    
113     if (argc > 1)
114     {
115     if (argv[1][0] == '?' || argv[1][1] == '?' || !strcmp( argv[1], "--help" ))
116     usage();
117    
118     for (i = 1; i < argc; ++i)
119     {
120     if (*argv[i] == '-')
121     {
122     switch (argv[i][1] | 0x20)
123     {
124     case 'o':
125     if (argv[i][2] == '\0' && argv[i+1] == NULL)
126     {
127     fputs( "ERROR: -o requires filename.\n", stderr );
128     return E_OPT;
129     }
130     outfile = (argv[i][2] == '\0') ? argv[++i] : argv[i] + 2;
131     break;
132    
133     case 'h':
134     usage ();
135     break;
136    
137     default:
138     fprintf( stderr, "ERROR: unknown option: %s.\n", argv[i] );
139     return E_OPT;
140     }
141     }
142     else
143     {
144     isofile = argv[i];
145     }
146     }
147     } else usage();
148    
149    
150     fdin = open( isofile, O_RDONLY );
151    
152     if (fdin == -1)
153     {
154     fprintf( stderr, "ERROR: Cannot open %s.\n", isofile );
155     return E_NOCD;
156     }
157    
158     buf = malloc( MAX << 11 ); // transfer up to MAX Sectors (0x800) at a time
159     if (buf == NULL)
160     {
161     fputs( "ERROR: Not enough memory.\n", stderr );
162     return E_MEM;
163     }
164    
165     if (!CDRead( 1, 0x11 )) // read the boot record
166     {
167     fputs( "Read error!\n", stderr );
168     return E_ABORTED;
169     }
170    
171     if (strcmp( buf+1, "CD001\01EL TORITO SPECIFICATION" ))
172     {
173     fprintf( stderr, "ERROR: %s is not EL TORITO.\n", isofile );
174     return E_NOCD;
175     }
176     bootfound = *(DWORD *)(buf+0x47);
177     printf( "Catalog Sector:\t%lx\n", (long unsigned int)bootfound );
178    
179     if (!CDRead( 1, bootfound )) // read the boot catalog
180     {
181     fputs( "Read error!\n", stderr );
182     return E_ABORTED;
183     }
184    
185     // Just check the key bytes, don't worry about the checksum.
186     if (buf[0x1e] != (char)0x55 || buf[0x1f] != (char)0xAA)
187     {
188     fprintf( stderr, "ERROR: %s has an invalid boot catalog.\n", isofile );
189     return E_NOCD;
190     }
191     type = (BYTE)buf[1];
192     printf( "Platform:\t%s (%02x)\n", (type < 3) ? platform[type] : "unknown",
193     type );
194     printf( "ID String:\t%.24s\n", (buf[4]) ? buf+4 : "not recorded" );
195     printf( "Bootable:\t%s (%02x)\n", (buf[0x20] == (char)0x88) ? "yes" : "no",
196     (BYTE)buf[0x20] );
197     type = buf[0x21] & 15;
198     printf( "Boot Type:\t%s (%02x)\n", (type < 5) ? boot_type[type] : "unknown",
199     (BYTE)buf[0x21] );
200     i = *(WORD *)(buf+0x22);
201     printf( "Load Segment:\t%04x\n", (i == 0) ? 0x7c0 : i );
202     printf( "System Type:\t%02x\n", (BYTE)buf[0x24] );
203     imgsize = *(WORD *)(buf+0x26);
204     printf( "Sector Count:\t%02x (%d)\n", (UINT)imgsize, (UINT)imgsize );
205     offset = *(DWORD *)(buf+0x28);
206     printf( "Image Sector:\t%lx\n", (long unsigned int)offset );
207    
208     switch (type)
209     {
210     case 0: // no emulation
211     break;
212    
213     case 1: // 1.2meg floppy
214     imgsize=1200*2;
215     break;
216    
217     case 2: // 1.44meg floppy
218     imgsize=1440*2;
219     break;
220    
221     case 3: // 2.88meg floppy
222     imgsize=2880*2;
223     break;
224    
225     case 4: // hard disk
226     CDRead( 1, offset ); // read the MBR
227     imgsize = *(DWORD *)(buf+0x1c6) + *(DWORD *)(buf+0x1ca); // offset + size of the first partition
228     break;
229    
230     default:
231     fprintf( stderr, "ERROR: EL TORITO boot media type not recognized\n", isofile );
232     return E_NOCD;
233     }
234    
235     imgsize *= 0x200; // Virtual Sector size = 0x200
236     printf( "Image Size:\t%ld bytes\n", (long int)imgsize );
237    
238     if (outfile)
239     {
240     fdout = open( outfile, OFLAG, OMODE );
241     if (fdout < 0)
242     {
243     fprintf( stderr, "ERROR: Cannot create %s.\n", outfile );
244     return E_CREATE;
245     }
246    
247     do
248     {
249     n = imgsize >> 11; // Sector size = 0x800
250     if (n > MAX)
251     n = MAX;
252     else if (n == 0)
253     n = 1;
254     if (!CDRead( (UINT)n, offset ))
255     {
256     fputs( "Read error!", stderr );
257     return E_ABORTED;
258     }
259     len = (UINT)n << 11;
260     if (len > imgsize)
261     len = (UINT)imgsize;
262     w = write( fdout, buf, len );
263     if (w != len)
264     {
265     fputs( "Write error!", stderr );
266     return E_ABORTED;
267     }
268     offset += n;
269     imgsize -= len;
270     } while (imgsize);
271     close( fdout );
272     printf( "\nThe output image has been saved in: %s\n", outfile );
273     }
274    
275     close( fdin );
276     return 0;
277     }

  ViewVC Help
Powered by ViewVC 1.1.26