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

操作系统开发

开发平台:

Visual C++

  1. TITLE DKOPEN - DISK OPEN routines
  2. ;***
  3. ; DKOPEN - Disk open and other utility routines
  4. ;
  5. ; Copyright <C> 1986, Microsoft Corporation
  6. ;
  7. ;Purpose:
  8. ;
  9. ; The routines in this module are used while opening files
  10. ; in all modes (disk and device files).
  11. ;
  12. ;******************************************************************************
  13. INCLUDE switch.inc
  14. INCLUDE rmacros.inc ; general runtime macros
  15. UseSeg _BSS
  16. UseSeg RT_TEXT
  17. UseSeg ER_TEXT
  18. UseSeg NH_TEXT 
  19. UseSeg DV_TEXT 
  20. UseSeg _DATA
  21. INCLUDE seg.inc  ; Segment definitions
  22. INCLUDE baslibma.inc
  23. INCLUDE files.inc
  24. INCLUDE devdef.inc
  25. INCLUDE rtps.inc ; constants shared with QBI
  26. INCLUDE nhutil.inc
  27. INCLUDE string.inc
  28. INCLUDE idmac.inc
  29. .xall
  30. .radix 10
  31. ;************************************************************************
  32. ;
  33. sBegin _BSS
  34. externB b$FILMOD
  35. externB b$PATHNAM
  36. externW b$Buf2
  37. PATH_LEN EQU b$Buf2
  38. globalW b$CLOS_HANDLE,0 ; file handle for B$TEST_CLOSE to close
  39. globalW b$CLOS_FDB,0 ; FDB for B$TEST_CLOSE to close the file
  40. ; and deallocate the FDB.
  41. externB b$LOCKTYPE
  42. externB b$ACCESS
  43. sEnd _BSS
  44. ;
  45. ;************************************************************************
  46. ;************************************************************************
  47. ;
  48. sBegin ER_TEXT
  49. externNP B$ERR_AFE
  50. externNP B$ERR_BFM
  51. externNP B$ERR_FNF
  52. externNP B$ERR_ACD
  53. externNP B$ERR_TMF
  54. externNP B$ERR_IOE
  55. externNP B$ERR_FAO
  56. externNP B$ERR_PNF
  57. sEnd ER_TEXT
  58. ;
  59. ;************************************************************************
  60. ;************************************************************************
  61. ;
  62. sBegin NH_TEXT 
  63. externNP B$LHALC_CPCT ; compact LH and allocate entry
  64. externNP B$LHDALC ; deallocate FDB
  65. externNP B$STDALCTMP
  66. sEnd NH_TEXT 
  67. sBegin DV_TEXT 
  68. externNP B$DOS3CHECK
  69. externNP B$OPENIT
  70. sEnd DV_TEXT 
  71. sBegin RT_TEXT
  72. externNP B$GETEXTERR ; Get extended error, if available
  73. externNP B$CLOSE
  74. externNP B$LHNXTFIL
  75. externNP B$FILESIZE
  76. externNP B$SeekFromStart 
  77. externNP B$DISK_SINP
  78. externNP B$OpenErr
  79. ;
  80. ;************************************************************************
  81. assumes cs,RT_TEXT
  82. SUBTTL disk OPEN
  83. page
  84. ;***
  85. ;  B$DISKOPEN - DISK device-dependent OPEN routine.
  86. ;
  87. ;Purpose:
  88. ; This routine does the actual opening of the files.
  89. ; It tries to open the file in the mode specified and
  90. ; if that fails it will then try to reopen the file
  91. ; in some of the other modes. (The reopen does not
  92. ; happen if the first try was for READ_ONLY).
  93. ; It also checks to see if it opened a character
  94. ; device and if so sets the appropriate fields in the
  95. ; FDB to reflect this. If the open is in the append mode
  96. ; it seeks to the end of the file and backs up over the
  97. ; first CTRL Z.
  98. ;
  99. ;Entry:
  100. ;
  101. ; AX = output from B$GET_PATHNAME
  102. ; BX = file number
  103. ; CX = record size
  104. ; DX = file name string descriptor (ignored)
  105. ;
  106. ;Exit:
  107. ; File opened and FDB filled in OR
  108. ; appropriate error message given.
  109. ;
  110. ;Uses:
  111. ; AX, BX, CX, DX
  112. ;
  113. ;****
  114. cProc B$DISKOPEN,<NEAR,PUBLIC>,<ES,DI>
  115. cBegin
  116. PUSH DS ; ES = DS
  117. POP ES
  118. ; First, allocate FDB with extra space for all disk files and
  119. ; space for the field buffer for random files.
  120. INC CX ; LEN specified?
  121. LOOP LEN_SPEC ; brif so -- use specified record length
  122. MOV CX,REC_LENGTH ; CX = default random record length
  123. TEST b$FILMOD,MD_RND ; random mode?
  124. JNZ LEN_SPEC ; brif so -- use random default
  125. MOV CX,SEQ_BUF_LEN ; use default sequential buffer length
  126. LEN_SPEC:
  127. TEST b$FILMOD,MD_BIN ; BINARY mode?
  128. JZ NOT_BIN ; brif not -- keep specified buffer size
  129. MOV CX,1 ; buffer size = 1
  130. NOT_BIN:
  131. PUSH CX ; save buffer size
  132. PUSH BX ; save file number
  133. PUSH AX ; save output from B$GET_PATHNAME
  134. MOV DI,OFFSET DGROUP:b$PATHNAM ; DI = pathname address for
  135. ; B$CHKFOPEN
  136. XOR SI,SI ; clear SI for B$AnalyzeErr, so it doesn't
  137. ; try to access a non-existing FDB.
  138. ; If the file is not random or sequential input, check if
  139. ; the file has been already opened in BASCOM.  If CF = 1, then
  140. ; give FILE ALREADY OPEN error.
  141. TEST b$FILMOD,MD_RND+MD_SQI+MD_BIN ; random or binary or seqin?
  142. JNZ DOPEN_NOCHK ;if so, then jump
  143. cCALL B$CHKFOPEN ; check if already open -- give
  144. ;  "file already open" error if so
  145. DOPEN_NOCHK:
  146. ; Determine the initial file access for the open.  The accesses
  147. ; attempted are based on the file mode and ACCESS clause type:
  148. ; [b$FILMOD] = MD_SQI (sequential input)
  149. ;     [b$ACCESS] = ACCESS_NONE read
  150. ;     [b$ACCESS] = ACCESS_READ read
  151. ; [b$FILMOD] = MD_SQO (sequential output)
  152. ;     [b$ACCESS] = ACCESS_NONE write
  153. ;     [b$ACCESS] = ACCESS_WRITE write
  154. ; [b$FILMOD] = MD_RND OR MD_BIN (random or binary) [13]
  155. ;     [b$ACCESS] = ACCESS_NONE read/write, write, read
  156. ;     [b$ACCESS] = ACCESS_READ read
  157. ;     [b$ACCESS] = ACCESS_WRITE write
  158. ;     [b$ACCESS] = ACCESS_READ_WRITE read/write
  159. ; [b$FILMOD] = MD_APP (append)
  160. ;     [b$ACCESS] = ACCESS_NONE read/write, write
  161. ;     [b$ACCESS] = ACCESS_WRITE write
  162. XOR BX,BX ;assume 0 for OPEN read
  163. CMP [b$ACCESS],ACCESS_READ ;test if ACCESS READ
  164. JE DOPEN_OPEN ;if so, jump to open file
  165. CMP b$FILMOD,MD_SQI ; test if input sequential
  166. JE DOPEN_OPEN ;if so, jump to open file
  167. INC BX ;assume 1 for OPEN write
  168. CMP [b$ACCESS],ACCESS_WRITE ;test if ACCESS WRITE
  169. JE DOPEN_OPEN ;if so, jump to open file
  170. CMP b$FILMOD,MD_SQO ; test if output sequential
  171. JE DOPEN_OPEN ;if so, jump to open file
  172. INC BX ;otherwise, read/write file
  173. ;  The file is opened with the mode in BX. It is either
  174. ; opened initially in the mode computed above, or reopened
  175. ; in the next mode determined from the above table after
  176. ; an open failure.
  177. ;
  178. ; File
  179. ;-----------------------------------------------
  180. ;    | doesn't  |      exists     |  OpenFlag
  181. ;    | exist  |    | in HEX
  182. ;-----------------------------------------------
  183. ;sqi | fail  | open file  | 01
  184. ;sqo | create  | replace    | 12
  185. ;rnd | create  | open file  | 11
  186. ;-----------------------------------------------
  187. ;
  188. DOPEN_OPEN:
  189. MOV DI,BX ;save mode for possible reopen
  190. CALL DiskOpenHelper ; open file with mode in BX
  191. ; AX = error code if error
  192. ; BX = file handle
  193. JC OPEN_FAILED ; brif open failed
  194. ; The OPEN succeeded.  The only error condition that could
  195. ; occur is if a file is to be appended with only a write
  196. ; access.  If this is so, close the file and fake a
  197. ; PATH/FILE ACCESS ERROR.
  198. CMP b$FILMOD,MD_APP ; test if append mode
  199. JNE JMP_DOPEN_PROCESS ; brif not -- process open
  200. CMP DI,1 ;test if WRITE access
  201. JNE JMP_DOPEN_PROCESS ; brif not -- process open
  202. CALL DO_CLOSE ; file is append with write mode and
  203. ;exists cannot be accessed...
  204. JMP SHORT ERCACD ; path/file access error
  205. ; The OPEN failed.  If mode was sequential input, either give
  206. ; correct access error (PERMISSION DENIED if sharing conflict
  207. ; or PATH/FILE ACCESS ERROR if directory access conflict) or
  208. ; FILE NOT FOUND.
  209. OPEN_FAILED:
  210. CMP AX,ERRPNF ;test if PATH NOT FOUND error
  211. JE ERCPNF ;if so, then report it
  212. CMP b$FILMOD,MD_SQI ; test if input sequential
  213. JNE DOPEN_NOT_SQI_FAIL ;if not, then jump
  214. CMP AX,ERRACD ; test if access error
  215. JE DOPEN_ACCESS_ERROR ;if so, jump to process it
  216. ERCFNF:
  217. JMP B$ERR_FNF ;jump to FILE NOT FOUND
  218. ERCPNF:
  219. JMP B$ERR_PNF ; jump to PATH NOT FOUND
  220. DOPEN_NOT_SQI_FAIL:
  221. CMP AX,ERRFNF ; test if FILE NOT FOUND
  222. JNE DOPEN_NEXT_ACCESS ;else error forces next one
  223. MOV DX,OFFSET DGROUP:b$PATHNAM ; address of file pathname
  224. XOR CX,CX ;attributes - none
  225. MOV AH,C_CREAT ;create file function
  226. CALLOS ;and make the DOS call
  227. ; AX = error code or handle
  228. JC DOPEN_CREATE_ERROR ; if creation error, jump
  229. XCHG BX,AX ; get handle in BX
  230. CALL DO_CLOSE ; close the file
  231. MOV BX,DI ;get the same access type
  232. CALL DiskOpenHelper ; and reopen the file
  233. ; AX = error code if CF
  234. ; BX = file handle
  235. JNC DOPEN_PROCESS ;jump if success
  236. ; The OPEN failed with the current access.  If an access
  237. ; failure occurred and the OPEN is allowed to retry using
  238. ; another access ([b$ACCESS]=ACCESS_NONE), determine the
  239. ; new access and retry the OPEN.
  240. DOPEN_NEXT_ACCESS:
  241. CMP AX,ERRACD ; test if access error
  242. JNE DOPEN_NOT_ACCESS_ERROR ;if not, then branch
  243. CMP [b$ACCESS],ACCESS_NONE ;is a retry possible?
  244. JNE DOPEN_ACCESS_ERROR ;if not, just process error
  245. TEST b$FILMOD,MD_RND+MD_BIN ; test for random or binary modes
  246. JE DOPEN_TRY_APPEND_RETRY ; if not, then jump
  247. OR DI,DI ;is access READ?
  248. JE DOPEN_ACCESS_ERROR ;if so, then jump
  249. MOV BX,DI ;get access code
  250. DEC BX ;r/w->write or write->read
  251. JMP DOPEN_OPEN ;retry random OPEN now
  252. JMP_DOPEN_PROCESS: ; Code is too big and ugly for relative
  253. JMP SHORT DOPEN_PROCESS ; jumps to DOPEN_PROCESS.
  254. DOPEN_TRY_APPEND_RETRY:
  255. CMP b$FILMOD,MD_APP ; test for append mode
  256. JNE DOPEN_ACCESS_ERROR ;jump if not
  257. CMP DI,2 ;test if read/write
  258. JNE DOPEN_ACCESS_ERROR ;jump if not
  259. MOV BX,1 ;make access WRITE
  260. JMP DOPEN_OPEN ;retry append OPEN now
  261. ; OPEN failed with error code 5 (carry set).  Use extended error
  262. ; call (if DOS 3 or later) to determine reported error.
  263. ; "PATH/FILE ACCESS ERROR" is reported when failure is due to
  264. ; directory restriction. "PERMISSION DENIED" is for DOS 2 or
  265. ; OPEN access conflict.
  266. DOPEN_ACCESS_ERROR:
  267. JMP B$OpenErr ; give proper error message, with SI <> FDB.
  268. ; (FL_CHAR bit of FD_FLAGS always clear)
  269. ; Error not access-related.
  270. DOPEN_NOT_ACCESS_ERROR:
  271. CMP AX,ERRFNF ; error was FILE NOT FOUND?
  272. JE ERCFNF ; brif so
  273. CMP b$FILMOD,MD_SQO ; interpreter compatability
  274. JE ERCTMF ; brif sequential output -- too many files
  275. ERCACD:
  276. JMP B$ERR_ACD
  277. DOPEN_CREATE_ERROR:
  278. CMP AX,ERRACD ; test if access error
  279. JNE DOPEN_NOT_ACCESS_ERROR ; if not, then branch
  280. CALL B$GETEXTERR ; get extended error after creation
  281. JC ERCTMF ; if DOS 2, then give too many files
  282. CMP AX,52H ; test if directory entry creation failed
  283. JNE ERCACD ; if not, then path/access error
  284. ERCTMF:
  285. JMP B$ERR_TMF ; too many files
  286. ; OPEN has been completed.  Finish details needed for BASCOM.
  287. ; BX = file handle
  288. DOPEN_PROCESS:
  289. POP AX ; AX = output from B$GET_PATHNAME
  290. POP DX ; DX = file number
  291. POP CX ; restore buffer size
  292. XCHG DX,BX ; BX = file #, DX = file handle
  293. PUSH DX ; save file handle
  294. ; allocate the FDB, and fill some fields
  295. PUSH CX ; save buffer size
  296. ADD CX,PATH_LEN ; add extra space for pathname
  297. MOV DL,255  ; (DL) = width
  298. ; fields
  299. MOV AH,255 ; (AH) = all file modes legal
  300. CALL B$DEVOPN  ; Allocate file block, set up some fields
  301. FDB_PTR ES,SI,SI ; (ES:)SI = *FDB
  302. POP CX ; get back buffer size
  303. MOV FileDB.FD_VRECL,CX  ; set record length/buffer size
  304. LEA DI,FileDB.FD_BUFFER ; ES:DI = address to put pathname in the
  305. ADD DI,CX ; FDB (after I/O buffer)
  306. MOV CX,PATH_LEN ; CX = length of pathname (including null)
  307. PUSH SI ; save FDB address
  308. MOV SI,OFFSET DGROUP:b$PATHNAM ; DS:SI = pathname address
  309. REP MOVSB ; and copy pathname into FDB
  310. POP SI ; SI = FDB address
  311. POP BX ; BX = file handle
  312. MOV FileDB.FD_HANDLE,BX ; save file handle
  313. OR FileDB.FD_FLAGS,FL_NEOF ;set flag for no EOF
  314. mov al,0
  315. callos ioctl ;discover whether character device
  316. mov al,dl
  317. test al,fl_char ;Is it a device?
  318. jz nochar ;Brif not a character device
  319. AND AL,FL_CHAR+FL_CONOUT+FL_CONINP ; Clean all bits except
  320. ; FL_CHAR, FL_CONINP, and FL_CONOUT
  321. OR FileDB.FD_FLAGS,AL  ;update FDB flags
  322. mov al,1
  323. or dx,32 ; set raw - preserve bits
  324. mov dh,0 ; Must set high byte to zero !
  325. CALLOS IOCTL,ERCIOE ; set raw mode -- I/O error upon failure
  326. ;Don't make CON out RAW if DOS 2.+
  327. TEST b$FILMOD,MD_RND+MD_BIN ; random or binary char device?
  328. JNZ NOCHAR ; brif so -- these files have a buffer size
  329. MOV FileDB.FD_VRECL,1 ;yes, set block size to one
  330. CMP b$FILMOD,MD_APP ; if append, convert to MD_SQO
  331. jne nochar
  332. MOV b$FILMOD,MD_SQO 
  333. nochar:
  334. MOV AL,b$FILMOD
  335. mov FileDB.FD_MODE,al ;set mode
  336. TEST FileDB.FD_FLAGS,FL_CHAR ; char device?
  337. JNZ NoTruncate ; brif so -- don't truncate file
  338. TEST AL,MD_SQO ; output?
  339. JZ NoTruncate ; brif not -- don't truncate file
  340. OR FileDB.FD_FLAGS,FL_TRUNC ; truncate file upon first write
  341. NoTruncate:
  342. cmp al,MD_APP ; is it append?
  343. JNE OpenExit ; brif not -- exit
  344. cCall B$FILESIZE ; seek to end of file [DX|AX] = file size/pos
  345. MOV CX,AX ; [DX|CX] = file size
  346. OR AX,DX ; empty file?
  347. JZ EmptyApp ; brif so -- don't seek back
  348. ; An empty file opened by BASCOM10 has a 1A (^Z) at the begining of
  349. ; a block of 128 characters which constitutes the file. Before this
  350. ; change the SEEK routine ]was seeking to one past the end of 128
  351. ; characters thereby retaining a ^Z at the beginning.  The new
  352. ; algorithm first seeks to the LAST BLOCK of 128 characters and
  353. ; then searches for the first available ^Z or end of file as the
  354. ; case may be and starts appending from that point.
  355. SUB CX,128 ; get the last block of 128
  356. SBB DX,0 ; characters
  357. JNB appfi1 ;brif file is more than 128 chars
  358. XOR CX,CX ; set postion to zero
  359. XOR DX,DX
  360. appfi1: ; [DX|CX] = new position
  361. CALL B$SeekFromStart ; position file pointer ([DX|AX] = result)
  362. XCHG AX,CX ; [DX|CX] = file position
  363. MOV b$CLOS_FDB,SI ; deallocate FDB and close file if error
  364. CALL B$DISK_SINP ; read a char.  Destroys AX.
  365. MOV b$CLOS_FDB,0 ; finished with critical section
  366. JB appfi2 ; brif got a ctrl z
  367. ADD CX,1 ; check the next guy
  368. ADC DX,0
  369. JMP SHORT appfi1 ; loop around
  370. appfi2: ; [DX|CX] = last position
  371. CALL B$SeekFromStart ; back up over CTRL Z ([DX|AX] = result)
  372. XCHG AX,CX ; [DX|CX] = current position
  373. EmptyApp:
  374. MOV FileDB.FD_BUFCNT,0 ; nothing in buffer
  375. ; No need to clear FD_INBUFCNT, since it
  376. ; will never be referenced again.
  377. ; commented out this code and associated code in DISK_LOC because LOC
  378. ; could return negative values if we SEEK to before where we started.
  379. ; MOV FileDB.FD_LOGREC,CX ; save starting position for append files
  380. ; MOV FileDB.FD_HIGHLR,DX 
  381. OpenExit:  ; done
  382. cEnd
  383. ERCIOE: 
  384. CALL B$LHDALC ; deallocate FDB
  385. JMP B$ERR_IOE ; device I/O error
  386. ;*** 
  387. ; DO_CLOSE -- close a file.
  388. ;
  389. ;Purpose:
  390. ; Closes a file whose handle is in BX.  Added with [15] to save code.
  391. ; Closes file but does not dealocate FDB upon INT 24 error.
  392. ;Entry:
  393. ; BX = file handle
  394. ;Exit:
  395. ; None
  396. ;Uses:
  397. ; None
  398. ;Preserves:
  399. ;
  400. ;Exceptions:
  401. ; None
  402. ;
  403. ;******************************************************************************
  404. cProc DO_CLOSE,<NEAR>
  405. cBegin
  406. MOV b$CLOS_HANDLE,BX ; close file, no FDB dealloc on INT24 error
  407. CALL B$CLOSE ; close the file
  408. MOV b$CLOS_HANDLE,0 ; finished with critical section
  409. cEnd
  410. ;*** 
  411. ; DiskOpenHelper -- open a file.
  412. ;
  413. ;Purpose:
  414. ; Actually open a file whose pathname is in b$PATHNAM.
  415. ;
  416. ;Entry:
  417. ; b$PATHNAM = pathname of file to open.
  418. ; BX =  mode of open
  419. ; CX = special open flag if OS/2
  420. ;
  421. ;Exit:
  422. ; AX = error code if error, 0 otherwise
  423. ; BX = file descriptor (if no error)
  424. ; IF NOT OM_DOS5
  425. ; Carry set if error; clear otherwise.
  426. ;Uses:
  427. ; DX
  428. ;Preserves:
  429. ; None
  430. ;Exceptions:
  431. ; None
  432. ;
  433. ;******************************************************************************
  434. cProc DiskOpenHelper,<NEAR>
  435. cBegin
  436. MOV DX,OFFSET DGROUP:b$PATHNAM ; address of pathname
  437. OR BL,[b$LOCKTYPE];add access code for DOS 3.0
  438. CALLOS OPEN,,,,DX,BX
  439. JC OpenRet ; brif error
  440. XCHG BX,AX ; BX = file descriptor
  441. XOR AX,AX ; AX = 0 (no error -- clears carry)
  442. OpenRet:
  443. cEnd
  444. PAGE
  445. ;***
  446. ;B$CHKFOPEN -- check if file already open.
  447. ;
  448. ;Purpose:
  449. ; Re-written as part of [11].
  450. ;
  451. ; Checks for file already open by searching all FDBs, and comparing
  452. ; their pathname fields, if they exist.
  453. ;
  454. ;Entry:
  455. ; DI = pointer to standard processed pathname (from B$GET_PATHNAME)
  456. ; ES = DS (only for NOT FV_FARFDB case)
  457. ;
  458. ;Exit:
  459. ; None
  460. ;Uses:
  461. ; AX,BX
  462. ;Exceptions:
  463. ; B$ERR_FAO -- file already open
  464. ;****
  465. cProc B$CHKFOPEN,<NEAR,PUBLIC>,<SI>
  466. cBegin
  467. XOR SI,SI ;prepare to get first FDB
  468. CHKFO_LOOP:
  469. CALL B$LHNXTFIL ; point to next FDB in SI
  470. JZ CHKFO_DONE ;if no more, then jump to exit
  471. FDB_PTR ES,SI,SI ; (ES:)SI = *FDB
  472. ;check pathname field of FDB pointed to by [SI] for match with pathname in [DI]
  473. CMP FileDB.FD_DEVICE,0 ;does this FDB have a pathname field?
  474. JNE CHKFO_LOOP ;brif not -- pathnames don't match
  475. LEA BX,FileDB.FD_BUFFER ;BX = pathname2 address
  476. ADD BX,FileDB.FD_VRECL  
  477. XCHG BX,SI ;SI = pathname2 address
  478. PUSH DI ;save pathname1 address
  479. CMP_LOOP: ;compare the two pathname strings for equality
  480. LODSB ;load byte from filename2 into AL
  481. SCASB ;compare bytes
  482. JNZ NEXT_FDB ;brif not equal -- try next FDB
  483. OR AL,AL ;last byte?
  484. JNZ CMP_LOOP ;brif not -- check another character
  485. JMP B$ERR_FAO ; names matched. File already open error
  486. NEXT_FDB: ;ZF if match, NZ if not a match
  487. POP DI ;restore pathname1 address
  488. XCHG BX,SI ;restore SI to FDB pointer
  489. JMP SHORT CHKFO_LOOP ;try next FDB
  490. CHKFO_DONE:
  491. cEnd ;End of B$CHKFOPEN
  492. ;*** 
  493. ; B$OPEN_DEV and B$DEVOPN -- Special device open common routines.
  494. ;  Re-wrote as part of [32].
  495. ;
  496. ;Purpose:
  497. ; Allocates an FDB for a device.
  498. ; B$DEVOPN is called when a buffer is to be allocated (if a non-zero
  499. ; buffer size is specified), while B$OPEN_DEV is called when no buffer
  500. ; is to be allocated (sets CX to 0)
  501. ;
  502. ;Entry:
  503. ; [AL] = file device
  504. ; [AH] = valid file modes
  505. ; [CX] = size of buffer(s) (not including basic FDB size)
  506. ; [DL] = file width
  507. ; [BX] = file number
  508. ;
  509. ;Exit:
  510. ; [SI] = pointer/handle to allocated FDB.
  511. ; FD_DEVICE, FD_WIDTH, and FD_MODE fields of FDB initialized.
  512. ;
  513. ;Uses:
  514. ;
  515. ;Preserves:
  516. ; AX,BX,DX (B$DEVOPN preserves CX)
  517. ;
  518. ;Exceptions:
  519. ; B$ERR_BFM -- Bad file mode
  520. ;
  521. ;******************************************************************************
  522. cProc B$OPEN_DEV,<PUBLIC,NEAR> 
  523. cBegin
  524. XOR CX,CX ; specify no buffer to be allocated
  525. cEnd nogen ; fall through into B$DEVOPN
  526. cProc B$DEVOPN,<PUBLIC,NEAR>,<CX> 
  527. cBegin
  528. TEST [b$FILMOD],AH ;Check for valid file mode
  529. JZ ercbfm1  ;  Bad file mode
  530. JCXZ NO_BUFFER ;brif buffer not requested
  531. ADD CX,FDB_EXTRA ;add in space for extra FDB fields
  532. NO_BUFFER:
  533. XCHG BX,CX ;put length in BX, file number in CX
  534. ADD BX,FDB_SIZE ;set size of data block needed
  535. PUSH DX ; save file width
  536. MOV DL,LH_FILE ;set type of entry to allocate
  537. CALL B$LHALC_CPCT ; compact local heap, and allocate FDB
  538. POP DX ;restore file width
  539. XCHG BX,CX ;[BX] = file number
  540. MOV CL,b$FILMOD ;get file mode of open
  541. MOV FileDB.FD_MODE,CL ;and save it in the FDB
  542. MOV FileDB.FD_DEVICE,AL ;set file device
  543. MOV FileDB.FD_WIDTH,DL  ;set file width
  544. cEnd
  545. ercbfm1: JMP B$ERR_BFM ;Bad file mode
  546. SUBTTL open interface -- B$OPEN & B$OOPN
  547. page
  548. ;***
  549. ;B$OPEN -- open a disk file using new syntax
  550. ;void B$OPEN(sd *psdName,I2 channel,I2 cbRecord,U2 ModeAccessLock)
  551. ;
  552. ;Purpose:
  553. ; This interface is for opening a file using the syntax as follows:
  554. ;
  555. ; OPEN "filespec" [FOR mode] [ACCESS access] [locking] AS [#] filenum
  556. ;     [LEN=recl]
  557. ; where mode ={INPUT, OUTPUT, APPEND, RANDOM},
  558. ; access ={READ, WRITE, READ WRITE}
  559. ; locking ={SHARED, LOCK {READ | WRITE | READ WRITE} }.
  560. ; If FOR clause is omitted, the default file mode is random.
  561. ;
  562. ; In BASCOM 2.0, multi-interfaces are used.  The usage is as follows:
  563. ;
  564. ; OPEN "filespec" [FOR mode] [sharing] AS [#]filenum [LEN=record len]
  565. ; |     | |     | |
  566. ; |   $DKO       $DKA     | |   $DKM
  567. ; |___________________________________|___________|_____|
  568. ;
  569. ; Where $DKO & $DKA set flags and do some checks, and $DKM dispatchs
  570. ; to the open routine.
  571. ;
  572. ; In BASCOM 3.0, a single interface is used, B$OPEN, which has all
  573. ; opening information in the stack when entering.  The order of
  574. ; parameters are different from the one above.  The correct order is
  575. ; defined in "Entry" section.
  576. ;
  577. ; When entering from the compiler, the value of access is different
  578. ; from the actual needs, so that the modification is necessary.  The
  579. ; reason for making the value different is to detect more easily the
  580. ; legal use of access & locking clauses (network features).
  581. ;
  582. ; sdName/*psdName sd for file name
  583. ;
  584. ; channel  1-255 valid
  585. ; 0,256-65535 illegal function call
  586. ;
  587. ; cbRecord 0 illegal function call
  588. ; 1-32767  valid
  589. ; 32767-65534 illegal function call
  590. ; 65535 default (-1)
  591. ;
  592. ; * Note: LEN=0 in the statement now gives 'illegal function call'
  593. ;
  594. ; ModeAccessLock (the following input values are adjusted to
  595. ;     correspond to those used in the runtime)
  596. ;
  597. ;     mode MD_SQI =1h input
  598. ; MD_SQO =2h output
  599. ; MD_RND =4h random
  600. ; MD_DEFAULT =4h default (to random)
  601. ; MD_APP =8h append
  602. ; MD_BIN =20h binary [29]
  603. ;
  604. ;     access ACCESS_DEFAULT =  0h no access clause
  605. ; ACCESS_READ =100h access read
  606. ; ACCESS_WRITE =200h access write
  607. ; ACCESS_BOTH =300h access read write
  608. ;
  609. ; * the actual access value needed by DOS func. call for opening are
  610. ;   0, 1 & 2 for access read, access write and access read write
  611. ;   respectively.
  612. ;
  613. ;     lock
  614. ; LOCK_COMPATIBLE =0000h compatible mode
  615. ; LOCK_DEFAULT =0000h no lock clause
  616. ; LOCK_BOTH =1000h lock read write
  617. ; LOCK_WRITE =2000h lock write
  618. ; LOCK_READ =3000h lock read
  619. ; LOCK_SHARED =4000h shared (lock none)
  620. ;
  621. ; Symbols listed above will be available in a runtime include file
  622. ; called "runtime.inc".
  623. ;
  624. ; Algorithm -- Pseudo C code
  625. ;
  626. ; B$OPEN(file_name,file_num,record_length,ModeAccessLock)
  627. ; sd *file_name
  628. ; int file_num,record_length
  629. ; ushort ModeAccessLock
  630. ; {
  631. ;     b$ACCESS = ModeAccessLock >> 8 & 0x0F; /* save access */
  632. ;     b$LOCKTYPE = ModeAccessLock >> 8 & 0xF0; /* save lock */
  633. ;     if (access || lock)  /* has access or locking clause ? */
  634. ; if DOSVER < 3.0  /* dos version has to be above 3.0 */
  635. ;     error("illegal function call")
  636. ;     openit(AX_open_mode,BX_file_num,CX_rec_length,DX_sd_filename)
  637. ; }
  638. ;Entry:
  639. ; Parameters were pushed in the stack.
  640. ; sd sdName (file name)
  641. ; int Channel  (file number)
  642. ; int cbRecord (record length)
  643. ; ushort ModeAccessLock (file mode, access right, locking status)
  644. ;Exit:
  645. ; b$PTRFIL is reset
  646. ;Uses:
  647. ; none
  648. ;Exceptions:
  649. ; (1) file name error -- Bad file name (B$ERR_BFN)
  650. ; (2) access & locking -- Illegal function call (B$ERR_AFE)
  651. ; -- Path/file access error
  652. ; -- Permission denied
  653. ; (3) file number  -- illegal file number (B$ERR_INF)
  654. ; (4) general -- File already open (B$ERR_FAO)
  655. ; -- File not found (B$ERR_FAO)
  656. ;*******************************************************************************
  657. cProc B$OPEN,<PUBLIC,FAR>
  658. ParmSD sdName ; sd to filename
  659. ParmW Channel  ;I2, file #
  660. ParmW cbRecord ;I2, record len
  661. ParmW ModeAccessLock ;U2, file mode, access method, sharing status
  662. cBegin
  663. MOV AX,ModeAccessLock ; get lock/access/mode info
  664. MOV BL,AH ;get the lock type
  665. AND BL,0F0H  ;isolate lock from access
  666. AND AH,0FH ;isolate access from lock
  667. MOV [b$ACCESS],AH ;save access
  668. MOV [b$LOCKTYPE],BL ; save it
  669. OR AH,BL ;has access clause or locking clause ?
  670. JZ DISPATCH ;Brif not, go dispatch
  671. cCall B$DOS3CHECK ;must be 3.0 or above
  672. JB ERCAFE ;Brif not, give advanced feature call
  673. DISPATCH:
  674. XOR AH,AH ;isolate mode from lock/access
  675. MOV BX,Channel ;file number in BX
  676. MOV CX,cbRecord ;record length in CX
  677. GetpSD DX,sdName ; [DX] = psdName
  678. cCall B$OPENIT ;dispatch to actual open routine
  679. cEnd ;end of B$OPEN
  680. ERCAFE: JMP B$ERR_AFE ;give advanced feature error
  681. page
  682. ;***
  683. ;B$OOPN -- old open form
  684. ;void B$OOPN(U2 mode, I2 channel, SD sdName, I2 cbRecord)
  685. ;
  686. ;Purpose:
  687. ; Simular to B$OPEN, B$OOPN is the single interface for old open form.
  688. ; (refer to the procedure head comments of B$OPEN for detail)
  689. ;
  690. ; In BASCOM 2.0, the mode passed in is a *sd to the mode string, whereas
  691. ; in BASCOM 3.0, the mode passed in is an U2, which is simular to B$OPEN.
  692. ;
  693. ; Algorithm -- pseudo C code
  694. ;
  695. ; B$OOPN(psdMode, channel, sdName, cbRecord)
  696. ; ushort mode
  697. ; int channel,cbRecord
  698. ; SD sdName
  699. ; {
  700. ;     b$ACCESS=b$LOCKTYPE=0; /* no access or locking clause */
  701. ;
  702. ;     substitute mode of "I" into MD_SQI
  703. ;     substitute mode of "O" into MD_SQO
  704. ;     substitute mode of "R" into MD_RND
  705. ;     substitute mode of "A" into MD_APP
  706. ;     substitute mode of "B" into MD_BIN; [29]
  707. ;
  708. ;     openit(AX_open_mode,BX_file_num,CX_cbRecord,DX_sd_filename)
  709. ; }
  710. ;Entry:
  711. ; Parameters were pushed in stack.
  712. ; SD sdMode (file mode)
  713. ; int Channel  (file number)
  714. ; SD sdName (file name)
  715. ; int cbRecord (record length)
  716. ;Exit:
  717. ; b$PTRFIL is reset
  718. ;Uses:
  719. ; per convention
  720. ;Exceptions:
  721. ; (1) file name error -- Bad file name (B$ERR_BFN)
  722. ; (2) access & locking -- Illegal function call (B$ERR_AFE)
  723. ; -- Path/file access error
  724. ; -- Permission denied
  725. ; (3) file number  -- illegal file number (B$ERR_INF)
  726. ; (4) general -- File already open (B$ERR_FAO)
  727. ; -- File not found (B$ERR_FAO)
  728. ;*******************************************************************************
  729. cProc B$OOPN,<PUBLIC,FAR>
  730. ParmSD sdMode :[33] sd, file mode
  731. ParmW Channel  ;I2, file number
  732. ParmSD sdName :sd, file name
  733. ParmW cbRecord ;I2, record length
  734. cBegin
  735. MOV [b$ACCESS],ACCESS_DEFAULT ;default compatible mode
  736. MOV [b$LOCKTYPE],LOCK_DEFAULT ; default no locking clause
  737. GetpSD BX,sdMode ; DX = *sd of file mode
  738. MOV CX,[BX]  ;get the length
  739. JCXZ ERCBFM1  ;Brif length = 0 -- "bad file mode"
  740. PUSH BX ;save sd
  741. MOV BX,2[BX] ;get the pointer to the first character
  742. MOV BL,BYTE PTR [BX];BL has the character
  743. AND BL,0DFH  ;convert lower case to upper case
  744. MOV AX,MD_SQI ; MD_SQI = 1
  745. CMP BL,"I" ;is input ?
  746. JZ ModeSet  ;Brif yes
  747. INC AX ; MD_SQO = 2
  748. CMP BL,"O" ;is output ?
  749. JZ ModeSet  ;Brif yes
  750. MOV AL,MD_RND ; MD_RND = 4
  751. CMP BL,"R" ;is random ?
  752. JZ ModeSet  ;Brif yes
  753. MOV AL,MD_APP ; MD_APP = 8
  754. CMP BL,"A" ;is append ?
  755. JZ ModeSet  ; Brif yes
  756. CMP BL,"B" ; is binary ?
  757. JNZ ERCBFM1  ;Brif not, give "Bad file mode"
  758. MOV AL,MD_BIN ; MD_BIN = 20H
  759. ModeSet:
  760. POP BX ;recover sd
  761. cCall B$STDALCTMP ;dealloc if temp sd
  762. MOV BX,Channel ;file number in BX
  763. MOV CX,cbRecord ;record length in CX
  764. GetpSD DX,sdName ; DX = *sd of file name
  765. cCall B$OPENIT ;dispatch to actual open routine
  766. cEnd ;end of B$OOPN
  767. sEnd RT_TEXT
  768. end