mirror of
https://github.com/Doczom/simple-httpd.git
synced 2025-09-21 22:53:54 +02:00
fix bugs and update sys_func.inc code
fixed size sockaddr struct update function CreateThread clear code in main file
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/modules/test_unit6.obj
Normal file
BIN
bin/modules/test_unit6.obj
Normal file
Binary file not shown.
Binary file not shown.
@@ -5,3 +5,4 @@
|
|||||||
- `test_unit4.asm` - Модуль отправляет в ответе заданную в файле конфигурации строку параметров и uri адрес запроса клиента. Используется chunked передача ответа.
|
- `test_unit4.asm` - Модуль отправляет в ответе заданную в файле конфигурации строку параметров и uri адрес запроса клиента. Используется chunked передача ответа.
|
||||||
- `test_unit5.asm` - Модуль отправляет ответ используя chunked передачу.
|
- `test_unit5.asm` - Модуль отправляет ответ используя chunked передачу.
|
||||||
- `srv_control.asm` - Модуль, позволяющий удалённо выключать сервер.
|
- `srv_control.asm` - Модуль, позволяющий удалённо выключать сервер.
|
||||||
|
- `test_unit6.asm` - Модуль выводящий данные об ipv4 адресе и порте клиента, с которого было установлено соединение с сервером.
|
||||||
|
@@ -4,7 +4,6 @@ public @EXPORT as 'EXPORTS'
|
|||||||
|
|
||||||
NO_DEBUG_INPUT = 0
|
NO_DEBUG_INPUT = 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
|
||||||
include "proc32.inc"
|
include "proc32.inc"
|
||||||
|
|
||||||
include '../module_api.inc'
|
include '../module_api.inc'
|
||||||
|
@@ -4,7 +4,6 @@ public @EXPORT as 'EXPORTS'
|
|||||||
|
|
||||||
NO_DEBUG_INPUT = 0
|
NO_DEBUG_INPUT = 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
|
||||||
include "proc32.inc"
|
include "proc32.inc"
|
||||||
|
|
||||||
include '../module_api.inc'
|
include '../module_api.inc'
|
||||||
@@ -83,6 +82,8 @@ server_entry:
|
|||||||
invoke IMPORT.send_resp, eax,\
|
invoke IMPORT.send_resp, eax,\
|
||||||
[esi + CONNECT_DATA.uri_path],\
|
[esi + CONNECT_DATA.uri_path],\
|
||||||
[esp + 4]
|
[esp + 4]
|
||||||
|
mov eax, [esp]
|
||||||
|
invoke IMPORT.finish_send_resp, eax
|
||||||
invoke IMPORT.destruct_resp ; arg in stack
|
invoke IMPORT.destruct_resp ; arg in stack
|
||||||
add esp, 4
|
add esp, 4
|
||||||
.exit:
|
.exit:
|
||||||
|
@@ -4,7 +4,6 @@ public @EXPORT as 'EXPORTS'
|
|||||||
|
|
||||||
NO_DEBUG_INPUT = 0
|
NO_DEBUG_INPUT = 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
|
||||||
include "proc32.inc"
|
include "proc32.inc"
|
||||||
|
|
||||||
include '../module_api.inc'
|
include '../module_api.inc'
|
||||||
|
113
example/test_unit6.asm
Normal file
113
example/test_unit6.asm
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
; test api 0.1.0 - get cmd path and get context unit
|
||||||
|
format MS COFF ;<- this is lib format
|
||||||
|
public @EXPORT as 'EXPORTS'
|
||||||
|
|
||||||
|
NO_DEBUG_INPUT = 0
|
||||||
|
include "macros.inc"
|
||||||
|
include "proc32.inc"
|
||||||
|
|
||||||
|
include '../module_api.inc'
|
||||||
|
|
||||||
|
section '.flat' code readable align 16
|
||||||
|
|
||||||
|
unit_init:
|
||||||
|
xor eax, eax
|
||||||
|
push esi edi
|
||||||
|
mov esi, [esp + 4*2 + 4]
|
||||||
|
|
||||||
|
cmp dword[esi + IMPORT_DATA.version], API_VERSION
|
||||||
|
jne .exit
|
||||||
|
|
||||||
|
mov edi, IMPORT
|
||||||
|
mov ecx, [esi + IMPORT_DATA.sizeof]
|
||||||
|
shr ecx, 2 ; div 4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
; create unit context
|
||||||
|
mov eax, 1
|
||||||
|
;unit init successful
|
||||||
|
.exit:
|
||||||
|
pop edi esi
|
||||||
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
|
server_entry:
|
||||||
|
push esi ebp
|
||||||
|
mov esi, [esp + 4*2 + 4] ; request context
|
||||||
|
|
||||||
|
mov ebp, esp
|
||||||
|
push dword '</p>'
|
||||||
|
push dword ' '
|
||||||
|
|
||||||
|
mov ecx, 10
|
||||||
|
movzx eax, word[esi + CONNECT_DATA.sockaddr.sin_port]
|
||||||
|
xchg al, ah
|
||||||
|
@@:
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
add dl, '0'
|
||||||
|
mov byte[esp], dl
|
||||||
|
add esp, -1
|
||||||
|
test eax, eax
|
||||||
|
jnz @b
|
||||||
|
|
||||||
|
inc esp
|
||||||
|
push dword 'ort:'
|
||||||
|
push dword ' p'
|
||||||
|
|
||||||
|
mov ecx, 4
|
||||||
|
.loop:
|
||||||
|
movzx eax, byte[esi + CONNECT_DATA.sockaddr.sin_addr + ecx - 1]
|
||||||
|
@@:
|
||||||
|
xor edx, edx
|
||||||
|
div dword[__10]
|
||||||
|
add dl, '0'
|
||||||
|
mov byte[esp], dl
|
||||||
|
add esp, -1
|
||||||
|
test eax, eax
|
||||||
|
jnz @b
|
||||||
|
|
||||||
|
mov byte[esp], '.'
|
||||||
|
add esp, -1
|
||||||
|
dec ecx
|
||||||
|
jnz .loop
|
||||||
|
|
||||||
|
add esp, 2
|
||||||
|
|
||||||
|
push dword 'ip: '
|
||||||
|
push dword '<p> '
|
||||||
|
|
||||||
|
invoke IMPORT.create_resp, esi, 0
|
||||||
|
test eax, eax
|
||||||
|
jz .exit
|
||||||
|
|
||||||
|
mov edx, ebp
|
||||||
|
mov ecx, esp
|
||||||
|
sub edx, esp
|
||||||
|
|
||||||
|
push eax
|
||||||
|
invoke IMPORT.send_resp, eax, ecx, edx
|
||||||
|
invoke IMPORT.destruct_resp
|
||||||
|
mov esp, ebp
|
||||||
|
.exit:
|
||||||
|
pop ebp esi
|
||||||
|
ret 8
|
||||||
|
|
||||||
|
server_close:
|
||||||
|
|
||||||
|
ret 4
|
||||||
|
|
||||||
|
|
||||||
|
section '.data' data readable writable align 16
|
||||||
|
|
||||||
|
__10: dd 10
|
||||||
|
|
||||||
|
|
||||||
|
@EXPORT:
|
||||||
|
export \
|
||||||
|
unit_init, 'httpd_init', \
|
||||||
|
server_entry, 'httpd_serv',\
|
||||||
|
server_close, 'httpd_close'
|
||||||
|
|
||||||
|
|
||||||
|
IMPORT IMPORT_DATA
|
@@ -3,7 +3,6 @@ public @EXPORT as 'EXPORTS'
|
|||||||
|
|
||||||
NO_DEBUG_INPUT = 0
|
NO_DEBUG_INPUT = 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
|
||||||
include "proc32.inc"
|
include "proc32.inc"
|
||||||
|
|
||||||
include '../module_api.inc'
|
include '../module_api.inc'
|
||||||
|
56
httpd.asm
56
httpd.asm
@@ -8,6 +8,9 @@
|
|||||||
; ;
|
; ;
|
||||||
;*****************************************************************************;
|
;*****************************************************************************;
|
||||||
|
|
||||||
|
HTTPD_FIRST_REQUEST_BUFFER = 0x8000
|
||||||
|
|
||||||
|
|
||||||
;include "macros.inc"
|
;include "macros.inc"
|
||||||
use32
|
use32
|
||||||
org 0
|
org 0
|
||||||
@@ -16,7 +19,6 @@
|
|||||||
M01header.params:
|
M01header.params:
|
||||||
dd PATH, 0
|
dd PATH, 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
|
||||||
|
|
||||||
include 'module_api.inc'
|
include 'module_api.inc'
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ include 'settings.inc'
|
|||||||
|
|
||||||
;CODE
|
;CODE
|
||||||
START:
|
START:
|
||||||
mcall SF_SYS_MISC, SSF_HEAP_INIT ; init heap
|
call InitHeap
|
||||||
mcall SF_SET_EVENTS_MASK, EVM_STACK ;set event bitmap
|
mcall SF_SET_EVENTS_MASK, EVM_STACK ;set event bitmap
|
||||||
|
|
||||||
; init library
|
; init library
|
||||||
@@ -75,17 +77,12 @@ START:
|
|||||||
je .sock_err
|
je .sock_err
|
||||||
mov [srv_socket], eax
|
mov [srv_socket], eax
|
||||||
|
|
||||||
push srv_sockaddr.length
|
stdcall netfunc_bind, [srv_socket], srv_sockaddr, srv_sockaddr.length
|
||||||
push dword srv_sockaddr
|
|
||||||
push dword[srv_socket]
|
|
||||||
call netfunc_bind; [srv_socket], srv_sockaddr, srv_sockaddr.length
|
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je .bind_err
|
je .bind_err
|
||||||
|
|
||||||
; listen()
|
; listen()
|
||||||
push dword[srv_backlog]
|
stdcall netfunc_listen, [srv_socket], [srv_backlog]
|
||||||
push dword[srv_socket]
|
|
||||||
call netfunc_listen; [srv_socket], [srv_backlog]
|
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
jz .listen_err
|
jz .listen_err
|
||||||
|
|
||||||
@@ -107,12 +104,11 @@ START:
|
|||||||
.shutdown:
|
.shutdown:
|
||||||
.listen_err:
|
.listen_err:
|
||||||
.bind_err:
|
.bind_err:
|
||||||
push dword[srv_socket]
|
stdcall netfunc_close, [srv_socket]
|
||||||
call netfunc_close; [srv_socket]
|
|
||||||
|
|
||||||
.err_settings:
|
.err_settings:
|
||||||
.sock_err:
|
.sock_err:
|
||||||
mcall SF_TERMINATE_PROCESS
|
ThreadExit
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -120,28 +116,23 @@ thread_connect:
|
|||||||
sub esp, sizeof.CONNECT_DATA
|
sub esp, sizeof.CONNECT_DATA
|
||||||
mcall SF_SET_EVENTS_MASK, EVM_STACK ; set event - network event
|
mcall SF_SET_EVENTS_MASK, EVM_STACK ; set event - network event
|
||||||
|
|
||||||
; ожидание подключения Accept, sockaddr находится на вершине стека нового потока
|
; Accept - wait connection, get socket and sockaddr
|
||||||
;lea edx, [esp + CONNECT_DATA.sockaddr] ; new sockaddr
|
lea edx, [esp + CONNECT_DATA.sockaddr] ; new sockaddr
|
||||||
;push dword 16 ; 16 byte - sockaddr length
|
push sizeof.sockaddr_in
|
||||||
;push edx
|
push edx
|
||||||
push srv_sockaddr.length
|
|
||||||
push dword srv_sockaddr
|
|
||||||
|
|
||||||
push dword[srv_socket]
|
push dword[srv_socket]
|
||||||
call netfunc_accept
|
call netfunc_accept
|
||||||
|
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
jz .err_accept
|
jz .err_accept
|
||||||
|
|
||||||
|
; connection is enable
|
||||||
mov [esp + CONNECT_DATA.socket], eax
|
mov [esp + CONNECT_DATA.socket], eax
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
; соединение установленно, теперь нужно выделить буфер(тоже на 16 кб наверное), и
|
; теперь нужно выделить буфер(тоже на 16 кб наверное), и
|
||||||
; прочитать в этот буфер из сокета, когда прочтём ноль(или больше 4 кб), тогда
|
; прочитать в этот буфер из сокета, когда прочтём ноль(или больше 4 кб), тогда
|
||||||
; выходим из цикла и анализируем заголовки и стартовую стоку.
|
; выходим из цикла и анализируем заголовки и стартовую стоку.
|
||||||
mov esi, 0x8000
|
stdcall Alloc, HTTPD_FIRST_REQUEST_BUFFER ;alloc memory 32 kib
|
||||||
push esi
|
|
||||||
call Alloc ;alloc memory 32 kib
|
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err_alloc
|
jz .err_alloc
|
||||||
|
|
||||||
@@ -153,7 +144,7 @@ thread_connect:
|
|||||||
;read data from socket
|
;read data from socket
|
||||||
push dword 0 ;flags
|
push dword 0 ;flags
|
||||||
mov eax, [esi + CONNECT_DATA.request_size]
|
mov eax, [esi + CONNECT_DATA.request_size]
|
||||||
push dword 0x8000
|
push dword HTTPD_FIRST_REQUEST_BUFFER
|
||||||
sub [esp], eax
|
sub [esp], eax
|
||||||
push dword[esi + CONNECT_DATA.buffer_request]
|
push dword[esi + CONNECT_DATA.buffer_request]
|
||||||
add [esp], eax
|
add [esp], eax
|
||||||
@@ -166,7 +157,7 @@ thread_connect:
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jz @f
|
jz @f
|
||||||
add [esi + CONNECT_DATA.request_size], eax
|
add [esi + CONNECT_DATA.request_size], eax
|
||||||
; cmp [esi + CONNECT_DATA.request_size], 0x8000 ; check end buffer
|
; cmp [esi + CONNECT_DATA.request_size], HTTPD_FIRST_REQUEST_BUFFER ; check end buffer
|
||||||
; jb @b
|
; jb @b
|
||||||
@@:
|
@@:
|
||||||
; после получения всего запроса(более или менее всего) выделяем озу для
|
; после получения всего запроса(более или менее всего) выделяем озу для
|
||||||
@@ -269,15 +260,14 @@ thread_connect:
|
|||||||
; free IN buffer
|
; free IN buffer
|
||||||
cmp dword[esp + CONNECT_DATA.buffer_request], 0
|
cmp dword[esp + CONNECT_DATA.buffer_request], 0
|
||||||
jz .err_alloc
|
jz .err_alloc
|
||||||
push dword[esp + CONNECT_DATA.buffer_request]
|
|
||||||
call Free
|
stdcall Free, [esp + CONNECT_DATA.buffer_request]
|
||||||
.err_alloc:
|
.err_alloc:
|
||||||
push dword[esp + CONNECT_DATA.socket]
|
stdcall netfunc_close, [esp + CONNECT_DATA.socket]
|
||||||
call netfunc_close
|
|
||||||
.err_accept:
|
.err_accept:
|
||||||
lea ecx,[esp + sizeof.CONNECT_DATA - 0x4000] ; get pointer to alloc memory
|
add esp, sizeof.CONNECT_DATA
|
||||||
mcall 68, 13 ; free
|
; close this thread
|
||||||
mcall SF_TERMINATE_PROCESS ; close thread
|
ret
|
||||||
|
|
||||||
include 'parser.inc'
|
include 'parser.inc'
|
||||||
|
|
||||||
|
@@ -19,9 +19,16 @@ FLAG_NO_CACHE_CONTROL = 0x80
|
|||||||
FLAG_TRANSFER_CHUNKED = 0x100
|
FLAG_TRANSFER_CHUNKED = 0x100
|
||||||
FLAG_RAW_STREAM = 0x200
|
FLAG_RAW_STREAM = 0x200
|
||||||
|
|
||||||
|
struct sockaddr_in
|
||||||
|
sin_family dw ? ; sa_family_t
|
||||||
|
sin_port dw ? ; in_port_t
|
||||||
|
sin_addr dd ? ; struct in_addr
|
||||||
|
sin_zero rb 8 ; zero
|
||||||
|
ends
|
||||||
|
|
||||||
struct CONNECT_DATA ; 16*4 = 64 bytes
|
struct CONNECT_DATA ; 16*4 = 64 bytes
|
||||||
socket dd 0 ; номер сокета подключения
|
socket dd 0 ; connection socket number
|
||||||
sockaddr dd 16/4 ; socaddr connection
|
sockaddr sockaddr_in ; socaddr connection
|
||||||
buffer_request dd 0 ; pointer to buffer for geting message socket
|
buffer_request dd 0 ; pointer to buffer for geting message socket
|
||||||
request_size dd 0 ; size geted data from client
|
request_size dd 0 ; size geted data from client
|
||||||
end_buffer_request dd 0 ; privat data for parser
|
end_buffer_request dd 0 ; privat data for parser
|
||||||
@@ -42,6 +49,8 @@ struct CONNECT_DATA ; 16*4 = 64 bytes
|
|||||||
message_body_len dd 0 ; length message_body in buffer
|
message_body_len dd 0 ; length message_body in buffer
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
diff10 'sizeof.CONNECT_DATA: ', 0, sizeof.CONNECT_DATA
|
||||||
|
|
||||||
struct FILED
|
struct FILED
|
||||||
opcode rd 1
|
opcode rd 1
|
||||||
offset rd 2
|
offset rd 2
|
||||||
@@ -113,3 +122,5 @@ struct IMPORT_DATA
|
|||||||
|
|
||||||
GLOBAL_DATA rd 1
|
GLOBAL_DATA rd 1
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
HTTPD_THREAD_STACK = 0x4000 ; 16 kib
|
||||||
|
39
sys_func.inc
39
sys_func.inc
@@ -57,13 +57,6 @@ SOL_SOCKET = 0xffff
|
|||||||
SO_BINDTODEVICE = 1 shl 9
|
SO_BINDTODEVICE = 1 shl 9
|
||||||
SO_NONBLOCK = 1 shl 31
|
SO_NONBLOCK = 1 shl 31
|
||||||
|
|
||||||
struct sockaddr_in
|
|
||||||
sin_family dw ? ; sa_family_t
|
|
||||||
sin_port dw ? ; in_port_t
|
|
||||||
sin_addr dd ? ; struct in_addr
|
|
||||||
sin_zero rb 8 ; zero
|
|
||||||
ends
|
|
||||||
|
|
||||||
struct addrinfo
|
struct addrinfo
|
||||||
ai_flags dd ? ; bitmask of AI_*
|
ai_flags dd ? ; bitmask of AI_*
|
||||||
ai_family dd ? ; PF_*
|
ai_family dd ? ; PF_*
|
||||||
@@ -162,30 +155,52 @@ netfunc_recv:
|
|||||||
pop ebx edi esi
|
pop ebx edi esi
|
||||||
ret 16
|
ret 16
|
||||||
|
|
||||||
|
macro ThreadExit {
|
||||||
|
mcall SF_TERMINATE_PROCESS
|
||||||
|
}
|
||||||
|
|
||||||
; stdcall CreatThread(void* entry_thread);
|
; stdcall CreatThread(void* entry_thread);
|
||||||
CreateThread:
|
CreateThread:
|
||||||
push ebx edi
|
push ebx edi
|
||||||
mcall SF_SYS_MISC, SSF_MEM_ALLOC, 0x4000 ;alloc memory 16 kib for stack
|
;alloc memory for stack
|
||||||
|
mcall SF_SYS_MISC, SSF_MEM_ALLOC, HTTPD_THREAD_STACK
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
|
|
||||||
mov ecx, 0x4000/4
|
mov ecx, HTTPD_THREAD_STACK/4
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
;start thread for new connection
|
;start thread for new connection
|
||||||
mov edx, eax
|
mov edx, eax
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
rep stosd
|
rep stosd
|
||||||
add edx, 0x4000
|
add edx, HTTPD_THREAD_STACK - 4
|
||||||
mcall SF_CREATE_THREAD, 1, [esp + 2*4 + 4] ;<- thread entry
|
m2m dword[edx], dword[esp + 2*4 + 4]
|
||||||
|
mcall SF_CREATE_THREAD, 1, .thread ;<- thread entry
|
||||||
.err:
|
.err:
|
||||||
pop ebx edi
|
pop ebx edi
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
|
.thread:
|
||||||
|
pop eax
|
||||||
|
call eax
|
||||||
|
lea ecx, [esp - HTTPD_THREAD_STACK]
|
||||||
|
mcall SF_SYS_MISC, SSF_MEM_FREE
|
||||||
|
ThreadExit
|
||||||
|
|
||||||
|
|
||||||
|
InitHeap:
|
||||||
|
push ebx
|
||||||
|
mcall SF_SYS_MISC, SSF_HEAP_INIT ; init heap
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
|
||||||
; stdcall Alloc(uint32_t size)
|
; stdcall Alloc(uint32_t size)
|
||||||
Alloc:
|
Alloc:
|
||||||
push ebx
|
push ebx
|
||||||
mcall SF_SYS_MISC, SSF_MEM_ALLOC, [esp + 4 + 4]
|
mcall SF_SYS_MISC, SSF_MEM_ALLOC, [esp + 4 + 4]
|
||||||
pop ebx
|
pop ebx
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
; stdcall Free(void* ptr)
|
; stdcall Free(void* ptr)
|
||||||
Free:
|
Free:
|
||||||
push ebx
|
push ebx
|
||||||
@@ -788,7 +803,7 @@ finish_send_resp:
|
|||||||
mov byte[esp], '0'
|
mov byte[esp], '0'
|
||||||
|
|
||||||
mov ecx, esp
|
mov ecx, esp
|
||||||
mov eax, [ebp + RESPD.session]
|
mov eax, [edx + RESPD.session]
|
||||||
|
|
||||||
push dword 0
|
push dword 0
|
||||||
push dword 5 ; size buffer
|
push dword 5 ; size buffer
|
||||||
|
@@ -4,7 +4,6 @@ public @EXPORT as 'EXPORTS'
|
|||||||
|
|
||||||
NO_DEBUG_INPUT = 0
|
NO_DEBUG_INPUT = 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
|
||||||
include "proc32.inc"
|
include "proc32.inc"
|
||||||
|
|
||||||
include '../module_api.inc'
|
include '../module_api.inc'
|
||||||
|
@@ -4,7 +4,6 @@ public @EXPORT as 'EXPORTS'
|
|||||||
|
|
||||||
NO_DEBUG_INPUT = 0
|
NO_DEBUG_INPUT = 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
|
||||||
include "proc32.inc"
|
include "proc32.inc"
|
||||||
|
|
||||||
include '../module_api.inc'
|
include '../module_api.inc'
|
||||||
|
Reference in New Issue
Block a user