.386
.model flat,stdcall
option casemap:none
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
Cut PROTO :DWORD,:DWORD,:DWORD,:BYTE
StrLen PROTO :DWORD
StrCmp PROTO :DWORD,:DWORD
StrCpy PROTO :DWORD,:DWORD
StrCat PROTO :DWORD,:DWORD
Ext PROTO
Resuming PROTO
FillList PROTO :DWORD,:DWORD
RemoveHex PROTO :DWORD,:DWORD
InsertHex PROTO :DWORD,:DWORD
FromHex PROTO :BYTE
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include shell32.inc
includelib shell32.lib
include wsock32.inc
includelib wsock32.lib
include advapi32.inc
includelib advapi32.lib
.data
ClassName db "DLGCLASS",0
DlgName db "Form1",0
IcoName db "i",0
DefPath db "C:",0
DefName db "index.htm",0
Star db "*.*",0
DTitle db "Select base webpage directory:",0
Get db "GET",0
Content db "Content Type",0
Msg200 db "HTTP/1.1 200 OK",13,10
db "Expires: 0",13,10
db "Last-Modified: 0",13,10
db "Accept-Range: bytes",13,10
db "Content-Type: %s",13,10
db "Content-Length: %lu",13,10,13,10,0
Msg206 db "HTTP/1.1 206 Partial Content",13,10
db "Expires: 0",13,10
db "Last-Modified: 0",13,10
db "Accept-Range: bytes",13,10
db "Content-Type: %s",13,10
db "Content-Range: bytes=%lu-%lu/%lu",13,10
db "Content-Length: %lu",13,10,13,10,0
Msg404 db "HTTP/1.1 404 Not Found",13,10
db "Expires: 0",13,10
db "Last-Modified: 0",13,10
db "Accept-Range: bytes",13,10
db "Content-Type: text/html",13,10
db "Content-Length: 124",13,10,13,10
db "404 errorError 404: Page not found
",13,10
db "The URL does not exist. Check the link and your spelling.",0
Redir db "HTTP/1.1 301 Moved Permanently",13,10
db "Location: %s",13,10,0
Range db "range: bytes",0
Str0 db "Directory of ",0
Str1 db "",13,10,0
Str2 db "File:
",13,10,13,10,0
Str3 db 13,10,"
Directory:
",13,10,13,10,0
Str4 db "",13,10,0
HTML db "text/html",0
Type0 db "text/plain",0
hFile dd 0
hSock1 dd 0
hReg dd 0
pType dd 0
bi BROWSEINFO <0,0,0,offset DTitle,BIF_RETURNONLYFSDIRS,0,0,0>
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
Count dd ?
Exist dd ?
FSize dd ?
FOffset dd ?
RFlag dd ?
hDlg dd ? ;Handles
hFind dd ?
hMem dd ?
pMem dd ?
BufSize dd ?
NotUsed dd ?
RSBuf db 1024 dup(?) ;String buffers
Buf1 db 1024 dup(?)
Buf2 db 1024 dup(?)
Buf3 db 1024 dup(?)
Buf4 db 1024 dup(?)
Path db 512 dup(?)
wsadata WSADATA <> ;WinSock
SA sockaddr_in <>
fd WIN32_FIND_DATA <>
.const
WM_SOCKET equ WM_USER+256
.code
program:
INVOKE GetModuleHandle,0
mov hInstance,eax
INVOKE GetCommandLine
mov CommandLine,eax
INVOKE WinMain,hInstance,0,CommandLine,SW_SHOWDEFAULT
INVOKE ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,0
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszClassName,OFFSET ClassName
mov wc.lpszMenuName,0
INVOKE LoadIcon,hInstance,offset IcoName
mov wc.hIcon,eax
mov wc.hIconSm,eax
INVOKE LoadCursor,0,IDC_ARROW
mov wc.hCursor,eax
INVOKE WSAStartup,101h,offset wsadata ;Use WinSock v1.1
INVOKE RegisterClassEx,addr wc ;Make Dialog box.
INVOKE CreateDialogParam,hInstance,offset DlgName,0,0,0
mov hDlg,eax
INVOKE ShowWindow,hDlg,SW_SHOWNORMAL
INVOKE UpdateWindow,hDlg
.WHILE TRUE ;Main window loop
INVOKE GetMessage,addr msg,0,0,0
.BREAK .IF (!eax)
INVOKE TranslateMessage,addr msg
INVOKE DispatchMessage,addr msg
.ENDW
INVOKE WSACleanup ;Done with WinSock
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.IF uMsg==WM_DESTROY
INVOKE closesocket,hSock1
INVOKE PostQuitMessage,0
.ELSEIF uMsg==WM_SHOWWINDOW
INVOKE SendDlgItemMessage,hWnd,1000,WM_SETTEXT,0,offset DefPath
INVOKE gethostname,offset Buf1,1024 ;Get name
INVOKE SendDlgItemMessage,hWnd,1004,WM_SETTEXT,0,offset Buf1
INVOKE gethostbyname,addr Buf1
mov eax,[eax+12]
mov eax,[eax] ;Get IP address
mov eax,[eax]
INVOKE inet_ntoa,eax
INVOKE SendDlgItemMessage,hWnd,1005,WM_SETTEXT,0,eax
INVOKE socket,PF_INET,SOCK_STREAM,IPPROTO_TCP
mov hSock1,eax ;Configure listening socket
mov SA.sin_family,AF_INET
mov SA.sin_addr.S_un.S_addr,INADDR_ANY
INVOKE htons,80
mov SA.sin_port,ax
INVOKE WSAAsyncSelect,hSock1,hWnd,WM_SOCKET,FD_ACCEPT
INVOKE bind,hSock1,offset SA,sizeof SA
INVOKE listen,hSock1,5 ;Listen for connections
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.IF ax==1003
mov Buf4,0 ;Prompt for directory
INVOKE SHBrowseForFolder,addr bi
.IF eax==0
xor eax,eax
ret
.ENDIF ;Turn return value into pathname
INVOKE SHGetPathFromIDList,eax,offset Buf4
.IF Buf4==0
xor eax,eax
ret
.ENDIF
.IF Buf4[3]==0 ;If C:\ change to C:
mov Buf4[2],0
.ENDIF
INVOKE StrLen,offset Buf4
mov ecx,eax
mov al,"\"
mov edi,offset Buf4
@@@5: repnz scasb
jnz @@@6
mov BYTE PTR[edi-1],"/"
jmp @@@5
@@@6: INVOKE SendDlgItemMessage,hWnd,1000,WM_SETTEXT,0,offset Buf4
.ENDIF
.ELSEIF uMsg==WM_SOCKET
mov eax,lParam
and eax,0FFFFh
.IF ax==FD_ACCEPT
INVOKE accept,hSock1,0,0
INVOKE WSAAsyncSelect,eax,hWnd,WM_SOCKET,FD_READ or FD_CLOSE
.ELSEIF ax==FD_READ
INVOKE recv,wParam,offset RSBuf,1024,0
mov al,32
mov ecx,10
lea edi,RSBuf
repnz scasb
dec edi
push edi
mov BYTE PTR[edi],0
INVOKE StrCmp,offset RSBuf,offset Get
.IF eax==1 ;If command other than GET, ignore.
INVOKE closesocket,wParam
xor eax,eax
ret
.ENDIF
pop edi
mov BYTE PTR[edi],32
INVOKE Cut,offset RSBuf,offset Buf2,4,32
INVOKE RemoveHex,offset Buf2,offset Buf1
INVOKE StrLen,offset Buf1
mov ecx,eax
mov edi,offset Buf1 ;Make sure there is no ../
mov al,"."
@@@7: repnz scasb
jnz @@@8
cmp BYTE PTR[edi],"."
jnz @@@7
cmp BYTE PTR[edi+1],"/"
jnz @@@7
jmp Bad
@@@8: mov Exist,0 ;Must determine request type
dec edi
.IF BYTE PTR[edi]=="/" ;Therefore, directory
INVOKE StrCpy,offset Buf1,offset Buf3
INVOKE SendDlgItemMessage,hWnd,1000,WM_GETTEXT,512,offset Path
INVOKE StrCpy,offset Path,offset Buf2
INVOKE StrCat,offset Buf2,offset Buf1
INVOKE SendDlgItemMessage,hDlg,1002,BM_GETCHECK,0,0
.IF eax==0
INVOKE StrCat,offset Buf2,offset DefName
jmp Index
%2