VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/biossums.c@ 7015

最後變更 在這個檔案從7015是 1,由 vboxsync 提交於 55 年 前

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 12.0 KB
 
1/* biossums.c --- written by Eike W. */
2
3#include <stdlib.h>
4#include <stdio.h>
5
6typedef unsigned char byte;
7
8void check( int value, char* message );
9
10#define LEN_BIOS_DATA 0x10000
11#define MAX_OFFSET (LEN_BIOS_DATA - 1)
12
13
14#define BIOS_OFFSET 0xFFFF
15
16long chksum_bios_get_offset( byte* data, long offset );
17byte chksum_bios_calc_value( byte* data, long offset );
18byte chksum_bios_get_value( byte* data, long offset );
19void chksum_bios_set_value( byte* data, long offset, byte value );
20
21
22#define _32__LEN 9
23#define _32__CHKSUM 10
24
25#define _32__MINHDR 16
26
27long chksum__32__get_offset( byte* data, long offset );
28byte chksum__32__calc_value( byte* data, long offset );
29byte chksum__32__get_value( byte* data, long offset );
30void chksum__32__set_value( byte* data, long offset, byte value );
31
32
33#define _MP__LEN 8
34#define _MP__CHKSUM 10
35
36#define _MP__MINHDR 16
37
38long chksum__mp__get_offset( byte* data, long offset );
39byte chksum__mp__calc_value( byte* data, long offset );
40byte chksum__mp__get_value( byte* data, long offset );
41void chksum__mp__set_value( byte* data, long offset, byte value );
42
43
44#define PCMP_BASELEN 4
45#define PCMP_CHKSUM 7
46#define PCMP_EXT_LEN 40
47#define PCMP_EXT_CHKSUM 42
48
49#define PCMP_MINHDR 42
50
51long chksum_pcmp_get_offset( byte* data, long offset );
52byte chksum_pcmp_calc_value( byte* data, long offset );
53byte chksum_pcmp_get_value( byte* data, long offset );
54void chksum_pcmp_set_value( byte* data, long offset, byte value );
55
56
57#define _PIR_LEN 6
58#define _PIR_CHKSUM 31
59
60#define _PIR_MINHDR 32
61
62long chksum__pir_get_offset( byte *data, long offset );
63byte chksum__pir_calc_value( byte* data, long offset );
64byte chksum__pir_get_value( byte* data, long offset );
65void chksum__pir_set_value( byte* data, long offset, byte value );
66
67
68byte bios_data[LEN_BIOS_DATA];
69
70
71int main( int argc, char* argv[] ) {
72
73 FILE* stream;
74 long offset, tmp_offset;
75 byte cur_val = 0, new_val = 0;
76 int hits;
77
78
79 if( argc != 2 ) {
80 printf( "Error. Need a file-name as an argument.\n" );
81 exit( EXIT_FAILURE );
82 }
83
84 if(( stream = fopen( argv[1], "rb" )) == NULL ) {
85 printf( "Error opening %s for reading.\n", argv[1] );
86 exit( EXIT_FAILURE );
87 }
88 if( fread( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) {
89 printf( "Error reading 64KBytes from %s.\n", argv[1] );
90 fclose( stream );
91 exit( EXIT_FAILURE );
92 }
93 fclose( stream );
94
95 hits = 0;
96 offset = 0L;
97 while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) {
98 offset = tmp_offset;
99 cur_val = chksum__32__get_value( bios_data, offset );
100 new_val = chksum__32__calc_value( bios_data, offset );
101 printf( "\nPCI-Bios header at: 0x%4lX\n", offset );
102 printf( "Current checksum: 0x%02X\n", cur_val );
103 printf( "Calculated checksum: 0x%02X ", new_val );
104 hits++;
105 }
106 if( hits == 1 && cur_val != new_val ) {
107 printf( "Setting checksum." );
108 chksum__32__set_value( bios_data, offset, new_val );
109 }
110 if( hits >= 2 ) {
111 printf( "Multiple PCI headers! No checksum set." );
112 }
113 if( hits ) {
114 printf( "\n" );
115 }
116
117
118 hits = 0;
119 offset = 0L;
120 while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) {
121 offset = tmp_offset;
122 cur_val = chksum__mp__get_value( bios_data, offset );
123 new_val = chksum__mp__calc_value( bios_data, offset );
124 printf( "\nMP header at: 0x%4lX\n", offset );
125 printf( "Current checksum: 0x%02X\n", cur_val );
126 printf( "Calculated checksum: 0x%02X ", new_val );
127 hits++;
128 }
129 if( hits == 1 && cur_val != new_val ) {
130 printf( "Setting checksum." );
131 chksum__mp__set_value( bios_data, offset, new_val );
132 }
133 if( hits >= 2 ) {
134 printf( "Warning! Multiple MP headers. No checksum set." );
135 }
136 if( hits ) {
137 printf( "\n" );
138 }
139
140
141 hits = 0;
142 offset = 0L;
143 while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) {
144 offset = tmp_offset;
145 cur_val = chksum_pcmp_get_value( bios_data, offset );
146 new_val = chksum_pcmp_calc_value( bios_data, offset );
147 printf( "\nPCMP header at: 0x%4lX\n", offset );
148 printf( "Current checksum: 0x%02X\n", cur_val );
149 printf( "Calculated checksum: 0x%02X ", new_val );
150 hits++;
151 }
152 if( hits == 1 && cur_val != new_val ) {
153 printf( "Setting checksum." );
154 chksum_pcmp_set_value( bios_data, offset, new_val );
155 }
156 if( hits >= 2 ) {
157 printf( "Warning! Multiple PCMP headers. No checksum set." );
158 }
159 if( hits ) {
160 printf( "\n" );
161 }
162
163
164 hits = 0;
165 offset = 0L;
166 while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) {
167 offset = tmp_offset;
168 cur_val = chksum__pir_get_value( bios_data, offset );
169 new_val = chksum__pir_calc_value( bios_data, offset );
170 printf( "\n$PIR header at: 0x%4lX\n", offset );
171 printf( "Current checksum: 0x%02X\n", cur_val );
172 printf( "Calculated checksum: 0x%02X ", new_val );
173 hits++;
174 }
175 if( hits == 1 && cur_val != new_val ) {
176 printf( "Setting checksum." );
177 chksum__pir_set_value( bios_data, offset, new_val );
178 }
179 if( hits >= 2 ) {
180 printf( "Warning! Multiple $PIR headers. No checksum set." );
181 }
182 if( hits ) {
183 printf( "\n" );
184 }
185
186
187 offset = 0L;
188 offset = chksum_bios_get_offset( bios_data, offset );
189 cur_val = chksum_bios_get_value( bios_data, offset );
190 new_val = chksum_bios_calc_value( bios_data, offset );
191 printf( "\nBios checksum at: 0x%4lX\n", offset );
192 printf( "Current checksum: 0x%02X\n", cur_val );
193 printf( "Calculated checksum: 0x%02X ", new_val );
194 if( cur_val != new_val ) {
195 printf( "Setting checksum." );
196 chksum_bios_set_value( bios_data, offset, new_val );
197 }
198 printf( "\n\n" );
199
200
201 if(( stream = fopen( argv[1], "wb" )) == NULL ) {
202 printf( "Error opening %s for writing.\n", argv[1] );
203 exit( EXIT_FAILURE );
204 }
205 if( fwrite( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) {
206 printf( "Error writing 64KBytes to %s.\n", argv[1] );
207 fclose( stream );
208 exit( EXIT_FAILURE );
209 }
210 fclose( stream );
211
212 return( EXIT_SUCCESS );
213}
214
215
216void check( int okay, char* message ) {
217
218 if( !okay ) {
219 printf( "\n\nError. %s.\n", message );
220 exit( EXIT_FAILURE );
221 }
222}
223
224
225long chksum_bios_get_offset( byte* data, long offset ) {
226
227 return( BIOS_OFFSET );
228}
229
230
231byte chksum_bios_calc_value( byte* data, long offset ) {
232
233 int i;
234 byte sum;
235
236 sum = 0;
237 for( i = 0; i < MAX_OFFSET; i++ ) {
238 sum = sum + *( data + i );
239 }
240 sum = -sum; /* iso ensures -s + s == 0 on unsigned types */
241 return( sum );
242}
243
244
245byte chksum_bios_get_value( byte* data, long offset ) {
246
247 return( *( data + BIOS_OFFSET ) );
248}
249
250
251void chksum_bios_set_value( byte* data, long offset, byte value ) {
252
253 *( data + BIOS_OFFSET ) = value;
254}
255
256
257byte chksum__32__calc_value( byte* data, long offset ) {
258
259 int i;
260 int len;
261 byte sum;
262
263 check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" );
264 len = *( data + offset + _32__LEN ) << 4;
265 check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" );
266 sum = 0;
267 for( i = 0; i < len; i++ ) {
268 if( i != _32__CHKSUM ) {
269 sum = sum + *( data + offset + i );
270 }
271 }
272 sum = -sum;
273 return( sum );
274}
275
276
277long chksum__32__get_offset( byte* data, long offset ) {
278
279 long result = -1L;
280
281 offset = offset + 0x0F;
282 offset = offset & ~( 0x0F );
283 while( offset + 16 < MAX_OFFSET ) {
284 offset = offset + 16;
285 if( *( data + offset + 0 ) == '_' && \
286 *( data + offset + 1 ) == '3' && \
287 *( data + offset + 2 ) == '2' && \
288 *( data + offset + 3 ) == '_' ) {
289 result = offset;
290 break;
291 }
292 }
293 return( result );
294}
295
296
297byte chksum__32__get_value( byte* data, long offset ) {
298
299 check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
300 return( *( data + offset + _32__CHKSUM ) );
301}
302
303
304void chksum__32__set_value( byte* data, long offset, byte value ) {
305
306 check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
307 *( data + offset + _32__CHKSUM ) = value;
308}
309
310
311byte chksum__mp__calc_value( byte* data, long offset ) {
312
313 int i;
314 int len;
315 byte sum;
316
317 check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" );
318 len = *( data + offset + _MP__LEN ) << 4;
319 check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" );
320 sum = 0;
321 for( i = 0; i < len; i++ ) {
322 if( i != _MP__CHKSUM ) {
323 sum = sum + *( data + offset + i );
324 }
325 }
326 sum = -sum;
327 return( sum );
328}
329
330
331long chksum__mp__get_offset( byte* data, long offset ) {
332
333 long result = -1L;
334
335 offset = offset + 0x0F;
336 offset = offset & ~( 0x0F );
337 while( offset + 16 < MAX_OFFSET ) {
338 offset = offset + 16;
339 if( *( data + offset + 0 ) == '_' && \
340 *( data + offset + 1 ) == 'M' && \
341 *( data + offset + 2 ) == 'P' && \
342 *( data + offset + 3 ) == '_' ) {
343 result = offset;
344 break;
345 }
346 }
347 return( result );
348}
349
350
351byte chksum__mp__get_value( byte* data, long offset ) {
352
353 check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
354 return( *( data + offset + _MP__CHKSUM ) );
355}
356
357
358void chksum__mp__set_value( byte* data, long offset, byte value ) {
359
360 check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
361 *( data + offset + _MP__CHKSUM ) = value;
362}
363
364
365byte chksum_pcmp_calc_value( byte* data, long offset ) {
366
367 int i;
368 int len;
369 byte sum;
370
371 check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" );
372 len = *( data + offset + PCMP_BASELEN ) + \
373 ( *( data + offset + PCMP_BASELEN + 1 ) << 8 );
374 check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" );
375 if( *( data + offset + PCMP_EXT_LEN ) | \
376 *( data + offset + PCMP_EXT_LEN + 1 ) | \
377 *( data + offset + PCMP_EXT_CHKSUM ) ) {
378 check( 0, "PCMP header indicates extended tables (unsupported)" );
379 }
380 sum = 0;
381 for( i = 0; i < len; i++ ) {
382 if( i != PCMP_CHKSUM ) {
383 sum = sum + *( data + offset + i );
384 }
385 }
386 sum = -sum;
387 return( sum );
388}
389
390
391long chksum_pcmp_get_offset( byte* data, long offset ) {
392
393 long result = -1L;
394
395 offset = offset + 0x0F;
396 offset = offset & ~( 0x0F );
397 while( offset + 16 < MAX_OFFSET ) {
398 offset = offset + 16;
399 if( *( data + offset + 0 ) == 'P' && \
400 *( data + offset + 1 ) == 'C' && \
401 *( data + offset + 2 ) == 'M' && \
402 *( data + offset + 3 ) == 'P' ) {
403 result = offset;
404 break;
405 }
406 }
407 return( result );
408}
409
410
411byte chksum_pcmp_get_value( byte* data, long offset ) {
412
413 check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
414 return( *( data + offset + PCMP_CHKSUM ) );
415}
416
417
418void chksum_pcmp_set_value( byte* data, long offset, byte value ) {
419
420 check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
421 *( data + offset + PCMP_CHKSUM ) = value;
422}
423
424
425byte chksum__pir_calc_value( byte* data, long offset ) {
426
427 int i;
428 int len;
429 byte sum;
430
431 check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" );
432 len = *( data + offset + _PIR_LEN ) + \
433 ( *( data + offset + _PIR_LEN + 1 ) << 8 );
434 check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" );
435 sum = 0;
436 for( i = 0; i < len; i++ ) {
437 if( i != _PIR_CHKSUM ) {
438 sum = sum + *( data + offset + i );
439 }
440 }
441 sum = -sum;
442 return( sum );
443}
444
445
446long chksum__pir_get_offset( byte* data, long offset ) {
447
448 long result = -1L;
449
450 offset = offset + 0x0F;
451 offset = offset & ~( 0x0F );
452 while( offset + 16 < MAX_OFFSET ) {
453 offset = offset + 16;
454 if( *( data + offset + 0 ) == '$' && \
455 *( data + offset + 1 ) == 'P' && \
456 *( data + offset + 2 ) == 'I' && \
457 *( data + offset + 3 ) == 'R' ) {
458 result = offset;
459 break;
460 }
461 }
462 return( result );
463}
464
465
466byte chksum__pir_get_value( byte* data, long offset ) {
467
468 check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
469 return( *( data + offset + _PIR_CHKSUM ) );
470}
471
472
473void chksum__pir_set_value( byte* data, long offset, byte value ) {
474
475 check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
476 *( data + offset + _PIR_CHKSUM ) = value;
477}
478
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette