📄 ftps.asm
字号:
noeaxz:
mov [pos],eax
newdata:
ret
;***************************************************************************
; Function
; disconnect
;
; Description
; Closes the command socket
;
; Inputs
; None
;
;***************************************************************************
disconnect:
mov eax, 53 ; Stack Interface
mov ebx,8 ; Close TCP socket
mov ecx,[CmdSocket]
int 0x40
ret
;***************************************************************************
; Function
; disconnectData
;
; Description
; Closes the data socket
;
; Inputs
; None
;
;***************************************************************************
disconnectData:
; This delay would be better done by allowing the socket code
; to wait for all data to pass through the stack before closing
pusha
mov eax,5
mov ebx,200 ; Delay for 2s
int 0x40
popa
mov eax, 53 ; Stack Interface
mov ebx,8 ; Close TCP socket
mov ecx,[DataSocket]
int 0x40
ret
;***************************************************************************
; Function
; connect
;
; Description
; Opens the command socket
;
; Inputs
; None
;
;***************************************************************************
connect:
pusha
mov eax, 53 ; Stack Interface
mov ebx, 5 ; Open TCP socket
mov esi, 0 ; No remote IP address
mov edx, 0 ; No remote port
mov ecx, 21 ; ftp command port id
mov edi, 0 ; passive open
int 0x40
mov [CmdSocket], eax
popa
ret
;***************************************************************************
; Function
; connectData
;
; Description
; Opens the data socket
;
; Inputs
; None
;
;***************************************************************************
connectData:
pusha
mov eax, 53 ; Stack Interface
mov ebx, 5 ; Open TCP socket
mov esi, [DataIP] ; remote IP address
mov edx, [DataPort] ; remote port
mov ecx, 20 ; ftp data port id
mov edi, 1 ; active open
int 0x40
mov [DataSocket], eax
popa
ret
;***************************************************************************
; Function
; findCmd
;
; Description
; Scans the command string for a valid command. The command string
; is in the global variable buff.
;
; Returns result in cmdPtr. This will be zero if none found
;
; Inputs
; None
;
;***************************************************************************
findCmd:
; Setup to return 'none' in cmdPtr, if we find no cmd
mov eax, 0
mov [cmdPtr], eax
cld
mov esi, buff
mov edi, CMDList
fc000:
cmp [edi], byte 0 ; Are we at the end of the CMDList?
je fc_exit
fc000a:
cmpsb
je fc_nextbyte
; Command is different - move to the next entry in cmd table
mov esi, buff
fc001:
; skip to the next command in the list
cmp [edi], byte 0
je fc002
inc edi
jmp fc001
fc002:
add edi, 5
jmp fc000
fc_nextbyte:
; Have we reached the end of the CMD text?
cmp [edi], byte 0
je fc_got ; Yes - so we have a match
jmp fc000a ; No - loop back
fc_got:
; Copy the function pointer for the selected command
inc edi
mov eax, [edi]
mov [cmdPtr], eax
fc_exit:
ret
;***************************************************************************
; Function
; decStr2Byte
;
; Description
; Converts the decimal string pointed to by esi to a byte
;
; Inputs
; string ptr in esi
;
; Outputs
; esi points to next character not in string
; eax holds result ( 0..255)
;
;***************************************************************************
decStr2Byte:
xor eax, eax
xor ebx, ebx
mov ecx, 3
dsb001:
mov bl, [esi]
cmp bl, '0'
jb dsb_exit
cmp bl, '9'
ja dsb_exit
imul eax, 10
add eax, ebx
sub eax, '0'
inc esi
loop dsb001
dsb_exit:
ret
;***************************************************************************
; Function
; parsePortStr
;
; Description
; Converts the parameters of the PORT command, and stores them in the
; appropriate variables.
;
; Inputs
; None ( string in global variable buff )
;
; Outputs
; None
;
;***************************************************************************
parsePortStr:
; skip past the PORT text to get the the parameters. The command format
; is
; PORT i,i,i,i,p,p,0x0d,0x0a
; where i and p are decimal byte values, high byte first.
xor eax, eax
mov [DataIP], eax
mov [DataPort], eax
mov esi, buff + 4 ; Start at first space character
pps001:
cmp [esi], byte ' ' ; Look for first non space character
jne pps002
inc esi
jmp pps001
pps002:
call decStr2Byte
add [DataIP], eax
ror dword [DataIP], 8
inc esi
call decStr2Byte
add [DataIP], eax
ror dword [DataIP], 8
inc esi
call decStr2Byte
add [DataIP], eax
ror dword [DataIP], 8
inc esi
call decStr2Byte
add [DataIP], eax
ror dword [DataIP], 8
inc esi
call decStr2Byte
add [DataPort], eax
shl [DataPort], 8
inc esi
call decStr2Byte
add [DataPort], eax
ret
;***************************************************************************
; Function
; sendDir
;
; Description
; Transmits the directory listing over the data connection.
; The data connection is already open.
;
; Inputs
; None
;
; Outputs
; None
;
;***************************************************************************
sendDir:
; Clear the file system access working area
mov edi, text + 0x1300 + 0x4000
mov eax, 0
mov ecx, 512
cld
rep stosb
mov [readblock], eax
mov [fileinfoblock], eax ; read cmd
; Copy across the directory filename '/RD/'
; into the fileinfoblock
mov eax, [dirpath]
mov [fname], eax
mov eax, [dirpath+4]
mov [fname+4], eax
sd001:
; Read the next 512 bytes of the FAT
mov eax,[readblock]
mov [fileinfoblock+4],eax
mov eax,58
mov ebx,fileinfoblock
int 0x40
inc dword [readblock] ; Prepare for next block read
; Do we have a valid FAT block?
cmp eax, 0
jne sd_exit
; Parse this FAT block. There could be up to 16 files specified
mov ecx, 0
sd002:
push ecx
shl ecx, 5 ; Multiply by 32
mov esi, text + 0x1300 + 0x4000
add esi, ecx ; esi now points to first byte of FAT block entry
; OK, lets parse the entry. Ignore deleted files and volume entries
cmp [esi], byte 0xE5
je sd003
mov al, [esi + 11]
and al, 0x08
cmp al, 0
jne sd003
; Valid file or directory. Start to compose the string we will send
mov edi, dirStr
; If we have been called as a result of an NLST command, we only display
; the filename
cmp [buff], byte 'N'
je sd006
mov [edi], byte '-'
mov al, [esi + 11]
and al, 0x10
cmp al, 0
je sd004
mov [edi], byte 'd'
sd004:
; Ok, now copy across the directory listing text that will be constant
; ( I dont bother looking at the read only or archive bits )
mov ebx, tmplStr
sd004a:
inc edi
mov al, [ebx]
cmp al, 0
je sd005
mov [edi], al
inc ebx
jmp sd004a
sd005:
; point to the last character of the string;
; We will write the file size here, backwards
push edi ; Remember where the string ends
dec edi
; eax holds the number
mov eax, [esi+28]
mov ebx,10
sd005a:
xor edx,edx
div ebx
add dl,48
mov [edi],dl
dec edi
cmp eax, 0
jne sd005a
pop edi
; now create the time & date fields
; Copy across fixed date & time, since menuet doesn't use them.
mov ebx, timeStr
sd005b:
mov al, [ebx]
cmp al, 0
je sd006
mov [edi], al
inc edi
inc ebx
jmp sd005b
sd006:
;** End of copying
; now copy the filename across
; File name starts at [esi]
; Place to write filename is [edi]
; We must convert filename + extension to nicely formated 8.3 style
; In the source, unused characters have 0x20 in them.
; If the extension starts with 0x20, do not put a '.ext' in at all
mov ecx, 8
lp:
mov al, [esi]
cmp al, 0x20
je nextf
mov [edi], al
inc edi
nextf:
inc esi
loop lp
cmp [esi], byte 0x20 ; Is there an extension?
je terminate
mov al, '.'
mov [edi], al
inc edi
mov ecx, 3
lp2:
mov al, [esi]
cmp al, 0x20
je terminate
mov [edi], al
inc edi
inc esi
loop lp2
terminate:
; Now terminate the line by putting CRLF sequence in
mov al, 0x0d
mov [edi], al
inc edi
mov al, 0x0a
mov [edi], al
inc edi
; Send the completed line to the user over data socket
mov esi, dirStr
mov edx, edi
sub edx, esi
call outputDataStr
sd003: ; Move to next entry in the block
pop ecx
inc ecx
cmp ecx, 16
jne sd002
jmp sd001
sd_exit:
ret
;***************************************************************************
; Function
; setupFilePath
;
; Description
; Copies the file name from the input request string into the
; file descriptor
;
; Inputs
; None
;
; Outputs
; None
;
;***************************************************************************
setupFilePath:
mov esi, buff + 4 ; Point to (1 before) first character of file
; Skip any trailing spaces or / character
sfp001:
inc esi
cmp [esi], byte ' '
je sfp001
cmp [esi], byte '/'
je sfp001
; esi points to start of filename.
; Copy across the directory path '/'
; into the fileinfoblock
mov edi, fname
mov [edi], byte '/'
inc edi
mov [edi], byte 'R'
inc edi
mov [edi], byte 'D'
inc edi
mov [edi], byte '/'
inc edi
mov [edi], byte '1'
inc edi
mov [edi], byte '/'
inc edi
; Copy across the filename
sfp002:
cld
movsb
cmp [esi], byte 0x0d
jne sfp002
mov [edi], byte 0
ret
;***************************************************************************
; Function
; sendFile
;
; Description
; Transmits the requested file over the open data socket
; The file to send is named in the buff string
;
; Inputs
; None
;
; Outputs
; None
;
;***************************************************************************
sendFile:
call setupFilePath
; init fileblock descriptor, for file read
xor eax, eax
mov [readblock], eax
mov [fileinfoblock], eax ; read cmd
mov [fileinfoblock+4], eax ; first block
; now read the file..
mov eax,58
mov ebx,fileinfoblock
int 0x40
; copy across the filesize..
mov [fsize], ebx
sf002a:
mov edx, 512 ; assume we are sending a sector
; do we have less than 512 bytes to send?
cmp [fsize], dword 512
ja sf003
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -