home *** CD-ROM | disk | FTP | other *** search
- ; This file is a part of SecureDevice 1.3
- ; Copyright (C) 1994 by Max Loewenthal and Arthur Helwig
-
- ; This program is free software; you can redistribute it and/or modify
- ; it under the terms of the GNU General Public License as published by
- ; the Free Software Foundation; either version 2 of the License, or
- ; (at your option) any later version.
-
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
-
- ; You should have received a copy of the GNU General Public License
- ; along with this program; if not, write to the Free Software
- ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- IDEAL
- MODEL TINY,C
-
- JUMPS
- LOCALS @@
-
- STRUC DirEntry
- FileName DB 11 DUP(?)
- Attr DB ?
- Reserved DB 10 DUP(?)
- DateTime DD ?
- Cluster DW ?
- Size DD ?
- ENDS DirEntry
-
- ; values for Attr:
- atReadOnly = 1h
- atHidden = 2h
- atSystem = 4h
- atVolLabel = 8h
- atDirectory = 10h
- atArchive = 20h
-
- StackSize = 2048
-
- KeySize = 104
-
- INCLUDE 'GLOBALS.ASM'
- INCLUDE 'DVSTRUCS.ASM'
-
- MinorName EQU "SECDEV.SYS"
- MinorVer EQU "1.03"
-
- MaxNofVols = 10
- MaxMaxTimeOut= 59
-
- STRUC ChainElm
- Cluster DW ?
- Count DW ?
- ENDS ChainElm
-
- STRUC VolumeRec
- FileName DB ' '
- Drive DB ?
- Unit DB ?
- MediaDesc DB ?
-
- DadsDPB DD ?
- DadsAttr DW ?
- DadsStrategy DD ?
- DadsInterrupt DD ?
-
- NofTicks DW -1
-
- MyBPB BPBRec <>
- FirstCluster DW ?
- Chain ChainElm MaxNofParts DUP (<0,0>)
- Key DB KeySize DUP (0)
- IV DW 4 DUP (?)
- Check DW 4 DUP (?)
- KeyOk DB 0 ; 1=key ok.
-
- Error DB 1 ; 0=no error on last op.
- ENDS VolumeRec
-
- ; format of Chain:
- ; Cluster , Count:WORD
- ; ... ...
- ; 0
-
- MACRO DumpString Msg
- ;; kills DX en AX
- MOV DX,Msg
- MOV AH,9
- INT 21h
- ENDM DumpString
-
- MACRO InBound Value,Lower,Upper
- LOCAL @@Exit
- ;; ZF := Lower<=Value<=Upper
- CMP Value,Lower
- JB @@Exit
- CMP Value,Upper
- JA @@Exit
- CMP AX,AX
- @@Exit:
- ENDM InBound
-
- CODESEG
- ORG 0
-
- ASSUME SS:NOTHING,DS:NOTHING,ES:NOTHING,CS:@CODE
-
- Header DeviceHeader <-1,2,OFFSET Strategy,OFFSET Interrupt,1>
-
- MASM
- INCLUDE IDEA.INC
- IDEAL
-
- RequestPtr DD ?
- OldInt2F DD ?
- OldInt08 DD ?
- MaxNofTicks DW 0
-
- LABEL BPBArray WORD
-
- i = 0
- REPT MaxNofVols
- DW i+OFFSET Volume.MyBPB
- i =i+SIZE VolumeRec
- ENDM
-
- NofVolumes DB 0
- DosVersion DW 0
- OldStack DD ?
-
- MaxCmd EQU 23
-
- JmpTab DW Init ; init
- DW MediaCheck ; media check
- DW Buildbpb ; build bpb
- DW Noerror ; IOCTL input
- DW Input ; input (read from device)
- DW Noerror ; non-destructive input [char]
- DW Noerror ; input status [char]
- DW Noerror ; input flush [char]
- DW Output ; output (write to device)
- DW Output ; output with verify
- DW Noerror ; output status [char]
- DW Noerror ; output flush [char]
- DW Noerror ; IOCTL output
- DW Noerror ; Device Open
- DW Noerror ; Device Close
- DW Noerror ; Removable Media
- DW Noerror ; --- reserved ---
- DW Noerror ; --- reserved ---
- DW Noerror ; --- reserved ---
- DW Noerror ; Generic IOCTL request
- DW Noerror ; --- reserved ---
- DW Noerror ; --- reserved ---
- DW Noerror ; --- reserved ---
-
- BaseDrive DB ? ; 0-based drive of 1st volume
- DriverIndex DW ? ; 0-based index of this driver (or how many
- ; drivers were loaded before this one)
-
- PROC NewInt2F FAR
- ; AH=E2
- ; Subfuncs:
-
- ; AL=0 Login to drive
- ; expects: DL drive (0=A)
- ; DS:SI ptr to key (104 bytes)
- ; returns: AL 0: don't know if key is good
- ; 1: key is good
- ; FF: key is not good
-
- ; AL=1 Get information
- ; expects: DX driver index (0-based)
- ; returns: AL number of volumes
- ; DL drive number of 1st volume (0=A)
-
- ; AL=3 Destroy password
- ; expects: DL drive (0=A, 0FFh=all)
- ; returns: nothing
-
- ; AL=9 counts drivers/installation check
- ; expects: DX=0,AX=0
- ; returns: DX number of drivers in memory
- ; AX 1DEAh on success
-
-
- ASSUME DS:NOTHING,SS:NOTHING,ES:NOTHING,CS:@CODE
- CMP AH,0E2h
- JE @@1
-
- @@DoOld: JMP [OldInt2F]
-
- @@1: CMP AL,0
- JNE @@2
-
- @@Login: CMP DL,[BaseDrive]
- JB @@DoOld
- PUSH DX
- SUB DL,[BaseDrive]
- CMP DL,[NofVolumes]
- POP DX
- JNB @@DoOld
- SUB DL,[BaseDrive]
-
- PUSH ES DI DX CX BX
-
- PUSH SI
- MOV DH,0
- MOV AX,SIZE VolumeRec
- MUL DX
- MOV BX,AX
- ADD BX,OFFSET Volume
- LEA DI,[(VolumeRec PTR CS:BX).Key]
- MOV [(VolumeRec PTR CS:BX).KeyOk],0
- PUSH CS
- POP ES
- POP SI
-
- MOV CX,KeySize
- REP MOVSB
- MOV AL,-1
- PUSH DS SI
- PUSH CS
- POP DS
- MOV SI,BX
- CALL CheckKey
- POP SI DS
- JNZ @@Exit
- MOV AL,1
- @@Exit: POP BX CX DX DI ES
- IRET
-
- @@2: CMP AL,1
- JNE @@4
- CMP DX,[DriverIndex]
- JNE @@DoOld
- MOV AL,[NofVolumes]
- MOV DL,[BaseDrive]
- IRET
-
- @@4: CMP AL,3
- JNE @@5
- CMP DL,0FFh
- JE @@KillAll
- CMP DL,[BaseDrive]
- JB @@DoOld
- PUSH DX
- SUB DL,[BaseDrive]
- CMP DL,[NofVolumes]
- POP DX
- JAE @@DoOld
- SUB DL,[BaseDrive]
-
- PUSH AX CX DI ES
-
- PUSH CS
- POP ES
-
- MOV DH,0
- MOV AX,SIZE VolumeRec
- MUL DX
- MOV DI,AX
- ADD DI,OFFSET Volume
-
- MOV [(VolumeRec PTR ES:DI).KeyOk],0
- LEA DI,[(VolumeRec PTR ES:DI).Key]
- MOV AL,0
- MOV CX,KeySize
- CLD
- REP STOSB
- POP ES DI CX AX
-
- JMP @@DoOld
-
- @@KillAll: PUSH AX CX DI ES
-
- PUSH CS
- POP ES
- MOV DI,OFFSET Volume
- MOV CL,[NofVolumes]
- MOV CH,0
- CLD
- JCXZ @@Done
-
- @@Next: MOV [(VolumeRec PTR ES:DI).KeyOk],0
- PUSH DI CX
- LEA DI,[(VolumeRec PTR ES:DI).Key]
- MOV AL,0
- MOV CX,KeySize
- REP STOSB
- POP CX DI
- ADD DI,SIZE VolumeRec
- LOOP @@Next
-
- @@Done: POP ES DI CX AX
- JMP @@DoOld
-
- @@5: CMP AL,9
- JNE @@DoOld
-
- MOV DX,[DriverIndex]
- INC DX
- MOV AX,1DEAh
- IRET
- ENDP NewInt2F
-
- PROC NewINT08
- ASSUME DS:NOTHING,SS:NOTHING,ES:NOTHING,CS:@CODE
-
- PUSH CX AX ES DI
-
- CMP [MaxNofTicks],0
- JE @@Leave
-
- MOV CH,0
- MOV CL,[NofVolumes]
- PUSH CS
- POP ES
- MOV DI,OFFSET Volume
-
- JCXZ @@Leave ; you never know
- @@Next: CMP [(VolumeRec PTR ES:DI).NofTicks],-1
- JE @@0
- INC [(VolumeRec PTR ES:DI).NofTicks]
- MOV AX,[(VolumeRec PTR ES:DI).NofTicks]
- CMP AX,[MaxNofTicks]
- JNGE @@0
-
- PUSH CX DI
- MOV AL,0
- CLD
- LEA DI,[(VolumeRec PTR ES:DI).Key]
- MOV CX,KeySize
- REP STOSB
- POP DI CX
- MOV [(VolumeRec PTR ES:DI).NofTicks],-1
- MOV [(VolumeRec PTR ES:DI).KeyOk],0
-
- @@0: ADD DI,SIZE VolumeRec
- LOOP @@Next
-
- @@Leave:
- POP DI ES AX CX
- JMP [OldInt08]
- ENDP NewINT08
-
- PROC Strategy FAR
- ASSUME DS:NOTHING,SS:NOTHING,ES:NOTHING,CS:@CODE
- MOV [WORD PTR RequestPtr],BX
- MOV [WORD PTR RequestPtr+2],ES
- RET
- ENDP Strategy
-
- PROC Interrupt FAR
- ASSUME DS:NOTHING,SS:NOTHING,ES:NOTHING,CS:@CODE
- PUSH AX BX CX DX DS ES SI DI
- PUSHF
-
- MOV [WORD PTR CS:OldStack],SP
- MOV [WORD PTR CS:OldStack+2],SS
- PUSH CS
- POP DS
- ASSUME DS:@CODE
-
- LES DI,[RequestPtr]
- MOV BL,[(RequestHeader PTR ES:DI).Command]
- XOR BH,BH
- IFDEF DEBUG
- CALL DebugCode
- ENDIF
- CMP BL,MaxCmd
- JBE @@1
- MOV AX,dverUnknownCommand+8000h
- JMP @@2
-
- @@1: CLI
- MOV AX,CS
- MOV SS,AX
- ASSUME SS:@CODE
- MOV SP,OFFSET StackTop
- STI
-
- CMP BX,dvcmInit
- JE @@3
-
- MOV DL,[(RequestHeader PTR ES:DI).Unit]
- CMP DL,[NofVolumes]
- MOV AL,dverUnknownUnit
- JNB @@2
- MOV DH,0
- MOV AX,SIZE VolumeRec
- MUL DX
- MOV SI,AX
- ADD SI,OFFSET Volume
- CMP [(VolumeRec PTR DS:SI).KeyOk],1
- JE @@3
- CMP BL,dvcmMediaChk
- JE @@3
- MOV AX,dverDeviceNotReady
- JMP @@Error
-
- @@3: SHL BX,1
- CALL [WORD PTR JmpTab+BX]
- MOV AH,0
- JNC @@2
-
- @@Error: MOV [(VolumeRec PTR SI).Error],1
- OR AX,swError
-
- @@2: OR AX,swDone
- MOV [(RequestHeader PTR ES:DI).Status],AX
- @@Exit: CLI
- MOV SP,[WORD PTR OldStack]
- MOV SS,[WORD PTR OldStack+2]
- STI
- POPF
- POP DI SI ES DS DX CX BX AX
- RET
- ENDP Interrupt
-
- PROC CryptData
- ; entry:
- ; BL = device command (if dvcmOutput: encrypt data
- ; if dvcmInput: decrypt data)
- ; DX:AX = sector number
- ; CX = count
- ; DS:SI -> VolumeRec
- ; ES:DI -> Buffer
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
-
- LOCAL IV:WORD:4,Encrypt:BYTE
-
- PUSH AX BX CX DX ES DI
- IFDEF DEBUG
- PUSH BX
- MOV BX,'G'-'0'
- CALL DebugCode
- POP BX
- ENDIF
-
- MOV [Encrypt],0
- CMP BL,dvcmInput
- JE @@CryptLoop
- INC [Encrypt]
-
- @@CryptLoop:OR AX,AX
- JNE @@NotBoot
- OR DX,DX
- JE @@Skip
- @@NotBoot: PUSH AX CX DX
- MOV BX,[(VolumeRec PTR DS:SI).IV]
- MOV [IV],BX
- MOV BX,[(VolumeRec PTR DS:SI+2).IV]
- MOV [IV+2],BX
- MOV BX,[(VolumeRec PTR DS:SI+4).IV]
- MOV [IV+4],BX
- MOV BX,[(VolumeRec PTR DS:SI+6).IV]
- MOV [IV+6],BX
- XOR [IV],AX
- XOR [IV+2],DX
- XOR [IV+4],AX
- XOR [IV+6],DX
-
- PUSH ES ; IDEA-routine destroys these!
-
- MOV AX,1 ;Actually zero blocks, will just pre-encrypt IV
- PUSH AX ;Store number of blocks
- SUB SP,8 ;Pretend to push plaintext/ciphertext addresses
- LEA BX,[(VolumeRec PTR DS:SI).Key]
- PUSH DS BX ; Push address of key
- LEA BX,[IV]
- PUSH SS BX
-
- CALL _IdeaCFB ; Encrypt IV
- ADD SP,18 ;Remove extra word
- POP ES
-
- PUSH ES
- MOV AX,1+(SectorSize/8) ;Nof Blocks
- PUSH AX ;Store number of blocks
- PUSH ES DI
- PUSH ES DI
- LEA BX,[(VolumeRec PTR DS:SI).Key]
- PUSH DS
- PUSH BX ; Push address of key
- LEA BX,[IV]
- PUSH SS
- PUSH BX
-
- TEST [Encrypt],1
- JNE @@2
- CALL _IdeaCFBx
- JMP @@3
- @@2: CALL _IdeaCFB
- @@3: ADD SP,18
- POP ES
-
- POP DX CX AX
- @@Skip: ADD AX,1
- ADC DX,0
-
- ADD DI,SectorSize
- LOOP @@CryptLoop
-
- POP DI ES DX CX BX AX
- RET
- ENDP CryptData
-
- PROC RebuildDPB
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; Rebuilds Dad's DPB out of his BPB
- ;
- ; DS:SI -> VolumeRec
-
- LOCAL ReqBuffer:BBPBRequest,Buffer:BYTE:400h
-
- PUSH BX CX DX ES
-
- IFDEF DEBUG
-
- MOV BL,'A'-'0'
- CALL DebugCode
-
- ENDIF
-
- MOV DX,0
- MOV AX,1
- MOV CX,1
- LEA DI,[Buffer]
- PUSH SS
- POP ES
- ASSUME ES:@CODE
- MOV BL,dvcmInput
- CALL DadsIO
- JC @@Exit
-
- MOV [ReqBuffer.Header.Command],dvcmBuildBPB
- MOV [ReqBuffer.Header.Length],SIZE BBPBRequest
- MOV BL,[(VolumeRec PTR SI).Unit]
- MOV [ReqBuffer.Header.Unit],BL
- MOV BL,[Buffer]
- MOV [ReqBuffer.MediaDesc],BL
- LEA BX,[Buffer]
- MOV [WORD PTR ReqBuffer.BufferPtr],BX
- MOV [(WORD PTR ReqBuffer.BufferPtr)+2],SS
- LEA BX,[ReqBuffer]
- CALL [(VolumeRec PTR SI).DadsStrategy]
- CALL [(VolumeRec PTR SI).DadsInterrupt]
- MOV AX,[ReqBuffer.Header.Status]
- TEST AX,swError
- STC
- JNE @@Exit
-
- PUSH DS SI BP
- LES BX,[(VolumeRec PTR SI).DadsDPB]
- ASSUME ES:NOTHING
- LDS SI,[ReqBuffer.BPBPtr]
- ASSUME DS:NOTHING
- MOV BP,BX
- MOV AH,53h
- INT 21h
- POP BP SI DS
- ASSUME DS:@CODE
- CLC
-
- @@Exit: POP ES DX CX BX
- RET
-
- ENDP RebuildDPB
-
- PROC MediaCheck
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; DS:SI -> VolumeRec
- ; ES:DI -> Request
-
- LOCAL ReqBuffer:MChkRequest
-
- PUSH BX
-
- MOV [ReqBuffer.Header.Command],dvcmMediaChk
- MOV [ReqBuffer.Header.Length],SIZE MChkRequest
- MOV BL,[(VolumeRec PTR SI).Unit]
- MOV [ReqBuffer.Header.Unit],BL
- MOV BL,[(VolumeRec PTR SI).MediaDesc]
- MOV [ReqBuffer.MediaDesc],BL
-
- LEA BX,[ReqBuffer]
- PUSH ES
- PUSH SS
- POP ES
- ASSUME ES:@CODE
- CALL [(VolumeRec PTR SI).DadsStrategy]
- CALL [(VolumeRec PTR SI).DadsInterrupt]
- POP ES
- MOV AX,[ReqBuffer.Header.Status]
- TEST AX,swError
- STC
- JNE @@Error
-
- MOV BL,[ReqBuffer.Result]
- MOV [(MChkRequest PTR ES:DI).Result],BL
- CMP BL,1
- JE @@NotChanged
- CALL RebuildDPB
- JC @@Error
- CALL ConstructBPB
- JC @@Error
- CLC
-
- @@Exit: MOV AX,[ReqBuffer.Header.Status] ; Return Daddy's error
- @@Error: POP BX
- RET
-
- @@NotChanged:
- CMP [(VolumeRec PTR SI).Error],0
- JNE @@1
- CMP [(VolumeRec PTR SI).KeyOK],1
- JE @@Exit
-
- @@1: MOV [(MChkRequest PTR ES:DI).Result],0FFh
- CALL ConstructBPB
- JC @@Error
- JMP @@Exit
- ENDP MediaCheck
-
- PROC MyIO
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; entry:
- ; BL = device command
- ; DX:AX = sector number
- ; CX = count
- ; DS:SI -> VolumeRec
- ; ES:DI -> Buffer
- ; return:
- ; IF Carry set then AX = status
-
- LOCAL pClusterSize:BYTE,MaxSector:BYTE,FirstData:WORD
- LOCAL InCluster:WORD,Bookmark:WORD,Command:BYTE
- LOCAL OldAX:WORD
-
- IFDEF DEBUG
- PUSH BX
- MOV BX,'B'-'0'
- CALL DebugCode
- POP BX
- ENDIF
- PUSH BX
- PUSH CX ES DI
- MOV [OldAX],AX
- LES DI,[(VolumeRec PTR SI).DadsDPB]
- MOV CL,[BYTE PTR ES:DI+4] ; Max sector in cluster
- MOV [MaxSector],CL
- MOV CX,[WORD PTR ES:DI+0Bh]
- MOV [FirstData],CX
- MOV CL,[BYTE PTR ES:DI+5]
- MOV [pClusterSize],CL
- MOV [Command],BL
-
- MOV BX,AX
- AND BL,[MaxSector] ; BX := offset in cluster
- MOV BH,0
- MOV [InCluster],BX
-
- MOV CH,0
- JCXZ @@01
- @@0: SHR DX,1 ; AX := cluster no
- RCR AX,1
- LOOP @@0
-
- @@01: POP DI ES CX
-
- PUSH CX DX DI
- PUSH SI
- CMP DX,0 ; cluster should be < FFFF
- JNE @@NotFound
- MOV DX,AX
- LEA SI,[(VolumeRec PTR SI).Chain]
- MOV [Bookmark],SI
-
- @@NextStroke:
- JCXZ @@Done
- @@1: LODSW
- CMP AX,0
- JE @@NotFound
- MOV BX,AX
- LODSW
- CMP DX,AX
- JB @@Found
- SUB DX,AX
- JMP @@1
-
- @@Found: ; Right now BX contains the first cluster in a
- ; contiguous area containing the 1st sector we need.
- ; This area is AX clusters long. 1st Sector lies in
- ; cluster # (BX+DX), sector [InCluster]
-
- PUSH CX ; DX:AX -> first sector to read
- MOV CL,[pClusterSize] ; BX = max n. of sectors readable in this stroke
- MOV CH,0
- XCHG BX,AX
- SUB BX,DX
- ADD AX,DX
- SUB AX,2
- PUSH CX
- JCXZ @@3
- @@2: SHL BX,1
- JC @@Max
- LOOP @@2
- JMP @@3
- @@Max: MOV BX,0FFFFh
- @@3: POP CX
- MOV DX,0
- JCXZ @@5
- @@4: SHL AX,1
- RCL DX,1
- LOOP @@4
- @@5: SUB BX,[InCluster]
- ADD AX,[InCluster]
- ADC DX,0
- ADD AX,[FirstData]
- ADC DX,0
- POP CX
-
- MOV [Bookmark],SI
- POP SI
-
- PUSH CX
- CMP BX,CX
- JA @@6
- MOV CX,BX
- @@6: MOV BL,[Command]
- CALL DadsIO
- MOV BX,CX
- POP CX
- PUSH SI
- MOV SI,[Bookmark]
- JC @@Error
-
- PUSH CX BX ; adjust pointer in write buffer
- MOV CL,pSectorSize
- SHL BX,CL
- ADD DI,BX
- POP BX CX
-
- SUB CX,BX
- MOV DX,0
- MOV [InCluster],0
- JMP @@NextStroke
-
- @@Done: CLC
-
- @@Exit: POP SI
- POP DI DX CX
- POP BX
- JC @@7
- MOV [(VolumeRec PTR SI).NofTicks],0
- MOV AX,[OldAX]
- @@7: RET
-
- @@Error: STC
- JMP @@Exit
-
- @@NotFound: STC
- MOV AL,dverGeneralFailure ; sector not found?
- JMP @@Exit
- ENDP MyIO
-
- PROC CheckKey
- ASSUME DS:NOTHING,SS:NOTHING,ES:NOTHING,CS:@CODE
- ; DS:SI -> VolumeRec
- ; return:
- ; Zero flag set if key is OK
- LOCAL KeyOk:BYTE,MyIV:WORD:4,MyCheck:WORD:4
-
- PUSH AX BX CX DX ES DI
- MOV BX,[(VolumeRec PTR DS:SI).IV]
- NOT BX
- MOV [MyIV],BX
- MOV BX,[(VolumeRec PTR DS:SI+2).IV]
- NOT BX
- MOV [MyIV+2],BX
- MOV BX,[(VolumeRec PTR DS:SI+4).IV]
- NOT BX
- MOV [MyIV+4],BX
- MOV BX,[(VolumeRec PTR DS:SI+6).IV]
- NOT BX
- MOV [MyIV+6],BX
-
- MOV BX,1
- PUSH BX
- SUB SP,8
- LEA BX,[(VolumeRec PTR DS:SI).Key]
- PUSH DS
- PUSH BX ; Push address of key
- LEA BX,[MyIV]
- PUSH SS
- PUSH BX
-
- CALL _IdeaCFB
- ADD SP,18
-
- MOV BX,2 ;Nof Blocks
- PUSH BX ;Store number of blocks
- LEA DI,[MyCheck]
- PUSH SS DI
- LEA DI,[(VolumeRec PTR DS:SI).Check]
- PUSH DS DI
- LEA BX,[(VolumeRec PTR DS:SI).Key]
- PUSH DS
- PUSH BX ; Push address of key
- LEA BX,[MyIV]
- PUSH SS
- PUSH BX
-
- CALL _IdeaCFBx
- ADD SP,18
-
- CMP [MyCheck],1234h
- JNE @@0
- MOV [(VolumeRec PTR DS:SI).NofTicks],0
-
- @@0: POP DI ES DX CX BX AX
- RET
- ENDP CheckKey
-
- PROC AskKey
- ; DS:SI -> VolumeRec
-
- PUSH AX DX ES DI
-
- LES DI,[RequestPtr]
- MOV DL,[(RequestHeader PTR ES:DI).Unit]
- ADD DL,[BaseDrive]
- MOV AX,0E202h
- INT 2Fh ; AL=02: ask for password
-
- POP DI ES DX AX
- RET
- ENDP AskKey
-
- PROC ConstructBPB
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; DS:SI -> VolumeRec
- ; Carry set if error in AL
-
- LOCAL BootRecord:BYTE:SectorSize
-
- IFDEF DEBUG
- PUSH BX
- MOV BX,'C'-'0'
- CALL DebugCode
- POP BX
- ENDIF
- PUSH BX CX DX ES DI
-
- MOV [(VolumeRec PTR DS:SI).KeyOk],0
-
- CALL MakeChain
- JC @@Error
-
- MOV DX,0
- MOV AX,0
- MOV CX,1
- PUSH SS
- POP ES
- ASSUME ES:@CODE
- LEA DI,[BootRecord]
- MOV BL,dvcmInput
- CALL MyIO
- JC @@Error
- PUSH DI SI
- LEA DI,[(VolumeRec PTR SI).MyBPB]
- LEA SI,[BootRecord+0bh]
- MOV CX,SIZE BPBRec
- CLD
- REP MOVSB
- POP SI
- PUSH SI
- LEA DI,[(VolumeRec PTR SI).IV]
- LEA SI,[BootRecord+3Eh]
- MOV CX,8 ; Size of IV
- REP MOVSB
- POP SI
- PUSH SI
- LEA DI,[(VolumeRec PTR SI).Check]
- LEA SI,[BootRecord+46h]
- MOV CX,8 ; Size of check
- REP MOVSB
- POP SI
- POP DI
-
- MOV AL,dverDeviceNotReady
- CALL CheckKey
- JE @@Ok
- CALL AskKey
- CALL CheckKey
- JNE @@Error
-
- @@Ok: MOV [(VolumeRec PTR DS:SI).KeyOk],1
- CLC
- MOV [(VolumeRec PTR SI).Error],0
- @@Exit: POP DI ES DX BX CX
- RET
-
- @@Error: STC
- JMP @@Exit
- ENDP ConstructBPB
-
- PROC BuildBPB
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; DS:SI -> VolumeRec
- ; ES:DI -> BBPBRequest
-
- PUSH BX
-
- MOV [(WORD PTR (BBPBRequest PTR ES:DI).BPBPtr)+2],CS
- LEA BX,[(VolumeRec PTR SI).MyBPB]
- MOV [WORD PTR (BBPBRequest PTR ES:DI).BPBPtr],BX
-
- POP BX
- CLC
- RET
- ENDP BuildBPB
-
- PROC Input
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; DS:SI -> VolumeRec
- ; ES:DI -> IORequest
-
- PUSH BX CX DX ES DI
- MOV CX,[(IORequest PTR ES:DI).Count]
- MOV AX,[(IORequest PTR ES:DI).Sector]
- MOV DX,0
- CMP AX,-1
- JNE @@DoIt
- MOV AX,[(WORD PTR (IORequest PTR ES:DI).Sector32b)]
- MOV DX,[(WORD PTR (IORequest PTR ES:DI).Sector32b)+2]
- @@DoIt: MOV BL,dvcmInput
- LES DI,[(IORequest PTR ES:DI).Buffer]
- CALL MyIO
- JC @@Error
- CALL CryptData
- @@Error: POP DI ES DX CX BX
- RET
- ENDP Input
-
- PROC Output
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; DS:SI -> VolumeRec
- ; ES:DI -> IORequest
- LOCAL OldAX:WORD
-
- PUSH BX CX DX ES DI
- MOV CX,[(IORequest PTR ES:DI).Count]
- MOV AX,[(IORequest PTR ES:DI).Sector]
- MOV DX,0
- CMP AX,-1
- JNE @@DoIt
- MOV AX,[(WORD PTR (IORequest PTR ES:DI).Sector32b)]
- MOV DX,[(WORD PTR (IORequest PTR ES:DI).Sector32b)+2]
- @@DoIt: MOV BL,dvcmOutput
- LES DI,[(IORequest PTR ES:DI).Buffer]
- MOV [OldAX],AX
- CALL CryptData
- CALL MyIO
- PUSH AX
- MOV AX,[OldAX]
- MOV BL,dvcmInput
- CALL CryptData
- POP AX
- POP DI ES DX CX BX
- RET
- ENDP Output
-
- PROC NoError
- CLC
- RET
- ENDP NoError
-
- PROC DadsIO
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- LOCAL ReqBuffer:IORequest
- ; entry:
- ; BL = device command
- ; DX:AX = sector number
- ; CX = count
- ; DS:SI -> VolumeRec
- ; ES:DI -> Buffer
- ; return:
- ; AX = status
- IFDEF DEBUG
- PUSH BX
- MOV BX,'D'-'0'
- CALL DebugCode
- POP BX
- ENDIF
- PUSH ES BX
- MOV [ReqBuffer.Header.Command],BL
-
- MOV [ReqBuffer.Header.Length],SIZE IORequest
- MOV BL,[(VolumeRec PTR SI).Unit]
- MOV [ReqBuffer.Header.Unit],BL
- MOV [WORD PTR (IORequest PTR ReqBuffer).Buffer],DI
- MOV [(WORD PTR (IORequest PTR ReqBuffer).Buffer)+2],ES
- MOV [ReqBuffer.Count],CX
-
- TEST [(VolumeRec PTR SI).DadsAttr],2 ; support >32M?
- JE @@2
- MOV [WORD PTR ReqBuffer.Sector32b],AX
- MOV [(WORD PTR ReqBuffer.Sector32b)+2],DX
- MOV [ReqBuffer.Sector],-1
- JMP @@3
- @@2: CMP DX,0
- JE @@21
- MOV AL,dverGeneralFailure
- JMP @@Error
-
- @@21: MOV [ReqBuffer.Sector],AX
- SUB [ReqBuffer.Header.Length],4
-
- @@3: LEA BX,[ReqBuffer]
- PUSH SS
- POP ES
- CALL [(VolumeRec PTR SI).DadsStrategy]
- CALL [(VolumeRec PTR SI).DadsInterrupt]
- MOV CX,[ReqBuffer.Count]
- MOV AX,[(RequestHeader PTR ReqBuffer).Status]
- CLC
- TEST AX,swError
- JE @@Exit
- @@Error: STC
- @@Exit: POP BX ES
- RET
- ENDP DadsIO
-
- PROC FindFile
- ASSUME DS:@CODE,SS:@CODE,ES:@CODE,CS:@CODE
- ; SI -> VolumeRec,
- ; CF set if error in AX ?
- ; else first cluster in AX
-
- LOCAL Sector:BYTE:SectorSize, SectorCounter:WORD
-
- PUSH BX CX DX ES DI
-
- LES BX,[(VolumeRec PTR SI).DadsDPB]
- ASSUME ES:NOTHING
- MOV DI,[ES:BX+09h] ; nof dir entries
- SHR DI,1
- SHR DI,1
- SHR DI,1
- MOV [SectorCounter],DI
-
- TEST DX,0D0h ; voor als ik rekening moet
- JE @@0 ; houden met extra entries
- AND DX,0D0h
- INC DX
- @@0:
-
- CMP [BYTE PTR DosVersion],4
- JB @@1
- INC BX
- @@1: MOV AX,[ES:BX+10h] ; first ROOT sector
- MOV DX,0
- PUSH SS
- POP ES
-
- @@NextSctr: MOV CX,SectorSize/SIZE DirEntry
- PUSH AX
- LEA DI,[Sector]
- MOV CX,1
- MOV BL,dvcmInput
- CALL DadsIO
- POP AX
- JC @@Error
- CMP CX,1 ; ??
- JNE @@Error
-
- MOV CX,SectorSize/SIZE DirEntry
- LEA DI,[Sector]
-
- @@NextEntry:CMP [BYTE PTR DI],0
- JE @@NotFound ; end of dir.
-
- PUSH DI SI CX
- LEA SI,[(VolumeRec PTR SI).FileName]
- MOV CX,11
- REP CMPSB
- POP CX SI DI
- JE @@Found
- ADD DI,SIZE DirEntry
- DEC CX
- JNZ @@NextEntry
-
- INC AX
- DEC [SectorCounter]
- JNZ @@NextSctr
-
- @@Found: TEST [(DirEntry PTR DI).Attr],atVolLabel+atDirectory
- JNE @@InvalidFile
- MOV AX,[(DirEntry PTR DI).Cluster]
- CLC
-
- @@Exit: POP DI ES DX CX BX
- RET
-
- @@Error: STC
- JMP @@Exit
- @@InvalidFile:
- @@NotFound: MOV AL,dverGeneralFailure
- JMP @@Error
- ENDP FindFile
-
- PROC MakeChain
- ASSUME DS:@CODE,SS:@CODE,ES:NOTHING,CS:@CODE
- ; DS:SI -> VolumeRec
- ; CF set if error in AX
-
- LOCAL FATBase:WORD,FATSector:BYTE:SectorSize,FATSectorNo:WORD
- LOCAL Shift:BYTE,Ofs:WORD,Sector:WORD
- LOCAL NofClusters:WORD,FAT12:BYTE ; 0=16 bit fat
-
- IFDEF DEBUG
- PUSH BX
- MOV BX,'E'-'0'
- CALL DebugCode
- POP BX
- ENDIF
- LES DI,[(VolumeRec PTR SI).DadsDPB]
- ASSUME ES:NOTHING
- CMP [WORD PTR ES:DI+2],SectorSize
- JNE @@Error
- MOV AX,[WORD PTR ES:DI+0Dh] ; n of clusters
- MOV [NofClusters],AX
- MOV [FAT12],1
- CMP AX,0FF6h
- JBE @@F
- MOV [FAT12],0
- @@F: MOV AX,[WORD PTR ES:DI+6] ; n of reserved
- MOV [FATBase],AX
-
- PUSH DS
- POP ES
- ASSUME ES:@CODE
- LEA DI,[(VolumeRec PTR SI).Chain]
- MOV BX,-4
- MOV [FATSectorNo],-1
-
- CALL FindFile
- JC @@Error
-
- @@NextCluster:
- CMP [FAT12],0
- JNE @@1
-
- CMP AX,0FFF8h
- JAE @@Ready
- InBound AX,0FFF0h,0FFF7h
- JZ @@Error
- JMP @@2
-
- @@1: CMP AX,0FF8h
- JAE @@Ready
- InBound AX,0FF0h,0FF7h
- JZ @@Error
-
- @@2: CMP BX,-4 ; add cluster to chain
- JE @@NewPart
- MOV CX,AX
- SUB CX,[(ChainElm PTR BX+DI).Cluster]
- CMP CX,[(ChainElm PTR BX+DI).Count]
- JNE @@NewPart
- INC [(ChainElm PTR DS:BX+DI).Count]
- JMP @@0
-
- @@NewPart: CMP BX,4*MaxNofParts
- JGE @@Error
- ADD BX,4
- MOV [(ChainElm PTR BX+DI).Count],1
- MOV [(ChainElm PTR BX+DI).Cluster],AX
-
- @@0: InBound AX,2,[NofClusters]
- JNZ @@Error
-
- CMP [FAT12],0
- JE @@Compute16
-
- MOV CX,AX ; compute Shift,Ofs,Sector for 12-bit FAT
- MOV DX,0
- SHL AX,1
- RCL DX,1
- ADD AX,CX
- ADC DX,0
- MOV [Shift],AL
- AND [Shift],1
- SHR DX,1
- RCR AX,1
- MOV [Ofs],AX
- AND [Ofs],SectorSize-1
- REPT pSectorSize
- SHR AX,1
- ENDM
- REPT 16-pSectorSize
- SHL DX,1
- ENDM
- OR AX,DX
- MOV [Sector],AX
- JMP @@4
-
- @@Compute16:SHL AX,1
- RCL DX,1
- MOV [Ofs],AX ; same for 16-bit FAT
- AND [Ofs],SectorSize-1
- REPT pSectorSize
- SHR DX,1
- RCR AX,1
- ENDM
- MOV [Sector],AX
- MOV [Shift],-1
-
- @@4: MOV AX,[Sector]
- CALL @@GetFATSector
- JC @@Error
- PUSH SI
- MOV SI,[Ofs]
- MOV CL,[FATSector+SI]
- POP SI
- INC [Ofs]
- CMP [Ofs],SectorSize
- JB @@3
- MOV [Ofs],0
- INC [Sector]
- MOV AX,[Sector]
- CALL @@GetFATSector
- JC @@Error
- @@3: PUSH SI
- MOV SI,[Ofs]
- MOV CH,[FATSector+SI]
- POP SI
-
- CMP [Shift],-1
- JE @@GotIt
- CMP [Shift],0
- JE @@5
- REPT 4
- SHR CX,1
- ENDM
- @@5: AND CX,0FFFh
-
- @@Gotit: MOV AX,CX
- JMP @@NextCluster
-
- @@Ready: ADD BX,4
- MOV [(ChainElm PTR DS:BX+DI).Count],0
- MOV [(ChainElm PTR DS:BX+DI).Cluster],0
-
- CLC
- @@Exit: RET
-
- @@Error: MOV [(VolumeRec PTR SI).Chain.Count],0
- MOV [(VolumeRec PTR SI).Chain.Cluster],0
- STC
- MOV AL,dverGeneralFailure
- JMP @@Exit
-
- @@GetFATSector:
- ; pre:
- ; AX = fat sector no.
- ; post:
- ; Carry set if error else wanted sector in [Sector]
- CMP [FATSectorNo],AX
- JE @@@Exit
- MOV [FATSectorNo],AX
- PUSH BX CX DX ES DI
- MOV DX,0
- ADD AX,[FATBase]
- ADC DX,0
- MOV CX,1
- PUSH SS
- POP ES
- ASSUME ES:@CODE
- LEA DI,[FATSector]
- MOV BL,dvcmInput
- CALL DadsIO
- POP DI ES DX CX BX
- ASSUME ES:NOTHING
- JNC @@@Exit
- MOV [FATSectorNo],-1
- STC
- @@@Exit: RETN
- ENDP MakeChain
-
- IFDEF DEBUG
-
- PROC DebugCode
- ASSUME DS:@CODE,SS:NOTHING,ES:NOTHING,CS:@CODE
- PUSH AX BX DX
-
- DumpString <OFFSET DebugMsg>
- MOV DX,BX
- ADD DX,30h
- MOV AH,06
- INT 21h
- DumpString <OFFSET CrLf>
- POP DX BX AX
- RET
-
- DebugMsg DB 'Request #$'
- CrLf DB 0Dh,0Ah,'$'
-
- ENDP DebugCode
-
- PROC DumpParms
- ASSUME DS:NOTHING,ES:NOTHING,SS:@CODE,CS:@CODE
-
- PUSH AX CX DX DS SI
- PUSH ES
- POP DS
- MOV SI,DI
- MOV CX,80
- MOV AH,2h
-
- @Loop: LODSB
- MOV DH,AL
- MOV DL,DH
- SHR DL,1
- SHR DL,1
- SHR DL,1
- SHR DL,1
- ADD DL,30h
- CMP DL,3Ah
- JB @Digit1
- ADD DL,7
- @Digit1: INT 21h
- MOV DL,DH
- AND DL,0Fh
- ADD DL,30h
- CMP DL,3Ah
- JB @Digit2
- ADD DL,7
- @Digit2: INT 21h
- LOOP @Loop
-
- POP SI DS DX CX AX
- RET
-
- ENDP DumpParms
-
- ENDIF
-
- PROC Init
- ASSUME DS:@CODE,ES:NOTHING,SS:@CODE,CS:@CODE
-
- LEA DX,[NameVersion]
- MOV AH,9
- INT 21h
-
- MOV AH,30h
- INT 21h
- MOV [DosVersion],AX
- MOV AL,[(InitRequest PTR ES:DI).DriveNo]
- MOV [BaseDrive],AL
-
- MOV DX,0
- MOV AX,0E209h
- INT 2Fh
- CMP AX,1DEAh
- JE @@2
- MOV DX,0
- @@2: MOV [DriverIndex],DX
-
- CALL ExtractParms
-
- MOV AL,[NofVolumes]
-
- MOV [(InitRequest PTR ES:DI).NofUnits],AL
- MOV [(WORD PTR (InitRequest PTR ES:DI).EndAddress)+2],CS
- MOV [(WORD PTR (InitRequest PTR ES:DI).ReturnBPB)],OFFSET BPBArray
- MOV [(WORD PTR (InitRequest PTR ES:DI).ReturnBPB)+2],CS
- PUSH SI ES CX AX DI
- PUSH CS
- POP ES
- MOV SI,OFFSET EndOfCode
- MOV DI,OFFSET Volume
- MOV AH,0
- MOV CX,SIZE VolumeRec
- MUL CX
- MOV CX,AX
- CLD
- JCXZ @@1
- REP MOVSB
- @@1: POP SI AX CX ES
- MOV [(WORD PTR (InitRequest PTR ES:SI).EndAddress)],DI
- MOV DI,SI
- POP SI
-
- CMP AL,0
- JE @@NotInst
- PUSH DS
- XOR AX,AX
- MOV DS,AX
- MOV AX,[WORD PTR DS:2Fh*4]
- MOV [WORD PTR CS:OldInt2F],AX
- MOV AX,[WORD PTR DS:2Fh*4+2]
- MOV [WORD PTR CS:OldInt2F+2],AX
- MOV AX,[WORD PTR DS:8h*4]
- MOV [WORD PTR CS:OldInt08],AX
- MOV AX,[WORD PTR DS:8h*4+2]
- MOV [WORD PTR CS:OldInt08+2],AX
- CLI
- MOV [WORD PTR DS:8h*4],OFFSET NewInt08
- MOV [WORD PTR DS:8h*4+2],CS
- MOV [WORD PTR DS:2Fh*4],OFFSET NewInt2F
- MOV [WORD PTR DS:2Fh*4+2],CS
- STI
- POP DS
- JMP @@Exit
- @@NotInst: DumpString <OFFSET NotInstMsg>
- MOV [(WORD PTR (InitRequest PTR ES:DI).EndAddress)],0
- @@Exit: CLC
- RET
- ENDP Init
-
- ALIGN 2h
-
- DB StackSize DUP ('!')
- LABEL Stacktop
-
- LABEL Volume VolumeRec
-
- PROC AddVolume
- ASSUME DS:@CODE,ES:NOTHING,SS:@CODE,CS:@CODE
- ; ES:DI -> file-spec
-
- PUSH DS SI ES DI
-
- PUSH ES
- POP DS
- ASSUME DS:NOTHING
- MOV SI,DI
-
- MOV AX,SIZE VolumeRec ; ES:DI -> VolumeRec
- MOV BL,[NofVolumes]
- MOV BH,0
- CMP BL,MaxNofVols
- MOV DX,OFFSET @@TooMany
- JAE @@Error
- MUL BX
- MOV DI,AX
- ADD DI,OFFSET EndOfCode
- PUSH CS
- POP ES
- PUSH DS DI SI CX
- LEA SI,[@@DefaultVR]
- MOV CX,SIZE VolumeRec
- PUSH CS
- POP DS
- CLD
- REP MOVSB
- POP CX SI DI DS
-
- MOV DX,BX ; get drive #
- ASSUME ES:@CODE
- LODSB
- CMP AL,'a'
- JB @@0
- CMP AL,'z'
- JA @@0
- SUB AL,'a'-'A'
- @@0: SUB AL,'A'
- CMP AL,[BaseDrive]
- MOV DX,OFFSET @@InvDrive
- JAE @@Error
- MOV [(VolumeRec PTR ES:DI).Drive],AL
- LODSB
- CMP AL,':'
- JNE @@Error
- LODSB
- CMP AL,'\'
- MOV DX,OFFSET @@InvName
- JNE @@Error
-
- MOV BX,0
- MOV CH,0
-
- @@Next: LODSB
- MOV DX,OFFSET @@InvName
- CMP AL,0Dh
- JE @@Ready
- CMP AL,9
- JE @@Ready
- CMP AL,' '
- JE @@Ready
- CMP AL,'\'
- JE @@Error
- CMP AL,'.'
- JNE @@1
- CMP CH,0
- JNE @@Error
- CMP BX,0
- JE @@Error
- MOV CH,1
- MOV BX,8
- JMP @@Next
- @@1: CMP BX,11
- JAE @@Next
- CMP BX,8
- JB @@2
- CMP CH,0
- JE @@Next
- @@2: CMP AL,'a'
- JB @@21
- CMP AL,'z'
- JA @@21
- SUB AL,'a'-'A'
- @@21: MOV [(VolumeRec PTR ES:DI+BX).FileName],AL
- INC BX
- JMP @@Next
-
- @@Ready: CMP BX,0
- JE @@Error
-
- PUSH ES DI
- MOV AH,52h
- INT 21h ; get list of lists
- LDS SI,[DWORD PTR ES:BX] ; get pointer to 1st DPB
- POP DI ES
- MOV AL,[(VolumeRec PTR ES:DI).Drive]
- MOV BX,0
- CMP [BYTE PTR CS:DosVersion],4
- JB @@3
- MOV BX,1
- @@3: CMP [BYTE PTR SI],AL
- JE @@Found
- CMP [WORD PTR SI+BX+18h],-1
- JNE @@Next2
- CMP [WORD PTR SI+BX+1Ah],-1
- JE @@Error
-
- @@Next2: LDS SI,[DWORD PTR SI+BX+18h]
- JMP @@3
-
- @@Found: MOV DL,[SI+1] ; unit no
- MOV [(VolumeRec PTR ES:DI).Unit],DL
- MOV DL,[SI+BX+16h] ; media ID
- MOV [(VolumeRec PTR ES:DI).MediaDesc],DL
- MOV [WORD PTR (VolumeRec PTR ES:DI).DadsDPB],SI
- MOV [(WORD PTR (VolumeRec PTR ES:DI).DadsDPB)+2],DS
- LDS SI,[DWORD PTR SI+BX+12h]
- MOV [(WORD PTR (VolumeRec PTR ES:DI).DadsStrategy)+2],DS
- MOV [(WORD PTR (VolumeRec PTR ES:DI).DadsInterrupt)+2],DS
- MOV DX,[(DeviceHeader PTR SI).Strategy]
- MOV [WORD PTR (VolumeRec PTR ES:DI).DadsStrategy],DX
- MOV DX,[(DeviceHeader PTR SI).Interrupt]
- MOV [WORD PTR (VolumeRec PTR ES:DI).DadsInterrupt],DX
- MOV DX,[(DeviceHeader PTR SI).Attr]
- MOV [(VolumeRec PTR ES:DI).DadsAttr],DX
-
- POP DI ES
- CALL DumpWord
-
- MOV AL,[NofVolumes]
- ADD AL,[BaseDrive]
- ADD AL,'A'
- MOV [@@Drive],AL
- POP SI DS
- ASSUME DS:@CODE
- DumpString <OFFSET @@Added>
- INC [NofVolumes]
- RET
-
- ASSUME DS:NOTHING,ES:NOTHING
- @@Error: POP DI ES
-
- CALL DumpWord
-
- POP SI DS
- PUSH DX
- ASSUME DS:@CODE
- DumpString <OFFSET @@NotAdded>
- POP DX
- DumpString DX
- RET
-
- @@DefaultVR VolumeRec <>
-
- @@Added DB ' added acting as drive '
- @@Drive DB 'A.',0Dh,0Ah,'$'
-
- @@NotAdded DB ' not added: ','$'
- @@TooMany DB 'Too many volumes.',0Dh,0Ah,'$'
- @@InvDrive DB 'Invalid drive letter.',0Dh,0Ah,'$'
- @@InvName DB 'Invalid file FileName.',0Dh,0Ah,'$'
- @@NoDPB DB 'Can''t find DPB.',0Dh,0Ah,'$'
- ENDP AddVolume
-
-
- PROC DumpWord
- ; ES:DI-> word
- PUSH DS SI AX DX
-
- PUSH ES
- POP DS
- MOV AH,2
- MOV SI,DI
-
- @@Next: LODSB
- CMP AL,' '
- JE @@Exit
- CMP AL,9
- JE @@Exit
- CMP AL,0Dh
- JE @@Exit
- MOV DL,AL
- INT 21h
- JMP @@Next
-
- @@Exit: POP DX AX SI DS
- ENDP DumpWord
-
- PROC NextWord
- ; entry:
- ; ES:DI-> string
- ; return:
- ; ES:DI-> beginning of next word in string
-
- CMP [BYTE PTR ES:DI],' '
- JE @@Next
- CMP [BYTE PTR ES:DI],09h
- JE @@Next
- RET
-
- @@Next: INC DI
- JMP NextWord
- ENDP NextWord
-
- PROC NextSpace
- ; entry:
- ; ES:DI-> string
- ; return:
- ; ES:DI-> beginning of next space/tab in string
- CMP [BYTE PTR ES:DI],' '
- JE @@Exit
- CMP [BYTE PTR ES:DI],09h
- JE @@Exit
- CMP [BYTE PTR ES:DI],0Ah
- JE @@Exit
- INC DI
- JMP NextSpace
-
- @@Exit: RET
- ENDP NextSpace
-
- PROC GetOption
- ; ES:DI-> option
-
- PUSH DI AX DX
- INC DI
-
- MOV AL,[ES:DI]
- CMP AL,'a'
- JB @@0
- CMP AL,'z'
- JA @@0
- SUB AL,'a'-'A'
- @@0: CMP AL,'T'
- JE @@TimeOut
-
- MOV AL,[ES:DI]
- MOV [@@Opt],AL
- DumpString <OFFSET @@UnkOpt>
-
- @@Exit: POP DX AX DI
- RET
-
- @@TimeOut: INC DI
- MOV SI,DI
- MOV AX,0
- MOV BX,10d
- MOV DH,0
-
- @@Next: XCHG DL,AL
- LODS [BYTE PTR ES:SI]
- XCHG DL,AL
- CMP DL,' '
- JE @@End
- CMP DL,0Dh ;? art
- JE @@End
- CMP DL,9
- JE @@End
- CMP DL,'0'
- JB @@Ill
- CMP DL,'9'
- JA @@Ill
- SUB DL,'0'
- MUL BL
- ADD AX,DX
- CMP AX,MaxMaxTimeOut
- JA @@Ill
- JMP @@Next
-
- @@End: MOV DX,AX
- MOV AX,0
- MOV BX,60
- DIV BX
- MOV [MaxNofTicks],AX
- DumpString <OFFSET @@AutoCl>
- CALL DumpWord
- DumpString <OFFSET @@Minutes>
- JMP @@Exit
-
- @@Ill: DumpString <OFFSET @@InvNum>
- JMP @@Exit
-
- @@UnkOpt DB 'Unknown option: '
- @@Opt DB ?,0dh,0ah,'$'
- @@AutoCl DB 'Auto-close timeout set at $'
- @@Minutes DB ' minutes.',0dh,0ah,'$'
- @@InvNum DB 'invalid value for auto-close timeout.',0dh,0ah,'$'
-
- ENDP GetOption
-
- PROC ExtractParms NEAR
- ASSUME DS:@CODE,ES:NOTHING,SS:@CODE,CS:@CODE
- ; entry:
- ; ES:DI -> InitRequest
-
- PUSH ES DI
-
- LES DI,[(InitRequest PTR ES:DI).ParamStr]
- MOV [NofVolumes],0
-
- IFDEF DEBUG
- CALL DumpParms
- ENDIF
-
- CALL NextWord
- @@Next: CALL NextSpace
- CALL NextWord
- CMP [BYTE PTR ES:DI],0Ah
- JE @@Exit
- CMP [BYTE PTR ES:DI],'/'
- JE @@opt
- CMP [BYTE PTR ES:DI],'-'
- JNE @@vol
- @@opt: CALL GetOption
- JMP @@Next
-
- @@vol: CALL AddVolume
- JMP @@Next
-
- @@Exit: POP DI ES
- RET
- ENDP ExtractParms
-
- NotInstMsg DB 'No volumes mounted, driver not installed.',0Dh,0Ah,'$'
- NameVersion DB MajorName,' ',MajorVer,'''s ',MinorName,' ',MinorVer,0Dh,0Ah
- DB 'Written by ',AuthorName,0Dh,0Ah,'$'
-
- LABEL EndOfCode
- END
-
-