REDIR.A86
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:46k
源码类别:

操作系统开发

开发平台:

Asm

  1. title 'REDIR - DOS file system network redirector interace support'
  2. ;    File              : $REDIR.A86$
  3. ;
  4. ;    Description       :
  5. ;
  6. ;    Original Author   : DIGITAL RESEARCH
  7. ;
  8. ;    Last Edited By    : $CALDERA$
  9. ;
  10. ;-----------------------------------------------------------------------;
  11. ;    Copyright Work of Caldera, Inc. All Rights Reserved.
  12. ;      
  13. ;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
  14. ;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
  15. ;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
  16. ;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
  17. ;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
  18. ;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
  19. ;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
  20. ;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
  21. ;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
  22. ;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
  23. ;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
  24. ;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
  25. ;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
  26. ;    CIVIL LIABILITY.
  27. ;-----------------------------------------------------------------------;
  28. ;
  29. ;    *** Current Edit History ***
  30. ;    *** End of Current Edit History ***
  31. ;    $Log: $
  32. ;    REDIR.A86 1.30 94/12/01 10:05:21 
  33. ;    added attribute support for open/move/unlink  
  34. ;    REDIR.A86 1.29 94/11/11 15:10:03
  35. ;    Code at redir_lseek30 changed to ensure that the file offset is 
  36. ;    updated. Previously, this did not happen when INT 21/4202 (seek from
  37. ;    end of file) was called, and consequently the game MYST could not 
  38. ;    be installed under NWDOS7.    
  39. ;    REDIR.A86 1.28 94/10/03 15:41:12
  40. ;    fix problem where VLM network mapping gets deleted if you try to access
  41. ;    a path greater than 66 characters long on a network drive.
  42. ;    REDIR.A86 1.27 94/02/22 18:05:09
  43. ;    fix problem with "d:\filename.ext" (Netware 4 LOGIN)
  44. ;    REDIR.A86 1.26 94/01/10 16:42:16
  45. ;    File delete uses file attributes of 06, not 16 (no directory bit)
  46. ;    REDIR.A86 1.25 93/12/10 00:03:09
  47. ;    Move non-inherited bit to correct place in file handle
  48. ;    REDIR.A86 1.22 93/11/19 23:59:00
  49. ;    If a read/write returns ED_LOCKFAIL turn into ED_ACCESS on shared files
  50. ;    REDIR.A86 1.21 93/09/24 19:50:50
  51. ;    Tidy up code on rename
  52. ;    REDIR.A86 1.15 93/06/16 16:22:21
  53. ;    Always initialise file search attributes to 16h (ie. sys+hidden+dir)
  54. ;    REDIR.A86 1.14 93/06/11 15:08:09
  55. ;    Return 0 from search first/next
  56. ;    REDIR.A86 1.13 93/06/11 02:06:53
  57. ;    zero space adjust on getddsc
  58. ;    ENDLOG
  59. eject ! include i:psp.def
  60. eject ! include i:fdos.equ
  61. eject ! include i:msdos.equ
  62. eject ! include i:mserror.equ
  63. eject ! include i:doshndl.def ; DOS Handle Structures
  64. eject ! include i:f52data.def ; DRDOS Structures
  65. eject ! include i:redir.equ
  66. FD_EXPAND equ 55h
  67. eject
  68. PCMODE_DATA dseg
  69. extrn current_dsk:byte
  70. extrn current_ddsc:dword
  71. extrn current_dhndl:dword
  72. extrn current_filepos:dword
  73. extrn current_ldt:dword
  74. extrn dma_offset:word
  75. extrn dma_segment:word
  76. extrn err_drv:byte
  77. extrn file_attrib:word
  78. extrn ldt_ptr:dword
  79. extrn last_drv:byte
  80. extrn phys_drv:byte
  81. extrn pri_pathname:byte
  82. extrn remote_call:word
  83. extrn sec_pathname:byte
  84. extrn srch_buf:byte
  85. ; Data for some int2f commands
  86. extrn int2f_cmd:word
  87. extrn int2f_stack:word
  88. extrn file_mode:word
  89. BDOS_CODE cseg
  90. Public islocal
  91. Public redir_asciiz_dev_offer
  92. Public redir_asciiz_offer
  93. Public redir_asciiz_file_offer
  94. Public redir_drv_offer
  95. Public redir_dhndl_offer
  96. Public redir_move_offer
  97. Public redir_snext_offer
  98. extrn toupper:near
  99. extrn check_delim:near
  100. extrn check_slash:near
  101. extrn check_dslash:near
  102. extrn copy_asciiz:near
  103. extrn unparse:near
  104. extrn find_xfn:near
  105. extrn find_dhndl:near
  106. extrn ifn2dhndl:near
  107. extrn get_xftptr:near
  108. if KANJI
  109. extrn dbcs_lead:near
  110. endif
  111. redir_dhndl_offer:
  112. ;================
  113. ; The FDOS has called this hook to see if we are operating on an MSNET drive.
  114. ; We return if we are not, or stay and process function here if we are
  115. test es:byte ptr DHNDL_WATTR+1[bx],DHAT_REMOTE/100h
  116.  jnz redir_dhndl_accept
  117. ret
  118. redir_dhndl_accept:
  119. ; copy some info from DHNDL_ to local variables
  120. push ds
  121. push ss ! pop ds
  122. mov ax,es:DHNDL_DEVOFF[bx]
  123. mov word ptr current_ddsc,ax
  124. mov ax,es:word ptr DHNDL_DEVSEG[bx]
  125. mov word ptr current_ddsc+WORD,ax
  126. mov ax,es:word ptr DHNDL_POS[bx]
  127. mov word ptr current_filepos,ax
  128. mov ax,es:word ptr DHNDL_POS+2[bx]
  129. mov word ptr current_filepos+2,ax
  130. pop ds
  131. jmps redir_accept ; now we can process the call
  132. redir_asciiz_dev_offer:
  133. ;======================
  134. ; The FDOS has called this hook to see if we are opening a redirected device.
  135. ; We return if we are not, or stay and process function here if we are
  136. ; Before we build it all ourselves do the appropriate INT 2F to allow
  137. ; other people to process the path themselves
  138. call redir_dev_check ; is it a device ?
  139.  jnc redir_accept ; it's been recognised
  140. ret
  141. redir_move_offer:
  142. ;================
  143. ; The FDOS has called this hook to see if the rename operation is on a
  144. ; redirected drive. Lantastic relies on the path check broadcast's being
  145. ; done in the order new_name, old_name.
  146. mov word ptr current_ldt,0ffffh
  147. mov err_drv,DHAT_DRVMSK
  148. push ds
  149. mov si,2[bp] ; SI -> parameter block
  150. lds si,10[si] ; DS:SI -> user supplied name
  151. push ss ! pop es
  152. mov di,offset sec_pathname ; DI -> where to build pathname
  153. push ds ! push si ! push di ! push bp
  154. mov ax,I2F_PPATH
  155. int 2fh ; offer path build to someone else
  156. pop bp ! pop di ! pop si ! pop ds
  157. mov cx,0 ; if accepted then it's a remote drive
  158.  jnc redir_move_offer10
  159. call build_remote_path ; build path if it a remote drive
  160. redir_move_offer10:
  161. pop ds
  162.  jc redir_asciiz_error ; return error's if we have any
  163.  jcxz redir_asciiz_offer ; it's a valid remote path
  164. ret ; it's not a remote path
  165. redir_asciiz_offer:
  166. ;==================
  167. ; The FDOS has called this hook to see if we are operating on an redirected
  168. ; drive. We return if we are not, or stay and process function here if we are.
  169. call redir_dev_check ; is it a device ?
  170.  jnc redir_accept ; it's been recognised
  171. ; jmp redir_asciiz_file_offer ; now try offering as a file
  172. redir_asciiz_file_offer:
  173. ;=======================
  174. ; entry: SS:BP -> function #, parameter address
  175. ; 1st level call (MXdisk not owned)
  176. ; exit: ZF = 1 if not networked
  177. ;
  178. ; This function is only called after an Int 2F/I2F_PPATH callout has been
  179. ; made and failed. On some functions (Open/Create) we do a check for devices
  180. ; between the redir_dev_offer and redir_asciiz_file offer
  181. ; We look for a "\" as the start of "\serverdirfile" form
  182. push ds ; save DS
  183. mov si,2[bp] ; SI -> parameter block
  184. lds si,2[si] ; get ASCIIZ # from parameter block
  185. mov di,offset pri_pathname ; SS:DI -> path buffer
  186. call build_remote_path ; build path if it a remote drive
  187. pop ds ; restore DS
  188.  jc redir_asciiz_error ; return error's if we have any
  189.  jcxz redir_accept ; it's a valid remote path
  190. ret ; it's not a remote path
  191. redir_asciiz_error:
  192. ; On Entry:
  193. ; BX = error code
  194. ; DS on stack
  195. ; On Exit:
  196. ; DS restored, BX preserved
  197. ; near return on stack discarded, and error returned to fdos_entry
  198. ;
  199. pop ax ; discard "offer" near ret
  200. ret ; drop straight back to caller
  201. redir_drv_offer:
  202. ;===============
  203. ; The FDOS has called this hook to see if we are operating on an MSNET drive.
  204. ; We return if we are not, or stay and process function here if we are
  205. ;
  206. ; entry: SS:BP -> function #, parameter address
  207. ; (MXdisk not owned)
  208. ; exit: return if not networked
  209. mov dl,current_dsk ; assume it's the default drive
  210. mov si,2[bp] ; SI -> parameter block
  211. mov ax,2[si] ; get drive # from parameter block
  212. test al,al ; test if default drive
  213.  jz redir_drv_offer10 ; skip if default drive
  214. dec ax ; else decrement for 0..26
  215. xchg ax,dx ; and use that
  216. redir_drv_offer10:
  217. call isremote
  218.  jnz redir_accept
  219. ret ; return if not
  220. redir_snext_offer:
  221. ;=================
  222. ; The FDOS has called this hook to see if we are operating on an MSNET drive.
  223. ; We return if we are not, or stay and process function here if we are
  224. call redir_restore_srch_state
  225. test al,80h ; MSNET drive ?
  226.  jnz redir_accept
  227. ret
  228. redir_accept:
  229. ;============
  230. ; We have decided to accept an FDOS function.
  231. ; Note by this time the functions have been validated as legal
  232. mov file_attrib,16h ; default search attribs to all
  233. pop si ; discard the near return address
  234. mov si,2[bp] ; SI -> parameter block
  235. mov si,ds:[si] ; fdos code number
  236. add si,si ; make it a word offset
  237. jmp cs:redir_tbl-(39h*WORD)[si] ; call the relevant function
  238. redir_badfunc:
  239. ;-------------
  240. mov bx,ED_FUNCTION ; bad function number
  241. ret ; (shouldn't get here...)
  242. redir_tbl dw redir_mkdir ; 39-make directory
  243. dw redir_rmdir ; 3A-remove directory
  244.   dw redir_chdir ; 3B-change directory
  245. dw redir_creat ; 3C-create file
  246. dw redir_open ; 3D-open file
  247. dw redir_close ; 3E-close file
  248. dw redir_read ; 3F-read from file
  249. dw redir_write ; 40-write to file
  250. dw redir_unlink ; 41-delete file
  251. dw redir_lseek ; 42-set file pointer
  252. dw redir_chmod ; 43-get/set file attributes
  253. dw redir_badfunc ; 44-IOCTL emulation
  254. dw redir_badfunc ; 45-duplicate handle
  255. dw redir_badfunc ; 46-force duplicate handle
  256. dw redir_badfunc ; 47-get current directory
  257. dw redir_getdpb ;*48*disk information
  258. dw redir_badfunc ;*49*flush buffers
  259. dw redir_badfunc ;*4A*drive select
  260. dw redir_badfunc ;*4B*create child PSP
  261. dw redir_badfunc ;*4C*close child PSP
  262. dw redir_badfunc ;*4D*generic FCB call
  263. dw redir_first ; 4E-find first matching file
  264. dw redir_next ; 4F-find next matching file
  265. dw redir_commit ;*50*commit file
  266. dw redir_mknew ;*51*make new file
  267. dw redir_lock ;*52*lock/unlock block
  268. dw redir_badfunc ; 53 build DDSC from BPB
  269. dw redir_badfunc ;*54*Int 25/26 emulation
  270. dw redir_expand ; 55 expand file name
  271. dw redir_move ; 56-rename file
  272. dw redir_dattim ; 57-get/set file name
  273. Public get_ldt
  274. ; To support func5D00 remote server calls we must bypass the LDT and
  275. ; go directly to the physical drive. To allow support of CDROM's etc
  276. ; on servers we do use the LDT's where no corresonding physical drive
  277. ; exists.
  278. get_ldt:
  279. ;-------
  280. ; On Entry:
  281. ; AL = drive (0 based)
  282. ; On Exit:
  283. ; ES:BX -> LDT for that drive, set CY if no valid LDT
  284. ; (All other regs preserved)
  285. ;
  286. cmp al,ss:phys_drv ; if there is no conflict with
  287.  jae get_ldt_raw ;  physical drives it's OK
  288. test ss:remote_call,0ffh ; remote calls must get to physical
  289.  jz get_ldt_raw ;  for server support
  290. mov bx,ED_DRIVE ; invalid drive
  291. stc ; no-go
  292. ret
  293. Public get_ldt_raw
  294. get_ldt_raw:
  295. ;-----------
  296. ; On Entry:
  297. ; AL = drive (0 based)
  298. ; On Exit:
  299. ; ES:BX -> LDT for that drive, set CY if no valid LDT
  300. ; (All other regs preserved)
  301. ;
  302. push ax
  303. mov bx,ED_DRIVE ; assume invalid drive
  304. cmp al,ss:last_drv ; do we have an LDT for this drive ?
  305.  jae get_ldt10 ;  if not we can't have an LDT
  306. cmp ss:word ptr ldt_ptr+2,0 ; are the LDT's allocated yet ?
  307.  je get_ldt10 ;  if not return an error
  308. mov bl,LDT_LEN
  309. mul bl ; AX = offset of LDT entry for drive
  310. les bx,ss:ldt_ptr ; get base of LDT's
  311. add bx,ax ; DS:BX -> LDT for this drive
  312. stc ; ie. CLC on exit
  313. get_ldt10:
  314. cmc
  315. pop ax
  316. ret
  317. get_ldt_flags:
  318. ;-------------
  319. ; entry: DL = drive number
  320. ; exit: AX = LDT_FLAGS entry for that drive
  321. ; (All other regs preserved)
  322. ;
  323. push es
  324. push bx
  325. xor ax,ax ; assume no LDT around...
  326. xchg ax,dx ; AL = drive number
  327. call get_ldt ; ES:BX -> LDT
  328. xchg ax,dx ; restore drive to DX
  329.  jc glf10 ; AX = zero if no LDT
  330. mov ss:word ptr current_ldt,bx ; set current_ldt
  331. mov ss:word ptr current_ldt+2,es
  332. mov ax,es:LDT_FLAGS[bx] ; return real flags
  333. glf10:
  334. pop bx
  335. pop es
  336. ret
  337. islocal:
  338. ;-------
  339. ; entry: AL = drive number (zero based)
  340. ; exit: CY = set if drive is remote
  341. ; (All other regs preserved)
  342. ;
  343. push ax
  344. push dx
  345. xchg ax,dx
  346. call get_ldt_flags
  347. if JOIN
  348. test ax,LFLG_JOINED+LFLG_NETWRKD
  349. ; are REMOTE/JOINED bits set ?
  350. else
  351. test ax,LFLG_NETWRKD ; is REMOTE bit set ?
  352. endif
  353.  jz islocal10
  354. stc ; indicate it's not local
  355. islocal10:
  356. pop dx
  357. pop ax
  358. ret
  359. isremote:
  360. ;--------
  361. ; entry: DL = drive number
  362. ; exit: ZF = clear if drive is remote
  363. ; CY = set if drive is JOIN'd
  364. ; (Only AX corrupted)
  365. ;
  366. call get_ldt_flags
  367. if JOIN
  368. test ax,LFLG_JOINED ; is JOINED bit set ?
  369.  jnz isremote10
  370. endif
  371. test ax,LFLG_NETWRKD ; is REMOTE bit set ?
  372. ret
  373. if JOIN
  374. isremote10:
  375. test ax,LFLG_NETWRKD ; is REMOTE bit set ?
  376. stc ; STC to indicate JOIN'd
  377. ret
  378. endif
  379. redir_dev_check:
  380. ;---------------
  381. ; Offer the name to the network as a device
  382. ; On Entry:
  383. ; PB+2 = dword ptr to ascii name
  384. ; DI -> buffer to parse into
  385. ; On Exit:
  386. ; CY set if not recognised
  387. ;
  388. mov word ptr current_ldt,0ffffh
  389. mov err_drv,DHAT_DRVMSK
  390. push ds ! push bp
  391. mov si,2[bp] ; SI -> parameter block
  392. lds si,2[si] ; DS:SI -> user supplied name
  393. mov dx,si ; DS:DX as well..
  394. push ss ! pop es
  395. mov di,offset pri_pathname ; DI -> where to build pathname
  396. mov ax,I2F_PPATH
  397. int 2fh ; offer path build to someone else
  398. pop bp ! pop ds
  399. ret
  400. build_remote_path:
  401. ;-----------------
  402. ; On Entry:
  403. ; DS:SI -> path to check
  404. ; SS:DI -> position to build remote path
  405. ; On Exit:
  406. ; CY clear, CX == 0 if it's a valid remote path
  407. ; CY clear, CX <> 0 if it's a local path
  408. ; CY set if there is an error to be returned (BX = error code)
  409. ;
  410. mov cx,si ; save source path in CX
  411. mov dl,ss:current_dsk ; assume current disk
  412. lodsw ; get 1st two characters
  413. test al,al ; make sure it's not a NUL string
  414.  jz build_remote_path10 ;  before we check it it's a
  415. cmp ah,':' ;  drive specified
  416.  jne build_remote_path10 ; we want to find "d:\" format too
  417. mov bx,ED_DRIVE ; assume "invalid drive" error
  418. and al,not 'a'-'A' ; cheap upper case
  419. sub al,'A'
  420.  jb build_remote_path30 ; return "invalid drive" if error
  421. cmp al,ss:last_drv ; check if > 'Z'
  422.  ja build_remote_path30 ; return "invalid drive" if error
  423. xchg ax,dx ; DL = ASCIIZ supplied drive
  424. lodsw ; get possible '\'
  425. build_remote_path10:
  426. mov ss:word ptr current_ldt,0ffffh
  427. call check_dslash ; is it "\"
  428.  je build_remote_path20 ; if so forget about the drive #
  429. call isremote ; test if drive DL is remote
  430. if JOIN
  431.  jb build_remote_path30 ; return "invalid drive" if JOINed
  432. endif
  433.  jnz build_remote_path20 ; it's remote, go build a path
  434. xor cx,cx ; CY clear (no error)
  435. inc cx ; CX <> 0, (non-remote drive)
  436. ret
  437. build_remote_path20:
  438. ; Build a path from the CSD and the pathname in the parameter block
  439. mov si,cx ; DS:SI -> source ASIIZ name
  440. push ss ! pop es ; ES:DI -> MSNET buffer
  441. call redir_build_path
  442.  jc build_remote_path30
  443. xor cx,cx ; CY clear, CX == 0
  444. ret ; it's a valid remote path
  445. build_remote_path30:
  446. stc ; CY set, we have error BX
  447. ret
  448. eject
  449. ; MAKE DIRECTORY (MKDIR)
  450. ; +----+----+----+----+----+----+
  451. ; |    39   |        name       |
  452. ; +----+----+----+----+----+----+
  453. ; entry:
  454. ; ------
  455. ; name: segmented address of ASCIIZ name
  456. ; exit:
  457. ; -----
  458. ; BX: 0000 or error code ( < 0)
  459. redir_mkdir:
  460. mov ax,I2F_MKDIR ; it's a make dir
  461. jmps redir_pathop_common
  462. eject
  463. ; REMOVE DIRECTORY (RMDIR)
  464. ; +----+----+----+----+----+----+
  465. ; |    3A   |        name       |
  466. ; +----+----+----+----+----+----+
  467. ; entry:
  468. ; ------
  469. ; name: segmented address of ASCIIZ name
  470. ; exit:
  471. ; -----
  472. ; BX: 0000 or error code ( < 0)
  473. redir_rmdir:
  474. mov ax,I2F_RMDIR ; it's a remove dir
  475. ; jmp redir_pathop_common
  476. redir_pathop_common:
  477. push ds
  478. push ss ! pop ds
  479. call int2f_ldt
  480. pop ds
  481.  jc redir_pathop_common10
  482. xor ax,ax ; no problems
  483. redir_pathop_common10:
  484. xchg ax,bx ; return result in BX
  485. ret
  486. eject
  487. ; CHANGE DIRECTORY (CHDIR)
  488. ; +----+----+----+----+----+----+
  489. ; |    3B   |        name       |
  490. ; +----+----+----+----+----+----+
  491. ; entry:
  492. ; ------
  493. ; name: segmented address of ASCIIZ name
  494. ; exit:
  495. ; -----
  496. ; BX: 0000 or error code ( < 0)
  497. redir_chdir:
  498. ;------------
  499. ; The following code throws out the ASSIGN/SUBST form "f:=d:"
  500. ; The alternative is to allow the Extentions to throw it out as a bad path
  501. ; but this is safer, and doesn't cost us much.
  502. push ds
  503. mov bx,ED_PATH ; assume we have a problem
  504. ; BX = ED_PATH ready for error
  505. mov si,2[bp] ; SI -> parameter block
  506. lds si,ds:2[si] ; DS:SI -> ASCIIZ string
  507. cmp ds:word ptr 1[si],'=:' ; 'd:=' specification?
  508.  je redir_chdir40
  509. push ss ! pop ds ; DS = PCMODE
  510. cmp word ptr current_ldt,-1
  511.  je redir_chdir40 ; we reject any chdir of the form
  512. ; "\serverpath"
  513. mov ax,I2F_CHDIR
  514. call int2f_ldt ; is this a valid path ?
  515.  jc redir_chdir30
  516. push  ds ! pop es
  517. mov si,offset pri_pathname
  518. ; DGM - don't allow path greater than 66 chars
  519. mov cx, LDT_FLAGS-LDT_NAME ; calculate max pathlen from LDT
  520. mov di, si
  521. sub ax,ax
  522. repne scasb
  523. mov ax, ED_PATH ; assume path too long
  524.  jne redir_chdir30 ; jump if path too long
  525. les di,current_ldt ; ES:DI -> path for this drive
  526. call copy_asciiz ; copy new path to LDT current dir
  527. xor ax,ax ; no errors
  528. redir_chdir30:
  529. xchg ax,bx ; return result in BX
  530. redir_chdir40:
  531. pop ds
  532. ret
  533. eject
  534. ; CREATE FILE (CREAT)
  535. ; +----+----+----+----+----+----+----+----+
  536. ; |    3C   |        name       |  mode   |
  537. ; +----+----+----+----+----+----+----+----+
  538. ; entry:
  539. ; ------
  540. ; name: segmented address of ASCIIZ name
  541. ;   mode:   attribute for file
  542. ; exit:
  543. ; -----
  544. ; BX: file handle or error code ( < 0)
  545. redir_creat:
  546. call get_attrib_mode ; AX = mode, CX = attrib
  547. xchg ax,cx
  548. or ax,20h ; set the ARCHIVE bit on create
  549. mov file_attrib,ax
  550. mov int2f_stack,ax ; attrib on stack
  551. mov int2f_cmd,I2F_CREATE
  552. cmp word ptr current_ldt,-1 ; valid LDT ?
  553.  jne redir_creat10 ; no, modify create function
  554. mov int2f_cmd,I2F_XCREATE
  555. redir_creat10:
  556. jmp redir_open_create_common
  557. eject
  558. ; OPEN FILE (OPEN)
  559. ; +----+----+----+----+----+----+----+----+----+----+
  560. ; |    3D   |        name       |  mode   |  attrib |
  561. ; +----+----+----+----+----+----+----+----+----+----+
  562. ; entry:
  563. ; ------
  564. ; name: segmented address of ASCIIZ name
  565. ;   mode:   open mode 
  566. ; attrib: file attrib for search (default = 16h)
  567. ; exit:
  568. ; -----
  569. ; BX: file handle or error code ( < 0)
  570. redir_open:
  571. ;----------
  572. ;
  573. call get_attrib_mode ; AX = mode, CX = attrib
  574. and ax,7fh ; remove inheritance bit
  575. mov int2f_stack,ax
  576. mov int2f_cmd,I2F_OPEN
  577. redir_open_create_common:
  578. call find_xfn ; get external file handle in DI
  579. mov bx,ED_HANDLE ;  assume no handles
  580.  jc redir_open20
  581. push di
  582. call redir_openfile ; now do the open
  583. pop di
  584.  jc redir_open20
  585. ; On Entry:
  586. ; AL = IFN
  587. ; DI = XFN
  588. ; ES:BX -> DHNDL_
  589. ; On Exit:
  590. ; PSP fixed up
  591. ;
  592. mov bx,di
  593. call get_xftptr ; ES:DI -> XFN table
  594.  jc redir_open10 ; no PSP, skip xfn stuff
  595. add di,bx ; add external file #
  596. stosb ; update table entry
  597. ret
  598. redir_open10:
  599. xchg ax,bx ; no PSP, return XFN in BX
  600. redir_open20:
  601. ret
  602. redir_openfile:
  603. ;--------------
  604. ; On Entry:
  605. ; pri_pathname and file_attrib have been set up
  606. ; On Exit:
  607. ; AL = IFN
  608. ; ES:BX = DHNDL_
  609. ; CY set on error, BX = error code
  610. ; We should set up COUNT, MODE, UID, PSP, and SHARE
  611. call find_dhndl ; find DHNDL_
  612.  jc redir_openf40 ; return if a problem with this
  613. push ax ; save IFN
  614. push es ! push bx ; save DHNDL_
  615. mov ax,file_mode
  616. and al,not DHM_LOCAL
  617. mov es:DHNDL_MODE[bx],ax ; save mode in DOSHNDL
  618. mov es:DHNDL_SHARE[bx],0 ; zero share record
  619. mov ax,int2f_cmd ; either open or create
  620. call int2f_dhndl ; lets try the command
  621. pop bx ! pop es ; recover DHNDL_
  622. pop dx ; recover IFN
  623.  jc redir_openf30 ; on error discard the handle
  624. xchg ax,dx ; return AL = IFN
  625. mov es:DHNDL_COUNT[bx],1 ; handle now properly in use
  626. mov cx,file_mode
  627. test ch,DHM_FCB/256 ; is this an FCB open ?
  628.  jz redir_openf10
  629. or es:byte ptr DHNDL_MODE+1[bx],DHM_FCB/100h
  630. redir_openf10:
  631. test cl,DHM_LOCAL ; is it a "private" file ?
  632.  jz redir_openf20
  633. or es:byte ptr DHNDL_WATTR+1[bx],DHAT_LOCAL/100h
  634. redir_openf20:
  635. ret
  636. redir_openf30:
  637. xchg ax,bx ;  returning error in BX
  638. ret
  639. redir_openf40:
  640. mov bx,ED_HANDLE ; no handles are left
  641. ret
  642. eject
  643. ; CLOSE FILE (CLOSE)
  644. ; +----+----+----+----+
  645. ; |    3E   |  handle |
  646. ; +----+----+----+----+
  647. ; entry:
  648. ; ------
  649. ; handle: open file handle to be closed
  650. ; exit:
  651. ; -----
  652. ; BX: 0000 or error code ( < 0)
  653. redir_close:
  654. ;------------
  655. ;
  656. mov si,2[bp] ; SI -> parameter block
  657. mov ax,2[si] ; get external file #
  658. call get_xftptr ; ES:DI -> xft table
  659.  jc redir_close10
  660. add di,ax ; add in XFN
  661. mov ax,0FFh ; get "unused" value for XFT
  662. xchg al,es:[di] ; release file & get internal #
  663. redir_close10: ; we can now do the actual close
  664. call ifn2dhndl ; ES:BX -> DHNDL_
  665.  jc redir_close30 ;  exit if error occurrs
  666.     mov ax,es:DHNDL_COUNT[bx]   
  667. mov ah,3eh ;  count, AH = 3E
  668. push ax
  669. mov ax,I2F_CLOSE
  670. call int2f_dhndl ; close it
  671. pop bx
  672.  jnc redir_close20 ; errors ?
  673. xchg ax,bx ; recover return code
  674. redir_close20:
  675. ret
  676. redir_close30:
  677. mov bx,ED_H_MATCH ; assume invalid IFN
  678. ret
  679. eject
  680. ; READ FROM FILE (READ)
  681. ; +----+----+----+----+----+----+----+----+----+----+
  682. ; |    3F   |  handle |       buffer      |  count  |
  683. ; +----+----+----+----+----+----+----+----+----+----+
  684. ; entry:
  685. ; ------
  686. ; handle: open file handle
  687. ; buffer: buffer to read into
  688. ; count: max. number of bytes to read
  689. ; exit:
  690. ; -----
  691. ; BX: error code ( < 0)
  692. redir_read:
  693. ;----------
  694. mov ax,I2F_READ
  695. redir_rw_handle:
  696. mov si,2[bp] ; SI -> parameter block
  697. mov cx,8[si] ; CX = Count
  698. push ds
  699. lds dx,4[si] ; DS:DX = DMA address
  700. call redir_rw
  701. pop ds
  702. mov si,2[bp] ; SI -> parameter block
  703. mov 8[si],cx ; CX = Count
  704. ret
  705. eject
  706. ; WRITE TO FILE (WRITE)
  707. ; +----+----+----+----+----+----+----+----+----+----+
  708. ; |    40   |  handle |       buffer      |  count  |
  709. ; +----+----+----+----+----+----+----+----+----+----+
  710. ; entry:
  711. ; ------
  712. ; handle: open file handle
  713. ; buffer: buffer to be wriiten
  714. ; count: max. number of bytes to write
  715. ; exit:
  716. ; -----
  717. ; BX: error code ( < 0)
  718. redir_write:
  719. ;-----------
  720. mov ax,I2F_WRITE
  721. jmps redir_rw_handle
  722. redir_rw:
  723. ;--------
  724. ; On Entry:
  725. ; AX = command code
  726. ; ES:BX = DHNDL_
  727. ; CX = count
  728. ; DS:DX = buffer
  729. ; On Exit:
  730. ; CX = count transferred
  731. ; BX = zero or error code
  732. ;
  733. cmp ax,I2F_WRITE ; is it a write ?
  734.  jne redir_rw10
  735. and es:DHNDL_WATTR[bx],not (DHAT_CLEAN+DHAT_TIMEOK)
  736. redir_rw10:
  737. push ss:dma_offset
  738. push ss:dma_segment
  739. push cx
  740. mov cl,4
  741. mov di,dx ; save dma offset
  742. and dx,15 ; make offset within para
  743. shr di,cl ; convert offset to para offset
  744. mov si,ds ; add to segment
  745. add di,si ; DI:DX -> DMA address
  746.  ja redir_rw15 ; are we within normal TPA ?
  747. inc di ; no adjust to offset within
  748. shl di,cl ;  magic segment FFFF
  749. add dx,di
  750. mov di,0ffffh ; use magic segment
  751. redir_rw15:
  752. pop cx
  753. mov ss:dma_offset,dx ; save for xfer
  754. mov ss:dma_segment,di
  755. call int2f_dhndl ; try the xfer
  756. pop ss:dma_segment
  757. pop ss:dma_offset
  758. mov bx,0 ; assume no error
  759.  jnc redir_rw20
  760. xchg ax,bx ; return error code
  761. cmp bx,ED_LOCKFAIL ; is it a lockfail error ?
  762.  jne redir_rw20 ; no, just return it
  763. les di,ss:current_dhndl ; compatibility modes should generate
  764. test es:DHNDL_MODE[di],DHM_SHAREMSK
  765.  jz redir_rw20 ;  critical errors fro ED_LOCKFAIL
  766. mov bx,ED_ACCESS ; sharing modes return access denied
  767. redir_rw20:
  768. ret
  769. eject
  770. ; DELETE FILE (UNLINK)
  771. ; +----+----+----+----+----+----+
  772. ; |    41   |        name       |
  773. ; +----+----+----+----+----+----+
  774. ; entry:
  775. ; ------
  776. ; name: segmented address of ASCIIZ name
  777. ; exit:
  778. ; -----
  779. ; BX: 0000 or error code ( < 0)
  780. redir_unlink:
  781. mov ax,I2F_DEL ; it's a delete
  782. ; mov file_attrib,6 ; only delete files
  783. redir_unlink_move_common:
  784. push ax
  785. call get_attrib_mode ; allow overrides for server calls
  786. pop ax
  787. jmp redir_pathop_common
  788. eject
  789. ; GET/SET FILE POSITION (LSEEK)
  790. ; +----+----+----+----+----+----+----+----+----+----+
  791. ; |    42   |  handle |       offset      |  method |
  792. ; +----+----+----+----+----+----+----+----+----+----+
  793. ; On Entry:
  794. ; ES:BX = DHDNL_
  795. ; method: 0 = begin, 1 = current, 2 = end of file
  796. ;
  797. ; On Exit:
  798. ; BX = Error Code, offset updated with new value
  799. ;
  800. redir_lseek:
  801. ;-----------
  802. mov di,bx ; ES:DI -> DHNDL_
  803. mov si,2[bp] ; SI -> parameter block
  804. mov dx,4[si] ; get 32-bit file offset
  805. mov cx,6[si] ; into CX,DX
  806. mov ax,8[si] ; get seek mode
  807. test ax,ax
  808.  jz redir_lseek20 ; seek from beginning
  809. dec ax
  810.  jz redir_lseek10 ; seek from current position
  811. dec ax
  812.  jz redir_lseek30 ; seek from end
  813. mov bx,ED_DATA ; else invalid seek mode
  814. ret
  815. redir_lseek10: ; seek mode 1: relative to position
  816. add dx,es:DHNDL_POSLO[di] ; add position + offset
  817. adc cx,es:DHNDL_POSHI[di]
  818. ; jmps redir_lseek20
  819. redir_lseek20: ; seek mode 0: set absolute position
  820. mov es:DHNDL_POSLO[di],dx ; set new file offset
  821. mov es:DHNDL_POSHI[di],cx ; SI = error code/0 at this point
  822. ; jmps redir_lseek90
  823. redir_lseek90:
  824. mov 4[si],dx ; set 32-bit file offset
  825. mov 6[si],cx ; for return
  826. xchg ax,bx ; error code in BX
  827. ret
  828. redir_lseek30: ; seek mode 2: relative to end
  829. mov bx,es:DHNDL_MODE[di] ; ask MSNET if anyone else can write
  830. and bl,DHM_SHAREMSK ; isolate sharing bits
  831. cmp bl,DHM_DENY_READ ; Only DENY_READ and DENY_NONE a
  832.  jb redir_lseek40 ;  problem - others might write to
  833. push si ;  the file so we must ask the server
  834. ;  how long the file is now
  835. mov ax,I2F_LSEEK ; CX:DX = position now
  836. call int2f_dhndl ; do a remote seek
  837. pop si ; DX:AX = EOF relative position
  838.  jc redir_lseek90 ; (unless we have an error)
  839. xchg ax,dx ; AX:DX = new EOF relative position
  840. xchg ax,cx ;  and finally get into CX:DX 
  841. xor ax,ax ; no problems...
  842. ;jmps redir_lseek90 ; MYST-removed,file offset wasn't updated
  843. jmps redir_lseek20 ; MYST-added,go and update the new file offset.
  844. redir_lseek40:
  845. add dx,es:DHNDL_SIZELO[di] ; add file size + offset
  846. adc cx,es:DHNDL_SIZEHI[di]
  847. jmps redir_lseek20
  848. eject
  849. ; GET/SET FILE ATTRIBUTES (CHMOD)
  850. ; +----+----+----+----+----+----+----+----+----+----+
  851. ; |    43   |        name       |   flag  | attrib  |
  852. ; +----+----+----+----+----+----+----+----+----+----+
  853. ; |        size       |
  854. ; +----+----+----+----+
  855. ; entry:
  856. ; ------
  857. ; name: pointer to ASCIIZ file name
  858. ; flag: 0 = get attribute,
  859. ; 1 = set attribute,
  860. ;       2-5 = passwords (ignored)
  861. ; attrib: new attribute if flag = 1
  862. ; password mode if flag = 3
  863. ;
  864. ; exit:
  865. ; -----
  866. ; BX: 0000 or error code ( < 0)
  867. ; attrib: file's attribute if flag = 0
  868. ; size: file's size
  869. redir_chmod:
  870. ;-----------
  871. ;
  872. mov bx,2[bp] ; BX -> parameter block
  873. mov cx,8[bx] ; get attribs
  874. mov bx,6[bx] ; get access flag
  875. mov ax,I2F_SET_ATTR ; assume it's a set
  876. cmp bl,1 ; is it a set ?
  877.  je redir_chmod10 ; if not then
  878. mov ax,I2F_GET_ATTR ; assume it's a get
  879. mov cx,16h ;  with everything attribs
  880.  jb redir_chmod10 ;  was it ?
  881. mov ax,ED_ACCESS ; no, return access denied
  882. jmps redir_chmod20 ;  cause it DR password stuff
  883. redir_chmod10:
  884. mov int2f_stack,cx ; attribs on the stack
  885. call int2f_ldt ; do the Int 2F
  886.  jc redir_chmod20
  887. mov si,2[bp] ; SI -> parameter block
  888. mov 8[si],ax ;  return attribute
  889. mov 10[si],di
  890. mov 12[si],bx
  891. xor ax,ax ;  success
  892. redir_chmod20:
  893. xchg ax,bx ; return result in BX
  894. ret
  895. eject
  896. ; GET DISK PARAMETER BLOCK
  897. ; +----+----+----+----+----+----+----+----+----+----+
  898. ; |    48   |  drive  |        dpb        | adjust  |
  899. ; +----+----+----+----+----+----+----+----+----+----+
  900. ; entry:
  901. ; ------
  902. ; drive: drive to get information about
  903. ; exit:
  904. ; -----
  905. ; BX: 0000 or error code ( < 0)
  906. ; dpb: address of DOS DPB (offset/segment)
  907. ; adjust: delwatch adjustment of free space
  908. ; NB. We only fill in the fields required by the Disk Free Space call.
  909. redir_getdpb:
  910. ;------------
  911. mov ax,I2F_SPACE
  912. call int2f_ldt ; get the info
  913.  jnc redir_getdpb10 ; if we get an error then make CLMSK=FE
  914.     mov al,0ffh        
  915. redir_getdpb10:        
  916. mov si,offset sec_pathname ; let's re-use this as a temp DPB
  917. dec al ; make cluster mask
  918. mov ds:DDSC_CLMSK[si],al ; and stuff into DPB
  919. mov ds:DDSC_FREE[si],dx
  920. mov ds:DDSC_SECSIZE[si],cx
  921. inc bx ; inc number of clusters
  922. mov ds:DDSC_NCLSTRS[si],bx
  923. mov al,err_drv ; also fill in drive number
  924. mov ds:DDSC_UNIT[si],al
  925. mov si,2[bp] ; DI -> parameter block
  926. mov 4[si],offset sec_pathname
  927. mov 6[si],ds ; point to my dummy DPB
  928. mov word ptr 8[si],0 ; zero adjust value
  929. mov bx,0ffh ; return 0xFF (ie. bad drive)
  930. ret
  931. eject
  932. ; FIND FIRST FILE
  933. ; +----+----+----+----+----+----+----+----+----+----+
  934. ; |    4E   |        name       |  *****  |  attrib |
  935. ; +----+----+----+----+----+----+----+----+----+----+
  936. ; entry:
  937. ; ------
  938. ; name: pointer to ASCIIZ file name
  939. ; attrib: attribute to be used in search
  940. ;
  941. ; exit:
  942. ; -----
  943. ; BX: 0001 or error code ( < 0)
  944. ; Note: This call returns matching files in
  945. ; the current DMA address and also saves
  946. ; the BDOS state in the there.
  947. ;
  948. ; If there is space for multiple file names we
  949. ; could return as many as will fit into the DTA
  950. ; but it's easier just to return 1 file
  951. ;
  952. redir_first: ; 13-find first matching file
  953. ;----------
  954. ; ONLY 1 file returned for now.....
  955. ;
  956. call get_attrib_mode ; AX = mode, CX = attrib
  957. mov ax,I2F_SFIRST ; srch first, valid LDT
  958. les di,current_ldt
  959. cmp di,-1 ; valid LDT ?
  960.  jne redir_first10
  961. mov ax,I2F_XSFIRST ; srch first, no valid LDT
  962. redir_first10:
  963. jmps srch_buf_common
  964. eject
  965. ; FIND NEXT FILE
  966. ; +----+----+
  967. ; |    4F   |
  968. ; +----+----+
  969. ;
  970. ; entry:
  971. ; ------
  972. ;
  973. ; exit:
  974. ; -----
  975. ; BX: 0000 or error code ( < 0)
  976. ; Note: This call returns matching files in
  977. ; the current DMA address and also saves
  978. ; the BDOS state in the there.
  979. redir_next: ; 14-find next matching file
  980. ;---------
  981. ; ONLY 1 file returned for now.....
  982. ;
  983. push ss ! pop es
  984. mov di,offset srch_buf ; point ES:DI -> search buffer
  985. mov ax,I2F_SNEXT
  986. srch_buf_common:
  987. push dma_offset
  988. push dma_segment
  989. mov dma_offset,offset srch_buf
  990. mov dma_segment,ds
  991. call int2f_op
  992. pop dma_segment
  993. pop dma_offset
  994.  jc srch_buf_common10
  995. call redir_save_srch_state ; if no error save state
  996. xor ax,ax ;  return AX = 1 file found
  997. srch_buf_common10:
  998. xchg ax,bx ; return code in BX
  999. ret
  1000. redir_save_srch_state:
  1001. ; On entry DS=PCMODE
  1002. les di,dword ptr dma_offset ; ES:DI -> search state in DMA address
  1003. mov si,offset srch_buf
  1004. mov cx,21 ; save 1st 21 bytes
  1005. rep movsb
  1006. push si ; save name/ext
  1007. add si,11 ; skip to name/ext
  1008. movsb ; copy the attribute
  1009. add si,10 ; skip reserved bytes
  1010. movsw ; copy the time
  1011. movsw ; copy the date
  1012. add si,2 ; skip starting cluster
  1013. movsw ; copy the file size
  1014. movsw
  1015. pop bx ; recover name
  1016. jmp unparse ; unparse the name
  1017. ; Restore DOS search area from user DTA
  1018. ;
  1019. redir_restore_srch_state:
  1020. ;------------------------
  1021. ; On Entry:
  1022. ; DS = SYSDAT
  1023. ; On Exit:
  1024. ; AL = 1st byte of srch buf
  1025. ; DS preserved
  1026. ;
  1027. push ss
  1028. pop es
  1029. mov di,offset srch_buf ; ES:DI -> internal state
  1030. push ds
  1031. lds si,ss:dword ptr dma_offset
  1032. lodsb ; DS:SI -> search state in DMA address
  1033. stosb
  1034. mov cx,20 ; copy 1st 21 bytes
  1035. rep movsb
  1036. pop ds
  1037. ret
  1038. eject
  1039. ; COMMIT FILE (COMMIT)
  1040. ; +----+----+----+----+
  1041. ; |    50   |  handle |
  1042. ; +----+----+----+----+
  1043. ; entry:
  1044. ; ------
  1045. ; handle: open file handle to be flushed
  1046. ; exit:
  1047. ; -----
  1048. ; BX: 0000 or error code ( < 0)
  1049. redir_commit:
  1050. test es:DHNDL_MODE[bx],DHM_WO+DHM_RW
  1051.  jz redir_commit10 ;  we don't need to commit it
  1052. mov ax,I2F_COMMIT
  1053. call int2f_dhndl ; commit this file
  1054.  jc redir_commit20
  1055. redir_commit10:
  1056. xor ax,ax ; success
  1057. redir_commit20:
  1058. xchg ax,bx ; return result in BX
  1059. ret
  1060. eject
  1061. ; CREATE NEW FILE
  1062. ; +----+----+----+----+----+----+----+----+
  1063. ; |    51   |        name       |  mode   |
  1064. ; +----+----+----+----+----+----+----+----+
  1065. ; entry:
  1066. ; ------
  1067. ; name: segmented address of ASCIIZ name
  1068. ;   mode:   attribute for file 
  1069. ; exit:
  1070. ; -----
  1071. ; BX: file handle or error code ( < 0)
  1072. ; Note: The function is identical to CREATE FILE
  1073. ; with the exception that an error is returned
  1074. ; if the specified file already exists.
  1075. redir_mknew:
  1076. call get_attrib_mode ; AX = mode, CX = attrib
  1077. xchg ax,cx
  1078. or ax,120h ; set ARCHIVE + MKNEW bits
  1079. mov file_attrib,ax
  1080. mov int2f_stack,ax
  1081. mov int2f_cmd,I2F_CREATE
  1082. mov file_mode,DHM_RW ; Open Compatibility mode, Read/Write
  1083. jmp redir_open_create_common
  1084. eject
  1085. ; LOCK/UNLOCK FILE DATA (LOCK/UNLOCK)
  1086. ; +----+----+----+----+----+----+----+----+
  1087. ; |    52   |  handle |       offset      |
  1088. ; +----+----+----+----+----+----+----+----+
  1089. ; |       length      |   lock  |
  1090. ; +----+----+----+----+----+----+
  1091. ; entry:
  1092. ; ------
  1093. ; handle: open file handle
  1094. ; offset: long integer offset
  1095. ; length: long integer byte count
  1096. ; lock: 0 = lock, 1 = unlock
  1097. ; exit:
  1098. ; -----
  1099. ; BX: byte count or error code ( < 0)
  1100. redir_lock:
  1101. ; Lock uses I2F_LOCK, with CX,DX,SI as per INT 21, DI on stack
  1102. ; Unlock uses I2F_UNLOCK with same.
  1103. mov bx,2[bp] ; BX -> parameter block
  1104. if DOS5
  1105. push bp
  1106. lea bp,4[bx] ; BP -> parameter block 
  1107. mov dx,bp ; as does DX
  1108. mov ax,I2F_LOCK
  1109. mov bl,ds:byte ptr 12[bx]
  1110. mov bh,5Ch ; lock/unlock in BX
  1111. call int2f_dhndl ; try the operation
  1112. pop bp
  1113. else
  1114. mov dx,ds:4[bx] ; get low word of offset in DX
  1115. mov cx,ds:6[bx] ;  and the hi word in CX
  1116. mov di,ds:8[bx] ; get low word of length in DI
  1117. mov si,ds:10[bx] ;  and high in SI
  1118. mov int2f_stack,di ; length low is on stack
  1119. mov ax,I2F_LOCK ; assume lock
  1120. cmp ds:word ptr 12[bx],0
  1121.  je redir_lock10
  1122. mov ax,I2F_UNLOCK ; no, it must be unlock
  1123. redir_lock10:
  1124. call int2f_dhndl ; try the operation
  1125. endif
  1126.  jc redir_lock20
  1127. xor ax,ax ; success
  1128. redir_lock20:
  1129. xchg ax,bx ; return result in BX
  1130. ret
  1131. eject
  1132. ; EXPAND FILE
  1133. ; +----+----+----+----+----+----+----+----+----+----+
  1134. ; |    55   |      old name     |      new name     |
  1135. ; +----+----+----+----+----+----+----+----+----+----+
  1136. ; entry:
  1137. ; ------
  1138. ; old name: segmented address of ASCIIZ name
  1139. ; new name: segmented address of ASCIIZ name
  1140. ; exit:
  1141. ; -----
  1142. ; BX: 0000 or error code ( < 0)
  1143. ; If we got here pri_pathname already contains expanded name - just copy it
  1144. ; back to the users buffer.
  1145. redir_expand:
  1146. ;------------
  1147. mov si,2[bp] ; SI -> parameter block
  1148. les di,10[si] ; ES:DI -> user supplied name
  1149. mov si,offset pri_pathname
  1150. call copy_asciiz
  1151. xor bx,bx ; no errors
  1152. ret
  1153. eject
  1154. ; RENAME FILE
  1155. ; +----+----+----+----+----+----+----+----+----+----+
  1156. ; |    56   |      old name     |      new name     |
  1157. ; +----+----+----+----+----+----+----+----+----+----+
  1158. ; entry:
  1159. ; ------
  1160. ; old name: segmented address of ASCIIZ name
  1161. ; new name: segmented address of ASCIIZ name
  1162. ; exit:
  1163. ; -----
  1164. ; BX: 0000 or error code ( < 0)
  1165. ; Note: R/O files can be renamed.
  1166. ;   ---
  1167. redir_move:
  1168. mov ax,I2F_REN ; it's a rename
  1169. jmp redir_unlink_move_common
  1170. eject
  1171. ; GET/SET FILE DATE/TIME
  1172. ; +----+----+----+----+----+----+----+----+----+----+
  1173. ; |    57   |  handle |   mode  |   date  |   time  |
  1174. ; +----+----+----+----+----+----+----+----+----+----+
  1175. ; entry:
  1176. ; ------
  1177. ; handle: open file handle
  1178. ; mode: 0 = get date/time, 1 = set date/time
  1179. ; date: date as in directory FCB
  1180. ; time: time as in directory FCB
  1181. ; exit:
  1182. ; -----
  1183. ; BX: 0000 or error code ( < 0)
  1184. ; date: date of last modification if mode = 0
  1185. ; time: date of last modification if mode = 0
  1186. redir_dattim:
  1187. ;------------
  1188. mov si,2[bp] ; DS:SI -> param block
  1189. cmp ds:word ptr 4[si],1 ; is it set ?
  1190.  ja redir_dattim30 ; if illegal say so
  1191.  je redir_dattim10
  1192. mov ax,es:DHNDL_DATE[bx] ; we need to copy the file date
  1193. mov word ptr 6[si],ax ;  into the parameter block
  1194. mov ax,es:DHNDL_TIME[bx]
  1195. mov word ptr 8[si],ax ; and the time
  1196. jmps redir_dattim20
  1197. redir_dattim10:
  1198. mov ax,word ptr 6[si] ; copy the date we are given
  1199. mov es:DHNDL_DATE[bx],ax ;  into the DOSHNDL
  1200. mov ax,word ptr 8[si] ; and the time
  1201. mov es:DHNDL_TIME[bx],ax
  1202. or es:DHNDL_WATTR[bx],DHAT_TIMEOK
  1203. and es:DHNDL_WATTR[bx],not DHAT_CLEAN
  1204. redir_dattim20:
  1205. xor bx,bx ;  all went OK
  1206. jmps redir_dattim40
  1207. redir_dattim30:
  1208. mov bx,ED_FUNCTION ; bad function number
  1209. redir_dattim40:
  1210. ret
  1211. Public redir_build_path
  1212. ; AH contains state of path processing, and is normally zero
  1213. BP_DOT equ 1 ; we have had a DOT end are processing the .EXT
  1214. BP_WILD equ 2 ; we have encountered a wild card
  1215. BP_BSLASH equ 4 ; the last character was a BSLASH
  1216. ; May be called with or without MXDisk
  1217. redir_build_path:
  1218. ;----------------
  1219. ; On Entry:
  1220. ; DS:SI -> source name
  1221. ; ES:DI -> destination name (in PCMODE data segment)
  1222. ; current_ldt -> LDT_ for specified drive
  1223. ; On Exit:
  1224. ; CY clear if we could build the path
  1225. ;
  1226. ; firstly we discard any drive portion
  1227. lodsw ; get 1st two characters
  1228. cmp ah,':' ; is a drive specified ?
  1229.  jne redir_bp10 ; discard "d:" if so
  1230. lodsw
  1231. redir_bp10:
  1232. ; Is it a "\serversharenamesubdirfilename.ext" format ?
  1233. call check_dslash ; if it is \
  1234.  je redir_bp20 ;  then just copy the lot
  1235. ; it's a normal "A:subdirfilename.ext" pathname format
  1236. dec si ; we have swallowed the 1st two
  1237. dec si ;  chars - now we change our mind
  1238. push ds ! push si
  1239. lds si,es:current_ldt
  1240. mov cx,ds:LDT_ROOTLEN[si] ; copy the root portion of the name
  1241. rep movsb ; copy the server stub name
  1242. mov dx,di ; ES:DX -> root position
  1243. call check_slash ; do we start from the root ?
  1244.  je redir_bp11 ; yes, then that's all
  1245. call copy_asciiz ; no, copy the rest of the path
  1246. call redir_bp_append_slash ; append '' for our path processing
  1247. redir_bp11:
  1248. pop si ! pop ds
  1249. jmps redir_bp_next_level ; continue processing given path
  1250. redir_bp20:
  1251. ; It is a "\serversharenamesubdirfilename.ext" format
  1252. stosw ; copy the "\"
  1253. xor ax,ax ; clear "flags" in AH
  1254. redir_bp21:
  1255. lodsb ; work along the name
  1256. test al,al ; unexpected end of name ?
  1257.  jz redir_bp_exit20 ; go with what we've got....
  1258. call check_slash ; have we found the root '' ?
  1259.  je redir_bp23
  1260. if KANJI
  1261. call dbcs_lead ; is it the 1st of a kanji pair
  1262.  jne redir_bp22 ; no, onto next char
  1263. stosb ; copy the 1st character
  1264. movsb ; copy 2nd byte of KANJI pair
  1265. jmps redir_bp21 ; now we can move onto next char
  1266. redir_bp22:
  1267. endif
  1268. call toupper ; upper case the character
  1269. stosb ; copy the character
  1270. jmps redir_bp21 ; go and do another one
  1271. redir_bp23:
  1272. mov dx,di ; bodge root to the top
  1273. ; mov al,''
  1274. stosb ; put in a ''
  1275. jmps redir_bp_next_level ; yes, this is the new "root"
  1276. ; We have reached the terminating NUL
  1277. redir_bp_exit:
  1278. test ah,BP_WILD ; did we get any wildcards ?
  1279.  je redir_bp_exit10
  1280. mov si,2[bp] ; SS:SI -> parameter block
  1281. mov al,ss:[si] ; fdos code number
  1282. cmp al,MS_X_FIRST ; search first ?
  1283.  je redir_bp_exit10
  1284. cmp al,FD_EXPAND ; expand pathname
  1285.  je redir_bp_exit10
  1286. cmp ss:remote_call,0 ; should we wildcard REN/DEL ?
  1287.  je redir_bp_ED_PATH ; reject as not allowed here
  1288. cmp al,MS_X_RENAME ; rename ?
  1289.  je redir_bp_exit10
  1290. cmp al,MS_X_UNLINK ; delete ?
  1291.  jne redir_bp_ED_PATH ; reject as not allowed here
  1292. redir_bp_exit10:
  1293. xor al,al ; make sure our string is zero
  1294. stosb ;  terminated
  1295. call redir_bp_append_slash ; append a trailing '' if we don't
  1296. dec di ;  have one so we can remove it
  1297. cmp di,dx ; are we talking about the root ?
  1298.  jne redir_bp_exit20
  1299. cmp es:byte ptr 0FFFFh[di],':'
  1300.  jne redir_bp_exit20 ; if we have a trailing ':' allow
  1301. inc di ;  a '' at the root
  1302. redir_bp_exit20:
  1303. xor al,al ;  KANJI aware way of removing trailing
  1304. stosb ;  '' from the path....
  1305. ; clc
  1306. ret
  1307. redir_bp_next_level:
  1308. ; DS:SI -> source pathname, ES:DI -> destination pathname, ES:DX -> root
  1309. ; AH = current status
  1310. mov cx,8 ; expansion count ready
  1311. xor ax,ax
  1312. redir_bp_next_char:
  1313. lodsb
  1314. test al,al ; end of the line ?
  1315.  jz redir_bp_exit ; do the exit
  1316. ; Is it a '' ?
  1317. redir_bp40:
  1318. call check_slash ; was it a seperator ?
  1319.  jne redir_bp50
  1320. test ah,BP_WILD ; have we encountered wildcards ?
  1321.  jnz redir_bp_ED_PATH ; reject as not allowed here
  1322. mov al,'' ; make sure it's a BSLASH
  1323. stosb
  1324. jmps redir_bp_next_level ; start at a new level
  1325. ; Is it a '.' ?
  1326. redir_bp50:
  1327. cmp al,'.' ; seperator ?
  1328.  jne redir_bp60
  1329. lodsb ; get next letter
  1330. test al,al ; is it trailing '.' ?
  1331.  je redir_bp_exit ;  then exit now
  1332. cmp cx,8 ; check for '.' and '..'
  1333.  je redir_bp52 ;  if at start of field
  1334. redir_bp51: ; othewise it's a ".EXT"
  1335. mov bx,ED_FILE ; assume we have a problem
  1336. test ah,BP_DOT ; have we had an extention before ?
  1337.  jnz redir_bp_err ;  we've got a problem
  1338. dec si ; rewind a character
  1339. mov ax,'.'+256*BP_DOT ; so we are back to the '.'
  1340. stosb ; store the '.' in destination
  1341. mov cx,3 ; expand the extention
  1342. jmps redir_bp_next_char
  1343. redir_bp52: ; It might be a "." or ".."
  1344. call check_slash ; is it '.'
  1345.  je redir_bp_next_char ; discard them both
  1346. cmp al,'.' ; is it '..' ?
  1347.  jne redir_bp51 ; no, must be an extention after all
  1348. call redir_bp_ddot ; rewind a level
  1349.  jnc redir_bp_next_level ; onto next level
  1350. redir_bp_ED_PATH:
  1351. ; set CY flag to indicate error then return
  1352. mov bx,ED_PATH ; return "invalid path" error
  1353. redir_bp_err:
  1354. stc
  1355. ret
  1356. ; Is it a '*' ?
  1357. redir_bp60:
  1358. call check_delim ; is it a delimiter ?
  1359.  jz redir_bp_ED_PATH ; thats illegal at this point
  1360. cmp al,'*' ; wildcards ?
  1361.  jne redir_bp70
  1362. mov al,'?'
  1363. rep stosb ; expand it
  1364. ; or ah,BP_WILD ; remember wild-card encountered
  1365. ; jmps redir_bp_next_char ;  check for wildcards
  1366. ;
  1367. ;   ; we can just fall through
  1368. ;
  1369. redir_bp70:
  1370. cmp al,'?' ; wild card is possibly OK
  1371.  jne redir_bp80
  1372. or ah,BP_WILD ; remember wild-card encountered
  1373. redir_bp80:
  1374. ; Normal Character
  1375. ; AL contains a normal character for us to process.
  1376. ; Uppercase the character, look out for KANJI etc
  1377.  jcxz redir_bp_next_char ; discard if no space is left
  1378. dec cx ; one less to expand
  1379. if KANJI
  1380. call dbcs_lead ; is it the 1st of a kanji pair
  1381.  jne redir_bp90
  1382. inc si ; skip 2nd byte
  1383.  jcxz redir_bp_next_char ; discard if no room for kanji char
  1384. dec cx ; one less to expand
  1385. stosb ; store 1st byte of kanji character
  1386. dec si ; point at 2nd byte again
  1387. movsb ; copy 2nd byte of kanji character
  1388. jmps redir_bp_next_char
  1389. redir_bp90:
  1390. endif
  1391. call toupper ; make it upper case
  1392. stosb ; plant the character
  1393. jmps redir_bp_next_char
  1394. redir_bp_ddot:
  1395. ; We have encountered a '..' in a pathname, so rewind up a level
  1396. ; On Entry:
  1397. ; DS:SI -> source position, ES:DI -> destination position
  1398. ; ES:DX -> root position, AL = Character
  1399. ; On Exit:
  1400. ; ES:DI -> start of field one level up, unless we get an error when CY set.
  1401. lodsb ; look at char after '..'
  1402. call check_slash ; is it '..'
  1403.  je redir_bp_ddot10
  1404. test al,al ; is it a trailing '..'
  1405.  jnz redir_bp_ED_PATH ; no, anything else is bad...
  1406. dec si ; trailing '..', rewind to NUL
  1407. redir_bp_ddot10:
  1408. dec di ; move back to last ''
  1409. cmp di,dx ; are we at the root anyway ?
  1410.  jle redir_bp_ED_PATH ;  then don't discard any
  1411. ; We now start at ES:DX and work along till ES:DI -> char after last ''
  1412. push ds ! push si
  1413. push es ! pop ds
  1414. mov si,dx ; DS:SI -> char after root
  1415. mov cx,dx ; last '' position in CX
  1416. redir_bp_ddot20:
  1417. lodsb
  1418. cmp si,di ; end of the line yet ?
  1419.  jae redir_bp_ddot30 ; yes, stop now
  1420. if KANJI
  1421. call dbcs_lead ; is it 1st of a kanji pair ?
  1422.  jne redir_bp_ddot25
  1423. lodsb ; skip the 2nd too
  1424. jmps redir_bp_ddot20 ; then go on to next char
  1425. redir_bp_ddot25:
  1426. endif
  1427. call check_slash ; is it a ''
  1428.  jne redir_bp_ddot20 ; no, do next
  1429. mov cx,si ; save position after the ''
  1430. jmps redir_bp_ddot20
  1431. redir_bp_ddot30:
  1432. mov di,cx ; last '' was here..
  1433. pop si ! pop ds
  1434. clc ; no errors
  1435. ret
  1436. redir_bp_append_slash:
  1437. ; On Entry:
  1438. ; ES:DX -> ASCIIZ string to append a '' to
  1439. ; On Exit:
  1440. ; ES:DI -> terminating NUL
  1441. ; All but AX preserved
  1442. ;
  1443. xor ax,ax ; AH = 0, initially no previous char
  1444. mov di,dx ; start processing from here
  1445. redir_bp_append_slash10:
  1446. mov ah,al ; save previous char in AH
  1447. mov al,es:[di] ; get a character
  1448. inc di ; point to next
  1449. test al,al ; is it NUL ?
  1450. if KANJI
  1451.  je redir_bp_append_slash20
  1452. call dbcs_lead ; is it 1st of a kanji pair ?
  1453.  jne redir_bp_append_slash10
  1454. inc di ; skip the 2nd too
  1455. jmps redir_bp_append_slash10 ;  (it might be '')
  1456. redir_bp_append_slash20:
  1457. else
  1458.  jnz redir_bp_append_slash10
  1459. endif
  1460. mov al,ah ; get previous char
  1461. call check_slash ; did we have a '' ?
  1462.  je redir_bp_append_slash30
  1463. dec di ; ES:DI -> existing NUL
  1464. mov ax,''
  1465. stosw ; new terminating ''
  1466. redir_bp_append_slash30:
  1467. dec di ; ES:DI -> NUL
  1468. ret
  1469. get_attrib_mode:
  1470. ;---------------
  1471. ; On Entry:
  1472. ; SS:2[BP] -> param block
  1473. ; On Exit:
  1474. ; AX = file mode
  1475. ; CX = file attributes
  1476. ;
  1477. mov si,2[bp] ; SI -> parameter block
  1478. mov ax,ds:6[si] ; get mode
  1479. mov cx,ds:8[si] ; get attribs
  1480. mov file_mode,ax ; save open mode
  1481. mov file_attrib,cx ; save file attribute
  1482. ret
  1483. int2f_ldt:
  1484. ;---------
  1485. ; On Entry:
  1486. ; AX = Int2F command
  1487. ; On Exit:
  1488. ; CY clear, AX returned unchanged
  1489. ; CY set, AX = Our Negative Error Code
  1490. ;
  1491. les di,ss:current_ldt
  1492. jmps int2f_op
  1493. int2f_dhndl:
  1494. ;----------
  1495. ; On Entry:
  1496. ; AX = Int2F command
  1497. ; On Exit:
  1498. ; CY clear, AX returned unchanged
  1499. ; CY set, AX = Our Negative Error Code
  1500. ;
  1501. les di,ss:current_dhndl
  1502. int2f_op:
  1503. push ds
  1504. push ss ! pop ds
  1505. push int2f_stack ; put word on stack
  1506. int 2fh ; get the info
  1507. pop int2f_stack ; clean up the stack
  1508. pop ds
  1509.  jnc int2f_op10
  1510. neg ax ; AX = we keep error codes negative
  1511. ; stc ; we have a problem
  1512. int2f_op10:
  1513. ret
  1514. end