summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/FDISK/FDISK.C
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/FDISK/FDISK.C')
-rw-r--r--v4.0/src/CMD/FDISK/FDISK.C1121
1 files changed, 1121 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FDISK/FDISK.C b/v4.0/src/CMD/FDISK/FDISK.C
new file mode 100644
index 0000000..b39baad
--- /dev/null
+++ b/v4.0/src/CMD/FDISK/FDISK.C
@@ -0,0 +1,1121 @@
1
2/* */
3
4
5
6/******************* START OF SPECIFICATIONS *******************/
7/* */
8/* SOURCE FILE NAME: FDISK */
9/* */
10/* DESCRIPTIVE NAME: FIXED DISK PARTITIONING UTILITY */
11/* */
12/* FUNCTION: */
13/* Allows creation and deletion of DOS related partitions */
14/* on fixed disk devices 80-81h (int 13h BIOS defined, */
15/* DOS). Also allows display of all partitions, and will */
16/* allow a partition to be marked active (bootable). The */
17/* user will be prompted for action thru a full screen */
18/* interface. The user can also create, delete and display */
19/* logical DOS drives within a EXTENDED DOS Partition. If a*/
20/* regular DOS partition is created, the beginning of the */
21/* partition will be scanned to insure a contiguous area of*/
22/* good sectors on the disk large enough to satisfy the */
23/* DOS system requirements. If a bad spot is found, the */
24/* start of the partition will be moved out until a good */
25/* area is located */
26/* */
27/* NOTES: The program will work by setting up a logical image */
28/* of all relevant disk information at initilization */
29/* time. All operations will be performed on this */
30/* logical image, thus reducing disk accesses to only */
31/* those required to initially set up the logical image,*/
32/* and to write the changed information at the end. The */
33/* user will be informed if there is a problem writing */
34/* the logical image back to the disk. */
35/* */
36/* FDISK will interface with the partition table in the */
37/* master boot record as defined in the PC-DOS technical*/
38/* reference manual. It will also create and manage the */
39/* EXTENDED DOS partition architecture as defined in the*/
40/* PC-DOS 3.30 functional spec (CP/DOS spec dcr pending)*/
41/* */
42/* ENTRY POINTS: MAIN */
43/* LINKAGE: [d:] [path] FDISK */
44/* */
45/* EXTERNAL REFERENCES: */
46/* Fixed Disk Master Boot Record */
47/* EXTENDED Partition Volume Boot Records */
48/* Note: Both of the above are physical data structures on */
49/* the surface of the disk */
50/* */
51/* P.S. - To whoever winds up maintaining this, I will */
52/* apoligize in advance. I had just learned 'C' when */
53/* writing this, so out of ignorance of the finer points*/
54/* of the langauge I did a lot of things by brute force.*/
55/* Hope this doesn't mess you up too much - MT 5/20/86 */
56/******************** END OF SPECIFICATIONS ********************/
57
58#include <dos.h>
59#include <fdisk.h>
60#include <subtype.h>
61#include <extern.h>
62#include <doscall.h>
63#include <ctype.h>
64#include <string.h> /* AN000 */
65#include <fdiskmsg.h> /* AN000 */
66#include <msgret.h> /* AN000 */
67#include <process.h> /* AN000 */
68#include <stdio.h> /* AN000 */
69
70/* */
71/**************************************************************************/
72/* */
73/* UTILITY NAME: FDISK.com */
74/* SOURCE FILE NAME: FDISK.c */
75/* STATUS: FDISK utility, DOS 3.3 */
76/* CHANGE HISTORY: UPDATED 5-29-87 DOS4.0 DRM */
77/* SYNTAX (Command line) */
78/* */
79/* [d:][path]FDISK */
80/* */
81/* or */
82/* */
83/* [d:][path]FDISK d [/PRI:m | /EXT:n | /LOG:o ...] */
84/* */
85/* d: Drive to load FDISK utility from */
86/* */
87/* path path to the directory on specified drive to */
88/* load FDISK from */
89/* */
90/* d Drive (1 or 2) that FDISK should operate on */
91/* */
92/* /PRI:m Size of Primary DOS partition to create in K */
93/* */
94/* /EXT:n Size of Extended DOS partition to create in K */
95/* */
96/* /LOG:o Size of Logical drive to create in K in the */
97/* extended partition */
98/* */
99/* UTILITY FUNCTION: */
100/* Allows you to create, set up, display, and delete the */
101/* DOS partitions on a fixed disk. */
102/* */
103/**************************************************************************/
104
105/* */
106/******************* START OF SPECIFICATIONS *******************/
107/* */
108/* SUBROUTINE NAME: CHANGE_ACTIVE_PARTITION */
109/* */
110/* DESCRIPTIVE NAME: Change bootable partition */
111/* */
112/* FUNCTION: Will allow user to select the partition that will */
113/* recieve control when system is IPL'd. This is */
114/* only for the first hardfile as far as booting is */
115/* concerned, although partitions can be set active */
116/* the second. There are reserved partitions that may*/
117/* not be set active and this routine will enforce */
118/* that. */
119/* */
120/* NOTES: If no valid partition is specified, then the active */
121/* partition setting is left unchanged. Screen can be */
122/* exited via the ESC command before active partition */
123/* is changed and no action will take place */
124/* */
125/* The following screen is managed */
126/* */
127/* ³0000000000111111111122222222223333333333³ */
128/* ³0123456789012345678901234567890123456789³ */
129/* ÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ */
130/* 00³ ³ */
131/* 01³ ³ */
132/* 02³ ³ */
133/* 03³ ³ */
134/* 04³Change Active Partition ³ */
135/* 05³ ³ */
136/* 06³Current Fixed Disk Drive: # ³ */
137/* 07³ ³ */
138/* 08³Partition Status Type Start End Size³ */
139/* 09³ # # ####### #### #### ####³ */
140/* 10³ ³ */
141/* 11³ ³ */
142/* 12³ ³ */
143/* 13³ ³ */
144/* 14³Total disk space is #### cylinders. ³ */
145/* 15³ ³ */
146/* 16³ ³ */
147/* 17³ ³ */
148/* 18³Enter the number of the partition you ³ */
149/* 19³want to make active...............: [#] ³ */
150/* 20³ ³ */
151/* 21³ ³ */
152/* 22³ ³ */
153/* 23³Press ESC to return to FDISK Options ³ */
154/* ÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ */
155/* */
156/* ENTRY POINTS: Change_Active_Partition */
157/* LINKAGE: change_active_partition () */
158/* NEAR CALL */
159/* */
160/* INPUT: None */
161/* */
162/* EXIT-NORMAL: ERROR=FALSE */
163/* */
164/* EXIT-ERROR: ERROR=TRUE */
165/* GOTO internal_program_error if invalid num */
166/* input is returned to this level */
167/* */
168/* EFFECTS: Display prompts needed to guide user input, and */
169/* gets input from user. */
170/* */
171/* */
172/* INTERNAL REFERENCES: */
173/* ROUTINES: */
174/* clear_screen */
175/* display */
176/* get_num_input */
177/* table_display */
178/* wait_for_ESC */
179/* internal_program_error */
180/* */
181/* EXTERNAL REFERENCES: */
182/* ROUTINES: */
183/* */
184/******************** END OF SPECIFICATIONS ********************/
185
186/* */
187void change_active_partition()
188
189BEGIN
190
191 char temp;
192 char default_value;
193 char input;
194 unsigned i;
195 unsigned x;
196 char num_partitions;
197 char valid_partitions;
198 char num_of_bootable_partitions;
199 char valid_input;
200 char input_default;
201
202
203
204 input = c(NUL);
205 /* Clear screen */
206 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
207
208 /* Display header */
209 display(menu_23);
210
211 /* Setup and print current disk */
212 insert[0] = cur_disk+1+'0';
213 display(menu_5);
214
215 /* print ESC prompt */
216 display(menu_11);
217
218 /* Only allow active partitions on the first (and bootable) disk */
219 if (cur_disk == c(0)) /* AC000 */
220
221 BEGIN
222 /* Display partition info and see if any partitions exist*/
223 if (table_display())
224
225 BEGIN
226 /* See if active partition is bootable */
227 for (i=u(0); i < u(4); i++) /* AC000 */
228 BEGIN
229 if (part_table[0][i].sys_id != uc(0) &&
230 part_table[0][i].boot_ind == uc(0x80)) /* AC000 */
231 BEGIN
232 if ((part_table[0][i].sys_id == uc(BAD_BLOCK)) ||
233 (part_table[0][i].sys_id==uc(EXTENDED))) /* AC000 */
234 BEGIN
235 /* The active partition is not bootable, so warn user */
236 display(error_24);
237 END
238 END
239 END
240
241 /* Check to see if only one partition */
242 num_partitions = c(0) ; /* AC000 */
243 num_of_bootable_partitions = c(0); /* AC000 */
244 for (i=u(0); i < u(4); i++) /* AC000 */
245
246 BEGIN
247 if (part_table[0][i].sys_id != uc(0)) /* AC000 */
248 BEGIN
249 /* Get a count of partitions */
250 num_partitions++;
251
252 /* Get a count of the number of defined partitions but don't*/
253 /* count those we know aren't bootable */
254 if ((part_table[0][i].sys_id != uc(BAD_BLOCK)) &&
255 (part_table[0][i].sys_id != uc(EXTENDED))) /* AC000 */
256 BEGIN
257 num_of_bootable_partitions++;
258 END
259 END
260 END
261 /* If only one partition found, see if it is active already */
262 if (num_of_bootable_partitions == c(1)) /* AC000 */
263 BEGIN
264
265 /* Find the partition and see if it is already active */
266 for (i=u(0); i < u(4); i++) /* AC000 */
267
268 BEGIN
269 if (part_table[0][i].sys_id !=uc(0) &&
270 part_table[0][i].boot_ind == uc(0x80)) /* AC000 */
271
272 BEGIN
273 /* Make sure it is not unbootable partition again*/
274 if ((part_table[0][i].sys_id != uc(BAD_BLOCK)) &&
275 (part_table[0][i].sys_id!=uc(EXTENDED))) /* AC000 */
276
277 BEGIN
278 /* Once it is found, put out the message */
279 display(error_15);
280
281 /* Wait for ESC, then get out */
282 wait_for_ESC();
283
284 /* clear the screen before going back to main menu*/
285 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
286 return;
287 END
288 END
289 END
290 END
291 /* See if any bootable partitions exist */
292 if (num_of_bootable_partitions == c(0)) /* AC000 */
293 BEGIN
294 /* At this point, we know at least one partition does exist due to*/
295 /* getting past the table_display call, so the only ones around */
296 /* must be unbootable */
297
298 /* Display this fact then get out of here */
299 display(error_25);
300 END
301 else
302 BEGIN
303 /* All is okay to go and set one, do display prompts */
304 number_in_msg((XFLOAT)total_mbytes[cur_disk],u(0)); /* AC000 */
305 display(menu_15);
306
307 /* Put up input prompt*/
308 display(menu_24);
309
310 /* Assume bad input until proven otherwise */
311 valid_input = FALSE;
312 valid_partitions = num_partitions;
313 input_default = c(NUL); /* AC000 */
314
315 while (!valid_input)
316 BEGIN
317 /* Go get partition to make active */
318 input = get_num_input(input_default,num_partitions,input_row,input_col);
319
320 /* Save the input for next time in case CR pressed */
321 input_default = input-'0';
322
323 clear_screen(u(18),u(0),u(23),u(79)); /* AC000 */
324
325 if (input != c(ESC)) /* AC000 */
326 BEGIN
327 /* See if known unbootable partition */
328 /* Set the new one */
329 valid_partitions = c(0); /* AC000 */
330
331 /* Make sure the partitions are in physical order*/
332 sort_part_table(c(4)); /* AC000 */
333
334 /* Go find existing partitiona */
335 for (i=u(0);i < u(4); i++) /* AC000 */
336 BEGIN
337 /* First we have to find it */
338 if (part_table[0][sort[i]].sys_id != uc(0)) /* AC000 */
339 BEGIN
340 /* If this is the 'input'th one, then we got it */
341 if (valid_partitions == (input-'1'))
342 BEGIN
343 /* See if it is an unbootable partition */
344 if ((part_table[0][sort[i]].sys_id != uc(BAD_BLOCK)) &&
345 (part_table[0][sort[i]].sys_id != uc(EXTENDED))) /* AC000 */
346
347 BEGIN
348 /* Its bootable, so we have good input */
349 valid_input = c(TRUE); /* AC000 */
350
351 /* Remove the active indicator from the old partition */
352 for (x=u(0); x < u(4); x++) /* AC000 */
353 BEGIN
354
355 if (part_table[0][x].boot_ind == uc(0x80)) /* AC000 */
356 BEGIN
357 part_table[0][x].changed = TRUE;
358 part_table[0][x].boot_ind = uc(0); /* AC000 */
359 END
360 END
361
362 /* Put in new active indicator */
363 part_table[0][sort[i]].boot_ind = uc(0x80); /* AC000 */
364
365 /* Indicate that it is changed */
366 part_table[0][sort[i]].changed = TRUE;
367
368 /* Update the partition info display */
369 table_display();
370
371 /* Clear off the old prompts */
372 clear_screen(u(16),u(0),u(21),u(79)); /* AC000 */
373
374 /* Say you did it */
375 insert[0] = input;
376 display(status_4);
377 break;
378 END
379 else
380 BEGIN
381 /* It is, so setup message and tell user */
382 insert[0] = input;
383 display(error_17);
384 break;
385 END
386 END
387 else
388 BEGIN
389 /* Indicate we found one but keep going */
390 valid_partitions++;
391 END
392 END
393 END
394 END
395 else
396 BEGIN
397 /* Mark ESC as ok input so we can get out of here */
398 valid_input = c(TRUE); /* AC000 */
399 END
400 END /* While loop */
401 END
402 END /* table display test endif */
403 else
404 BEGIN
405 /* No partitions to make active */
406 display(error_16);
407 END
408 END
409 else
410 BEGIN
411 display(error_26);
412 END
413 /* clear the screen before going back to main menu */
414 if (input != c(ESC)) /* AC000 */
415 BEGIN
416 wait_for_ESC();
417 END
418 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
419 return;
420END
421
422
423/* */
424/******************* START OF SPECIFICATIONS *******************/
425/* */
426/* SUBROUTINE NAME: DISPLAY_PARTITION_INFORMATION */
427/* */
428/* DESCRIPTIVE NAME: Display partition information */
429/* */
430/* FUNCTION: Displays defined partition information and prompt */
431/* user to display disk volumes if they exist */
432/* */
433/* NOTES: */
434/* */
435/* The following screen is managed */
436/* */
437/* ³0000000000111111111122222222223333333333³ */
438/* ³0123456789012345678901234567890123456789³ */
439/* ÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ */
440/* 00³ ³ */
441/* 01³ ³ */
442/* 02³ ³ */
443/* 03³ ³ */
444/* 04³Display Partition Information ³ */
445/* 05³ ³ */
446/* 06³Current Fixed Disk Drive: # ³ */
447/* 07³ ³ */
448/* 08³Partition Status Type Start End Size³ */
449/* 09³ # # ####### #### #### ####³ */
450/* 10³ ³ */
451/* 11³ ³ */
452/* 12³ ³ */
453/* 13³ ³ */
454/* 14³Total disk space is #### cylinders. ³ */
455/* 15³ ³ */
456/* 16³ ³ */
457/* 17³ ³ */
458/* 18³The EXTENDED DOS partition contains DOS ³ */
459/* 19³disk volumes. Do you want to display ³ */
460/* 20³the volume information............? [Y] ³ */
461/* 21³ ³ */
462/* 22³ ³ */
463/* 23³Press ESC to return to FDISK Options ³ */
464/* ÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ */
465/* */
466/* ENTRY POINTS: Display_Partition_Information */
467/* LINKAGE: display_partition_information () */
468/* NEAR CALL */
469/* */
470/* INPUT: None */
471/* */
472/* EXIT-NORMAL: ERROR=FALSE */
473/* */
474/* EXIT-ERROR: ERROR=TRUE */
475/* GOTO internal_program_error if invalid input */
476/* returned to this routine */
477/* */
478/* EFFECTS: No data directly modified by this routine, but */
479/* child routines will modify data. */
480/* */
481/* INTERNAL REFERENCES: */
482/* ROUTINES: */
483/* clear_screen */
484/* wait_for_ESC */
485/* display */
486/* table_display */
487/* get_yn_input */
488/* find_partition_type */
489/* display_volume_information */
490/* internal_program_error */
491/* */
492/* EXTERNAL REFERENCES: */
493/* ROUTINES: */
494/* */
495/******************** END OF SPECIFICATIONS ********************/
496
497/* */
498void display_partition_information()
499
500BEGIN
501
502 char input;
503 char temp;
504
505 input = c(NUL); /* AC000 */
506 /* Clear_screen */
507 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
508
509 /* Display Header */
510 display(menu_35);
511
512 /* Setup and print current disk */
513 insert[0] = cur_disk+1+'0';
514 display(menu_5);
515
516 /* print ESC prompt */
517 display(menu_11);
518
519 /* Display information */
520 if (table_display())
521 BEGIN
522
523 /* Setup and print disk space msg */
524 number_in_msg((XFLOAT)total_mbytes[cur_disk],u(0)); /* AC000 */
525 display(menu_15);
526
527 /* See if any logical drive stuff to display */
528 if (find_partition_type(uc(EXTENDED))) /* AC000 */
529 BEGIN
530 /* See if any logical drives exist */
531 if (find_logical_drive())
532 BEGIN
533
534 /* Prompt to see if they want to see EXTENDED info */
535 display(menu_36);
536
537 /* Get Y/N input, default is YES */
538 input = get_yn_input(c(Yes),input_row,input_col); /* AC000 AC011 */
539 switch(input)
540 BEGIN
541
542 case 1: display_volume_information(); /* AC000 */
543 break;
544
545 case 0: break; /* AC000 */
546
547 case ESC: break;
548
549 default: internal_program_error();
550 break;
551 END
552 END
553 else
554 input = wait_for_ESC();
555 END
556 else
557 input = wait_for_ESC();
558 END
559 else
560 input = wait_for_ESC();
561 /* clear the screen before going back to main menu */
562 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
563 return;
564END
565
566
567
568/* */
569/******************* START OF SPECIFICATIONS *******************/
570/* */
571/* SUBROUTINE NAME: DISPLAY_VOLUME_INFORMATION */
572/* */
573/* DESCRIPTIVE NAME: Display DOS disk Volume Information */
574/* */
575/* FUNCTION: Displays disk volume size and existence */
576/* */
577/* NOTES: */
578/* */
579/* The following screen is managed */
580/* */
581/* ³0000000000111111111122222222223333333333³ */
582/* ³0123456789012345678901234567890123456789³ */
583/* ÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ */
584/* 01³Display DOS Disk Volume Information ³ */
585/* 02³ ³ */
586/* 03³Vol Start End Size Vol Start End Size³ */
587/* 04³ # #### #### #### # #### #### ####³ */
588/* 05³ ³ */
589/* 06³ ³ */
590/* 07³ ³ */
591/* 08³ ³ */
592/* 09³ ³ */
593/* 10³ ³ */
594/* 11³ ³ */
595/* 12³ ³ */
596/* 13³ ³ */
597/* 14³ ³ */
598/* 15³ ³ */
599/* 16³ ³ */
600/* 17³ ³ */
601/* 18³ ³ */
602/* 19³ ³ */
603/* 20³ ³ */
604/* 21³ ³ */
605/* 22³ ³ */
606/* 23³Press ESC to return to FDISK Options ³ */
607/* ÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ */
608/* */
609/* ENTRY POINTS: Display_Volume_Information */
610/* LINKAGE: display_volume_information () */
611/* NEAR CALL */
612/* */
613/* INPUT: None */
614/* */
615/* EXIT-NORMAL: ERROR=FALSE */
616/* */
617/* EXIT-ERROR: ERROR=TRUE */
618/* */
619/* EFFECTS: No data directly modified by this routine, but */
620/* child routines will modify data. */
621/* */
622/* INTERNAL REFERENCES: */
623/* ROUTINES: */
624/* clear_screen */
625/* wait_for_ESC */
626/* display */
627/* volume_display */
628/* */
629/* EXTERNAL REFERENCES: */
630/* ROUTINES: */
631/* */
632/******************** END OF SPECIFICATIONS ********************/
633
634/* */
635void display_volume_information()
636
637BEGIN
638
639 char input;
640 char temp;
641
642 input = c(NUL); /* AC000 */
643 /* clear the screen */
644 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
645
646 /* Display Header */
647 display(menu_37);
648
649 /* Display information */
650 temp = volume_display();
651
652 /* Set up partition size message */
653 sprintf(insert,"%4.0d",get_partition_size( uc(EXTENDED) ) );
654 display(menu_21);
655
656 /* print ESC prompt */
657 display(menu_11);
658
659 /* Wait to exit */
660 input = wait_for_ESC();
661 return;
662END
663
664/* */
665char check_valid_environment()
666BEGIN
667
668 /* See if the net is there */
669 regs.x.ax = u(INSTALLATION_CHECK); /* AC000 */
670 int86((int)NETWORK,&regs,&regs); /* AC000 */
671
672#ifdef DEBUG /* AN006 */
673 regs.h.al = uc(0); /* AN006 */
674#endif /* AN006 */
675
676 /* Is it ? */
677 if (regs.h.al != uc(0)) /* AC000 */
678 BEGIN
679
680 /* See if server is loaded, otherwise okay */
681 if ((regs.x.bx & SERVER_CHECK) != u(0)) /* AC000 */
682 BEGIN
683 no_fatal_error = FALSE;
684 display_msg((int)4,(int)DosStdEr,(int)nosubcnt,(int)nosubptr,c(noinput),c(Utility_Msg_Class)); /* AN000 AC014*/
685 return(FALSE);
686 END
687 END
688 return(TRUE);
689END
690
691
692
693/* */
694void init_partition_tables()
695BEGIN
696
697unsigned i;
698unsigned char j;
699unsigned k;
700unsigned l;
701unsigned partition_location;
702char temp;
703char more_drives_exist;
704char num_logical_drives;
705unsigned insert;
706unsigned index;
707
708 /* initialize first drive found to "C" */
709 next_letter = c(SEA); /* AC000 */
710
711 /* Look at both disks */
712 for (j = uc(0); j < number_of_drives; j++) /* AC000 */
713 BEGIN
714
715 /* Initialize the cur_disk field to the drive in question so */
716 /* that the calls to the partition information routines will work */
717 cur_disk = ((char)(j));
718
719 /* Read in the master boot record and see if it was okay */
720 if (read_boot_record(u(0),j,uc(0),uc(1))) /* AC000 */
721 BEGIN
722
723 /* See if there was a valid boot record there */
724 if ((boot_record[510] == uc(0x55)) && (boot_record[511] == uc(0xAA))) /* AC000 */
725 BEGIN
726
727 /* What was on the disk is a valid boot record, so save it */
728 for (i=u(0);i < u(BYTES_PER_SECTOR); i++) /* AC000 */
729 BEGIN
730 master_boot_record[j][i] = boot_record[i];
731 END
732 END
733 /* We've now got a copy of the master boot record saved. Now we need */
734 /* to translate what in the boot record to the area that it's going */
735 /* to be worked on (part_table) */
736
737 /* Read in the data from the master boot record partition entries*/
738 for (i=u(0); i < u(4); i++) /* AC000 */
739 BEGIN
740 index = i*16;
741
742 /* Get boot ind */
743 part_table[j][i].boot_ind = master_boot_record[j][0x1BE+index];
744
745 /* Start head */
746 part_table[j][i].start_head = master_boot_record[j][0x1BF+index];
747
748 /* Start sector - unscramble it from INT 13 format*/
749 part_table[j][i].start_sector= (master_boot_record[j][0x1C0+index] & 0x3F);
750
751 /* Start cyl - unscramble it from INT 13 format*/
752 part_table[j][i].start_cyl= ((((unsigned)master_boot_record[j][0x1C0+index]) & 0x00C0) << 2)
753 + ((unsigned)master_boot_record[j][0x1C1+index]);
754
755 /* System id */
756 part_table[j][i].sys_id = master_boot_record[j][0x1C2+index];
757
758 /* End head */
759 part_table[j][i].end_head = master_boot_record[j][0x1C3+index];
760
761 /* End sector - unscramble it from INT 13 format*/
762 part_table[j][i].end_sector= (master_boot_record[j][0x1C4+index] & 0x3F);
763
764 /* End cyl - unscramble it from INT 13 format*/
765 part_table[j][i].end_cyl= ((((unsigned)master_boot_record[j][0x1C4+index]) & 0x00C0) << 2)
766 + ((unsigned)master_boot_record[j][0x1C5+index]);
767
768 /* Relative sectors */
769
770 part_table[j][i].rel_sec =
771 ((unsigned long)master_boot_record[j][0x1C9+index]) << 24;
772
773 part_table[j][i].rel_sec = part_table[j][i].rel_sec +
774 (((unsigned long)master_boot_record[j][0x1C8+index]) << 16);
775
776 part_table[j][i].rel_sec = part_table[j][i].rel_sec +
777 (((unsigned long)master_boot_record[j][0x1C7+index]) << 8);
778
779 part_table[j][i].rel_sec = part_table[j][i].rel_sec +
780 ((unsigned long)master_boot_record[j][0x1C6+index]);
781
782 /* Number of sectors */
783 part_table[j][i].num_sec =
784 ((unsigned long)master_boot_record[j][0x1CD+index]) << 24;
785
786 part_table[j][i].num_sec = part_table[j][i].num_sec +
787 (((unsigned long)master_boot_record[j][0x1CC+index]) << 16);
788
789 part_table[j][i].num_sec = part_table[j][i].num_sec +
790 (((unsigned long)master_boot_record[j][0x1CB+index]) << 8);
791
792 part_table[j][i].num_sec = part_table[j][i].num_sec +
793 ((unsigned long)master_boot_record[j][0x1CA+index]);
794
795 part_table[j][i].mbytes_used =
796 cylinders_to_mbytes(((part_table[j][i].end_cyl-part_table[j][i].start_cyl)+1),
797 cur_disk); /* AN004 */
798
799 part_table[j][i].percent_used =
800 cylinders_to_percent(((part_table[j][i].end_cyl-part_table[j][i].start_cyl)+1),
801 total_disk[cur_disk]); /* AN000 */
802
803 /* Set drive letter */
804 if ( (part_table[j][i].sys_id == DOS12) || /* AN000 */
805 (part_table[j][i].sys_id == DOS16) || /* AN000 */
806 (part_table[j][i].sys_id == DOSNEW) ) /* AN000 */
807 part_table[j][i].drive_letter = next_letter++; /* AN000 */
808
809 /* Set changed flag */
810 part_table[j][i].changed = FALSE;
811 END
812 END
813 else
814 BEGIN
815 return;
816 END
817 END
818
819 /* Look at both disks */
820 for (j = uc(0); j < number_of_drives; j++) /* AC000 */
821 BEGIN
822
823 /* Initialize the cur_disk field to the drive in question so */
824 /* that the calls to the partition information routines will work */
825 cur_disk = ((char)(j));
826
827 /* Read in the master boot record and see if it was okay */
828 if (read_boot_record(u(0),j,uc(0),uc(1))) /* AC000 */
829 BEGIN
830 /* Now, go read in extended partition info */
831 if (find_partition_type(uc(EXTENDED))) /* AC000 */
832 BEGIN
833 /* Initialize the array to zero's - include one dummy entry */
834 for (i=u(0); i < u(24); i++) /* AC000 */
835 BEGIN
836 ext_table[j][i].boot_ind = uc(0); /* AC000 */
837 ext_table[j][i].start_head = uc(0); /* AC000 */
838 ext_table[j][i].start_sector = uc(0); /* AC000 */
839 ext_table[j][i].start_cyl = u(0); /* AC000 */
840 ext_table[j][i].sys_id = uc(0); /* AC000 */
841 ext_table[j][i].end_head = uc(0); /* AC000 */
842 ext_table[j][i].end_sector = uc(0); /* AC000 */
843 ext_table[j][i].end_cyl = u(0); /* AC000 */
844 ext_table[j][i].rel_sec = ul(0); /* AC000 */
845 ext_table[j][i].num_sec = ul(0); /* AC000 */
846 ext_table[j][i].mbytes_used = f(0); /* AN000 */
847 ext_table[j][i].percent_used = u(0); /* AN000 */
848 ext_table[j][i].changed = FALSE;
849 ext_table[j][i].drive_letter = NUL; /* AN000 */
850
851 strcpy(ext_table[cur_disk][i].system,NUL); /* AN000 */
852 strcpy(ext_table[cur_disk][i].vol_label,NUL); /* AN000 */
853
854 END
855
856 /* Find where the first extended boot record is */
857 temp = find_partition_location(uc(EXTENDED)); /* AC000 */
858 partition_location = part_table[j][temp].start_cyl;
859
860 /* Go find extended boot records as long as there are more of them */
861 more_drives_exist = TRUE;
862
863 /* Init the number of logical drives, for a array index */
864 num_logical_drives = c(0); /* AC000 */
865
866 while (more_drives_exist)
867 BEGIN
868 /* Assume we won't find another logical drive */
869 more_drives_exist = FALSE;
870
871 /*Read in the extended boot record */
872 if (read_boot_record(partition_location,
873 j,
874 uc(0),
875 uc(1))) /* AC000 */
876 BEGIN
877 load_logical_drive(num_logical_drives,j);
878
879
880 /* find the next logical drive */
881 for (i = u(0); i < u(4); i++) /* AC000 */
882 BEGIN
883 index = i*16;
884 /* See if a sys id byte of exteneded exists */
885 if (boot_record[0x1C2+index] == uc(EXTENDED)) /* AC000 */
886 BEGIN
887 /* Found another drive, now get its location */
888 partition_location= (((((unsigned)(boot_record[0x1C0 + index])) & 0x00C0) << 2));
889 partition_location = partition_location + ((unsigned)(boot_record[0x1C1+index]));
890
891 /* Indicate we found another one */
892 more_drives_exist = TRUE;
893
894 /* Up the count of found ones */
895 num_logical_drives++;
896 break;
897 END
898 END
899 END
900 END
901 END
902 END
903 END
904 return;
905END
906
907
908/* */
909void load_logical_drive(point,drive)
910
911char point;
912unsigned char drive;
913
914BEGIN
915
916char volume_label[13]; /* AC000 *//*Used be 11*/
917unsigned ext_part_num; /* AN000 */
918unsigned i;
919unsigned j; /* AN000 */
920unsigned k; /* AN000 */
921unsigned length; /* AN000 */
922unsigned index;
923unsigned dx_pointer; /* AN000 */
924unsigned partition_location; /* AN000 */
925
926 /* Check to see if anything is there */
927 if ((boot_record[510] == uc(0x55)) && (boot_record[511] == uc(0xAA))) /* AC000 */
928 BEGIN
929 /* The boot record is there - read in the logical drive if it is there */
930 for (i = u(0); i < u(4); i++) /* AC000 */
931 BEGIN
932
933 index = i*16;
934 /* See if it is a defined extended drive*/
935 if ((boot_record[0x1C2 + index] != uc(0)) && (boot_record[0x1C2 + index] != uc(EXTENDED))) /* AC000 */
936 BEGIN
937 /* Get boot ind */
938 ext_table[drive][point].boot_ind = boot_record[0x1BE + index];
939
940 /* Start head */
941 ext_table[drive][point].start_head = boot_record[0x1BF + index];
942
943 /* Start sector - unscramble it from INT 13 format*/
944 ext_table[drive][point].start_sector= (boot_record[0x1C0 + index] & 0x3F);
945
946 /* Start cyl - unscramble it from INT 13 format*/
947 ext_table[drive][point].start_cyl= ((((unsigned)boot_record[0x1C0+index]) & 0x00C0) << 2)
948 + ((unsigned)boot_record[0x1C1+index]);
949
950
951 /* System id */
952 ext_table[drive][point].sys_id = boot_record[0x1C2+index];
953
954 /* End head */
955 ext_table[drive][point].end_head = boot_record[0x1C3+index];
956
957 /* End sector - unscramble it from INT 13 format*/
958 ext_table[drive][point].end_sector= (boot_record[0x1C4+index] & 0x3F);
959
960
961 /* End cyl - unscramble it from INT 13 format*/
962 ext_table[drive][point].end_cyl= ((((unsigned)boot_record[0x1C4+index]) & 0x00C0) << 2)
963 + ((unsigned)boot_record[0x1C5+index]);
964
965 /* Relative sectors */
966 ext_table[drive][point].rel_sec =
967 ((unsigned long)boot_record[0x1C9+index]) << 24;
968
969 ext_table[drive][point].rel_sec =
970 ext_table[drive][point].rel_sec+(((unsigned long)boot_record[0x1C8+index]) << 16);
971
972 ext_table[drive][point].rel_sec =
973 ext_table[drive][point].rel_sec + (((unsigned long)boot_record[0x1C7+index]) << 8);
974
975 ext_table[drive][point].rel_sec =
976 ext_table[drive][point].rel_sec + ((unsigned long)boot_record[0x1C6+index]);
977
978 /* Number of sectors */
979
980 ext_table[drive][point].num_sec =
981 ((unsigned long)boot_record[0x1CD+index]) << 24;
982
983 ext_table[drive][point].num_sec =
984 ext_table[drive][point].num_sec+(((unsigned long)boot_record[0x1CC+index]) << 16);
985
986 ext_table[drive][point].num_sec =
987 ext_table[drive][point].num_sec + (((unsigned long)boot_record[0x1CB+index]) << 8);
988
989 ext_table[drive][point].num_sec =
990 ext_table[drive][point].num_sec + ((unsigned long)boot_record[0x1CA+index]);
991
992 ext_table[drive][point].mbytes_used =
993 cylinders_to_mbytes(((ext_table[drive][point].end_cyl - ext_table[drive][point].start_cyl)+1),
994 cur_disk); /* AN004 */
995
996 ext_part_num = find_partition_location(uc(EXTENDED));
997
998 ext_table[drive][point].percent_used =
999 cylinders_to_percent(((ext_table[drive][point].end_cyl-ext_table[drive][point].start_cyl)+1),
1000 ((part_table[drive][ext_part_num].end_cyl-part_table[drive][ext_part_num].start_cyl)+1)); /* AN000 */
1001
1002 ext_table[drive][point].drive_letter = next_letter++; /* AN000 */
1003
1004 partition_location = ext_table[drive][point].start_cyl;
1005
1006 if (read_boot_record(ext_table[drive][point].start_cyl,
1007 drive,
1008 ext_table[drive][point].start_head,
1009 ext_table[drive][point].start_sector));
1010 BEGIN /* AN000 */
1011 /* See if the disk has already been formated */
1012 if (check_format(ext_table[drive][point].drive_letter) == TRUE ) /* AN002 */
1013 BEGIN /* AN000 */
1014 /* get volume and system info */
1015
1016 /* AC000 Just for cleaning up purposes */
1017
1018 for (k = u(0); k < u(12); k++) /* AC000 */
1019 BEGIN /* AC000 */
1020 ext_table[drive][point].vol_label[k]=u(0); /* AC000 */
1021 END /* AC000 */
1022
1023 for (k = u(0); k < u(9); k++) /* AC000 */
1024 BEGIN /* AC000 */
1025 ext_table[drive][point].system[k]=u(0); /* AC000 */
1026 END /* AC000 */
1027
1028 get_volume_string(ext_table[drive][point].drive_letter,&volume_label[0]); /* AN000 AC015 */
1029
1030 for (k = u(0); k < strlen(volume_label); k++) /* AC000 AC015 */
1031 BEGIN /* AC000 AC015 */
1032 ext_table[drive][point].vol_label[k]=volume_label[k]; /* AC000 AC015 */
1033 END /* AC000 AC015 */
1034
1035 /* Now try to get it using GET MEDIA ID function */
1036 if (get_fs_and_vol(ext_table[drive][point].drive_letter)) /* AN000 */
1037
1038 BEGIN /* AN000 */
1039 /* AC000 Just use more conceptually simple logic */
1040 for (k=u(0); k < u(8); k++) /* AC000 */
1041
1042 BEGIN /* AC000 */
1043 if (dx_buff.file_system[k] != ' ') /* AC000 */
1044 length = k+1; /* AC000 */
1045 END /* AC000 */
1046
1047 strncpy(ext_table[drive][point].system,&dx_buff.file_system[0],u(length)); /* AN000 */
1048 END /* AN000 */
1049
1050 else /* AN000 */
1051
1052 BEGIN /* AN000 */
1053 if (ext_table[drive][point].num_sec > (unsigned long)FAT16_SIZE) /* AN000 */
1054 strcpy(ext_table[drive][point].system,FAT16); /* AN000 */
1055 else
1056 strcpy(ext_table[drive][point].system,FAT12); /* AN000 */
1057 END /* AN000 */
1058 END /* AN000 */
1059 else /* AN000 */
1060 BEGIN /* AN000 */
1061 /* set up array to say no file system or volume label */
1062 strcpy(ext_table[drive][point].vol_label,NOVOLUME); /* AN000 */
1063 strcpy(ext_table[drive][point].system,NOFORMAT); /* AN000 */
1064 END /* AN000 */
1065
1066 regs.x.dx = u(0);
1067 regs.x.ax = NETWORK_IOCTL;
1068 regs.h.bl = ((ext_table[drive][point].drive_letter - 'A') + 1);
1069 intdos(&regs,&regs);
1070 if (regs.x.dx & 0x1000) strcpy(ext_table[drive][point].vol_label,"* Remote * ");
1071 END
1072 read_boot_record(ext_table[drive][point].start_cyl,
1073 drive,
1074 uc(0),
1075 uc(1)); /* AN000 */
1076 END
1077 END
1078 END
1079
1080 return;
1081
1082END
1083
1084
1085
1086/* */
1087void reboot_system()
1088BEGIN
1089
1090
1091 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
1092 if (quiet_flag == FALSE)
1093 BEGIN
1094 display(menu_38);
1095 getch();
1096 reboot();
1097 END
1098 else
1099 BEGIN
1100 cur_disk = c(0); /* AN001 */
1101 reset_video_information(); /* AN006 */
1102 if ( (find_partition_type(uc(DOS12))) ||
1103 (find_partition_type(uc(DOS16))) ||
1104 (find_partition_type(uc(DOSNEW))) ) /* AN001 */
1105 exit(ERR_LEVEL_0); /* AN001 */
1106 else /* AN001 */
1107 exit(ERR_LEVEL_1); /* AN001 */
1108 END
1109END
1110
1111
1112/* */
1113void internal_program_error()
1114
1115BEGIN
1116 display(internal_error);
1117 DOSEXIT(u(0),u(0)); /* AC000 */
1118 return;
1119END
1120
1121