dkstmt.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:17k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. TITLE DKSTMT - Disk I/O Interfaces
  2. page 56,132
  3. ;***
  4. ;DKSTMT - Disk I/O Interfaces
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; This module contains disk I/O interfaces for BASIC statements.
  10. ;
  11. ; This module came from iodisk.asm, which had been split into three
  12. ; modules, -- diskio.asm, dkopen.asm and fileio.asm.  Diskio.asm
  13. ; contains all drivers for disk I/O except disk open and close.
  14. ; Disk open is in dkopen.asm.  This module contains interfaces for
  15. ; file I/O statements.
  16. ;
  17. ;BASIC Syntax mapping to included runtime entry points:
  18. ;
  19. ;- FILES Statement:
  20. ;
  21. ;     FILES Statement:
  22. ;
  23. ;     FILES [filespec]
  24. ;  |
  25. ;     B$FILS
  26. ;
  27. ;- KILL Statement:
  28. ;
  29. ;     KILL filespec
  30. ;  |
  31. ;     B$KILL
  32. ;
  33. ;- LOCK Statement:
  34. ;
  35. ;     LOCK [#]filenum [{, record} | [start] TO end]
  36. ;  |
  37. ;     B$LOCK
  38. ;
  39. ;- NAME Statement:
  40. ;
  41. ;     NAME oldname AS newname
  42. ;  |
  43. ;     B$NAME
  44. ;
  45. ;- RESET Statement:
  46. ;
  47. ;     RESET
  48. ;  |
  49. ;     B$REST
  50. ;
  51. ;- UNLOCK Statement:
  52. ;
  53. ;     UNLOCK [#]filenum [{, record} | [start] TO end]
  54. ;   |
  55. ; B$LOCK
  56. ;
  57. ;******************************************************************************
  58. INCLUDE switch.inc
  59. INCLUDE rmacros.inc ;Runtime Macro Defintions
  60. ;Code segmetns
  61. useSeg DK_TEXT
  62. useSeg ER_TEXT
  63. useSeg NH_TEXT
  64. useSeg RT_TEXT
  65. ;Data segments
  66. useSeg CONST
  67. useSeg _DATA
  68. useSeg _BSS
  69. INCLUDE seg.inc
  70. INCLUDE ascii.inc
  71. INCLUDE baslibma.inc
  72. INCLUDE devdef.inc
  73. INCLUDE files.inc
  74. INCLUDE idmac.inc
  75. INCLUDE messages.inc
  76. INCLUDE rtps.inc
  77. INCLUDE string.inc
  78. SUBTTL local constant definitions
  79. page
  80. sBegin CONST
  81. externB b$EightSpaces ; buffer of 8 spaces
  82. staticB DirStr,"<DIR> "
  83. sEnd CONST
  84. sBegin _DATA
  85. sEnd _DATA
  86. sBegin _BSS
  87. externB b$PATHNAM  ; defined in GWINI.ASM
  88. externB b$Buf2  ; defined in GWINI.ASM
  89. b$PATHNAM2 EQU b$Buf2
  90. externW b$PN_NAME
  91. sEnd _BSS
  92. SUBTTL code externals
  93. page
  94. sBegin DK_TEXT
  95. externNP B$GET_PATHNAME
  96. externNP B$GET_CUR_DIR
  97. externFP B$PSI4
  98. externNP B$PUTS
  99. externNP B$OUTCNT
  100. externNP B$$WCHT
  101. externNP B$$TCR
  102. externNP B$TTY_GPOS
  103. externNP B$TTY_GWID
  104. externNP B$CLOSF
  105. externNP B$CHKFOPEN
  106. externNP B$DOS3CHECK ;check for >= DOS 3.00
  107. externNP B$MUL32
  108. sEnd DK_TEXT
  109. sBegin NH_TEXT
  110. externNP B$STDALCTMP
  111. externNP B$LHFDBLOC
  112. sEnd NH_TEXT
  113. sBegin ER_TEXT
  114. externNP B$PUTNUM ; output message
  115. externNP B$ERR_FC
  116. externNP B$ERR_BFN
  117. externNP B$ERR_BRN
  118. externNP B$ERR_FAE
  119. externNP B$ERR_FNF
  120. externNP B$ERR_IFN
  121. externNP B$ERR_ACD
  122. externNP B$ERR_FWP
  123. externNP B$ERR_AFE
  124. externNP B$ERR_PNF
  125. externNP B$ERR_RAD
  126. sEnd ER_TEXT
  127. sBegin RT_TEXT
  128. sEnd RT_TEXT
  129. PAGE
  130. assumes CS,DK_TEXT
  131. sBegin DK_TEXT
  132. ;***
  133. ;B$KILL - KILL filename
  134. ;
  135. ;Purpose:
  136. ;
  137. ;Entry:
  138. ; fname = filename sdesc
  139. ;
  140. ;Exit:
  141. ;
  142. ;Uses:
  143. ; Per convention
  144. ;
  145. ;Exceptions:
  146. ; B$ERR_FNF -- for file not found
  147. ; B$ERR_ACD -- for access denied
  148. ; B$ERR_FAO -- for file already open
  149. ;
  150. ;******************************************************************************
  151. cProc B$KILL,<FAR,PUBLIC>,<SI,DI,ES> 
  152. parmSD fname
  153. cbegin
  154. PUSH DS ; set ES=DS for string operations
  155. POP ES
  156. MOV BX,fname ; get *sd of filename
  157. MOV DI,OFFSET DGROUP:b$PATHNAM ; Where to put the pathname
  158. CALL B$GET_PATHNAME ; generate pathname, checking for errors
  159. ; sets ES = DS
  160. CALL B$STDALCTMP ;delete temporaries
  161. CALL SearchNoDir ; find first file, or give "file not found"
  162. KILL_NEXT:
  163. ; DI --> pointer to processed filename
  164. PUSH DI ; save pathname buffer address
  165. MOV DI,b$PN_NAME ; DI = address past last "" in pathname
  166. ; (filename.ext field of pathname)
  167. mov si,offset dgroup:b$PATHNAM2+30 ; Where dos put the filename
  168. ; store name into the name field of pathname
  169. dkk22:
  170. lodsb ;get a byte from the filename
  171. stosb ;store it into the pathname
  172. or al,al ;end ?
  173. jnz dkk22 ;no
  174. pop di ;--> pathname
  175. CALL B$CHKFOPEN ; Check for conflict with open files
  176. ; (doesn't return if error)
  177. ; delete the link
  178. mov dx,di ; DX = address of pathname to delete
  179. CALLOS unlink,,,,dx
  180. JB KILL_ERR ; give proper error message
  181. CALLOS FINDN ;find next
  182. JNB KILL_NEXT ; found next, continue
  183. cEnd
  184. KILL_ERR:
  185. CMP AX,ERRACD ;test if access error
  186. JNE ERFNF ; if not, then KILL defaults to file not
  187. ; found error
  188. JMP B$ERR_ACD   ;treat as access error
  189. ERFNF:
  190. JMP B$ERR_FNF ; File not found
  191. ;***
  192. ; B$NAME - Name statement
  193. ;
  194. ;Purpose:
  195. ; Rename a file
  196. ;
  197. ;Entry:
  198. ; oldname = Name of existing file
  199. ; newname = name to change to
  200. ;
  201. ;Exit:
  202. ;
  203. ;Uses:
  204. ; Per convention
  205. ;
  206. ;Exceptions:
  207. ; B$ERR_FAE if newname already exists.
  208. ;
  209. ;******************************************************************************
  210. cProc B$NAME,<FAR,PUBLIC>,<ES,SI,DI> 
  211. parmSD oldname 
  212. parmSD newname 
  213. cBegin
  214. PUSH DS ; set ES=DS
  215. POP ES
  216. GetpSD BX,newname
  217. MOV DI,OFFSET DGROUP:b$PATHNAM2 
  218. CALL NAME_COMMON ; do common processing for second name
  219. GetpSD BX,oldname ; source pathname sdesc
  220. MOV DI,OFFSET DGROUP:b$PATHNAM 
  221. CALL NAME_COMMON ; do common processing for first name
  222. MOV DX,OFFSET DGROUP:b$PATHNAM ;source
  223. MOV DI,OFFSET DGROUP:b$PATHNAM2 ;destination
  224. CALLOS RENAME
  225. JC NAME_ERR
  226. cEnd
  227. NAME_ERR: 
  228. CMP AL,ERRFNF ; file not found?
  229. JE ERFNF ; brif so
  230. CMP AL,ERRPNF ; path not found?
  231. JE ERPNF ; brif so
  232. CMP AL,ERRACD ; access denied?
  233. JE ERFAE ; brif so -- File already exists
  234. CMP AL,ERRNSD ; not same device?
  235. JE ERRAD ; brif so -- Rename across disks
  236. ; default to Illegal function call error
  237. ; for NAME if not one of the above.
  238. ERFC:
  239. JMP B$ERR_FC ; Illegal function call
  240. ERFAE:
  241. JMP B$ERR_FAE ; File already exists
  242. ERPNF:
  243. JMP B$ERR_PNF ; Path not found
  244. ERRAD:
  245. JMP B$ERR_RAD ; Rename across disks
  246. ERBFN:
  247. JMP B$ERR_BFN ; Bad file name
  248. ERCFNF2:
  249. JMP SHORT ERFNF ; give "file not found" error
  250. ;*** 
  251. ; NAME_COMMON - common processing.  Added as part of [14].
  252. ;
  253. ;Purpose:
  254. ; Common processing for each filename of B$NAME.
  255. ;
  256. ; Algorithm:
  257. ; call B$GET_PATHNAME
  258. ; if (wildcards in filename) then error
  259. ; deallocate the string temp
  260. ; if (file already open) then error
  261. ;
  262. ;Entry:
  263. ; DI = *space for pathname
  264. ; BX = pointer to user-specified filename string descriptor
  265. ;
  266. ;Exit:
  267. ; DI = *processed pathname
  268. ; CX = length of pathname (including null byte)
  269. ;
  270. ;Uses:
  271. ; per convention
  272. ;
  273. ;Preserves:
  274. ;
  275. ;Exceptions:
  276. ; B$ERR_BFN -- for bad file name
  277. ; B$ERR_FAO -- for file already open
  278. ;
  279. ;******************************************************************************
  280. NAME_COMMON:
  281. CALL B$GET_PATHNAME ; Scan file name
  282. ; sets ES = DS
  283. cCall B$STDALCTMP ; deallocate string temp
  284. TEST AL,FN_WILD ; wildcards in filename?
  285. JNZ ERBFN  ; brif so -- error
  286. ; [DI] = processed pathname
  287. ; [CX] = number of bytes in pathname
  288. JMP B$CHKFOPEN ; check for file already open and return
  289. ; (doesn't return if error)
  290. ;*** 
  291. ; Search/SearchNoDir - search for file
  292. ;
  293. ;Purpose:
  294. ; Search for files
  295. ;Entry:
  296. ; b$PATHNAM has pathname to search for
  297. ;Exit:
  298. ; Conditions after DOS search function:
  299. ; b$PATHNAM2 has directory entry for first matching file
  300. ; DX -> b$PATHNAM
  301. ; ZF ==> file found, NZ ==> error
  302. ;
  303. ;Uses:
  304. ; AX,CX,DX
  305. ;
  306. ;Preserves:
  307. ;
  308. ;Exceptions:
  309. ;
  310. ;******************************************************************************
  311. Search:
  312. mov cx,ATTR_SUBDIR ; Search attributes
  313. SKIP 2 ; eat the XOR and fall into common code
  314. cProc SearchNoDir,<NEAR> ; no directory
  315. cBegin
  316. xor cx,cx ;no search attributes (files only)
  317. MOV DX,OFFSET DGROUP:b$PATHNAM2 
  318. CALLOS BUFF ;Set buffer address
  319. MOV DX,OFFSET DGROUP:b$PATHNAM ; Address of pathname to search
  320. CALLOS FINDF ; Use new one
  321. JC ERCFNF2 ; brif error -- file not found
  322. cEnd
  323. SUBTTL B$REST - Reset statement
  324. PAGE
  325. ;***
  326. ; B$REST - Reset statement
  327. ;
  328. ;Purpose:
  329. ; Runtime entry. Close all open files.
  330. ;
  331. ;******************************************************************************
  332. cProc B$REST,<FAR,PUBLIC,FORCEFRAME> 
  333. cBegin
  334. CALL B$CLOSF ;Close all files
  335. CALLOS GDRV ;Get drive number
  336. PUSH AX
  337. CALLOS REST ;Restore
  338. POP AX
  339. MOV DL,AL
  340. CALLOS SDRV ;Set drive number
  341. cEnd
  342. SUBTTL FILE interface
  343. page
  344. newlin:  ;moved here from below
  345. CALL B$TTY_GPOS
  346. XCHG AL,AH
  347. ADD AL,18 ;Position after next file name
  348. CALL B$TTY_GWID
  349. CMP AL,AH
  350. RET
  351. ;***
  352. ;B$FILS - FILES Statement
  353. ;
  354. ;Purpose:
  355. ; Print a listing of all files in the current directory, which match the given
  356. ; string pattern
  357. ;
  358. ;Input:
  359. ; fname = filename sd
  360. ;
  361. ;Output:
  362. ; None
  363. ;
  364. ;Modifies:
  365. ; Per convention
  366. ;
  367. ;Exceptions:
  368. ; Control could be transfered to error code, such as B$ERR_FNF
  369. ;
  370. ;******************************************************************************
  371. cProc B$FILS,<FAR,PUBLIC>,<ES,DI,SI> 
  372. parmW fname
  373. cBegin
  374. PUSH DS ; set ES=DS for string operations
  375. POP ES
  376. MOV BX,fname
  377. MOV DI,OFFSET DGROUP:b$PATHNAM 
  378. call B$GET_PATHNAME ; convert to standard pathname format
  379. CALL B$STDALCTMP ;delete string if temp
  380. PUSH DI ; save pathname buffer address
  381. MOV AX,[DI] ; load drive letter and colon into AX
  382. MOV DI,OFFSET DGROUP:b$PATHNAM2 ; buffer for current directory
  383. PUSH DI ; save buffer address (for printing)
  384. STOSW ; store drive letter and ":" into buffer
  385. SUB AX,':' SHL 8 + 'A' - 1 ; convert AX to drive number (1-26)
  386. XCHG AX,DX ; DX = drive number
  387. CALL B$GET_CUR_DIR  ; store current directory path for this
  388. ; drive into buffer, after the drive letter
  389. ; print the current directory for specified drive
  390. POP AX ; AX = buffer offset
  391. PUSH DX ; save drive number
  392. MOV DX,DS ; DX = buffer segment
  393. CALL B$PUTS ; print the null-terminated buffer
  394. CALL B$$TCR ; print a CR
  395. ; add "*.*" to the pathname if necessary
  396. ; CX and DX preserved from above
  397. POP DX ; restore drive number
  398. POP DI ; restore pathname buffer address
  399. PUSH DX ; save drive number for free space check
  400. ADD DI,CX ; one past null byte
  401. DEC DI ; DI = address of null byte
  402. CMP DI,b$PN_NAME ; does pathname end with a ""?
  403. JNZ NO_ADD_EXT ; brif not -- don't add the extention
  404. MOV AX,".*" ; add "*." to the pathname
  405. STOSW
  406. MOV AX,"*" ; add "*0" to the pathname
  407. STOSW
  408. NO_ADD_EXT:
  409. CALL Search ; search for first file with this name
  410. ; or give "file not found"
  411. d2off:
  412. mov si,offset dgroup:b$PATHNAM2+30 ; name
  413. mov cx,8
  414. mov dx,"."
  415. call outnam
  416. mov cx,4
  417. xor dx,dx
  418. call outnam
  419. mov si,offset dgroup:b$EightSpaces
  420. cmp byte ptr b$PATHNAM2+21,ATTR_SUBDIR ; check for directory attr
  421. jne d2space
  422. mov si,offset dgroup:DirStr
  423. d2space:
  424. mov cx,6 ; print 6 chars
  425. CALL B$OUTCNT ; print CX bytes
  426. call newlin
  427. jl findn
  428. call B$$TCR
  429. findn:
  430. callos findn
  431. jnb d2off
  432. CALL B$$TCR ; list of files done -- output a CR
  433. POP DX ; get back drive number
  434. CALLOS FREES ;get disk free space
  435. mul cx ;[ax]=bytes/sect*sect/alloc
  436. mul bx ;[dxax]=[ax]*free alloc units
  437. PUSH DX ; pass the I4
  438. PUSH AX
  439. call B$PSI4 ; and output that
  440. MOV AX,MS_BYTESFREE ;output "Bytes free"
  441. cCall B$PUTNUM ;output the message
  442. cEnd
  443. outnam:
  444. mov al," "
  445. cmp byte ptr[si],dh ;end of string?
  446. je atend
  447. cmp byte ptr[si],dl ;possible end of name
  448. je atend
  449. lodsb
  450. atend:
  451. call B$$WCHT ;write char
  452. loop outnam
  453. ret
  454. page
  455. SUBTTL LOCK/UNLOCK interfaces
  456. page
  457. ERCFNF: JMP B$ERR_FNF ;file not found
  458. ERCAFE: JMP B$ERR_AFE ;advanced feature
  459. ;***
  460. ;B$LOCK -- LOCK/UNLOCK statement interface
  461. ;void B$LOCK (I2 channel, I4 first_rec, I4 last_rec, U2 mode)
  462. ;
  463. ;Purpose:
  464. ; Lock or unlock an opened file according to the value of mode.  The
  465. ; file must be opened using the new OPEN syntax with the lock clause,
  466. ; and DOS version must be 3.0 or above;otherwise a runtime error will
  467. ; occur. Between 2.0 and 3.0, the range of record number is slightly
  468. ; different.  In 2.0, a 24-bit record number is supported, whereas a
  469. ; 31-bit record number is supported.
  470. ;
  471. ; Note: BASICA 3.2 supports 32-bit record number.
  472. ;
  473. ; BASCOM 2.0 uses two separate interfaces, $ULK & $LK0, for UNLOCK and
  474. ; LOCK statement respectively.  In BASCOM 3.0, a single interface is
  475. ; used with mode containing valuable information. The beauty of the mode
  476. ; is that the first bit tells whether it is a lock or an unlock, and the
  477. ; second bit tells whether it is to lock/unlock the whole file or not.
  478. ;
  479. ; The syntax for LOCK/UNLOCK is as follows:
  480. ; LOCK/UNLOCK [#]channel [,[first-rec] [TO last-rec]]
  481. ;
  482. ; B$CHAN WILL NOT be called prior to B$LOCK, this routine has to
  483. ; check the file is opened or not.
  484. ;
  485. ; The 'first-rec' is the 'from' record # and 'last-rec' is the 'to'
  486. ; record #.  The default 'first-rec' is 1 and the default 'last-rec'
  487. ; is the same record number as the 'first-rec.'  For example,
  488. ; "LOCK #1, TO 3" will generate first=1, last=3 & mode=2, and
  489. ; "UNLOCK #1, 5" will generate first=5, last=5 & mode=3.
  490. ;
  491. ; NOTE: Currently, record number is only meaningful to the random file.
  492. ; Sequential file is always lock/unlocked the whole file, and
  493. ; there is no range check of 'first-rec' or 'last-rec' for a
  494. ; sequential file.  (the compiler or the interpreter parser
  495. ; does check whether the parameter is a numerical type.)
  496. ;
  497. ; The low order byte of mode may contain the following values according
  498. ; to different situations (the high order word should wlays be IGNORED,
  499. ; as the interpeter uses it):
  500. ;
  501. ; mode = 0 -- lock entire file
  502. ; mode = 2 -- lock from first to last
  503. ;
  504. ; mode = 1 -- unlock entire file
  505. ; mode = 3 -- unlock from first to last
  506. ;
  507. ; The reason is illustrated as the following bit map.
  508. ; mode:
  509. ; _________________________________
  510. ; | 0 | 0 | 0 | 0 | 0 | 0 | X | Y |
  511. ; ---------------------------------
  512. ; MSB LSB
  513. ; where:
  514. ; X is used to represent whether to lock/unlock the whole file, and
  515. ; Y is used to decide whether it is a lock or is an unlock.
  516. ;
  517. ; The runtime may then use one AND, instead of one AND & one SHR, before
  518. ; call DOS lock/unlock function. (The value needed in AL is 0 for lock
  519. ; and 1 for unlock.  Refer to the next paragraph.)
  520. ;
  521. ; The DOS function call for lock/unlock a file needs:
  522. ; [AH] = 5CH
  523. ; [AL] = 0 -- lock
  524. ; 1 -- unlock
  525. ; [BX] = file handle
  526. ; [CX] = offset high
  527. ; [DX] = offset low
  528. ; [SI] = length high
  529. ; [DI] = length low
  530. ;Entry:
  531. ; Parameters are pushed in stack
  532. ; int channel
  533. ; long int first_rec
  534. ; long int last_rec
  535. ; ushort mode
  536. ;Exit:
  537. ; none
  538. ;Uses:
  539. ; none
  540. ;Exceptions:
  541. ;
  542. ;*******************************************************************************
  543. cProc B$LOCK,<PUBLIC,FAR>,<SI,DI> ;push di,si
  544. ParmW Channel  ;I2 file number
  545. ParmD First ;I4 first record number
  546. ParmD Last ;I4 last record number
  547. ParmW Mode ;U2 mode
  548. cBegin ;set up stack frame
  549. cCall B$DOS3CHECK ;must be DOS 3.0 or above
  550. JB ERCAFE ;Brif not, give "advanced feature"
  551. MOV BX,Channel ;get file number
  552. CALL B$LHFDBLOC ;NZ then SI has the pointer to FDB
  553. JZ ERCIFN ; Brif not, give "bad file number"
  554. FDB_PTR ES,SI,SI ;(ES:)[SI] = *FDB
  555. MOV BX,FileDB.FD_HANDLE ; get file handle in BX
  556. PUSH BX ;save file handle
  557. TEST Mode,LOCK_1stToLast ; test the "entire file" bit
  558. JZ LockEntire ; jump if we want to lock it all
  559. TEST FileDB.FD_MODE,MD_RND+MD_BIN
  560. ; is opened for random or binary ?
  561. JNZ  LockOffset ; Brif yes, record number is meaningful
  562. LockEntire:
  563. XOR CX,CX ;starting record
  564. MOV DX,CX ;(0-relative)
  565. MOV SI,CX ;offset
  566. DEC SI ;SI=0FFFFh
  567. MOV DI,SI ;lock the whole file
  568. JMP SHORT LockFile ;go lock it
  569. ERCIFN: JMP B$ERR_IFN ; bad file number
  570. LockOffset:
  571. MOV CX,Off_First ; get first record number low
  572. MOV DX,Seg_First ; get first record number high
  573. OR DX,DX ; negative number?
  574. JS ERCBRN ; Brif yes, give "bad record number"
  575. SUB CX,1 ;decrement one, set carry if not big enough
  576. SBB DX,0 ;if CY ([DX|CX] = 0), then give error
  577. PUSH CX ;save 0-relative first rec# low
  578. PUSH DX ;save 0-relative first rec# high
  579. JB ERCBRN ;give "bad record number"
  580. MOV AX,CX ;get a copy of rec# low
  581. OR AX,DX ;is 0 ?
  582. MOV AX,FileDB.FD_VRECL ; [AX] = multiplicant (also used below)
  583. JZ LockLen  ;Brif yes, no translate needed, to get length
  584. PUSH AX ;save multiplicand
  585. cCall B$MUL32 ;[DX|CX]=[DX|CX]*[AX], if CY then overflow
  586. ; generates Bad record number on overflow
  587. POP AX
  588. LockLen:
  589. POP SI ;get first 0-relative first rec# high
  590. POP DI ;get first 0-relative first rec# low
  591. PUSH CX ;push low offset
  592. PUSH DX ;push high offset
  593. MOV CX,Off_Last ; get Second record number low
  594. MOV DX,Seg_Last ; get Second record number high
  595. MOV BX,CX
  596. OR BX,DX ; Make sure non-zero
  597. JZ ERCBRN
  598. OR DX,DX ; negative number?
  599. JS ERCBRN ; Brif yes, give "bad record number"
  600. SUB CX,DI ;calculate how many records
  601. SBB DX,SI ;[DX|CX]= second# - (first# - 1)
  602. JB ERCBRN ; Brif second > first, give bad record num
  603. ; [AX] = multiplicant, set up above...
  604. cCall B$MUL32 ;[DX|CX]=[DX|CX]*[AX], if CY then overflow
  605. ; generates Bad record number on overflow
  606. MOV DI,CX ;DI=length low
  607. MOV SI,DX ;SI=length high
  608. POP CX ;CX=offset high
  609. POP DX ;DX=offset low
  610. LockFile:
  611. POP BX ;get back file handle
  612. MOV AX,Mode  ;get mode
  613. AND AL,1 ;lock or unlock
  614. CALLOS LOCKING,ULKERR ;go lock it
  615. cEnd ;pop si,di and exit to caller
  616. ULKERR:
  617. CMP AX,ERRIVH ;invalid handle ?
  618. JZ ERCIFN ;bad file number
  619. JMP B$ERR_FWP ;now "Permission Denied"
  620. ERCBRN: JMP B$ERR_BRN ; bad record number
  621. cEnd
  622. sEnd DK_TEXT
  623. END