]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/RECOVER/RECINIT.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / RECOVER / RECINIT.ASM
1 ;AN000;bgb
2 page ,132 ;\ f
3 TITLE 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
13 INCLUDE SYSCALL.INC ;AN000;BGB
14 INCLUDE RECEQU.INC ;AN000;BGB
15 INCLUDE RECMACRO.INC ;AN000;BGB
16 INCLUDE RECPARSE.INC ;AN000;BGB
17 .list
18
19 ;
20 ;*****************************************************************************
21 ; External Data Declarations
22 ;*****************************************************************************
23 data 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
50 ifdef 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
57 endif
58 data ends ;an000;bgb
59
60
61 code segment public para 'CODE' ;an000;bgb
62 pathlabl recinit
63 ;*****************************************************************************
64 ; recinit procedures
65 ;*****************************************************************************
66 public Main_Init, Init_Io, Preload_Messages, Parse_recover
67 public Parse_good, Parse_err, Validate_Target_Drive
68 public Check_Target_Drive, Check_For_Network, Check_Translate_Drive
69 public Hook_interrupts, Clear_Append_X, RECOVER_IFS, Reset_Append_X
70 public 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 ;*****************************************************************************
114 procedure 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:
138 exitpgm: mov al,ExitStatus ;Get Errorlevel ;AN000;
139 DOS_Call Exit ;Exit program ;AN000;
140 int 20h ;If other exit fails ;AN000;
141
142 Main_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 ;*****************************************************************************
167 Procedure 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
183 get_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 ;*****************************************************************************
210 Procedure 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
233 get_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 ;*****************************************************************************
265 Procedure Init_IO ;;AN000;
266 ; load the error messages from the system ;an022;bgb
267 call Preload_Messages ;Load up message retriever ;AN000;
268 ifdef 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:
298 endif ;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
303 ifdef 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:
329 endif ;an022;bgb
330 ret ; ;AN000;
331 Init_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 ;*****************************************************************************
355 Procedure 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
365 Preload_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 ;*****************************************************************************
409 Procedure 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
444 Parse_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 ;\f
478 Procedure 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
519 parse_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 ;\f
550 Procedure 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
561 nextsi:
562 public 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
571 parse_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 ;\f
605 Procedure 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
616 Validate_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 ;\f
650 Procedure 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;
676 Check_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 ;\f
712 Procedure 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
746 Check_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 ;\f
775 Procedure 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
805 Check_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 ;\f
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 ;\f
926 Procedure 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
941 Clear_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 ;\f
970 Procedure RECOVER_IFS ; ;AN000;
971 ifdef 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
976 endif ;an022;bgb
977 call clear_append_x ;BGB
978 call Main_Routine ;Use canned code! ;AN000;
979 call reset_append_x ;BGB
980 ifdef fsexec ;an022;bgb
981 ; $ENDIF ; ;AN000; ;an022;bgb
982 endif ;an022;bgb
983 ret ; ;AN000;
984
985 RECOVER_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 ;\f
1011 Procedure 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
1022 Reset_Append_X endp ; ;AN000;
1023
1024 pathlabl recinit
1025 code ends
1026 end main_init ;AC000;bgb
1027
1028 \1a