home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / batutl / battutor.arc / SETDISK.ASM < prev    next >
Assembly Source File  |  1983-08-28  |  15KB  |  315 lines

  1.                PAGE 60,132
  2. TITLE  SETDISK.COM  VER.2.0  14-AUG-83  19:15
  3. comment *
  4.  
  5.                         SETDISK.COM
  6.  
  7.  
  8.         VERSION 2.0     14-AUG-83
  9.  
  10.         Written by      Warren Craycroft
  11.                         6236 Oakdale Ave.
  12.                         Oakland, CA  94605
  13.  
  14.  
  15.         (C)  1983  by Warren Craycroft.  Permission is granted to copy and
  16.         distribute this program, including source code, provided that no
  17.         charge shall be made except for a reasonable charge for the media
  18.         and handling, and that this notice shall remain intact in all copies.
  19.  
  20.  
  21. *
  22. comment *
  23.         This program is a utility that can be used with DOS 2.0 to
  24.         find the disk drive number that contains a certain file.
  25.  
  26.         SETDISK is similar to FINDFILE, with one additional feature.
  27.         When SETDISK finds the file, it sets the DOS default
  28.         drive designator to the drive on which the file was found.
  29.  
  30.         A common use of SETDISK is to help a batch file "orient"
  31.         itself by discovering on which drive the Batch File itself is
  32.         running, and on what drives other files (such as useful system
  33.         utilities) can be found.  A lot of this orientation can be done
  34.         without bothering or confusing the user with a lot of questions
  35.         or constraints in locating disks in certain drives.
  36.  
  37.         A key feature of this search (and where this method of orien-
  38.         tation differs from the use of PATH or IF EXIST ) is that
  39.         searching on the disk drives is done "benignly".  By this we mean
  40.         that SETDISK doesn't come to a grinding halt if an empty
  41.         disk drive is searched.  Instead, it continues the search on
  42.         the rest of the drives.  This further relieves the user from
  43.         having to locate certain disks on certain drives.  The target
  44.         file may be on the B: or C: drive with the A: drive empty, and
  45.         SETDISK will find it without the annoying "ignore, abort, retry"
  46.         message.  If the file is not found, then you may gently prod the
  47.         user to place the required disk "in any drive" and try again.
  48.  
  49.         The syntax of the command line is the following:
  50.  
  51.                 findfile  fname
  52.  
  53.         where fname is a standard DOS path, filename, and extention.
  54.         If you include a drive specification (like "a:" for example),
  55.         the drive spec will be ignored by SETDISK.
  56.  
  57.         SETDISK benignly searches all disk drives that  are claimed
  58.         to be present by the system board switches, in order A:, B:, C:, and
  59.         D:.  If the file is found, the disk number of the first disk on
  60.         which it was found is returned in errorlevel and may be tested
  61.         by a Batch File IF Subcommand. SETDISK also changes the DOS default
  62.         drive designator to the disk on which the file was found.
  63.  
  64.  
  65.                 If fname found:         errorlev = 0 if fname on A:
  66.                                         errorlev = 1 if fname on B:
  67.                                         errorlev = 2 if fname on C:
  68.                                         errorlev = 3 if fname on D:
  69.                                         (in all of above cases, the default
  70.                                          drive designator is changed to the
  71.                                          drive on which fname was found )
  72.  
  73.                 If fname not found:     errorlev = 255
  74.  
  75.                 If fname is missing:    errorlev = 255 , and a CNTRL BREAK
  76.                                                    halts the Batch File
  77.  
  78. *
  79. ;
  80. ;               constant equates
  81. ;
  82. BEL_CHAR        EQU     07              ;ascii BEL keycode
  83. CR              EQU     0DH             ;ascii carriage return
  84. LF              EQU     0AH             ;ascii line feed
  85. TAB_CHAR        EQU     09              ;ascii tab
  86. BLANK_CHAR      EQU     ' '             ;ascii blank
  87. COLON_CHAR      EQU     ':'             ;ascii colon
  88. NOT_FOUND_CODE  EQU     255             ;errorlev returned for fname not
  89.                                         ;found
  90. DISK_MASK       EQU     00C0H           ;mask for equipment word's disk
  91.                                         ;count field
  92. ;
  93. ;
  94. ;       declare a relocatable segment.  Follow the .COM file requirements
  95. ;       of entry point at 100H and making all seg register references relative
  96. ;       to CS (no relocatable values MOV'ed into segment registers).
  97. ;
  98. ;
  99. COM_CODE      SEGMENT
  100. ;
  101.                 ORG     80H             ;PSP offset 80:  user's command line
  102. PSP_CMD_LINE    LABEL   BYTE            ;define a label for address refs
  103. ;
  104.                 ORG     100H            ;for COM file
  105. ;
  106. ;
  107.                 ASSUME  CS:COM_CODE,DS:COM_CODE    ;tell assembler value of CS
  108.                 ASSUME  ES:COM_CODE                ; DS, and ES
  109. ;
  110. ;
  111. START           PROC            FAR     ;FAR is meaningless; no RETS
  112. ;
  113.                 MOV     SI,OFFSET PSP_CMD_LINE  ;offset of user's cmd line
  114.                 SUB     CX,CX                   ;clear CX
  115.                 MOV     CL,[SI]                 ;byte count of line
  116.                 OR      CL,CL                   ;zero?
  117.                 JZ      NO_FNAME                ;jump if yes, no fname param
  118.                 SUB     BX,BX                   ;else zero index
  119. ;
  120. ;       find first non-blank or non-tab character of command line
  121. ;
  122. STRIP_BLANKS:   INC     SI                      ;point to next char
  123.                 MOV     AL,[SI]                 ;get next char from cmd line
  124.                 CMP     AL,BLANK_CHAR           ;is it blank?
  125.                 JE      LOOP_BLANKS             ;jump if yes, keep looking
  126.                 CMP     AL,TAB_CHAR             ;is it a tab?
  127.                 JNE     GOT_NON_BLANK           ;jump if not, first non-blank
  128. LOOP_BLANKS:    LOOP    STRIP_BLANKS            ;else keep looking
  129. ;
  130. ;       fname is missing from command line (all blanks or tabs, or else
  131. ;       zero characters on line
  132. ;
  133. NO_FNAME:       MOV     DX,OFFSET ERROR_MESSAGE ;adr offset of error message
  134.                 MOV     AH,9                    ;DOS fn call, "print string"
  135.                 INT     21H                     ;call DOS
  136.                 INT     23H                     ;cause a control break, cause
  137.                                                 ;this is probably a bug in
  138.                                                 ;batch file creation.
  139.                 JMP     NO_FILE_EXIT            ;then exit with errorlevel =
  140.                                                 ; "NOT_FOUND_CODE"
  141. ;
  142. ;       found first non-blank/tab character on command line
  143. ;       at [SI][BX] .  Check for disk designator " n: " and
  144. ;       "strip" it from string by moving up pointer and decreasing
  145. ;       remaining bytes count.
  146. ;
  147. GOT_NON_BLANK:  CMP     BYTE PTR [SI+1],COLON_CHAR  ;2nd non-blank char ":"?
  148.                 JNE     ADD_DRIVE               ;if not, [SI] is start of strng
  149.                 INC     SI                      ;else strip off the drive spec
  150.                 INC     SI
  151.                 DEC     CX                      ;and decr remaining byte count
  152.                 JZ      NO_FNAME                ;if string hits zero bytes left,
  153.                 DEC     CX
  154.                 JZ      NO_FNAME                ;  it's a "no param" error
  155. ;
  156. ;       SI now points to start of ASCIIZ string that we want to use as
  157. ;       the path/file name to search drives for
  158. ;
  159. ;       Put a byte of zeros at the end of string, and an "A:" in front
  160. ;       of string to initialize search.
  161. ;
  162. ADD_DRIVE:      MOV     BX,CX                   ;number of bytes remaining
  163.                 MOV     BYTE PTR [SI][BX],0     ;points to 1 char past end
  164.                                                 ; of string
  165.                 MOV     BYTE PTR [SI-2],'A'     ;"A:" in front of string
  166.                 MOV     BYTE PTR [SI-1],':'
  167. ;
  168. ;       Replace the current critical error handler with our own
  169. ;
  170. ;       First, get the address of the critical error handler assigned
  171. ;       by "parent" process (probably system) to this process.  Save its
  172. ;       address, so that we can use it if our handler is handed a non-disk
  173. ;       error  ( "we don't do non-disk errors ..." )
  174. ;
  175.                 MOV     AH,35H                  ;DOS fn "get vector"
  176.                 MOV     AL,24H                  ;"critical error" vector no.
  177.                 INT     21H                     ;call DOS
  178.                 MOV     WORD PTR PARENT_HAND,BX ;save offset vector adr
  179.                 MOV     WORD PTR PARENT_HAND+2,ES  ;save seg vector adr
  180. ;
  181. ;       Now, take control of critical error vector by assigning a handler
  182. ;       to the vector address.
  183. ;
  184. ;       DOS will restore the "parent"'s vector when this process returns to
  185. ;       DOS.
  186. ;
  187.                 MOV     DX,OFFSET CRIT_HAND     ;address of handler
  188.                 MOV     AL,24H                  ;the vector to be replaced
  189.                 MOV     AH,25H                  ;DOS fn call "ret int vector"
  190.                 INT     21H                     ;call DOS and replace vector
  191. ;
  192. ;       Get the number of drives that DOS knows about
  193. ;       Dont disturb the current default disk setting when getting number
  194. ;       of drives from DOS.
  195. ;
  196.                 MOV     AH,19H                  ;DOS fn "get current disk"
  197.                 INT     21H                     ;current disk retd in AL
  198.                 MOV     DL,AL                   ;cur disk in DL for next call
  199.                 MOV     AH,0EH                  ;DOS fn "sel disk, return numb"
  200.                 INT     21H                     ;number of drives retd in AL
  201.                 SUB     CH,CH                   ;clear CH
  202.                 MOV     CL,AL                   ;number of drives
  203.                 INC     CX                      ;is now (1,2,3, or 4)
  204. ;
  205. ;       Now loop through all drives present, trying to find the file
  206. ;       (using fn call 4EH) on each drive.  If successful, return the
  207. ;       disk number to caller in errorlevel.
  208. ;
  209. ;       If not successful, return errorlevel = NOT_FOUND_CODE
  210. ;
  211.                 MOV     DX,SI                   ;offset adr of drive spec and
  212.                 DEC     DX                      ;  filename
  213.                 DEC     DX
  214. FIND_FILE:      MOV     AH,4EH                  ;DOS fn "find first file"
  215.                 PUSH    CX                      ;save the loop count
  216.                 SUB     CX,CX                   ;attribute says search
  217.                                                 ;"normal" files only
  218.                 PUSH    [SI-2]                  ;save drive letter (DOS call
  219.                                                 ;destroys it if file found)
  220.                 INT     21H                     ;call DOS
  221.                 POP     [SI-2]                  ;restore drive letter
  222.                 POP     CX                      ;restore loop count
  223.                 JNC     FOUND_FILE              ;if carry not set, then search
  224.                                                 ;was successful - jump.
  225.                 INC     BYTE PTR [SI-2]         ;increment drive letter char
  226.                 LOOP    FIND_FILE               ;and look on next drive
  227. ;
  228. ;       did not find file.  Return NOT_FOUND_CODE in errorlevel
  229. ;
  230. NO_FILE_EXIT:   MOV     AL,NOT_FOUND_CODE       ;file not found on any drive
  231. EXIT:           MOV     AH,4CH                  ;DOS fn call to exit w/ errlev
  232.                 INT     21H                     ;call DOS and exit
  233. ;
  234. ;       found the file.  Retrieve the drive letter used in this last call,
  235. ;       map it to disk number (A = 0, B = 1, etc) and return it in errorlevel.
  236. ;
  237. FOUND_FILE:     MOV     AL,[SI-2]               ;get the drive letter (upper
  238.                                                 ;case ascii code)
  239.                 SUB     AL,'A'                  ;map it to 0,1,2,3
  240. ;
  241. ;       Set the default drive designator to the drive on which the file
  242. ;       was found
  243. ;
  244.                 PUSH    AX                      ;save AL
  245.                 MOV     DL,AL                   ;drive number (0,1,2,...)
  246.                 MOV     AH,0EH                  ;DOS fn "select disk"
  247.                 INT     21H                     ;call DOS and set default
  248.                 POP     AX                      ;restore AL
  249.                 JMP     EXIT                    ;and return it in errorlevel
  250. START           ENDP
  251. page
  252. ;
  253. ;               CRIT_HAND               Critical Error Handler
  254. ;
  255. ;       This handler will be called by DOS functions when any critical
  256. ;       error (disk or non-disk) occurs during DOS INT 21H calls that
  257. ;       are made during execution of this process.
  258. ;
  259. ;       We only want to ignore disk errors, so we first test if the disk
  260. ;       is the cause of error.
  261. ;
  262. ;       If not a disk error, we jump to the parent's critical error handler
  263. ;       (we JMP so that stack looks as if we were never there).
  264. ;
  265. ;       If it is a disk error, we return an IGNORE code to the calling
  266. ;       DOS function.  The effect of all this is that when a DOS function
  267. ;       tries to access a disk drive that has a door open, or no disk, or
  268. ;       disk is unformatted, or disk is garbled, etc, the DOS function will
  269. ;       simply give up and return to the function's caller "empty handed".
  270. ;       There will be no "abort, retry, ignore" message from the critical
  271. ;       error handler.
  272. ;
  273. ;       on entry:       Bit 7 of AH = 0 if disk error
  274. ;                                   = 1 if not a disk error
  275. ;
  276. ;       on exit:        If disk error, we set AL = 0, "ignore error"
  277. ;
  278. ;       registers affected:     AH, AL
  279. ;
  280. CRIT_HAND       PROC    FAR                     ;RETS are typed FAR
  281.                 TEST    AH,80H                  ;bit 7 set?
  282.                 JNZ     NOT_DISK                ;jump if yes,not disk error,
  283.                                                 ;don't treat it
  284. ;
  285. ;       Treatment of disk errors is easy, just tell system to ignore them
  286. ;
  287.                 SUB     AL,AL                   ;zero AL, "ignore" code
  288.                 IRET                            ;caller used INT so we IRET
  289. ;
  290. ;       It was not a disk error, so let the "parent" critical error handler
  291. ;       treat it by JMPing to its address that we saved.
  292. ;
  293. ;       We JMP so we dont disturb the stack.  Stack looks like we were
  294. ;       never called.
  295. ;
  296. NOT_DISK:       JMP     DWORD PTR PARENT_HAND   ;jump to parent crit err hand
  297. ;
  298. CRIT_HAND       ENDP
  299. ;
  300. ;
  301. ;       temporary storage of parent's critical handler address
  302. ;
  303. PARENT_HAND     DD      1 DUP(?)                ;double word for FAR address
  304. ;
  305. ;
  306. ;
  307. ;       error message string
  308. ;
  309. ERROR_MESSAGE   DB      CR,LF,'***** No filename was given with '
  310.                 DB      'SETDISK *****',CR,LF,'$'
  311. ;
  312. ;
  313. COM_CODE        ENDS
  314.                 END     START
  315. Ä├╣QÜ└éÄ^■ïσ]╦MW_F