;
;
;
;
include '%fasminc%/win32ax.inc'

;-------------------------------------------------------------------

	struct CHARFORMAT
	       .cbSize		dd ?
	       .dwMask		dd ?
	       .dwEffects	dd ?
	       .yHeight 	dd ?
	       .yOffset 	dd ?
	       .crTextColor	dd ?
	       .bCharSet	db ?
	       .bPitchAndFamily db ?
	       .szFaceName	rb 32
	       ._wPad2		dw ?
	ends


	WsaData 		WSADATA
	Saddr			sockaddr_in
	Saddr_Size	=	$ - Saddr
	InitCommonCtlX		INITCOMMONCONTROLSEX
	CharFormat		CHARFORMAT
	EM_SETCHARFORMAT	= WM_USER + 68
	SCF_SELECTION		= 0001h
	CFM_COLOR		= 40000000h
	WM_SOCK 		= WM_USER + 100

	Sock_Idle		= 0
	Sock_Listen		= 1
	Sock_Server		= 2					; Listen Accepted
	Sock_Client		= 3

.data
	_Title		db	'Title',00
	_Sample_Url	rb	100					; Url To Connect
	_Wsa_Int_Err	db	'Error Iniatilizing WinSocket',13,10,00
	_Bad_Socket	db	'Error Iniatilizing Socket',13,10,00
	_Bad_Url	db	'Bad URL or IP Address',13,10,00
	_Bad_Host	db	'Fist fill Host name, then click me!',13,10,00
	_Invalid_Url	db	'Invalud Url/IP Address!',13,10,00
	_Connect_Err	db	'No responce from selected port',13,10,00
	_Connected	db	'Connected .....',13,10,00
	_Disconnect	db	'Disconnecting .....',13,10,00
	_Port_Err	db	'Missing port, using port 80 as default',13,10,00
	_Bad_LPort	db	'Fill Listen Port .....',13,10,00
	_Accepted	db	'Accepted Incomming .....',13,10,00
	_Port_Err_Size	=	$ - _Port_Err
	_Riched 	db	'RICHED32.DLL',00			; Load Riched32.Dll
	_Host_Addr	rb	600					; Url/IP Addr
	_Url_Size	dd	00					; Size Of Url/IP Addr
	_Connect_Flag	dw	00					; Connected Or Not
	_Listen_Flag	dw	00					; Listning Or Not
	_Port_No	dd	00					; Port For Connection
	_LPort_No	dd	00					; Listen Port
	Mhwnd		dd	00					; Module Handler
	hSock		dd	00					; Sock Handler
	My_Version	=	0101h					; WSock Version
	_Disconnect_Btn db	'&Disconnect',00
	_Connect_Btn	db	'&Connect',00
	_Listen_Btn	db	'&Listen',00
	_Stop_Btn	db	'&Stop',00
	_Recv_Buffer	rb	1000
	_Recv_Size	=	$ - _Recv_Buffer
	_Send_Buffer	rb	1000
	_Send_Size	=	$ - _Send_Buffer
	Status		dw	00


;---------------------------------------------------------------------
.code
	Start:
		Mov	[InitCommonCtlX.dwSize],sizeof.INITCOMMONCONTROLSEX
		Mov	[InitCommonCtlX.dwICC],ICC_INTERNET_CLASSES
		invoke	InitCommonControlsEx,InitCommonCtlX
		invoke	GetModuleHandle,0
		Mov	[Mhwnd],eax
		invoke	LoadLibrary,_Riched
		Or	Eax,Eax
		Jz	Exit
		invoke	WSAStartup,My_Version,WsaData
		Cmp	eax,00
		Jnz	Wsa_Err
	Wsock_Ok:
		invoke	DialogBoxParam,[Mhwnd],IDR_DIALOG,00,Dialog_Proc,00
		invoke	WSACleanup
		Jmp	Exit
	Wsa_Err:
		Mov	Esi,_Wsa_Int_Err
		Call	Write_Richedit
	Exit:
		invoke	ExitProcess,00



proc	Dialog_Proc,dHwnd,dMsg,dWparam,dLparam
		Push	Ebx Esi Edi
		Cmp	[dMsg],WM_COMMAND
		Je	Wm_Command
		Cmp	[dMsg],WM_CLOSE
		Je	Wm_Close
		Cmp	[dMsg],WM_SOCK
		Je	Wm_Sock_
		Cmp	[dMsg],WM_INITDIALOG
		Je	Wm_Init_
		Jmp	Finish_Dialog

	Wm_Init_:
		Mov	[Status],Sock_Idle
		Jmp	Finish_Dialog

	Wm_Command:
		Cmp	[dWparam],ID_CONNECT
		Je	wmConnect_
		Cmp	[dWparam],ID_LISTEN
		Je	wmListen_
		Cmp	[dWparam],ID_SEND
		Je	Wm_Send_
		Cmp	[dWparam],ID_CANCEL
		Je	wmCancel_
;                Cmp     [dWparam],ID_GETHOSTBYNAME
;                Je      _Convert_TO_IP
		Jmp	Finish_Dialog

	wmConnect_:
		Cmp	[_Connect_Flag],01			; already connected
		Je	_DisConnected				; yes, disconnect it else
		invoke	GetDlgItemText,[dHwnd],ID_HOSTNAME,_Host_Addr,500	; try to connect
		Or	Eax,Eax
		Jnz	Check_Host_Port
		invoke	MessageBox,00,_Bad_Host,_Title,MB_OK
		Jmp	Finish_Dialog
	Check_Host_Port:
		Mov	[_Url_Size],Eax
		invoke	GetDlgItemInt,[dHwnd],ID_PORT,_Port_No,04
		Or	Eax,Eax
		Jnz	_Connect
		Mov	Esi,_Port_Err
		Call	Write_Richedit
		Mov	Eax,80
	_Connect:
		Mov	[_Port_No],Eax
;                invoke  CharLower,_Host_Addr                            ; LowerCase Url
		invoke	inet_addr,_Host_Addr				; Check For IP Addr
		Cmp	Eax,-1h 					; If, No
		Je	_Check_By_Name					; Assume URL NAME
		Or	Eax,Eax
		Je	_Check_By_Name
		Jmp	_Host_Process					; If, Yes, Process
	_Check_By_Name:
		invoke	GetDlgItemText,[dHwnd],ID_HOSTNAME,_Host_Addr,500
		invoke	gethostbyname,_Host_Addr			; Check URL NAME
		Or	Eax,Eax 					; If,Not
		Jnz	_Host_Process					; Then It Is Neith IP
		Mov	Esi,_Invalid_Url				; Nor URL NAME
		Call	Write_Richedit					; QUIT
		Jmp	Finish_Dialog

	_Host_Process:
		Mov	[Saddr.sin_addr],Eax				; Save IP/URL
		Mov	Ax,Word Ptr _Port_No				; Get Port
		Xchg	Ah,Al
		Mov	[Saddr.sin_port],Ax				; & Save
		Mov	[Saddr.sin_family],AF_INET			; Save Socket Family

		invoke	socket,AF_INET,SOCK_STREAM,06		      ; Initalize Socket
		Mov	[hSock],Eax
		invoke	connect,[hSock],Saddr,Saddr_Size
		Or	Eax,Eax
		Jnz	connect_err
		Mov	[_Connect_Flag],01
		invoke	SetDlgItemText,[dHwnd],ID_CONNECT,_Disconnect_Btn
		Mov	Esi,_Connected
		Call	Write_Richedit
		invoke	GetDlgItem,[dHwnd],ID_SEND
		invoke	EnableWindow,Eax,TRUE
		invoke	GetDlgItem,[dHwnd],ID_LISTEN
		invoke	EnableWindow,Eax,FALSE

		invoke	WSAAsyncSelect,[hSock],[dHwnd],WM_SOCK,FD_READ or FD_CLOSE
		Jmp	Finish_Dialog

	connect_err:
		Mov	Esi,_Connect_Err
		Call	Write_Richedit
		Jmp	Finish_Dialog

	_DisConnected:
		Mov	Esi,_Disconnect
		Call	Write_Richedit
		invoke	SetDlgItemText,[dHwnd],ID_CONNECT,_Connect_Btn
		invoke	SetDlgItemText,[dHwnd],ID_LISTEN,_Listen_Btn
		invoke	closesocket,[hSock]
		Mov	[_Connect_Flag],00
		invoke	GetDlgItem,[dHwnd],ID_SEND
		invoke	EnableWindow,Eax,FALSE
		invoke	GetDlgItem,[dHwnd],ID_CONNECT
		invoke	EnableWindow,Eax,TRUE
		invoke	GetDlgItem,[dHwnd],ID_LISTEN
		invoke	EnableWindow,Eax,TRUE
		Jmp	Finish_Dialog

	wmListen_:
		Cmp	[_Listen_Flag],01			 ; Already Listning
		Je	.Stop_Listen				 ; Yes, Stop It
		Cmp	[_Connect_Flag],01			 ; If Connected
		Je	Finish_Dialog				 ; Skip
		invoke	socket,AF_INET,SOCK_STREAM,00
		Cmp	Eax,-1
		Je	Finish_Dialog
		Mov	[hSock],Eax
		Mov	[Saddr.sin_addr],00
		Mov	[Saddr.sin_family],AF_INET
		invoke	GetDlgItemInt,[dHwnd],ID_SERVPORT,_LPort_No,04
		Cmp	[_LPort_No],00
		Je	Finish_Dialog
		Cmp	Eax,0FFFFh
		Je	Finish_Dialog
		Xchg	Ah,Al
		Mov	[Saddr.sin_port],Ax
		invoke	bind,[hSock],Saddr,Saddr_Size
		Or	Eax,Eax
		Jnz	.Bind_Failed
		invoke	listen,[hSock],01
		invoke	WSAAsyncSelect,[hSock],[dHwnd],WM_SOCK,FD_ACCEPT
		Mov	[Status],Sock_Listen
		invoke	SetDlgItemText,[dHwnd],ID_LISTEN,_Stop_Btn
		invoke	GetDlgItem,[dHwnd],ID_CONNECT
		invoke	EnableWindow,Eax,FALSE
		Mov	[_Listen_Flag],01
		Jmp	Finish_Dialog

	.Bind_Failed:
		invoke	closesocket,[hSock]
		Jmp	Finish_Dialog
	.Stop_Listen:
		Mov	[_Listen_Flag],00				; Stop Listning
		Jmp	_DisConnected

	Wm_Send_:
		invoke	GetDlgItemText,[dHwnd],ID_COMMAND,_Send_Buffer,_Send_Size
		Or	Eax,Eax
		Jz	_Send_
		Mov	[_Send_Buffer+Eax],13
		Inc	Eax
		Mov	[_Send_Buffer+Eax],10
		Inc	Eax
		Mov	[_Send_Buffer+Eax],00
		Inc	Eax
		invoke	send,[hSock],_Send_Buffer,Eax,00
		Mov	Esi,_Send_Size
		Mov	Esi,_Send_Buffer
		Call	Write_Richedit
	_Send_:
		Jmp	Finish_Dialog

	_Convert_TO_IP:
		invoke	GetDlgItemText,[dHwnd],ID_HOSTNAME,_Host_Addr,500
		invoke	gethostbyname,_Host_Addr
		or	eax,eax
		jz	.bad_name
		virtual at eax
		.host	hostent
		end	virtual
		mov	eax,[.host.h_addr_list]
		mov	eax,[eax]
		mov	eax,[eax]
		bswap	eax
		invoke	SendDlgItemMessage,[dHwnd],ID_IPADDR,IPM_SETADDRESS,0,Eax
		invoke	SendDlgItemMessage,[dHwnd],ID_HOSTNAME,CB_ADDSTRING,0,_Host_Addr
		invoke	GetDlgItem,[dHwnd],ID_PORT
		invoke	SendMessage,[dHwnd],WM_NEXTDLGCTL,eax,TRUE
	.bad_name:
		Jmp	Finish_Dialog


	Write_Richedit:
;                mov     [CharFormat.cbSize],sizeof.CHARFORMAT           ; Color
;                mov     [CharFormat.dwMask],CFM_COLOR                   ; & Effects
;                mov     [CharFormat.dwEffects],0                        ; & Size
;                mov     [CharFormat.crTextColor],Eax                    ; For RichText Edit

		invoke	GetDlgItem,[dHwnd],ID_STATUS			; Get Handler
		Mov	Ebx,Eax 					; Ebx=Handler
		invoke	SendMessage,ebx,EM_SCROLLCARET,0,0		; Scroll Down
		invoke	SendMessage,Ebx,EM_REPLACESEL,FALSE,Esi 	; Print
		Ret


	Wm_Sock_:
		Cmp	[Status],Sock_Listen
		Je	.accept
		invoke	recv,[hSock],_Recv_Buffer,_Recv_Size,00
		Or	Eax,Eax
		Je	.disconnected
		Cmp	Eax,-1
		Je	.no_response
		Mov	Esi,_Recv_Buffer
		Call	Write_Richedit
	.no_response:
		Jmp	Finish_Dialog
	.disconnected:
		Mov	[Status],Sock_Idle				; Status = 00
		Jmp	_DisConnected
	.accept:
		invoke	accept,[hSock],0,0
		Cmp	Eax,-1
		Je	Finish_Dialog
		Xchg	Eax,[hSock]
		invoke	closesocket,Eax
		Mov	Esi,_Accepted
		Call	Write_Richedit
		Mov	[Status],Sock_Server				; We are connected
		invoke	WSAAsyncSelect,[hSock],[dHwnd],WM_SOCK,FD_READ or FD_CLOSE
		invoke	GetDlgItem,[dHwnd],ID_SEND
		invoke	EnableWindow,Eax,TRUE
		invoke	GetDlgItem,[dHwnd],ID_CONNECT
		invoke	EnableWindow,Eax,FALSE
		Jmp	Finish_Dialog

	wmCancel_:
	Wm_Close:
		invoke	EndDialog,[dHwnd],00
		invoke	closesocket,[hSock]
	Finish_Dialog:
		Pop	Edi Esi Ebx
		return
endp

.end Start
;---------------------------------------------------------------------
	IDR_DIALOG		=	140			; Resource Dialog
	ID_HOSTNAME		=	150			; Host_Name EditBox
	ID_PORT 		=	151			; Client Port EditBox
	ID_CONNECT		=	152			; Client Connection Button
	ID_SERVPORT		=	153			; Server Port EditBox
	ID_LISTEN		=	154			; Server Connection Button
	ID_COMMAND		=	155			; Send Message EditBox
	ID_SEND 		=	156			; Send Message Button
	ID_CANCEL		=	157			; Exit
	ID_STATUS		=	158			; View Received Msgs + Status
	ID_IPADDR		=	159			; IP Addr
	ID_GETHOSTBYNAME	=	160			; > Button


.resource
	directory RT_DIALOG,dialogs

	resource dialogs,\
		 IDR_DIALOG,LANG_ENGLISH+SUBLANG_DEFAULT,main_dialog

	dialog	main_dialog,'Dialog',70,70,332,176,WS_CAPTION+WS_POPUP+WS_SYSMENU+WS_MINIMIZEBOX+DS_MODALFRAME
		dialogitem 'STATIC','&Host name:',-1,4,26,148,8,WS_VISIBLE
		dialogitem 'EDIT','',ID_HOSTNAME,4,36,148,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_AUTOHSCROLL
		dialogitem 'STATIC','&Port:',-1,256,26,20,8,WS_VISIBLE
		dialogitem 'EDIT','',ID_PORT,256,36,24,12,WS_VISIBLE+WS_BORDER+ES_NUMBER+WS_TABSTOP
		dialogitem 'BUTTON','&Connect',ID_CONNECT,284,36,44,12,WS_VISIBLE+BS_PUSHBUTTON+WS_TABSTOP
		dialogitem 'STATIC','&Port:',-1,256,2,20,8,WS_VISIBLE
;                dialogitem 'BUTTON','>',ID_GETHOSTBYNAME,156,36,20,12,WS_VISIBLE+BS_PUSHBUTTON+WS_TABSTOP
;                dialogitem 'SysIPAddress32','',ID_IPADDR,180,36,72,12,WS_VISIBLE+BS_PUSHBUTTON+WS_TABSTOP
		dialogitem 'EDIT','',ID_SERVPORT,256,12,24,12,WS_VISIBLE+WS_BORDER+ES_NUMBER+WS_TABSTOP
		dialogitem 'BUTTON','&Listen',ID_LISTEN,284,12,44,12,WS_VISIBLE+BS_PUSHBUTTON+WS_TABSTOP
		dialogitem 'RichEdit','',ID_STATUS,4,52,324,104,WS_VISIBLE+WS_BORDER+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE+ES_READONLY+WS_TABSTOP
		dialogitem 'EDIT','',ID_COMMAND,4,160,228,12,WS_VISIBLE+WS_BORDER+ES_AUTOHSCROLL+WS_TABSTOP
		dialogitem 'BUTTON','&Send',ID_SEND,236,160,44,12,WS_VISIBLE+WS_DISABLED+BS_PUSHBUTTON+WS_TABSTOP
		dialogitem 'BUTTON','E&xit',ID_CANCEL,284,160,44,12,WS_VISIBLE+BS_PUSHBUTTON+WS_TABSTOP
		dialogitem 'STATIC','Made By: Mr.Janib Soomro (The One)',-1,04,4,120,8,WS_VISIBLE
		dialogitem 'STATIC','Mini_Chat, Freeware Version',-1,14,14,100,8,WS_VISIBLE

	enddialog