PAGE 72,128 TITLE FILSBRT - CCBBS FILE HANDLING ROUTINES PAGE .XLIST INCLUDE CCBBS.DEF INCLUDE CCBBS.MAC .LIST ;----------------------------------------------- ;SYSTEM DATA SEGMENT ;----------------------------------------------- SYSDATA SEGMENT PARA PUBLIC 'DATA' EXTRN USERH:WORD,USRINXA:WORD,USRINXL:WORD DFCBADR DW 0 ;SHARED FILE CONTROL BLOCK SYSDATA ENDS ;----------------------------------------------- ;CODE SEGMENT ;----------------------------------------------- CSEG SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CSEG,DS:NOTHING,ES:SYSDATA EXTRN CMPSTA:NEAR,GETBUF:NEAR,YIELD:NEAR EXTRN FREBUF:NEAR,GETSBF:NEAR,ERROR:NEAR EXTRN CRCCLC:NEAR,CRCBFR:NEAR PUBLIC SKEOF,WFBLK,RFBLK,SKBLK,CPYFIL,CKFSPC PUBLIC GETUSR,PUTUSR,UPDUSR,FREUSR,ADDUSR SUBRTNS PROC NEAR ;----------------------------------------------- ;GENERAL FILE READ/WRITE/SEEK ROUTINES (BLKSIZE=128) ;INPUT: AX - BLOCK NUMBER ; CX - FILE HANDLE ; SI - FILE BUFFER ADDRESS ;OUTPUT: ; AX - ACTUAL TRANSFER COUNT IF NO ERROR (C=0) ; ELSE AX = ERROR CODE ;----------------------------------------------- ;Seek to End of File and Return Block Number SKEOF: PUSH BX PUSH CX PUSH DX MOV BX,CX ;FILE HANDLE MOV AX,4202H ;LSEEK EOF XOR CX,CX XOR DX,DX INT 21H ;DOS FUNCTION CALL MOV CX,128 ;BLOCK SIZE DIV CX POP DX POP CX POP BX RET ;READ BLOCK FROM FILE RFBLK: PUSH BX PUSH CX PUSH DX CALL SKBLK ;SEEK TO DESIRED BLOCK MOV AH,3FH ;READ FILE MOV BX,CX ;FILE HANDLE MOV DX,SI ;BUFFER ADDRESS MOV CX,128 ;RECORD LENGTH INT 21H ;DOS FUNCTION CALL POP DX POP CX POP BX RET ;WRITE BLOCK TO FILE WFBLK: PUSH BX PUSH CX PUSH DX CALL SKBLK ;SEEK TO DESIRED BLOCK MOV AH,40H ;WRITE FILE MOV BX,CX ;FILE HANDLE MOV CX,128 ;RECORD LENGTH MOV DX,SI ;BUFFER ADDRESS INT 21H ;DOS FUNCTION CALL POP DX POP CX POP BX RET ;SEEK TO BLOCK # IN AX SKBLK: PUSH BX PUSH CX PUSH DX MOV BX,CX ;FILE HANDLE MOV CX,128 ;BLOCK SIZE MUL CX ;CONVERT TO OFFSET MOV CX,DX MOV DX,AX MOV AX,4200H ;LSEEK INT 21H ;DOS FUNCTION CALL POP DX POP CX POP BX RET ;----------------------------------------------------------- ;FILE COPY ROUTINE ; BP+6 TARGET FILE NAME STRING ; BP+4 SOURCE FILE NAME STRING ; BP-2 SOURCE FILE HANDLE ; BP-4 TARGET FILE HANDLE ; BP-6 BUFFER ADDRESS ; BP-8 BUFFER LENGTH ;------------------------------------------------------------ CPYFIL: PUSH BP ;CALLER'S FRAME MOV BP,SP ;LOCAL FRAME SUB SP,8 ;LOCAL VARIABLES PUSH AX PUSH CX PUSH DX PUSH SI PUSH DI XOR AX,AX ;NULL MOV [BP-2],AX ;NO SOURCE FILE MOV [BP-4],AX ;NO TARGET FILE MOV SI,[BP+4] ;SOURCE FILE MOV DI,[BP+6] ;TARGET FILE CALL CMPSTA ;COMPARE STRINGS JZ CPYF80 ;COPYING TO SELF MOV AX,1024 ;TWO SECTORS MOV [BP-8],AX ;BUFFER LENGTH CALL GETBUF ;GET BUFFER MOV [BP-6],SI ;BUFFER ADDRESS MOV AX,3D00H ;OPEN FOR INPUT MOV DX,[BP+4] ;SOURCE FILE NAME INT 21H ;DOS REQUEST JC CPYF90 ;FAILED MOV [BP-2],AX ;SOURCE FILE HANDLE MOV AH,3CH ;CREATE FILE XOR CX,CX ;NORMAL ATTRIBUTE MOV DX,[BP+6] ;TARGET FILE NAME INT 21H ;DOS REQUEST JC CPYF90 ;FAILED MOV [BP-4],AX ;TARGET FILE HANDLE CPYF10: PUSH BX CALL YIELD ;LET OTHERS RUN MOV AH,3FH ;READ MOV BX,[BP-2] ;SOURCE FILE HANDLE MOV CX,[BP-8] ;BUFFER LENGTH MOV DX,[BP-6] ;BUFFER ADDRESS INT 21H ;DOS REQUEST POP BX OR AX,AX ;ANYTHING? JZ CPYF90 ;END OF FILE PUSH BX CALL YIELD ;LET OTHERS RUN MOV CX,AX ;BYTES READ MOV AH,40H ;WRITE MOV BX,[BP-4] ;TARGET FILE HANDLE INT 21H ;DOS REQUEST POP BX CMP AX,CX ;ALL BYTE WRITTEN? JZ CPYF10 ;YES CPYF80: STC ;SHOW ERROR CPYF90: PUSHF ;ERROR FLAG MOV SI,[BP-6] ;BUFFER CALL FREBUF ;FREE BUFFER MOV AH,3EH ;CLOSE PUSH BX MOV BX,[BP-2] ;SOURCE FILE HANDLE INT 21H ;DOS REQUEST MOV AH,3EH ;CLOSE MOV BX,[BP-4] ;TARGET FILE HANDLE INT 21H ;DOS REQUEST POP BX POPF ;ERROR FLAG POP DI POP SI POP DX POP CX POP AX MOV SP,BP ;FREE LOCAL VARIABLES POP BP ;CALLER'S FRAME RET ;---------------------------------------------------------------- ;GET AMOUNT OF FREE SPACE (K BYTES) ON SYSTEM AND UPLOAD DISKS ; RETURNS AX= SYSTEM DX= UPLOAD ; BP-2 SPACE ON SYSTEM DISK ; BP-4 SPACE ON FILE UPLOAD DISK ;---------------------------------------------------------------- CKFSPC: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL VARIABLES PUSH BX PUSH CX XOR DX,DX ;DEFAULT DRIVE CALL DOSGSP ;GET AVAILABLE SPACE MOV [BP-2],AX ;SAVE RESULT MOV [BP-4],AX ;ASSUME SINGLE DISK CMP BYTE PTR DS:MSGCKPT+MFPATH+1,':' ;DISK SPECIFIED? JNZ CKFS90 ;NO - SAME AS SYSTEM MOV DL,BYTE PTR DS:MSGCKPT+MFPATH ;DISK ID AND DX,00DFH ;ENSURE UPPER CASE SUB DL,40H ;CONVERT TO DISK NUMBER CALL DOSGSP ;GET AVAILABLE SPACE MOV [BP-4],AX ;SAVE RESULT CKFS90: POP CX POP BX MOV AX,[BP-2] ;SYSTEM DISK MOV DX,[BP-4] ;FILE DISK MOV SP,BP ;FREE LOCAL VARIABLES POP BP ;RESTORE CALLER'S FRAME RET DOSGSP: MOV AH,36H ;GET FREE SPACE INT 21H ;DOS REQUEST MUL BX ;=SECTORS MOV CX,2 ;SECTPRS PER 'K' DIV CX ;K BYTES RET ;--------------------------------------------------------------- ;USER FILE SUBROUTINES ; INPUT AX = USER SLOT NUMBER ; OUTPUT SI -> USER RECORD OR ZERO ; CARRY = 0 IF NO ERROR ; LOCAL STORAGE ; BP-2 USER SLOT NUMBER ; BP-4 DFCB ENTRY POINTER ;--------------------------------------------------------------- GETUSR: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL STORAGE MOV [BP-2],AX ;SAVE PASSED PARM PUSH BX PUSH CX PUSH DX PUSH DI CALL FNDUSR ;FIND USER ENTRY MOV [BP-4],DI ;DFCB POINTER INC WORD PTR [DI+4] ;INCREMENT USE COUNT JNC GETU30 ;RECORD ALREADY IN BUFFER MOV [DI],AX ;ENTER SLOT NUMBER MOV AX,USRSIZ ;USER RECORD SIZE CALL GETSBF ;GET SYSTEM BUFFER MOV [DI+2],SI ;ENTER IN DFCB CALL RUSR00 ;READ RECORD INTO BUFFER JZ GETU30 ;GOOD READ CALL FREBUF ;FREE BUFFER MOV CX,3 ;ENTRY LENGTH XOR AX,AX ;FILL CHAR push es push ds pop es REP STOSW ;CLEAR ENTRY pop es MOV SI,AX ;SHOW RECORD GONE STC ;SHOW END OF FILE JMP GETU90 ;EXIT GETU30: MOV SI,[DI+2] ;LOAD BUFFER ADDRESS MOV AX,[BP-2] ;RESTORE SLOT # CLC ;SHOW GOOD RETURN GETU90: POP DI POP DX POP CX POP BX MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET PUTUSR: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL STORAGE MOV [BP-2],AX ;SAVE PASSED PARM PUSH BX PUSH CX PUSH DX PUSH DI MOV [BP-2],AX ;SAVE PARM CALL FNDUSR ;FIND USER SLOT JNC PUTU10 ;FOUND IT ERR 701H PUTU10: MOV SI,[DI+2] ;BUFFER ADDRESS CALL WUSR00 ;WRITE RECORD PUTU15: DEC WORD PTR [DI+4] ;REDUCE USE COUNT JNZ PUTU20 ;RETAIN RECORD CALL FREBUF ;FREE BUFFER MOV CX,3 ;ENTRY LENGTH XOR AX,AX ;FILL CHAR push es push ds pop es REP STOSW ;CLEAR ENTRY pop es MOV SI,AX ;SHOW RECORD GONE PUTU20: MOV AX,[BP-2] ;RESTORE SLOT # POP DI POP DX POP CX POP BX MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET UPDUSR: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL STORAGE MOV [BP-2],AX ;SAVE PASSED PARM PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI CALL FNDUSR ;FIND USER SLOT JNC UPDU10 ;FOUND IT ERR 701H UPDU10: MOV SI,[DI+2] ;BUFFER ADDRESS CALL WUSR00 ;WRITE RECORD POP DI POP SI POP DX POP CX POP BX POP AX MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET FREUSR: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL STORAGE MOV [BP-2],AX ;SAVE SLOT NUMBER PUSH BX PUSH CX PUSH DX PUSH DI OR AX,AX ;NULL POINTER? JZ PUTU20 ;YES - IGNORE CALL FNDUSR ;FIND USER SLOT JC PUTU20 ;NOT IN TABLE - IGNORE MOV SI,[DI+2] ;BUFFER ADDRESS JMP PUTU15 ;ENTER COMMON CODE FNDUSR: PUSH CX PUSH DX CMP DFCBADR,0 ;DFCB EXIST? JNZ FNDU10 ;YES PUSH AX PUSH SI MOV AX,21 ;NUMBER OF DFCB ENTRIES PUSH AX MOV CX,6 ;ENTRY SIZE MUL CX ;SIZE FOR ENTRIES ADD AX,2 ;PREAMBLE SIZE CALL GETSBF ;ALLOCATE STORAGE MOV DFCBADR,SI ;REMEMBER WHERE POP AX MOV WORD PTR [SI],AX ;SET NUMBER OF ENTRIES POP SI POP AX FNDU10: MOV DI,DFCBADR ;POINT TO DFCB MOV CX,[DI] ;ENTRY COUNT XOR DX,DX ;NO AVAILABLE SLOT YET ADD DI,2 ;1ST DFCB ENTRY FNDU20: CMP [DI],AX ;THIS ENTRY? JZ FNDU90 ;YES - EXIT OR DX,DX ;FOUND EMPTY SLOT YET? JNZ FNDU30 ;YES - KEEP IT MOVING CMP WORD PTR [DI],0 ;EMPTY SLOT? JNZ FNDU30 ;NO MOV DX,DI ;REMEMBER EMPTY SLOT FNDU30: ADD DI,6 ;NEXT ENTRY LOOP FNDU20 ;TRY AGAIN MOV DI,DX ;1ST EMPTY SLOT OR DI,DI ;FIND ONE? JNZ FNDU40 ;YES - SET STATUS ERR 701H ;SHOULD NOT OCCUR FNDU40: STC ;SHOW ENTRY NOT FOUND FNDU90: POP DX POP CX RET RUSR00: MOV AH,3FH ;READ FUNCTION PUSH AX RWUSR: MOV AX,[BP-2] ;BLOCK NUMBER MOV CX,UESIZE ;BLOCK SIZE MUL CX ;CONVERT TO OFFSET MOV CX,DX MOV DX,AX MOV AX,4200H ;LSEEK PUSH BX MOV BX,USERH ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC RUSR10 ;SEEK OK ERR 1 RUSR10: MOV CX,USRSIZ ;RECORD LENGTH MOV DX,SI ;RECORD BUFFER POP AX ;READ OR WRITE FUNCTION PUSH BX MOV BX,USERH ;FILE HANDLE INT 21H ;DOS REQUEST POP BX JNC RUSR20 ;GOOD READ ERR 1 RUSR20: CMP AX,CX ;END OF FILE? RET WUSR00: MOV AH,40H ;WRITE FUNCTION PUSH AX JMP RWUSR ;ENTER COMMON CODE ;----------------------------------------------------------- ;ADD NEW USER TO DATA BASE ; INPUT SI -> NEW USER RECORD ; RETURNS SI -> USER RECORD ; AX -> SLOT NUMBER ; LOCAL STORAGE ; BP-2 USER RECORD ; BP-4 USER DSCB ENTRY ; BP-6 NEW SLOT NUMBER ;---------------------------------------------------------- ADDUSR: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,6 ;ALLOCATE LOCAL STORAGE PUSH CX PUSH DX PUSH DI MOV [BP-2],SI ;USER RECORD MOV AX,-1 ;INVALID SLOT NUMBER CALL FNDUSR ;GET A BUFFER SLOT MOV [BP-4],DI ;SLOT ADDRESS INC WORD PTR [DI+4] ;INCREMENT USE COUNT MOV [DI+2],SI ;ENTER IN DFCB MOV WORD PTR [SI-4],-1 ;MARK AS SYSTEM BUFFER ;SEEK TO END OF FILE MOV AX,4202H ;SEEK EOF XOR CX,CX MOV DX,CX PUSH BX MOV BX,USERH ;USER FILE HANDLE INT 21H ;DOS CALL POP BX JNC ADDU10 ;OK ERR 1 ;CALCULATE NEW RECORD BLOCK NUMBER ADDU10: MOV CX,128 ;RECORD LENGTH DIV CX ;CALCULATE BLOCK # MOV [BP-6],AX ;SAVE BLOCK # MOV DS:MSGCKPT+MLASTU,AX ;ALSO UPDATE STATS MOV DI,[BP-4] ;DSCB ENTRY MOV [DI],AX ;SLOT NUMBER IN DSCB MOV SI,[BP-2] ;LOGON RECORD ADD SI,UENAM ;USER NAME MOV CX,UELNK-UENAM ;LENGTH OF NAME MOV DI,SI ;WORK REG ADD DI,UELNK ;POINT PAST END ADDU15: CMP BYTE PTR [DI-1],' ' ;TRAILING BLANK? JNZ ADDU16 ;NO - GO HASH DEC DI ;TRIM TRAILING BLANK LOOP ADDU15 ;CHECK NEXT ADDU16: CALL CRCBFR ;HASH LOGON NAME AND AX,USRINXL ;FOLD TO TABLE LENGTH SHL AX,1 ;INDEX IN WORDS MOV SI,AX ;NEED INDEX REG ADD SI,USRINXA ;START OF TABLE MOV AX,WORD PTR [SI] ;GET BLOCK # MOV DI,[BP-2] ;USER RECORD MOV WORD PTR [DI+UELNK],AX ;SET LINK FIELD MOV AX,[BP-6] ;USER BLOCK # MOV WORD PTR [SI],AX ;ENTRY IN HASH TABLE ;WRITE NEW USER RECORD MOV AH,40H ;WRITE TO FILE MOV CX,USRSIZ ;RECORD SIZE MOV DX,[BP-2] ;RECORD ADDRESS PUSH BX MOV BX,USERH ;FILE HANDLE INT 21H ;DOS CALL POP BX CMP AX,CX ;WRITE FULL RECORD? JZ ADDU20 ;YES ERR 1 ;CHECKPOINT INDEX ADDU20: MOV AX,1 ;BLOCK NUMBER MOV CX,USERH ;FILE HANDLE MOV SI,USRINXA ;INDEX ADDRESS CALL WFBLK ;WRITE 1ST INDEX BLOCK MOV AX,2 ;BLOCK NUMBER ADD SI,128 ;2ND HALF OF INDEX CALL WFBLK ;WRITE 2ND INDEX BLOCK ;EXIT POP DI POP DX POP CX MOV AX,[BP-6] ;RETURN SLOT NUMBER MOV SI,[BP-2] ;RETURN BUFFER ADDRESS MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET SUBRTNS ENDP CSEG ENDS END