📄 http.asm
字号:
invoke String2Dword,addr PortString
mov HTTPPort,eax
.else
mov al,byte ptr [edi]
mov byte ptr [esi],al
inc edi
inc esi
inc ecx
.endif
.endw
.if ecx==URLLength ; if there's no relative URL , we must add "/" to it.
mov byte ptr [RelativeURL],"/"
.endif
ret
ParseURL endp
;==========================================================================
; GetFileName
;==========================================================================
; This function searches the url string for the last "/" character. If "/"
; is found, it's assumed that the file name follows "/" character.
;--------------------------------------------------------------------------
GetFileName proc URL:DWORD
invoke RtlFillMemory,addr FileName,256,0
invoke lstrlen,URL
std ; We will search for "/" in reverse direction
mov edi,URL
add edi,eax
dec edi
mov ecx,eax
mov al,"/"
repne scasb
cld
jne No_name
cmp byte ptr [edi],"/"
je No_name
inc edi
inc edi
invoke lstrcpy,addr FileName,edi
No_name:
ret
GetFileName endp
;=====================================================================
; ShowProgress
;=====================================================================
; This procedure updates the progress bar and displays the number
; of bytes downloaded so far on the status bar
;=====================================================================
ShowProgress proc uses ebx edx hWnd:DWORD
LOCAL temp[100]:BYTE
.if ContentLength!=0
xor edx,edx
mov eax,CurrentDataSize
mov ebx,1000
mul ebx
mov ebx,ContentLength
div ebx
invoke SendDlgItemMessage,hWnd,IDC_PROGRESS,PBM_SETPOS,eax,NULL
.endif
push CurrentDataSize
push offset Downloading
lea eax,temp
push eax
call wsprintfA
add esp,12
invoke SetStatusText,addr temp,NULL
ret
ShowProgress endp
;====================================================================
; TranslateErrorCode
;====================================================================
; This function takes the error code and an address of a buffer and
; looks up the error string in the string resource.
;====================================================================
TranslateErrorCode proc ErrCode:DWORD, pErrString:DWORD
invoke LoadString,hInstance,ErrCode,pErrString,512
.if eax==0
invoke LoadString,hInstance,1,pErrString,512
.endif
ret
TranslateErrorCode endp
;====================================================================
; GetErrorString
;====================================================================
; This function calls WSAGetLastError to retrieve the error code of
; the last socket operation and looks up the error string in
; the string resource.
;====================================================================
GetErrorString proc pErrString:DWORD
invoke WSAGetLastError
push eax
invoke TranslateErrorCode,eax,pErrString
pop eax
ret
GetErrorString endp
;====================================================================
; CloseSock
;====================================================================
; This function performs winsock library shutdown. It closes socket,
; output file, kills timer,and calls WSACleanup. It also clears the
; status bar and resets the progress bar control.
;====================================================================
CloseSock proc
.if sock!=0
invoke closesocket,sock
mov sock,0
.endif
.if FileHandle!=0
invoke CloseHandle,FileHandle
.endif
.if TimerID!=0
invoke KillTimer,hwnd,TimerID
invoke ClearMessages,hwnd,WM_SOCKET
invoke ClearMessages,hwndStatus,SB_SETTEXT
invoke SendMessage,hwndStatus,SB_SETTEXT,1,NULL
.endif
invoke SendDlgItemMessage,hwnd,IDC_PROGRESS,PBM_SETPOS,0,0
invoke SetWindowText,hwndStatus,NULL
invoke SetDlgItemText,hwnd,IDC_NAME,NULL
ret
CloseSock endp
SetStatusText PROC Text:DWORD, Text1:DWORD
push Text1
push Text
push offset ErrorString
call wsprintfA
add esp,12
invoke SetWindowText,hwndStatus,addr ErrorString
ret
SetStatusText ENDP
EnableControls PROC
invoke EnableWindow,hwndConnectButton,TRUE
invoke EnableMenuItem,hMenu,IDM_CONNECT,MF_ENABLED
ret
EnableControls ENDP
DisableControls PROC
invoke EnableWindow,hwndConnectButton,FALSE
invoke EnableMenuItem,hMenu,IDM_CONNECT,MF_GRAYED
ret
DisableControls ENDP
ConnectSocket PROC
invoke DisableControls
mov sock,0 ; We use the value of sock to check if the socket is closed so we must initialize it to 0
; which means "closed or not created yet"
invoke ParseURL,addr URLString ; Parse the URL into host name, relative url and the http port
invoke lstrlen,addr URLString
.if eax>40
invoke lstrcpyn,addr CommandString,addr URLString,20
invoke lstrcat,addr CommandString,addr Dots
invoke lstrlen,addr URLString
sub eax,20
push edi
mov edi,offset URLString
add edi,eax
invoke lstrcat,addr CommandString,edi
pop edi
.else
invoke lstrcpy,addr CommandString,addr URLString
.endif
invoke SetDlgItemText,hwnd,IDC_NAME,\
addr CommandString
invoke socket,PF_INET,SOCK_STREAM,0 ; Create a stream socket
.if eax!=INVALID_SOCKET
mov sock,eax
.if Resuming==FALSE
invoke SetStatusText,addr ResolvingServer,addr HostName
invoke inet_addr,addr HostName ; Assume that the host name is not an ip address. If the host name is really an ip address,
; the function will fail with eax==INADDR_NONE
.if eax==INADDR_NONE
invoke gethostbyname,addr HostName ; Use this function to get the host ip address from host name.
.if eax==NULL
invoke ShowErrorMessage
ret
.endif
mov eax,[eax+12]
mov eax,[eax]
mov eax,[eax]
mov SocketAddress.sin_addr,eax
.else
mov SocketAddress.sin_addr,eax
.endif
mov SocketAddress.sin_family,AF_INET
.endif
invoke htons,HTTPPort ; We must convert host byte order to network byte order
mov SocketAddress.sin_port,ax
invoke WSAAsyncSelect,sock,hwnd,WM_SOCKET,\ ; We choose to receive notification about successful connection,
FD_CONNECT or FD_READ or FD_CLOSE ; incoming data, and when the socket is closed
.if eax==NULL
invoke SetStatusText,addr Connecting,addr HostName
invoke connect,sock,addr SocketAddress,sizeof SocketAddress ; Make a connection with the remote host
; Since we operate in non-blocking mode, we wait for the window socket to call us when
; the events we are interested in occur.
.if eax==SOCKET_ERROR
invoke WSAGetLastError
.if eax!=WSAEWOULDBLOCK
invoke ShowErrorMessage
.endif
.endif
.else
invoke ShowErrorMessage
.endif
.else
invoke SetWindowText,hwndStatus,NULL
invoke ShowErrorMessage
.endif
ret
ConnectSocket ENDP
ShowErrorMessage PROC
invoke GetErrorString,addr ErrorString
invoke MessageBox,hwnd,addr ErrorString,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
ret
ShowErrorMessage ENDP
WriteOutputFile PROC buffer1:DWORD, BytesToWrite:DWORD
.if ContentLength!=0
mov eax,BytesToWrite
add eax,CurrentDataSize
.if eax>ContentLength
mov eax,ContentLength
sub eax,CurrentDataSize
mov BytesToWrite,eax
.endif
.endif
invoke WriteFile,FileHandle,buffer1,\
BytesToWrite,\
addr BytesWritten,NULL
push eax
.if eax==TRUE
mov eax,BytesWritten
add CurrentDataSize,eax
add ActualDataRead,eax
invoke ShowProgress,hwnd
.else
invoke MessageBox,hwnd,addr WriteError,addr AppName,MB_OK+MB_ICONERROR
invoke SetDlgItemText,hwnd,IDC_NAME,NULL
invoke SetWindowText,hwndStatus,NULL
.endif
pop eax
ret
WriteOutputFile endp
;=====================================================================
; StrLen
;=====================================================================
; This procedure takes an address of a string as its parameter and
; returns the length of the string in eax
;=====================================================================
StrLen PROC uses edi String:DWORD
mov edi,String
mov al,0
mov ecx,0FFFFFFFFh
repne scasb
sub ecx,0FFFFFFFFh
neg ecx
dec ecx
mov eax,ecx
ret
StrLen ENDP
;=====================================================================
; StrCpy
;=====================================================================
; This procedure copies a string into a buffer. If the buffer is smaller
; than the string to copy, it returns 0.
;=====================================================================
StrCpy PROC uses edi esi StrBuffer:DWORD,String:DWORD
invoke StrLen,String
mov ecx,eax
mov edi,StrBuffer
mov esi,String
rep movsb
ret
StrCpy ENDP
;=========================================================================
; InString
;=========================================================================
; Search for a substring in one string. Case Sensitive
; Return Value: -1 if substring not found, offset of the first byte
; of the substring if successful
;=========================================================================
InString PROC uses ebx edi esi StrMain:DWORD, StrSub:DWORD
invoke StrLen,StrMain
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -