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

操作系统开发

开发平台:

Asm

  1. title 'FDOS IOCTL - DOS file system input/output control'
  2. ;    File              : $FIOCTL.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. ;    FIOCTL.A86 1.18 93/12/09 23:39:17
  33. ;    Move non-inherited bit to correct place in file handle
  34. ;    FIOCTL.A86 1.17 93/11/03 13:38:29
  35. ;    Int 21 4409 return 0x0080 if drive is joined
  36. ;    FIOCTL.A86 1.16 93/11/02 18:04:17
  37. ;    Int21/4400 from file returns AH=0
  38. ;    FIOCTL.A86 1.15 93/09/14 20:03:15
  39. ;    Trust LFLG_PHYSICAL
  40. ;    FIOCTL.A86 1.12 93/06/17 22:11:50 
  41. ;    support for ioctl 10/11 query ioctl support
  42. ;    FIOCTL.A86 1.11 93/06/16 16:21:37
  43. ;    Codepage preparation bug fixed
  44. ;    ENDLOG
  45. ;   Date       Modification
  46. ;   ---------  ---------------------------------------
  47. ;   29 Jun 89  Initial version splits from FDOS
  48. ;   21 Nov 89  iocE/F use relative unit number
  49. ;   12 Dec 89  ioc2/3 zero the unused portions of req hdr
  50. ;              save a few bytes in other ioc's while I'm here
  51. ;    4 Jun 90  default file access permissions and user group support
  52. ;    5 Jun 90  ioc0/1 tidied up
  53. ;   12 Jun 90  get_doshndl parameter in BX not AX
  54. ;    2 Oct 90  net_vec moves to per-VC basis (info held in CCB_)
  55. ;   13 feb 91  ioc1 tests FHIO_DEV, not HM_DEV, (123 MSNet printing)
  56. ;    7 may 91  ioc2,ioc3,ioc6,ioc7,iocC destabilised for Lanstatic
  57. ;              by-product is ioc6 for disks returns read-ahead char
  58. ;              in AH
  59. ;   28 feb 92  ioctl C checks bit 6 not bit 14 in DH_ATTRIB
  60. ;    3 aug 92  ioctl C/D pass thru' SI/DI
  61. ;    5 aug 92  substatial ioctl rework saves a few bytes - ioctl
  62. ;              request header now built by PCMODE
  63. eject ! include i:fdos.equ
  64. eject ! include rh.equ
  65. eject ! include i:msdos.equ
  66. eject ! include i:mserror.equ
  67. eject ! include i:doshndl.def ; DOS Handle Structures
  68. eject ! include i:driver.equ
  69. eject ! include i:f52data.def ; DRDOS Structures
  70. eject
  71. PCMODE_DATA dseg BYTE
  72. extrn ioctlRH:byte ; request header is build in PCMODE
  73. ;  data area
  74. BDOS_DATA dseg word
  75. extrn fdos_pb:word
  76. extrn fdos_ret:word
  77. extrn last_drv:byte
  78. extrn req_hdr:byte
  79. if PASSWORD
  80. extrn global_password:word
  81. endif
  82. BDOS_CODE cseg
  83. extrn local_disk:near
  84. extrn device_driver:near
  85. extrn block_device_driver:near
  86. extrn fdos_error:near
  87. extrn fdos_ED_DRIVE:near
  88. extrn fdos_ED_FUNCTION:near
  89. extrn fdos_read:near
  90. extrn get_ddsc:near
  91. extrn vfy_dhndl_ptr:near
  92. extrn get_pb2_drive:near
  93. extrn ioc6_dev:near ; IOCTL(6): input status for device
  94. extrn ioc7_dev:near ; IOCTL(7): output status for device
  95. extrn vfy_dhndl_ptr:near
  96. extrn verify_handle:near
  97. extrn reload_registers:near
  98. if JOIN
  99. extrn get_ldt:near
  100. endif
  101. if PASSWORD
  102. extrn hash_pwd:near
  103. endif
  104. public fdos_ioctl
  105. eject
  106. ; INPUT/OUTPUT CONTROL (IOCTL)
  107. ; +----+----+----+----+----+----+----+----+----+----+
  108. ; |    26   |  param  |  func   |   request header  |
  109. ; +----+----+----+----+----+----+----+----+----+----+
  110. ; entry:
  111. ; ------
  112. ; param: handle/drive on some functions
  113. ; func: sub function (0-A)
  114. ; request header: far pointer to IOCTL request header
  115. ; exit:
  116. ; -----
  117. ; AX: return code or error code ( < 0)
  118. ; param: return value from some functions
  119. ioctl_tbl dw ioctl0 ; 0-get handle status
  120. dw ioctl1 ; 1-set handle status
  121. dw ioctl2 ; 2-receive control string (handle)
  122. dw ioctl3 ; 3-send control string (handle)
  123. dw ioctl4 ; 4-receive control string (drive)
  124. dw ioctl5 ; 5-send control string (drive)
  125. dw ioctl6 ; 6-input status
  126. dw ioctl7 ; 7-output status
  127. dw ioctl8 ; 8-removable media check
  128. dw ioctl9 ; 9-networked drive check
  129. dw ioctlA ; A-networked handle check
  130. if PASSWORD
  131. dw ioctl54 ; B-set global password
  132. else
  133. dw device_ED_FUNCTION
  134. endif
  135. dw ioctlC ; C-code page support
  136. dw ioctlD ; D-generic IOCTL disk i/o
  137. dw ioctlE ; E-get logical drive
  138. dw ioctlF ; F-set logical drive
  139. dw ioctl10 ; 10-query IOCTL for char devs
  140. dw ioctl11 ; 11-query IOCTL for disks
  141. NUM_IOCTL equ (offset $ - offset ioctl_tbl)/WORD
  142. fdos_ioctl:
  143. ;----------
  144. mov bx,2[bp] ; BX -> parameter block
  145. mov bx,4[bx] ; get I/O control subfunction
  146. cmp bx,NUM_IOCTL ; is it in the supported range?
  147.  jae device_ED_FUNCTION ; skip if value too large
  148. shl bx,1 ; else make it word index
  149. jmp ioctl_tbl[bx] ; call the right function
  150. device_ED_FUNCTION:
  151. mov bx,ED_FUNCTION ; "invalid function"
  152. ret
  153. ioctl0: ; get device status
  154. ;------
  155. ; Note: We store the binary flag for the standard console
  156. ; handles in the console mode, not in the file handle,
  157. ; as the handles are shared across all consoles...
  158. call vfy_dhndl_ptr ; check if good handle
  159. mov ax,es:DHNDL_WATTR[bx] ; get attrib from doshndl
  160. test ah,DHAT_REMOTE/256
  161. mov ah,0 ; files/networks return 0 in AH/DH
  162.  jnz device_OK ; return attrib if network device
  163. test al,DHAT_DEV ; or a file
  164.  jz device_OK
  165. les bx,es:DHNDL_DEVPTR[bx] ; get real device driver address
  166. mov ah,es:byte ptr 5[bx] ; get device driver attribute
  167. ; jmp device_OK
  168. device_OK:
  169. ;---------
  170. mov bx,2[bp] ; get parameter block address
  171. mov 6[bx],ax ; save returned status
  172. xor bx,bx ; successful return code
  173. ret
  174. ioctl1: ; set device status
  175. ;------
  176. call vfy_dhndl_ptr ; make sure this is an open handle
  177. test es:DHNDL_WATTR[bx],DHAT_DEV
  178.  jz device_ED_FUNCTION ; can't set status of disk files
  179. mov ax,word ptr ioctlRH+14
  180. ; pick up new device status
  181. test ah,ah ; test if high byte is zero
  182.  jnz device_ED_FUNCTION ; skip if O.K.
  183. or al,DHAT_DEV ; make sure it stays a device
  184. mov es:DHNDL_ATTR[bx],al ; store ioctl state in doshndl
  185. jmps device_OK ; success
  186. ioctl2: ; receive control string (devicehandle)
  187. ;------
  188. ioctl3: ; send control string (device handle)
  189. ;------
  190. ioctlC: ; generic ioctl (device handle)
  191. ;------
  192. ioctl10: ; query ioctl support (device handle)
  193. ;-------
  194. call vfy_dhndl_ptr ; check file handle #
  195. call local_disk ; get MXdisk
  196. call verify_handle ; make sure the handle is good
  197.  jnc short_fdos_ED_FUNCTION ;  and is for a DEVICE
  198. xor cx,cx ; device relative unit # always zero
  199. les si,es:DHNDL_DEVPTR[bx] ; ES:SI -> device driver
  200. jmps ioc2345CDcommon ;  now use common code
  201. ioctl4: ; receive control string (drive)
  202. ;------
  203. ioctl5: ; send control string (drive)
  204. ;------
  205. ioctlD: ; generic ioctl (drive)
  206. ;------
  207. ioctl11: ; query ioctl support (drive)
  208. ;-------
  209. call local_disk ; get MXdisk, switch stack
  210. call get_pb2_ddsc ; get drives DDSC_
  211. mov cl,es:DDSC_RUNIT[bx] ; get relative unit #
  212. les si,es:DDSC_DEVHEAD[bx] ; ES:SI -> device header
  213. ; jmps ioctl2345Common ;  now use common code
  214. ioc2345CDcommon:
  215. ;---------------
  216. ; On Entry:
  217. ; ES:SI -> device driver header
  218. ; CL = media byte (0 if character device)
  219. ; CH = relative unit  (0 if character device)
  220. ; MXDisk obtained
  221. ; On Exit:
  222. ; IOCTL performed
  223. ;
  224. mov ax,fdos_pb+6 ; device driver support required
  225. test es:DH_ATTRIB[si],ax ; does device driver support function ?
  226.  jz short_fdos_ED_FUNCTION
  227. push ds
  228. push es ! pop ds ; DS:SI -> device driver
  229. push ss ! pop es
  230. mov bx,offset ioctlRH ; ES:BX -> request header
  231. mov es:RH_UNIT[bx],cl ; set relative unit for block devices
  232. call device_driver ; call the device driver
  233. pop ds ; check for errors on return
  234. ; jmp fdos_error_check
  235. fdos_error_check:
  236. ;-------------
  237. ; On Entry:
  238. ; AX = Req Status
  239. ; On Exit:
  240. ; SIGN set if an error, AX&BX = Internal DOS error code
  241. ;
  242. test ax,ax ; top bit == 1 if error
  243.  jns fdos_ioc_ec10 ; skip if no errors
  244. xor ah,ah
  245.     add ax,-ED_PROTECT      
  246.     neg ax          
  247. jmp fdos_error ; return critical error
  248. fdos_ioc_ec10:
  249. ret
  250. ; IOCTL subfunctions:
  251. get_pb2_ddsc:
  252. ;------------
  253. ; On Entry:
  254. ; local_disk called, pick us drive from pb2
  255. ; On Exit:
  256. ; ES:BX -> DDSC_ for the drive
  257. ;
  258. call get_pb2_drive ; get specified drive
  259. cmp al,last_drv ; is it a valid drive
  260.  ja bad_drive
  261. call get_ldt ; ES:BX -> LDT for this drive
  262.  jc get_pb2_ddsc10 ;  no LDT, physical=logical
  263. mov ax,es:LDT_FLAGS[bx]
  264. test ah,LFLG_NETWRKD/256
  265.  jnz short_fdos_ED_FUNCTION ; reject network drives
  266. test ah,LFLG_PHYSICAL/256
  267.  jz bad_drive
  268. test ah,LFLG_JOINED/256
  269.  jnz bad_drive ; reject JOIN'd drives
  270. mov al,es:LDT_NAME[bx] ; get physical drive from LDT
  271. and al,1Fh ; convert to 1 based drive
  272. dec ax ; make that zero based
  273. get_pb2_ddsc10:
  274. call get_ddsc ; ES:BX -> DDSC_
  275.  jc bad_drive ;  or does it?
  276. ret
  277. bad_drive:
  278. jmp fdos_ED_DRIVE ; invalid drive specified
  279. short_fdos_ED_FUNCTION:
  280. jmp fdos_ED_FUNCTION
  281. ioctl8: ; removable media check
  282. ;------
  283. call local_disk ; get MXdisk, switch stack
  284. call get_pb2_ddsc ; get drives DDSC_
  285. push ds
  286. lds si,es:DDSC_DEVHEAD[bx] ; DS:SI -> device driver
  287. test ds:DH_ATTRIB[si],DA_REMOVE
  288. pop ds ; do we support the check ?
  289.  jz short_fdos_ED_FUNCTION ; if we don't then don't ask
  290. mov req_hdr,RH15_LEN
  291. mov req_hdr+2,CMD_FIXED_MEDIA
  292. call block_device_driver ; call the device driver
  293.  js short_fdos_ED_FUNCTION
  294. and ax,RHS_BUSY ; BUSY bit set if permanent - we just
  295. xchg ah,al ;  need to get bit in the right place
  296. shr ax,1 ; now 1 if permanent media
  297. mov fdos_pb+6,ax ; return status removable (=0)
  298. ioctl8_10:
  299. ret
  300. ioctl6: ; file input status
  301. ;------
  302. call vfy_dhndl_ptr ; make sure this is an open handle
  303. mov ax,es:DHNDL_WATTR[bx]
  304. test ax,DHAT_REMOTE
  305.  jnz ioctl6_10 ; always ask networked handles
  306. test ax,DHAT_DEV
  307.  jz ioctl6_10 ; files are always askable
  308. jmp ioc6_dev
  309. ioctl6_10: ; disk files/network devices
  310. push es:DHNDL_POSLO[bx] ; save current position in file
  311. push es:DHNDL_POSHI[bx] ;  so we can read ahead
  312. push es
  313. push bx ; save DHNDL_ too..
  314. push bp ; save stack frame
  315. mov si,2[bp] ; SI -> parameter block
  316. mov ax,1
  317. push ax ; read 1 byte ahead
  318. push ds ; use fdos_pb as read-ahead
  319. lea ax,6[si] ;  buffer
  320. push ax
  321. push ds:word ptr 2[si] ; user file number 
  322. mov ax,MS_X_READ ; READ function #, so we create
  323. push ax ;  a dummy fdos_pb
  324. mov bx,sp ; SS:BX -> dummy fdos_pb
  325. mov cx,offset ioctl6_20 ; CX -> return address
  326. push cx ; Return to here
  327. push ss ; save parameter segment
  328. push bx ; save parameter offset
  329. push ax ; save sub-function
  330. mov bp,sp ; SS:BP -> working variables
  331. call fdos_read ; make FDOS_READ do the hard word
  332. add sp,4*WORD ; discard param's on stack
  333. ioctl6_20:
  334. add sp,4*WORD ; discard most of dummy fdos_pb
  335. pop cx ; return # read
  336. cmp bx,ED_LASTERROR ; did we succeed ?
  337.  jb ioctl6_30 ; if so we can trust # read
  338. xor cx,cx ; else in error assume nothing
  339. ioctl6_30:
  340. pop bp ; recover stack frame
  341. pop bx ; rewind DHNDL_POS to where
  342. pop es
  343. pop es:DHNDL_POSHI[bx] ;  it was before we started
  344. pop es:DHNDL_POSLO[bx]
  345. mov ax,1a00h ; assume not ready
  346.  jcxz ioctl6_40
  347. dec ax ; AL = FF, ie. ready
  348. mov si,2[bp] ; SI -> parameter block
  349. mov ah,ds:byte ptr 6[si] ; get character we read
  350. ioctl6_40:
  351. jmp device_OK
  352. ioctl7: ; file output status
  353. ;------
  354. call vfy_dhndl_ptr ; make sure this is an open handle
  355. mov ax,0FFh ; assume it's networked/disk
  356. mov dx,es:DHNDL_WATTR[bx]
  357. test dx,DHAT_REMOTE
  358.  jnz ioctl6_40 ; networked handles are always ready
  359. test dx,DHAT_DEV
  360.  jz ioctl6_40 ; files are always ready
  361. jmp ioc7_dev ; devices we ask...
  362. ioctl9: ; networked drive check
  363. ;------
  364. call local_disk ; get disk semaphore
  365. call get_pb2_drive ; get specified drive
  366. call get_ldt ; ES:BX -> LDT for this drive
  367.  jc ioctl940
  368. mov ax,es:LDT_FLAGS[bx]
  369. test ah,LFLG_NETWRKD/256
  370.  jz ioctl910
  371. if 1
  372. mov ax,1000h ; return drive as remote
  373. else
  374. les di,es:LDT_PDT[bx] ; pick up network internal pointer
  375. mov ax,es:4[di] ; pick up garbage
  376. or ah,10h ; return drive as remote
  377. endif
  378. jmps ioctl930
  379. ioctl910:
  380. test ah,LFLG_PHYSICAL/256
  381.  jz ioctl940
  382. test ah,LFLG_SUBST/256
  383. xchg ax,dx ; save flags
  384. mov ax,8000h ; assume it's SUBST'd
  385.  jnz ioctl920
  386. test dh,LFLG_JOINED/256
  387. xchg al,ah ; assume it's JOIN'd
  388.  jnz ioctl930
  389. xor ax,ax ; clear if not
  390. ioctl920:
  391. push ax
  392. call get_pb2_ddsc ; get drives DDSC_
  393. pop ax
  394. les si,es:DDSC_DEVHEAD[bx] ; ES:SI -> device driver
  395. or ax,es:4[si] ; get device attributes
  396. ioctl930:
  397. mov fdos_pb+6,ax ; return updated status
  398. ret
  399. ioctl940:
  400. jmp fdos_ED_DRIVE ; return ED_DRIVE error
  401. ioctlA: ; networked handle check
  402. ;------
  403. call vfy_dhndl_ptr
  404. mov ax,es:DHNDL_WATTR[bx]
  405. jmp device_OK ; return attributes
  406. ioctlE:
  407. ;------
  408. call local_disk
  409. mov al,CMD_GET_DEVICE ; get logical device
  410. jmps iocEFcommon ; common code for IOCTL(E)/IOCTL(F)
  411. ioctlF:
  412. ;------
  413. call local_disk
  414. mov al,CMD_SET_DEVICE ; set logical device
  415. iocEFcommon:
  416.     mov req_hdr,RH24_LEN    
  417. mov req_hdr+2,al
  418. call get_pb2_ddsc ; get drives DDSC_
  419. inc ax ; make drive one-relative
  420. mov req_hdr+13,al ; set this as new drive
  421. xor ax,ax ; assume not supported
  422. push ds
  423. lds si,es:DDSC_DEVHEAD[bx] ; does device driver support function ?
  424. test ds:DH_ATTRIB[si],DA_GETSET
  425. pop ds
  426.  jz iocF_single ; skip if not supported
  427. call block_device_driver ; call the device driver
  428. call fdos_error_check ; return any errors
  429. mov al,req_hdr+1 ; get returned drive
  430. iocF_single: ; AX = return value
  431.     mov ah,7            
  432. mov fdos_pb+6,ax ; return the drive
  433. ret
  434. if PASSWORD
  435. ioctl54: ; set global password
  436. ;-------
  437. call local_disk ; get the MX disk
  438. push ds
  439. lds si,dword ptr ioctlRH+14
  440. call hash_pwd ; encrypt new default password
  441. pop ds
  442. mov global_password,ax
  443. ret
  444. endif
  445. end