Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

781 lines
21 KiB

  1. page ,132
  2. ; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
  3. ; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
  4. TITLE PART4 COMMAND Transient routines.
  5. ;/*
  6. ; * Microsoft Confidential
  7. ; * Copyright (C) Microsoft Corporation 1991
  8. ; * All Rights Reserved.
  9. ; */
  10. ; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER
  11. .xlist
  12. .xcref
  13. include dossym.inc
  14. include bpb.inc
  15. include syscall.inc
  16. include filemode.inc
  17. include sf.inc
  18. include comseg.asm
  19. include comsw.asm ;ac000;
  20. include comequ.asm
  21. include ioctl.inc ;an000;
  22. .list
  23. .cref
  24. DATARES SEGMENT PUBLIC BYTE ;AN020;AC068;
  25. EXTRN append_flag:byte ;AN020;AC068;
  26. EXTRN append_state:word ;AN020;AC068;
  27. EXTRN SCS_PAUSE:BYTE ; yst 4-5-93
  28. DATARES ENDS ;AN020;AC068;
  29. TRANDATA SEGMENT PUBLIC BYTE ;AC000;
  30. EXTRN badcpmes_ptr:word ;AC022;
  31. EXTRN Extend_buf_ptr:word ;AC000;
  32. EXTRN Extend_buf_sub:byte ;AN000;
  33. EXTRN inornot_ptr:word
  34. EXTRN msg_disp_class:byte ;AC000;
  35. EXTRN parse_erase:byte ;AC000;
  36. EXTRN parse_mrdir:byte ;AC000;
  37. EXTRN parse_rename:byte ;AC000;
  38. EXTRN parse_vol:byte ;AC000;
  39. EXTRN PauseMes_ptr:word
  40. EXTRN renerr_ptr:word
  41. EXTRN slash_p_syn:word ;AC000;
  42. EXTRN volmes_ptr:word ;AC000;
  43. EXTRN volmes_ptr_2:word ;AC000;
  44. EXTRN volsermes_ptr:word ;AC000;
  45. TRANDATA ENDS
  46. TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
  47. EXTRN bytcnt:word
  48. EXTRN charbuf:byte
  49. EXTRN comsw:word
  50. EXTRN curdrv:byte
  51. EXTRN destinfo:byte
  52. EXTRN destisdir:byte
  53. EXTRN dirbuf:byte
  54. EXTRN msg_numb:word ;AN022;
  55. EXTRN one_char_val:byte
  56. EXTRN parse1_addr:dword ;AN000;
  57. EXTRN parse1_syn:word ;AN000;
  58. EXTRN resseg:word ;AN020;AC068;
  59. EXTRN srcbuf:byte ;AN000;
  60. EXTRN string_ptr_2:word ;AN000;
  61. EXTRN TPA:word
  62. EXTRN vol_drv:byte
  63. EXTRN vol_ioctl_buf:byte ;AC000;
  64. EXTRN vol_label:byte ;AC000;
  65. EXTRN vol_serial:dword ;AC000;
  66. EXTRN zflag:byte
  67. extrn TypeFilSiz:dword
  68. TRANSPACE ENDS
  69. TRANCODE SEGMENT PUBLIC BYTE
  70. ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
  71. ;---------------
  72. TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
  73. EXTRN arg:byte ; the arg structure!
  74. transpace ends
  75. ;---------------
  76. EXTRN cerror:near
  77. EXTRN error_output:near
  78. EXTRN notest2:near
  79. EXTRN slashp_erase:near ;AN000;
  80. EXTRN std_printf:near
  81. EXTRN tcommand:near
  82. PUBLIC badpath_err ;AN022;
  83. PUBLIC crename
  84. PUBLIC DisAppend
  85. PUBLIC erase
  86. PUBLIC extend_setup ;AN022;
  87. PUBLIC Get_ext_error_number ;AN022;
  88. PUBLIC pause
  89. PUBLIC Set_ext_error_msg ;AN000;
  90. PUBLIC typefil
  91. PUBLIC volume
  92. break Pause
  93. PAUSE:
  94. push ds
  95. mov ds, ResSeg
  96. assume ds:resgroup
  97. cmp SCS_PAUSE, 0
  98. pop ds
  99. jne pause_break
  100. assume ds:trangroup,es:trangroup
  101. mov dx,offset trangroup:pausemes_ptr
  102. call std_printf
  103. invoke GetKeystroke
  104. invoke crlf2
  105. pause_break:
  106. return
  107. break Erase
  108. ;****************************************************************
  109. ;*
  110. ;* ROUTINE: DEL/ERASE - erase file(s)
  111. ;*
  112. ;* FUNCTION: PARSE command line for file or path name and /P
  113. ;* and invoke PATHCRUNCH. If an error occurs, set
  114. ;* up an error message and transfer control to CERROR.
  115. ;* Otherwise, transfer control to NOTEST2 if /P not
  116. ;* entered or SLASHP_ERASE if /P entered.
  117. ;*
  118. ;* INPUT: command line at offset 81H
  119. ;*
  120. ;* OUTPUT: if no error:
  121. ;* FCB at 5ch set up with filename(s) entered
  122. ;* Current directory set to entered directory
  123. ;*
  124. ;****************************************************************
  125. assume ds:trangroup,es:trangroup
  126. ERASE:
  127. mov si,81H ;AC000; get command line
  128. mov comsw,0 ;AN000; clear switch indicator
  129. mov di,offset trangroup:parse_erase ;AN000; Get adderss of PARSE_erase
  130. xor cx,cx ;AN000; clear cx,dx
  131. erase_scan:
  132. xor dx,dx ;AN000;
  133. invoke parse_with_msg ;AC018; call parser
  134. cmp ax,end_of_line ;AN000; are we at end of line?
  135. jz good_line ;AN000; yes - done parsing
  136. cmp ax,result_no_error ;AC000; did we have an error?
  137. jnz errj2 ;AC000; yes exit
  138. cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered?
  139. je set_erase_prompt ;AN000; yes - go set prompt
  140. ;
  141. ; Must be filespec since no other matches occurred. move filename to srcbuf
  142. ;
  143. push si ;AC000; save position in line
  144. lds si,parse1_addr ;AC000; get address of filespec
  145. cmp byte ptr[si+1],colon_char ;AC000; drive specified?
  146. jnz Erase_drive_ok ;AC000; no - continue
  147. cmp byte ptr[si+2],end_of_line_out ;AC000; was only drive entered?
  148. jnz erase_drive_ok ;AC000; no - continue
  149. mov ax,error_file_not_found ;AN022; get message number in control block
  150. jmp short extend_setup ;AC000; exit
  151. erase_drive_ok:
  152. invoke move_to_srcbuf ;AC000; move to srcbuf
  153. pop si ;AC000; get position back
  154. jmp short erase_scan ;AN000; continue parsing
  155. set_erase_prompt:
  156. cmp comsw,0 ;AN018; was /P already entered?
  157. jz ok_to_set_erase_prompt ;AN018; no go set switch
  158. mov ax,moreargs_ptr ;AN018; set up too many arguments
  159. invoke setup_parse_error_msg ;AN018; set up an error message
  160. jmp short errj2 ;AN018; exit
  161. ok_to_set_erase_prompt: ;AN018;
  162. inc comsw ;AN000; indicate /p specified
  163. jmp short erase_scan ;AN000; continue parsing
  164. good_line: ;G We know line is good
  165. invoke pathcrunch
  166. jnc checkdr
  167. mov ax,[msg_numb] ;AN022; get message number
  168. cmp ax,0 ;AN022; was message flag set?
  169. jnz extend_setup ;AN022; yes - print out message
  170. cmp [destisdir],0 ; No CHDIRs worked
  171. jnz badpath_err ;AC022; see if they should have
  172. checkdr:
  173. cmp comsw,0 ;AN000; was /p specified
  174. jz notest2j ;AN000; no - go to notest2
  175. jmp slashp_erase ;AN000; yes - go to slashp_erase
  176. notest2j:
  177. jmp notest2
  178. badpath_err: ;AN022; "Path not found" message
  179. mov ax,error_path_not_found ;AN022; set up error number
  180. extend_setup: ;AN022;
  181. mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class
  182. mov dx,offset TranGroup:Extend_Buf_ptr ;AC022; get extended message pointer
  183. mov Extend_Buf_ptr,ax ;AN022; get message number in control block
  184. errj2: ;AC022; exit jump
  185. jmp Cerror ;AN022;
  186. break Rename
  187. ; ****************************************************************
  188. ; *
  189. ; * ROUTINE: CRENAME - rename file(s)
  190. ; *
  191. ; * FUNCTION: PARSE command line for one full filespec and one
  192. ; * filename. Invoke PATHCRUNCH on the full filespec.
  193. ; * Make sure the second filespec only contains a
  194. ; * filename. If both openands are valid, attempt
  195. ; * to rename the file.
  196. ; *
  197. ; * INPUT: command line at offset 81H
  198. ; *
  199. ; * OUTPUT: none
  200. ; *
  201. ; ****************************************************************
  202. assume ds:trangroup,es:trangroup
  203. CRENAME:
  204. mov si,81H ;AC000; Point to command line
  205. mov di,offset trangroup:parse_rename;AN000; Get adderss of PARSE_RENAME
  206. xor cx,cx ;AN000; clear cx,dx
  207. xor dx,dx ;AN000;
  208. invoke parse_with_msg ;AC018; call parser
  209. cmp ax,result_no_error ;AC000; did we have an error?
  210. ;; jz crename_no_parse_error ;AC000; no - continue
  211. jnz crename_parse_error ;AC000; Yes, fail. (need long jump)
  212. ;
  213. ; Get first file name returned from parse into our buffer
  214. ;
  215. crename_no_parse_error:
  216. push si ;AN000; save position in line
  217. lds si,parse1_addr ;AN000; get address of filespec
  218. invoke move_to_srcbuf ;AN000; move to srcbuf
  219. pop si ;AN000; restore position in line
  220. xor dx,dx ;AN000; clear dx
  221. invoke parse_with_msg ;AC018; call parser
  222. cmp ax,result_no_error ;AN000; did we have an error?
  223. JNZ crename_parse_error ;AN000; Yes, fail.
  224. ;
  225. ; Check the second file name for drive letter colon
  226. ;
  227. push si ;AN000; save position in line
  228. lds si,parse1_addr ;AC000; get address of path
  229. mov al,':' ;AC000;
  230. cmp [si+1],al ;AC000; Does the 2nd parm have a drive spec?
  231. jnz ren_no_drive ;AN000; Yes, error
  232. mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
  233. mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
  234. mov Extend_Buf_ptr,BadParm_ptr ;AN000; get "Invalid parameter" message number
  235. pop si ;AN000;
  236. crename_parse_error: ;AC022;
  237. jmp short errj ;AC000;
  238. ;
  239. ; Get second file name returned from parse into the fCB. Save
  240. ; character after file name so we can later check to make sure it
  241. ; isn't a path character.
  242. ;
  243. ren_no_drive:
  244. mov di,FCB+10H ;AC000; set up to parse second file name
  245. mov ax,(Parse_File_Descriptor SHL 8) OR 01H ;AC000;
  246. int 21h ;AC000; do the function
  247. lodsb ;AC000; Load char after filename
  248. mov one_char_val,al ;AN000; save char after filename
  249. pop si ;AN000; get line position back
  250. ;
  251. ; We have source and target. See if any args beyond.
  252. ;
  253. mov di,offset trangroup:parse_rename;AC000; get address of parse_rename
  254. invoke parse_check_eol ;AC000; are we at end of line?
  255. jnz crename_parse_error ;AN000; no, fail.
  256. invoke pathcrunch
  257. mov dx,offset trangroup:badcpmes_ptr
  258. jz errj2 ; If 1st parm a dir, print error msg
  259. jnc notest3
  260. mov ax,[msg_numb] ;AN022; get message number
  261. cmp ax,0 ;AN022; was message flag set?
  262. jnz extend_setup ;AN022; yes - print out message
  263. cmp [destisdir],0 ; No CHDIRs worked
  264. jz notest3 ; see if they should have
  265. Jmp badpath_err ;AC022; set up error
  266. notest3:
  267. mov al,one_char_val ;AN000; move char into AX
  268. mov dx,offset trangroup:inornot_ptr ; Load invalid fname error ptr
  269. invoke pathchrcmp ; Is the char in al a path sep?
  270. jz errj ; Yes, error - 2nd arg must be
  271. ; filename only.
  272. mov ah,FCB_Rename
  273. mov dx,FCB
  274. int 21h
  275. cmp al, 0FFH ; Did an error occur??
  276. jnz renameok
  277. invoke get_ext_error_number ;AN022; get extended error
  278. SaveReg <AX> ;AC022; Save results
  279. mov al, 0FFH ; Restore original error state
  280. renameok:
  281. push ax
  282. invoke restudir
  283. pop ax
  284. inc al
  285. retnz
  286. RestoreReg <AX> ;AC022; get the error number back
  287. cmp ax,error_file_not_found ;AN022; error file not found?
  288. jz use_renerr ;AN022; yes - use generic error message
  289. cmp ax,error_access_denied ;AN022; error file not found?
  290. jz use_renerr ;AN022; yes - use generic error message
  291. jmp extend_setup ;AN022; need long jump - use extended error
  292. use_renerr:
  293. mov dx,offset trangroup:RenErr_ptr ;AC022;
  294. ERRJ:
  295. jmp Cerror
  296. ret56: ret
  297. break Type
  298. ;****************************************************************
  299. ;*
  300. ;* ROUTINE: TYPEFIL - Display the contents of a file to the
  301. ;* standard output device
  302. ;*
  303. ;* SYNTAX: TYPE filespec
  304. ;*
  305. ;* FUNCTION: If a valid filespec is found, read the file until
  306. ;* 1Ah and display the contents to STDOUT.
  307. ;*
  308. ;* INPUT: command line at offset 81H
  309. ;*
  310. ;* OUTPUT: none
  311. ;*
  312. ;****************************************************************
  313. assume ds:trangroup,es:trangroup
  314. TYPEFIL:
  315. mov si,81H
  316. mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR
  317. xor cx,cx ;AN000; clear cx,dx
  318. xor dx,dx ;AN000;
  319. invoke parse_with_msg ;AC018; call parser
  320. cmp ax,result_no_error ;AC000; did we have an error?
  321. jnz typefil_parse_error ;AN000; yes - issue error message
  322. push si ;AC000; save position in line
  323. lds si,parse1_addr ;AC000; get address of filespec
  324. invoke move_to_srcbuf ;AC000; move to srcbuf
  325. pop si ;AC000; get position back
  326. mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir
  327. invoke parse_check_eol ;AC000; are we at end of line?
  328. jz gottarg ;AC000; yes - continue
  329. typefil_parse_error: ;AN000; no - set up error message and exit
  330. jmp Cerror
  331. gottarg:
  332. invoke setpath
  333. test [destinfo],00000010b ; Does the filespec contain wildcards
  334. jz nowilds ; No, continue processing
  335. mov dx,offset trangroup:inornot_ptr ; Yes, report error
  336. jmp Cerror
  337. nowilds:
  338. mov ax,ExtOpen SHL 8 ;AC000; open the file
  339. mov bx,read_open_mode ;AN000; get open mode for TYPE
  340. xor cx,cx ;AN000; no special files
  341. mov dx,read_open_flag ;AN000; set up open flags
  342. mov si,offset trangroup:srcbuf ;AN030; get file name
  343. int 21h
  344. jnc typecont ; If open worked, continue. Otherwise load
  345. Typerr: ;AN022;
  346. push cs ;AN022; make sure we have local segment
  347. pop ds ;AN022;
  348. invoke set_ext_error_msg ;AN022;
  349. mov string_ptr_2,offset trangroup:srcbuf ;AC022; get address of failed string
  350. mov Extend_buf_sub,one_subst ;AC022; put number of subst in control block
  351. jmp cerror ;AC022; exit
  352. typecont:
  353. mov bx,ax ;AC000; get Handle
  354. ;M043
  355. ; We should do the LSEEK for filesize only if this handle belongs to a file
  356. ;and not if it belongs to a device. If device, set TypeFilSiz+2 to -1 to
  357. ;indicate it is a device.
  358. ;
  359. mov ax,(IOCTL shl 8) or 0
  360. int 21h
  361. test dl,80h ;is it a device?
  362. jz not_device ;no, a file
  363. mov word ptr TypeFilSiz+2,-1 ;indicate it is a device
  364. jmp short dotype
  365. not_device:
  366. ;SR;
  367. ; Find the filesize by seeking to the end and then reset file pointer to
  368. ;start of file
  369. ;
  370. mov ax,(LSEEK shl 8) or 2
  371. xor dx,dx
  372. mov cx,dx ;seek to end of file
  373. int 21h
  374. mov word ptr TypeFilSiz,ax
  375. mov word ptr TypeFilSiz+2,dx ;store filesize
  376. mov ax,(LSEEK shl 8) or 0
  377. xor dx,dx
  378. int 21h ;reset file pointer to start
  379. dotype: ;M043
  380. mov zflag,0 ; Reset ^Z flag
  381. mov ds,[TPA]
  382. xor dx,dx
  383. ASSUME DS:NOTHING
  384. typelp:
  385. cmp cs:[zflag],0 ;AC050; Is the ^Z flag set?
  386. retnz ; Yes, return
  387. mov cx,cs:[bytcnt] ;AC056; No, continue
  388. ;
  389. ;Update the filesize left to read
  390. ;
  391. cmp word ptr cs:TypeFilSiz+2,-1 ;is it a device? M043
  392. je typ_read ;yes, just read from it; M043
  393. cmp word ptr cs:TypeFilSiz+2,0 ;more than 64K left?
  394. jz lt64k ;no, do word subtraction
  395. sub word ptr cs:TypeFilSiz, cx
  396. sbb word ptr cs:TypeFilSiz+2, 0 ;update filesize
  397. jmp short typ_read ;do the read
  398. lt64k:
  399. cmp cx,word ptr cs:TypeFilSiz ;readsize <= buffer?
  400. jbe gtbuf ;yes, just update readsize
  401. ;
  402. ;Buffer size is larger than bytes to read
  403. ;
  404. mov cx,word ptr cs:TypeFilSiz
  405. jcxz typelp_ret
  406. mov word ptr cs:TypeFilSiz,0
  407. jmp short typ_read
  408. gtbuf:
  409. sub word ptr cs:TypeFilSiz,cx ;update filesize remaining
  410. typ_read:
  411. mov ah,read
  412. int 21h
  413. jnc @f ;M043
  414. jmp typerr ;M043
  415. @@: ;M043
  416. ;M043; jc typerr ;AN022; Exit if error
  417. mov cx,ax
  418. jcxz typelp_ret ;AC000; exit if nothing read
  419. push ds
  420. pop es ; Check to see if a ^Z was read.
  421. assume es:nothing
  422. xor di,di
  423. push ax
  424. mov al,1ah
  425. repnz scasb
  426. pop ax
  427. xchg ax,cx
  428. cmp ax,0
  429. jnz foundz ; Yes, handle it
  430. cmp byte ptr [di-1],1ah ; No, double check
  431. jnz typecont2 ; No ^Z, continue
  432. foundz:
  433. sub cx,ax ; Otherwise change cx so that only those
  434. dec cx ; bytes up to but NOT including the ^Z
  435. push cs ; will be typed.
  436. pop es
  437. assume es:trangroup
  438. not zflag ; Turn on ^Z flag so that the routine
  439. typecont2: ; will quit after this write.
  440. push bx
  441. mov bx,1
  442. mov ah,write
  443. int 21h
  444. pop bx
  445. jc Error_outputj
  446. cmp ax,cx
  447. jnz @f ;M043
  448. jmp typelp ;M043
  449. @@: ;M043
  450. ;M043; jz typelp
  451. dec cx
  452. cmp ax,cx
  453. retz ; One less byte OK (^Z)
  454. Error_outputj:
  455. mov bx,1
  456. mov ax,IOCTL SHL 8
  457. int 21h
  458. test dl,devid_ISDEV
  459. retnz ; If device, no error message
  460. jmp error_output
  461. typelp_ret:
  462. ret
  463. break Volume
  464. assume ds:trangroup,es:trangroup
  465. ;
  466. ; VOLUME command displays the volume ID on the specified drive
  467. ;
  468. VOLUME:
  469. mov si,81H
  470. mov di,offset trangroup:parse_vol ;AN000; Get adderss of PARSE_VOL
  471. xor cx,cx ;AN000; clear cx,dx
  472. xor dx,dx ;AN000;
  473. invoke parse_with_msg ;AC018; call parser
  474. cmp ax,end_of_line ;AC000; are we at end of line?
  475. jz OkVolArg ;AC000; Yes, display default volume ID
  476. cmp ax,result_no_error ;AC000; did we have an error?
  477. jnz BadVolArg ;AC000; Yes, fail.
  478. ;
  479. ; We have parsed off the drive. See if there are any more chars left
  480. ;
  481. mov di,offset trangroup:parse_vol ;AC000; get address of parse_vol
  482. xor dx,dx ;AC000;
  483. invoke parse_check_eol ;AC000; call parser
  484. jz OkVolArg ;AC000; yes, end of road
  485. ;
  486. ; The line was not interpretable. Report an error.
  487. ;
  488. badvolarg:
  489. jmp Cerror
  490. ;*** DisAppend - disable APPEND
  491. ;
  492. ; ENTRY nothing
  493. ;
  494. ; EXIT nothing
  495. ;
  496. ; USED AX,BX
  497. ;
  498. ; EFFECTS
  499. ;
  500. ; APPEND is disabled. If it was active, it will be re-enabled
  501. ; after the command finishes, by the HeadFix routine.
  502. ;
  503. ; NOTE
  504. ;
  505. ; This routine must not be called more than once during a single
  506. ; command cycle. The second call would permanently disable APPEND.
  507. DisAppend proc
  508. assume ds:TRANGROUP,es:NOTHING
  509. push ds ; save DS
  510. push es ; save ES
  511. push di
  512. mov ax,APPENDINSTALL ; AX = Append Installed Check code
  513. int 2Fh ; talk to APPEND via multiplex
  514. or al,al
  515. jz daRet ; APPEND not installed, return
  516. mov ax,APPENDDOS ; AX = Get Append Version code
  517. int 2Fh ; talk to APPEND via multiplex
  518. cmp ax,0FFFFh
  519. jne daRet ; it's not a local version, return
  520. mov ax,APPENDGETSTATE ; AX = Get Function State code
  521. int 2Fh ; talk to APPEND via multiplex
  522. mov ds,ResSeg ; DS = resident seg addr
  523. assume ds:RESGROUP
  524. mov Append_State,bx ; Append_State = saved APPEND state
  525. mov Append_Flag,-1 ; Append_Flag = true, restore state
  526. xor bx,bx ; BX = APPEND state = off
  527. mov AX,APPENDSETSTATE ; AX = Set Append State code
  528. int 2Fh ; talk to APPEND via multiplex
  529. daRet: pop di
  530. pop es ; restore ES
  531. pop ds ; restore DS
  532. assume ds:TRANGROUP
  533. ret
  534. DisAppend endp
  535. ;
  536. ; Find the Volume ID on the disk.
  537. ;
  538. PUBLIC OkVolArg
  539. OKVOLARG:
  540. assume ds:TRANGROUP,es:TRANGROUP
  541. call DisAppend ; disable APPEND
  542. invoke crlf2
  543. mov al,blank ;AN051; Print out a blank
  544. invoke print_char ;AN051; before volume message
  545. push ds
  546. pop es
  547. ;
  548. ; Volume IDs are only findable via extended FCBs or find_first with attributes
  549. ; of volume_id ONLY.
  550. ;
  551. mov di,FCB-7 ; Point to extended FCB beginning
  552. mov al,-1 ; Tag to indicate Extention
  553. stosb
  554. xor ax,ax ; Zero padding to volume label
  555. stosw
  556. stosw
  557. stosb
  558. mov al,attr_volume_ID ; Look for volume label
  559. stosb
  560. inc di ; Skip drive byte; it is already set
  561. mov cx,11 ; fill in remainder of file
  562. mov al,'?'
  563. rep stosb
  564. ;
  565. ; Set up transfer address (destination of search first information)
  566. ;
  567. mov dx,offset trangroup:dirbuf
  568. mov ah,set_DMA
  569. int 21h
  570. ;
  571. ; Do the search
  572. ;
  573. mov dx,FCB-7
  574. mov ah,Dir_Search_First
  575. int 21h
  576. ;********************************
  577. ; Print volume ID info
  578. push ax ;AC000; AX return from SEARCH_FIRST for VOL ID
  579. mov al,DS:[FCB] ;AC000; get drive letter
  580. add al,'@'
  581. cmp al,'@'
  582. jnz drvok
  583. mov al,[curdrv]
  584. add al,capital_A
  585. drvok:
  586. mov vol_drv,al ;AC000; get drive letter into argument
  587. pop ax ;AC000; get return code back
  588. or al,al ;AC000; volume label found?
  589. jz Get_vol_name ;AC000; volume label exists - go get it
  590. mov dx,offset trangroup:VolMes_ptr_2 ;AC000; set up no volume message
  591. jmp short print_serial ;AC000; go print it
  592. Get_vol_name:
  593. mov di,offset trangroup:charbuf
  594. mov dx,di
  595. mov si,offset trangroup:dirbuf + 8 ;AN000; 3/3/KK
  596. mov cx,11 ;AN000; 3/3/KK
  597. rep movsb ;AN000; 3/3/KK
  598. xor al,al ;AC000; store a zero to terminate the string
  599. stosb
  600. mov dx,offset trangroup:VolMes_ptr ;AC000; set up message
  601. PRINT_SERIAL:
  602. ;
  603. ; Attempt to get the volume serial number from the disk. If an error
  604. ; occurs, do not print volume serial number.
  605. ;
  606. push dx ;AN000; save message offset
  607. mov ax,(GetSetMediaID SHL 8) ;AC036; Get the volume serial info
  608. mov bl,DS:[FCB] ;AN000; get drive number from FCB
  609. mov dx,offset trangroup:vol_ioctl_buf ;AN000;target buffer
  610. int 21h ;AN000; do the call
  611. pop dx ;AN000; get message offset back
  612. jc printvol_end ;AN000; if error, just go print label
  613. call std_printf ;AC000; go print volume message
  614. mov al,blank ;AN051; Print out a blank
  615. invoke print_char ;AN051; before volume message
  616. mov dx,offset trangroup:VolSerMes_ptr ;AN000; get serial number message
  617. printvol_end:
  618. jmp std_printf ;AC000; go print and exit
  619. ;****************************************************************
  620. ;*
  621. ;* ROUTINE: Set_ext_error_msg
  622. ;*
  623. ;* FUNCTION: Sets up extended error message for printing
  624. ;*
  625. ;* INPUT: return from INT 21
  626. ;*
  627. ;* OUTPUT: extended error message set up in extended error
  628. ;* buffer.
  629. ;*
  630. ;****************************************************************
  631. Set_ext_error_msg proc near ;AN000;
  632. call get_ext_error_number ;AC022; get the extended error
  633. mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
  634. mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
  635. mov Extend_Buf_ptr,ax ;AN000; get message number in control block
  636. stc ;AN000; make sure carry is set
  637. ret ;AN000; return
  638. Set_ext_error_msg endp ;AN000;
  639. ;****************************************************************
  640. ;*
  641. ;* ROUTINE: Get_ext_error_number
  642. ;*
  643. ;* FUNCTION: Does get extended error function call
  644. ;*
  645. ;* INPUT: return from INT 21
  646. ;*
  647. ;* OUTPUT: AX - extended error number
  648. ;*
  649. ;****************************************************************
  650. Get_ext_error_number proc near ;AN022;
  651. SaveReg <BX,CX,DX,SI,DI,BP,ES,DS> ;AN022; save registers
  652. mov ah,GetExtendedError ;AN022; get extended error
  653. xor bx,bx ;AN022; clear BX
  654. int 21h ;AN022;
  655. RestoreReg <DS,ES,BP,DI,SI,DX,CX,BX> ;AN022; restore registers
  656. ret ;AN022; return
  657. Get_ext_error_number endp ;AN022;
  658. trancode ends
  659. end
  660.