summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/RECOVER/RECINIT.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/RECOVER/RECINIT.ASM')
-rw-r--r--v4.0/src/CMD/RECOVER/RECINIT.ASM1028
1 files changed, 1028 insertions, 0 deletions
diff --git a/v4.0/src/CMD/RECOVER/RECINIT.ASM b/v4.0/src/CMD/RECOVER/RECINIT.ASM
new file mode 100644
index 0000000..a1f5f84
--- /dev/null
+++ b/v4.0/src/CMD/RECOVER/RECINIT.ASM
@@ -0,0 +1,1028 @@
1 ;AN000;bgb
2page ,132 ;
3TITLE RECINIT.SAL - MS-DOS File/Disk Recovery Utility
4;*****************************************************************************
5;*****************************************************************************
6; Include files
7;*****************************************************************************
8;
9 .xlist
10 include pathmac.inc
11 INCLUDE RECSEG.INC ;AN000;bgb
12 INCLUDE DOSSYM.INC ;AN000;BGB
13INCLUDE SYSCALL.INC ;AN000;BGB
14INCLUDE RECEQU.INC ;AN000;BGB
15INCLUDE RECMACRO.INC ;AN000;BGB
16INCLUDE RECPARSE.INC ;AN000;BGB
17 .list
18
19;
20;*****************************************************************************
21; External Data Declarations
22;*****************************************************************************
23data segment public para 'Data' ;an000;bgb
24 EXTRN movsi:word ;move si pointer here for display of invalid parm ;an031;bgb
25 extrn command_line_buffer:byte ;AN000;bgb
26 extrn ExitStatus:Byte ;AN000;bgb
27 Extrn FATTbl:byte
28 Extrn SubstErr:Byte
29 Extrn NotNetM:Byte
30 Extrn User_Drive:Byte ;AN000;BGB
31 Extrn Baddrv:Byte
32 Extrn Drive_Letter_Msg:Byte ;AN000;BGB
33 Extrn Parse_Error_Msg:Byte
34 extrn fname_buffer:byte ;AN000;BGB
35 extrn PSP_Segment:word ;AN000;bgb
36 extrn fatal_error:byte ;AN000;bgb
37 extrn found:byte ;AN000;bgb
38 extrn done:byte ;AN000;bgb
39 extrn bpb_buffer:byte ;AN000;bgb
40 extrn data_start_low:word ;AN000;bgb
41 extrn data_start_high:word ;AN000;bgb
42 extrn driveletter:byte ;AN000;bgb
43 extrn drive:byte ;AN000;bgb
44 extrn transrc:byte ;AN000;bgb
45 extrn int_23_old_off:word ;AN000;bgb
46 extrn int_23_old_seg:word ;AN000;bgb
47 extrn int_24_old_off:word ;AN000;bgb
48 extrn int_24_old_seg:word ;AN000;bgb
49 extrn append:byte ;AN000;bgb
50ifdef fsexec
51 extrn fat12_string:byte ;AN000;bgb
52 extrn fat16_string:byte ;AN000;bgb
53 extrn media_id_buffer:byte ;AN000;bgb
54 extrn fs_not_fat:byte ;AN000;bgb ;an022;bgb
55 extrn FS_String_Buffer:Byte ;AN011;bgb ;an022;bgb
56 extrn FS_String_end:Byte ;AN011;bgb ;an022;bgb
57endif
58data ends ;an000;bgb
59
60
61code segment public para 'CODE' ;an000;bgb
62 pathlabl recinit
63;*****************************************************************************
64; recinit procedures
65;*****************************************************************************
66public Main_Init, Init_Io, Preload_Messages, Parse_recover
67public Parse_good, Parse_err, Validate_Target_Drive
68public Check_Target_Drive, Check_For_Network, Check_Translate_Drive
69public Hook_interrupts, Clear_Append_X, RECOVER_IFS, Reset_Append_X
70public exitpgm ;an026;bgb
71;*****************************************************************************
72; External Routine Declarations
73;*****************************************************************************
74; Extrn EXEC_FS_Recover:Near ;an022;bgb
75 Extrn SysLoadMsg:Near
76 Extrn SysDispMsg:Near
77 Extrn Main_Routine:Near
78 Extrn INT_23:Near
79 Extrn INT_24:Near
80
81;*****************************************************************************
82;Routine name: MAIN_INIT
83;*****************************************************************************
84;
85;description: Main routine for recover program
86;
87;Called Procedures: get_psp
88; Init_IO
89; Validate_Target_Drive
90; Hook_Interrupts
91; RECOVER_IFS (goes to main-routine)
92;
93;Input: None
94;
95;Output: None
96;
97;Change History: Created 5/8/87 MT
98;
99;Psuedocode
100;----------
101; get info from psp
102; Parse input and load messages (CALL Init_Input_Output)
103; IF no error
104; Check target drive letter (CALL Validate_Target_Drive)
105; IF no error
106; Set up Control Break (CALL Hook_Interrupts)
107; IF no error
108; CALL RECOVER_IFS (goes to main routine)
109; ENDIF
110; ENDIF
111; ENDIF
112; Exit program
113;*****************************************************************************
114procedure Main_Init ;;AN000;
115 xor bp,bp
116 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;bgb
117 call get_psp
118 mov Fatal_Error,No ;Init the error flag ;AN000;
119 call Init_Io ;Setup messages and parse ;AN000;
120 cmp Fatal_Error,Yes ;Error occur? ;AN000;
121; $IF NE ;Nope, keep going ;AN000;
122 JE $$IF1
123 call Validate_Target_Drive ;Check drive letter ;AN000;
124 cmp Fatal_Error,Yes ;Error occur? ;AN000;
125; $IF NE ;Nope, keep going ;AN000;
126 JE $$IF2
127 call Hook_Interrupts ;Set CNTRL -Break hook ;AN000;
128 cmp Fatal_Error,Yes ;Error occur? ;AN000;
129; $IF NE ;Nope, keep going ;AN000;
130 JE $$IF3
131 call RECOVER_IFS ;RECOVER correct file system ;AN000;
132; $ENDIF ; ;AN000;
133$$IF3:
134; $ENDIF ; ;AN000;
135$$IF2:
136; $ENDIF ; ;AN000;
137$$IF1:
138exitpgm: mov al,ExitStatus ;Get Errorlevel ;AN000;
139 DOS_Call Exit ;Exit program ;AN000;
140 int 20h ;If other exit fails ;AN000;
141
142Main_Init endp ; ;AN000;
143
144;*****************************************************************************
145;Routine name: get_psp
146;*****************************************************************************
147;Description: get info from the psp area
148;
149;Called Procedures: get_drive
150;
151;Change History: Created 8/7/87 bgb
152;
153;Input: none
154;
155;Output: psp_segment
156; command_line_buffer
157;
158;Psuedocode
159;----------
160; get addr of psp
161; move command line into data seg
162; get drive number of target
163; get addr of data seg
164; call get_drive
165; ret
166;*****************************************************************************
167Procedure get_psp ;;AN000;
168 DOS_Call GetCurrentPSP ;Get PSP segment address :AN000;bgb
169 mov PSP_Segment,bx ;Save it for later ;AN000;bgb
170; get command line from psp ;AN000;bgb
171 mov cx,PSP_Segment ;point ds to data seg ;AN000;bgb
172 mov ds,cx ; " " " " " ;AN000;bgb
173 assume ds:NOTHING,es:dg ; " " " " " ;AN000;bgb
174 mov si,Command_Line_Parms ;ds:si --> old area in psp ;AN000;bgb
175 LEA di,command_line_buffer ; es:di -> new area in data
176 mov cx,128 ; do for 128 bytes
177 rep movsb ; mov 1 byte until cx=0
178; get the drive number of the target from the psp (0=default, a=1, b=2, c=3) ;AN000;bgb
179 mov bl,ds:[FCB1] ;Get target drive from FCB -74 ;AN000;
180 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;bgb
181 call get_drive
182 ret
183get_psp endp ; ;AN000;
184
185
186;*****************************************************************************
187;Routine name: get_drive
188;*****************************************************************************
189;Description: get drive letter from reg bl
190;
191;Change History: Created 8/7/87 bgb
192;
193;Input: bl = drive num (default=0)
194;
195;Output: driveletter
196; drive_letter_msg
197; user_drive
198;
199;Psuedocode
200;----------
201; IF drive-num = default
202; get default drive number (a=1)
203; convert to letter
204; ELSE
205; convert to letter
206; ENDIF
207; move letter into data areas
208; ret
209;*****************************************************************************
210Procedure get_drive ;;AN000;
211; convert drive number to drive letter
212 cmp bl,0 ;a=1 b=2 c=3 ;Is it default drive? 0=default ;AN000;
213; $IF E ;Yes, turn it into drive letter ;AN000;
214 JNE $$IF7
215; get default drive number
216 DOS_Call Get_Default_Drive ;Get default drive num in al ;AN000;
217 ;a=0, b=1, c=2
218 mov drive,al ; ;AN000;bgb
219; $ELSE ;Not default, A=1 ;AN000;
220 JMP SHORT $$EN7
221$$IF7:
222; bl already contains the correct drive number - save it
223 dec bl ;a=0 b=1 c=2
224 mov drive,bl ; ;AN000;bgb
225 mov al,bl
226; $ENDIF ; 74+40=b4
227$$EN7:
228 add al,"A" ;convert it to letter ;AN000;
229 mov driveletter,al ;set up prompt msg ;AN000;bgb
230 mov Drive_Letter_Msg,al ;Save it in message ;AN000;
231 mov User_Drive,al ;Put it into path strings ; ;
232 ret
233get_drive endp ; ;AN000;
234
235;*****************************************************************************
236;Routine name: Init_Io
237;*****************************************************************************
238;description: Initialize messages, Parse command line if FAT file system
239;
240;Called Procedures: Preload_Messages
241; Parse_Recover
242;
243;Change History: Created 5/10/87 MT
244;
245;Input: PSP command line at 81h and length at 80h
246;
247;Output: FS_Not_FAT = YES/NO
248; Drive_Letter_Msg set up for any future messages that need it
249;
250;Psuedocode
251;----------
252; Load messages (CALL Preload_Messages)
253; IF no fatal error
254; Get file system type (12-bit fat, 16-bit fat, big fat, ifs)
255; IF old-type-diskette, or
256; dos4.00 12-bit fat, or
257; dos4.00 16-bit fat, then
258; Go handle FAT based Recover syntax's (Call Parse_Recover)
259; ELSE
260; FS_Not_FAT = YES
261; ENDIF
262; ENDIF
263; ret
264;*****************************************************************************
265Procedure Init_IO ;;AN000;
266; load the error messages from the system ;an022;bgb
267 call Preload_Messages ;Load up message retriever ;AN000;
268ifdef fsexec ;an022;bgb
269 mov FS_Not_FAT,No ;an022;bgb
270 cmp Fatal_Error,YES ;Quit? ;AN000; ;an022;bgb
271; $IF NE ;Nope, keep going ;AN000; ;an022;bgb
272 JE $$IF10
273; get file system type from ioctl ;an022;bgb
274 mov al,generic_ioctl ;al=0d (get media id) ;AN000;;an030;bgb
275 xor bx,bx ;use default drive ;AN009;b;an022;bgbgb
276 mov ch,Rawio ;8 = disk io ;an030;bgb;an022;bgb
277 mov cl,Get_Media_Id ;66h ;an030;bgb
278 lea dx,Media_ID_Buffer ;Point at buffer ;AN000; ;an022;bgb
279 DOS_Call IOCtl ;Do function call ah=44 ;AN000; ;an022;bgb
280; is it DOS 3.3 or below? ;carry flag means old dos ;an022;bgb
281; $IF C,OR ;Old style diskette, OR ;AN000; ;an022;bgb
282 JC $$LL11
283; is it a new-12 bit fat? ;an022;bgb
284 lea si,FAT12_String ;Check for FAT_12 string ;AN000; ;an022;bgb
285 lea di,Media_ID_Buffer.Media_ID_File_System ; ;AN0;an022;bgb00;
286 mov cx,Len_FS_ID_String ;Length of compare ;AN00;an022;bgb0;
287 repe cmpsb ;Find it? ;AN00;an022;bgb0;
288; $IF E,OR ;Nope, keep going ;AN000; ;an022;bgb
289 JE $$LL11
290; is it a new 16-bit fat? ;an022;bgb
291 lea si,FAT16_String ;Check for FAT_16 string ;AN000; ;an022;bgb
292 lea di,Media_ID_Buffer.Media_ID_File_System ; ;AN0;an022;bgb00;
293 mov cx,Len_FS_ID_String ;Length of compare ;AN00;an022;bgb0;
294 repe cmpsb ;Do compare ;AN00;an022;bgb0;
295; $IF E ; is it new 16-bit fat? ;AN000; ;an022;bgb
296 JNE $$IF11
297$$LL11:
298endif ;an022;bgb
299; file system is fat based, continue (old or new) ;an022;bgb
300 call Parse_Recover ;Yes, go sort out syntax ;an022;bgb
301; ;an022;bgb
302; non-fat based system ;an022;bgb
303ifdef fsexec ;an022;bgb
304; $ELSE ;We got FS other than FAT ;AN000; ;an022;bgb
305 JMP SHORT $$EN11
306$$IF11:
307 mov FS_Not_FAT,Yes ;Indicate exec file system ;AN000; ;an022;bgb
308 mov cx,8 ;an022;bgb;an011;bgb
309 lea si,Media_ID_Buffer.Media_ID_File_System ;get file system;an022;bgb ;an011;bgb
310 lea di,fs_string_buffer ;put it here ;an022;bgb;an011;bgb
311 rep movsb ;an022;bgb;an011;bgb
312 lea di,fs_string_buffer ;point to beginning again ;an022;bgb;an011;bgb
313; $DO COMPLEX ;search th string until eol found ;an022;bgb;an011;bgb
314 JMP SHORT $$SD13
315$$DO13:
316 inc di ;next char ;an022;bgb;an011;bgb
317; $STRTDO ;start loop here ;an022;bgb;an011;bgb
318$$SD13:
319 cmp byte ptr [di],' ' ;end of string ? ;an022;bgb ;an011;bgb
320; $ENDDO E ;end loop when eol found ;an022;bgb;an011;bgb
321 JNE $$DO13
322 lea si,fs_string_end ;get end of string - rec.exe ;an022;bgb;an011;bgb
323 mov cx,8 ; 8 more chars ;an022;bgb;an011;bgb
324 rep movsb ;move it in ;an022;bgb;an011;bgb
325; $ENDIF ; fat based file system ;AN000; ;an022;bgb
326$$EN11:
327; $ENDIF ; no error from msg retreiver ;AN00;an022;bgb0;
328$$IF10:
329endif ;an022;bgb
330 ret ; ;AN000;
331Init_Io endp ; ;AN000;
332
333;*****************************************************************************
334;Routine name: Preload_Messages
335;*****************************************************************************
336;Description: Preload messages using common message retriever routines.
337;
338;Called Procedures: SysLoadMsg
339;
340;Change History: Created 5/1/87 MT
341;
342;Input: Fatal_Error = NO
343;
344;Output: Fatal_Error = YES/NO
345;
346;Psuedocode
347;----------
348; Preload All messages (Call SysLoadMsg)
349; IF error
350; Display SysLoadMsg error message
351; Fatal_Error = YES
352; ENDIF
353; ret
354;*****************************************************************************
355Procedure Preload_Messages ;;AN000; ;
356 call SysLoadMsg ;Preload the messages ;AN000;
357; $IF C ;Error? ;AN000;
358 JNC $$IF18
359 call SysDispMsg ;Display preload msg ;AN000;
360 mov Fatal_Error, YES ;Indicate error exit ;AN000;
361; $ENDIF ; ;AN000;
362$$IF18:
363 ret ; ;AN000;
364
365Preload_Messages endp ; ;AN000;
366
367;*****************************************************************************
368;Routine name: Parse_Command_Line
369;*****************************************************************************
370;Description: Parse the command line. Check for errors, and display error and
371; exit program if found. Use parse error messages except in case
372; of no parameters, which has its own message
373;
374;Called Procedures: Message (macro)
375; SysParse
376; parse_good
377; parse_err
378;
379;Change History: Created 5/1/87 MT
380;
381;Input: Fatal_Error = NO
382;
383;Output: Fatal_Error = YES/NO
384; PARSE-ADDR
385; DRIVELETTER
386; PARSE-ADDR
387;
388;Psuedocode
389;----------
390; set up regs to call sysparse
391;DO UNTIL error=yes or return(ax)=finish(-1)
392; call sysparse
393; IF ax=good return(0)
394; call parse-good
395; ELSE
396; call parse-err
397; ENDIF
398;ENDLOOP
399;ret
400;
401;A. normal proc == 1- ax=good 0
402; 2- ax=done -1
403;B. no parm == 1- ax=error 2
404;
405;C. too many == 1- ax=good 0
406; 2- ax=error 1
407;D. syntax == 1- ax=error 9
408;*****************************************************************************
409Procedure Parse_recover ; ;AN000;bgb
410 push ds ; save ds ;AN000;bgb
411; set up to call sysparse ;AN000;bgb
412 set_data_segment ;ds,es point to data seg
413 LEA si,command_line_buffer ;ds:si -> cmd line
414 LEA di,parms_input_block ;es:di--> parms input block ;AN000;bgb
415 xor cx,cx ;cx = 0 ;AN000;bgb
416 xor dx,dx ;dx = 0 ;AN000;bgb
417 mov done,no
418; call sysparse until error or end of cmd line ;AN000;bgb
419; $DO ;AN000;bgb
420$$DO20:
421 call SysParse ;go parse ;AN000;bgb
422 cmp ax,$p_rc_eol ; -1 end of command line? ;AN000;bgb
423; $LEAVE E ; yes - done ;AN000;bgb
424 JE $$EN20
425 cmp ax,$p_no_error ; good return code ??? (0) ;AN000;bgb
426; $IF E ; yes ;AN000;bgb
427 JNE $$IF22
428 call parse_good ; go get it ;AN000;bgb
429; $ELSE ; ax not= good ;AN000;bgb
430 JMP SHORT $$EN22
431$$IF22:
432 call parse_err ; check for error ;AN000;bgb
433; $ENDIF ; eol ;AN000;bgb
434$$EN22:
435 cmp Fatal_Error,YES ;Can we continue? ;AN000;bgb
436; $LEAVE E ;NO ;AN000;bgb
437 JE $$EN20
438; $ENDDO ; ;AN000;bgb
439 JMP SHORT $$DO20
440$$EN20:
441 pop ds ; ;AN000;bgb
442 ret ; ;AN000;bgb
443 ; ;AN000;bgb
444Parse_recover endp ; ;AN000;bgb
445 ; ;AN000;bgb
446 ;AN000;bgb
447;*****************************************************************************
448;Routine name: parse_good
449;*****************************************************************************
450;
451;Description: when the ax register returned by sysparse indicates and error,
452; this procedure is called. it then determines which error
453; occurred, and calls parse_message to display the msg.
454;
455;Called Procedures: parse_message (macro)
456;
457;Change History: Created 7/23/87 bgb
458;
459;Input:
460;
461;Output: Fatal_Error = YES/NO
462;
463;Psuedocode
464;----------
465;
466; found=yes
467; IF data=drive
468; save drive number and letter
469; ELSE
470; IF data=filespec
471; save filespec
472; ELSE
473; call parse-msg
474; ENDIF
475; ENDIF
476;*****************************************************************************
477;
478Procedure Parse_good ; ;AN000;bgb
479 cmp parse_type,$p_drive ; 6 if data=drive ;AN000;bgb
480; $IF E ; not eol, good syntax, drive entered ;AN000;bgb
481 JNE $$IF27
482 mov bl,byte ptr parse_addr ;AN000;bgb
483 dec bl ;Make drive 0 based ;AN000;bgb
484 mov drive,bl ;AN000;bgb
485 add bl,'A' ;make it character ;AN000;bgb
486 mov driveletter,bl ;save into drive letter ;AN000;bgb
487; $ELSE ; no - filespec entered ;AN000;bgb
488 JMP SHORT $$EN27
489$$IF27:
490 cmp parse_type,$p_file_spec ; 5 if data = filespec ;AN000;bgb
491; $IF E ; was file spec entered ;AN000;bgb
492 JNE $$IF29
493; push si ; save input offset reg ;AN000;bgb
494; push ds ; save input seg reg ;AN000;bgb
495; push cx ; save count ;AN000;bgb
496; push es ; save other seg reg ;AN000;bgb
497; mov cx,ds ;es points to data ;AN000;bgb
498; mov es,cx ;es points to data ;AN000;bgb
499; mov si,word ptr parse_addr ;get offset to filespec ;AN000;bgb
500; mov ds,word ptr parse_addr+2 ;get segment to filespec ;AN000;bgb
501; mov cx,128 ; mov 128 bytes ;AN000;bgb
502; rep movs es:fname_buffer,ds:[si] ;move it ;AN000;bgb
503; pop es ; save other seg reg ;AN000;bgb
504; pop cx ; save other seg reg ;AN000;bgb
505; pop ds ; save other seg reg ;AN000;bgb
506; pop si ; save other seg reg ;AN000;bgb
507; $ELSE ; no, no drive or filespec ;AN000;bgb
508 JMP SHORT $$EN29
509$$IF29:
510 mov ax,$p_syntax ;tell user bad syntax ;AN000;bgb
511 parse_message ;display msg ;AN000;bgb
512 mov Fatal_Error,YES ;Indicate death! ;AN000;bgb
513; $ENDIF ; was drive entered ? ;AN000;bgb
514$$EN29:
515; $ENDIF ;if data=drive ;AN000;bgb
516$$EN27:
517 ret ; ;aN000;bgb
518 ;AN000;bgb
519parse_good endp ; ;AN000;bgb
520
521 ;AN000;bgb
522;*****************************************************************************
523;Routine name: parse_err
524;*****************************************************************************
525;
526;Description: when the ax register returned by sysparse indicates and error,
527; this procedure is called. it then determines which error
528; occurred, and calls parse_message to display the msg.
529;
530;Called Procedures: parse_message (macro)
531;
532;Change History: Created 7/23/87 bgb
533;
534;Input:
535;
536;Output: Fatal_Error = YES/NO
537;
538;Psuedocode
539;----------
540;
541; IF ax=done (end of cmd line?) -1
542; IF found=no (eol, but no parameters listed)
543; call parse-msg
544; ENDIF
545; ELSE (error other than eol)
546; call parse-msg
547; ENDIF
548;*****************************************************************************
549;
550Procedure Parse_err ; ;AN000;bgb
551 mov Fatal_Error,YES ;Indicate death! ;AN000;bgb ;AN000;bgb
552 cmp ax,$P_Op_Missing ; 2 = no parameters ? ;AN000;bgb
553; $IF E ; ;AN000;bgb
554 JNE $$IF33
555 message baddrv ; yes (invalid drive or filename) ;AN000;bgb
556; $ELSE ;AN000;bgb
557 JMP SHORT $$EN33
558$$IF33:
559 mov byte ptr [si],00 ;zero terminate display string ;an031;bgb
560 dec si ;look at previous char ;an031;bgb
561nextsi:
562public nextsi
563 dec si ;look at previous char ;an031;bgb
564 cmp byte ptr [si],' ' ;find parm separator ;an031;bgb
565 jnz nextsi ;loop until begin of parm found
566 mov movsi,si ;mov si into display parms ;an031;bgb
567 parse_message ;no- display parse message ;AN000;bgb ;AN000;bgb
568; $ENDIF ;AN000;bgb
569$$EN33:
570 ret ; ;AN000;bgb
571parse_err endp ; ;AN000;bgb
572
573
574;*****************************************************************************
575;Routine name: Validate_Target_Drive
576;*****************************************************************************
577;
578;Description: Control routine for validating the specified format target drive.
579; If any of the called routines find an error, they will print
580; message and terminate program, without returning to this routine
581;
582;Called Procedures: Check_Target_Drive
583; Check_For_Network
584; Check_Translate_Drive
585;
586;Change History: Created 5/1/87 MT
587;
588;Input: Fatal_Error = NO
589;
590;Output: Fatal_Error = YES/NO
591;
592;Psuedocode
593;----------
594;
595; CALL Check_Target_Drive
596; IF !Fatal_Error
597; CALL Check_For_Network
598; IF !Fatal_Error
599; CALL Check_Translate_Drive
600; ENDIF
601; ENDIF
602; ret
603;*****************************************************************************
604;
605Procedure Validate_Target_Drive ; ;AN000;
606 call Check_For_Network ;See if Network drive letter ;AN000;
607 cmp Fatal_Error,YES ;Can we continue? ;AN000;
608; $IF NE ;Yep ;AN000;
609 JE $$IF36
610 call Check_Translate_Drive ;See if Subst, Assigned ;AN000;
611 call Check_Target_Drive ;See if valid drive letter ;AN000;
612; $ENDIF ;- Fatal_Error passed back ;AN000;
613$$IF36:
614 ret ; ;AN000;
615
616Validate_Target_Drive endp ; ;AN000;
617
618;*****************************************************************************
619;Routine name: Check_Target_Drive
620;*****************************************************************************
621;
622;Description: Check to see if valid DOS drive by checking if drive is
623; removable. If error, the drive is invalid. Save default
624; drive info. Also get target drive BPB information, and compute
625; the start of the data area
626;
627;Called Procedures: Message (macro)
628;
629;Change History: Created 5/1/87 MT
630;
631;Input: Fatal_Error = NO
632;
633;Output: Fatal_Error = YES/NO
634; User_Drive = default drive
635;
636;Psuedocode
637;----------
638;
639; Get default drive
640; See if drive LOCAL (INT 21h, AX=4409h IOCtl)
641; IF error - drive invalid
642; Display Invalid drive message
643; Fatal_Error= YES
644; ENDIF
645; Get BPB of target drive (Generic IOCtl Get Device parameters)
646; Compute start of data area
647; ret
648;*****************************************************************************
649;
650Procedure Check_Target_Drive ; ;AN000;
651 mov al,0Dh ;Get BPB information ;AN000;
652 mov cx,0860h ; " " " " ;AN000;
653;;;;;;;;mov bl,byte ptr parse_addr ; " " " " ;AN000;
654 mov bl,drive ;drive number ;A=0,B=1 ;AN000;bgb
655 inc bl ;a=1 ;AN000;bgb
656 lea dx,BPB_Buffer ; " " " " ;AN000;
657 DOS_Call IOCtl ; " " " " ;AN000;
658 xor cx,cx ;Find # sectors used by FAT's ;AN000;
659 mov cl,BPB_Buffer.NumberOfFATs ; " " " " ;AN000;
660 mov ax,BPB_Buffer.SectorsPerFAT ; " " " " ;AN000;
661 mul cx ; " " " " ;AN000;
662 push dx ;Save results ;AN000;
663 push ax ; " " ;AN000;
664 mov ax,BPB_Buffer.RootEntries ;Find number of sectors in root ;AN000;
665 mov cl,Dir_Entries_Per_Sector ; by dividing RootEntries ;AN000;
666 div cl ; by (512/32) ;AN000;
667 pop bx ;Get low sectors per FAT back ;AN000;
668 pop dx ;Get high part ;AN000;
669 add ax,bx ;Add to get FAT+Dir sectors ;AN000;
670 adc dx,bp ;zero ;High part ;AN000;
671 add ax,ReservedSectors ;Add in Boot record sectors ;AN000;
672 adc dx,bp ;zero ;to get start of data (DX:AX) ;AN000;
673 mov Data_Start_Low,ax ;Save it ;AN000;
674 mov Data_Start_High,dx ; ;AN000;
675 ret ;And we're outa here ;AN000;
676Check_Target_Drive endp ; ;AN000;
677
678;*****************************************************************************
679;Routine name: Check_For_Network
680;*****************************************************************************
681;
682;Description: See if target drive isn't local, or if it is a shared drive. If
683; so, exit with error message. The IOCtl call is not checked for
684; an error because it is called previously in another routine, and
685; invalid drive is the only error it can generate. That condition
686; would not get this far
687;
688;Called Procedures: Message (macro)
689;
690;Change History: Created 5/1/87 MT
691;
692;Input: Drive
693; Fatal_Error = NO
694;
695;Output: Fatal_Error = YES/NO
696;
697;Psuedocode
698;----------
699; See if drive is local (INT 21h, AX=4409 IOCtl)
700; IF not local
701; Display network message
702; Fatal_ERROR = YES
703; ELSE
704; IF 8000h bit set on return
705; Display assign message
706; Fatal_Error = YES
707; ENDIF
708; ENDIF
709; ret
710;*****************************************************************************
711;
712Procedure Check_For_Network ; ;AN000;
713; is device local? int 21, ah=44, al=9
714 mov bl,drive ;drive number ;A=0,B=1 ;AN000;bgb
715 inc bl ;drive number ;A=1,B=2 for IOCtl call;AN000;bgb
716 mov al,09h ;See if drive is local ;AC000;bgb
717 DOS_Call IOCtl ;-this will fail if bad drive ;AC000;
718; $IF C ;CarrY means invalid drive ;AC000;
719 JNC $$IF38
720 Message BadDrv ;Print message ;AC000;
721 mov Fatal_Error,Yes ;Indicate error ;AN000;
722; $ELSE
723 JMP SHORT $$EN38
724$$IF38:
725 test dx,Net_Check ;if (x & 1200H)(redir or shared); ;
726; $IF NZ ;Found a net drive ;AC000;
727 JZ $$IF40
728 Message NotNetM ;Tell 'em ;AC000;
729 mov Fatal_Error,Yes ;Indicate bad stuff ;AN000;
730; $ELSE ;Local drive, now check assign ;AN000;
731 JMP SHORT $$EN40
732$$IF40:
733 test dx,Assign_Check ;8000h bit is bad news ; ;
734; $IF NZ ;Found it ;AC000;
735 JZ $$IF42
736 Message SubstErr ;Tell error ;AC000;
737 mov Fatal_Error,Yes ;Indicate bad stuff ;AN000;
738; $ENDIF ; ;AN000;
739$$IF42:
740; $ENDIF ; ;AN000;
741$$EN40:
742; $ENDIF ; ;AN000;
743$$EN38:
744 ret ; ;AN000;
745
746Check_For_Network endp ; ;AN000;
747
748;*****************************************************************************
749;Routine name: Check_Translate_Drive
750;*****************************************************************************
751;
752;Description: Do a name translate call on the drive letter to see if it is
753; assigned by SUBST or ASSIGN
754;
755;Called Procedures: Message (macro)
756;
757;Change History: Created 5/1/87 MT
758;
759;Input: Drive_Letter_Msg has drive string
760; Fatal_Error = NO
761;
762;Output: Fatal_Error = YES/NO
763;
764;Psuedocode
765;----------
766; Put drive letter in ASCIIZ string "d:\",0
767; Do name translate call (INT 21)
768; IF drive not same
769; Display assigned message
770; Fatal_Error = YES
771; ENDIF
772; ret
773;*****************************************************************************
774;
775Procedure Check_Translate_Drive ; ;AN000;
776 mov al,Drive_Letter_Msg ;Get target drive letter into ;AN000;
777 mov TranSrc,al ; "d:\",0 string ;AN000;
778 lea si,TranSrc ;Point to translate string ;AN000;
779 push ds ;Set ES=DS (Data segment) ; ;
780 pop es ; " " " " ; ;
781 lea di,FatTbl ;Point at output buffer ; ;
782 DOS_Call xNameTrans ;Get real path ;AC000;
783; $IF NC ;an017;bgb
784 JC $$IF46
785 mov bl,byte ptr [TranSrc] ;Get drive letter from path ; ;
786 cmp bl,byte ptr [Fattbl] ;Did drive letter change? ; ;
787; $IF NE ;If not the same, it be bad ;AC000;
788 JE $$IF47
789 Message SubstErr ;Tell user ;AC000;
790 mov Fatal_Error,Yes ;Setup error flag ;AN000;
791; $ENDIF ; ;AN000;
792$$IF47:
793; $ELSE ;an017;bgb
794 JMP SHORT $$EN46
795$$IF46:
796 mov Fatal_Error,Yes ;Setup error flag ;AN000; ;an017;bgb
797 mov bx,1 ;an017;bgb
798 mov cx,bp ;zero ;an017;bgb
799 mov dx,0100h ;an017;bgb
800 call sysdispmsg ;an017;bgb
801; $ENDIF ; ;AN000; ;an017;bgb
802$$EN46:
803 ret ; ;AN000;
804
805Check_Translate_Drive endp ; ;AN000;
806
807;*****************************************************************************
808;Routine name: Hook_Interrupts
809;*****************************************************************************
810;
811;Description: Change the interrupt handler for INT 13h to point to the
812; ControlC_Handler routine
813;
814;Called Procedures: None
815;
816;Change History: Created 4/21/87 MT
817;
818;Input: None
819;
820;Output: None
821;
822;Psuedocode
823;----------
824;
825; Point at ControlC_Handler routine
826; Set interrupt handler (INT 21h, AX=2523h)
827; ret
828;*****************************************************************************
829;
830 Procedure Hook_Interrupts ; ;AN000;
831 mov al,23h
832 DOS_Call Get_Interrupt_Vector ;Get the INT 23h handler ;AC000;
833 mov word ptr INT_23_Old_Off,bx ;
834 mov bx,es ; ;AN000;
835 mov word ptr INT_23_Old_Seg,bx ; ;AN000;
836 mov al,23h ;Specify CNTRL handler ; ;
837 lea dx, INT_23 ;Point at it ; ;
838 push ds ;Save data seg ; ;
839 push cs ;Point to code segment ; ;
840 pop ds ; ; ;
841 DOS_Call Set_Interrupt_Vector ;Set the INT 23h handler ;AC000;
842 pop ds ;Get Data degment back ; ;
843 mov al,24h ;
844 DOS_Call Get_Interrupt_Vector ;Get the INT 24h handler ;AC000;
845 mov word ptr INT_24_Old_Off,bx ;Save it
846 mov bx,es ; ;AN000;
847 mov word ptr INT_24_Old_Seg,bx ;
848 mov al,24h ;Specify handler ; ;
849 lea dx, INT_24 ;Point at it ; ;
850 push ds ;Save data seg ; ;
851 push cs ;Point to code segment ; ;
852 pop ds ; ; ;
853 DOS_Call Set_Interrupt_Vector ;Set the INT 23h handler ;AC000;
854 pop ds ;Get Data degment back ; ;
855 ret ; ;AN000;
856
857 Hook_Interrupts endp ; ;AN000;
858
859;*****************************************************************************
860;Routine name: Hook_CNTRL_C
861;*****************************************************************************
862;
863;Description: Change the interrupt handler for INT 13h to point to the
864; ControlC_Handler routine
865;
866;Called Procedures: None
867;
868;Change History: Created 4/21/87 MT
869;
870;Input: None
871;
872;Output: None
873;
874;Psuedocode
875;----------
876;
877; Point at ControlC_Handler routine
878; Set interrupt handler (INT 21h, AX=2523h)
879; ret
880;*****************************************************************************
881;
882;rocedure Hook_CNTRL_C ; ;AN000;
883; mov al,23H ;Specify CNTRL handler ; ;
884; mov dx, offset ControlC_Handler ;Point at it ; ;
885; push ds ;Save data seg ; ;
886; push cs ;Point to code segment ; ;
887; pop ds ; ; ;
888; DOS_Call Set_Interrupt_Vector ;Set the INT 23h handler ;AC000;
889; pop ds ;Get Data degment back ; ;
890; ret ; ;AN000;
891;ook_CNTRL_C endp ; ;AN000;
892;
893;ontrolC_Handler:
894; set_data_segment
895;;;;;;; Message msgInterrupt ; ;AC000;
896;;;;;;;;mov ExitStatus, ExitCtrlC
897; jmp ExitPgm
898;*****************************************************************************
899;Routine name: Clear_Append_X
900;*****************************************************************************
901;
902;Description: Determine if Append /XA is turned on thru INT 2Fh, and shut
903; off for life of RECOVER if it is.
904;
905;Called Procedures: None
906;
907;
908;Change History: Created 5/13/87 MT
909;
910;Input: None
911;
912;Output: APPEND = YES/NO
913;
914;Psuedocode
915;----------
916;
917; Append = NO
918; See if APPEND /X is present (INT 2Fh, AX=0B706h)
919; IF present
920; Turn append /X off (INT 2Fh, AX=B707h, BX = 0)
921; Append = YES
922; ENDIF
923; ret
924;*****************************************************************************
925;
926Procedure Clear_Append_X ; ;AN000;
927 mov Append,NO ;Init the Append /X flag ;AN000;
928 mov ax,Append_X ;Is Append /X there? ;AN000;
929 int Multiplex ; " " " " ;AN000;
930 cmp bx,Append_X_Set ;Was it turned on? ;AN000;
931; $IF E ;Yep ;AN000;
932 JNE $$IF51
933 mov Append,YES ;Indicate that it was on ;AN000;
934 mov ax,Set_Append_X ;Turn Append /X off ;AN000;
935 xor bx,bx ;Append_Off ; " " " " ;AN000;
936 int Multiplex ; " " " " ;AN000;
937; $ENDIF ; ;AN000;
938$$IF51:
939 ret ; ;AN000;
940
941Clear_Append_X endp ; ;AN000;
942
943
944;*****************************************************************************
945;Routine name: RECOVER_IFS
946;*****************************************************************************
947;
948;description:
949;
950;Called Procedures: Main_Routine
951; EXEC_FS_RECOVER
952;
953;Change History: Created 5/8/87 MT
954;
955;Input: FS_Not_FAT = Yes/No
956;
957;Output: None
958;
959;Psuedocode
960;----------
961;
962; IF File system other than FAT
963; Go call file system specific RECOVER (CALL EXEC_FS_RECOVER)
964; ELSE
965; Do FAT based RECOVER (CALL Main_Routine)
966; ENDIF
967; ret
968;*****************************************************************************
969;
970Procedure RECOVER_IFS ; ;AN000;
971ifdef fsexec ;an022;bgb
972; cmp FS_Not_Fat,YES ;Is the target FS a FAT? ;AN000; ;an022;bgb
973; $IF E ;No, so need to exec the ;AN000; ;an022;bgb
974; call EXEC_FS_RECOVER ; file system specific prog. ;AN000; ;an022;bgb
975; $ELSE ;It's a FAT ;AN000; ;an022;bgb
976endif ;an022;bgb
977 call clear_append_x ;BGB
978 call Main_Routine ;Use canned code! ;AN000;
979 call reset_append_x ;BGB
980ifdef fsexec ;an022;bgb
981; $ENDIF ; ;AN000; ;an022;bgb
982endif ;an022;bgb
983 ret ; ;AN000;
984
985RECOVER_IFS endp ; ;AN000;
986
987;*****************************************************************************
988;Routine name: Reset_Append_X
989;*****************************************************************************
990;
991;description: If APPEND /XA was on originally, turn it back on
992;
993;Called Procedures: None
994;
995;
996;Change History: Created 5/13/87 MT
997;
998;Input: None
999;
1000;Output: APPEND = YES/NO
1001;
1002;Psuedocode
1003;----------
1004;
1005; IF APPEND = YES
1006; Turn append /X on (INT 2Fh, AX=B707h, BX = 1)
1007; ENDIF
1008; ret
1009;*****************************************************************************
1010;
1011Procedure Reset_Append_X ; ;AN000;
1012 cmp Append,Yes ;Was Append /X on to start with?;AN000;
1013; $IF E ;Yep ;AN000;
1014 JNE $$IF53
1015 mov ax,Set_Append_X ;Turn Append /X off ;AN000;
1016 mov bx,Append_On ; " " " " ;AN000;
1017 int Multiplex ; " " " " ;AN000;
1018; $ENDIF ; ;AN000;
1019$$IF53:
1020 ret ; ;AN000;
1021
1022Reset_Append_X endp ; ;AN000;
1023
1024 pathlabl recinit
1025code ends
1026 end main_init ;AC000;bgb
1027
1028 \ No newline at end of file