Added file server

Added file server for no units URI paths.
Fixed a lot of bugs in parser and mainloop.
Added function Get_MIME_Type
This commit is contained in:
Doczom
2023-11-19 13:15:58 +05:00
committed by GitHub
parent 3d3fa69481
commit 6030a5f8fe
7 changed files with 613 additions and 53 deletions

278
file_server.inc Normal file
View File

@@ -0,0 +1,278 @@
; Это модуль для обработки стандартных запросов на получение файла
; по пути, который не относится к другому модулю
file_server:
; check http version (skip RTSP)
mov ecx, [esi + CONNECT_DATA.http_verion]
cmp dword[ecx], 'HTTP'
jne .err_http_501
cmp word[ecx + 4], '/1'
jne .err_http_501
; cmp byte[ecx + 7], '1'
; je .http_1_1
; ; http 1.0;
;
;.http_1_1:
; check name on ../../ and other bad items
mov ecx, [esi + CONNECT_DATA.uri_path]
@@:
cmp byte[ecx], 0
je .good_name
inc ecx
cmp dword[ecx - 1], '/../' ; if path "/.." then system read dir and
jne @b ; and skip this path with 404 error
jmp .err_http_501
.good_name:
; check file of name (generate full name: work_dir + path)
;
; alloc 4 kib for path to file name
; memory alloced on stack and for working program alloced with buffer
; for code stack
lea edx, [esp - 6*1024 - 4096] ; edx <- buffer for full path
mov edi, edx
sub edi, sizeof.FILED; edi <- struct FILED
mov [edi + FILED.path], edx
mov eax, esi
push esi edi
;; copy work_dir
mov esi, GLOBAL_DATA.work_dir
mov edi, edx
mov ecx, [GLOBAL_DATA.work_dir.size]
rep movsb
;; copy path
mov esi, [eax + CONNECT_DATA.uri_path]
@@:
movsb
cmp byte[esi - 1], 0
jne @b
mov eax, edi
dec eax
pop edi esi
mov [edi + FILED.end_path], eax
;; check file info (skip of directory and if syscall return error)
lea eax, [edi - 40] ; buffer for file info
mov [edi + FILED.buffer], eax
push edi
call FileInfo
test eax, eax
jnz .err_not_found
test dword[edi - 40], 11000b ; check dir OR disk partition
jnz .err_not_found
; check method OPTIONS
mov ecx, [esi + CONNECT_DATA.http_method]
cmp dword[ecx], 'OPTI'
jne @f
cmp dword[ecx + 4], 'ONS'
je .send_options
@@:
cmp dword[ecx], 'POST'
jne @f
cmp byte[ecx + 4], 0
je .send_file
@@:
cmp dword[ecx], 'GET'
jne .err_http_501
.send_file:
; create http response (set 200 code, MINE type and length of body)
;; alloc 33 kib
push dword 33*1024
call Alloc
test eax, eax
jz .err_http_501 ; error memory
push esi
push edi
push eax ; save pointer for Free
mov esi, base_response
mov ecx, response.body
mov edi, [esp]
rep movsb
mov edi, [esp]
mov dword[edi + response.code], '200 '
push dword[esp + 4] ; <-FILED
call Get_MIME_Type
add edi, response.content_type
mov esi, eax
@@:
movsb
cmp byte[esi], 0
jne @b
pop edi ; buffer on 32 kib
pop ebx ; FD
pop esi ; CONNECT_DATA
; copy length
mov edx, [ebx - 40 + 36]
mov eax, [ebx - 40 + 32]
lea ecx, [edi + response.content_len + 21]
test eax, eax
jne @f
test edx, edx
jz .err_not_found_1
@@:
cmp edx, 1000 ; 999*4 - max length of file
jae .err_not_found_1
; edx:eax ecx - end char in string '000000'
.div1000:
div dword[_DIV_1000_]
push eax
mov eax, edx
xor edx, edx
;.div100:
div dword[_DIV_100_]
push eax
mov eax, edx
xor edx, edx
div dword[_DIV_10_]
add byte[ecx], dl
add byte[ecx - 1], al
sub ecx, 3
pop eax
add byte[ecx + 1], al
;xor edx, edx
;test eax, eax
;jne .div100
pop eax
xor edx, edx
test eax, eax
jne .div1000
;send_response_header
push dword 0 ; flags
push response.body
push edi
push dword[esi + CONNECT_DATA.socket]
call netfunc_send
cmp eax, -1
je .exit_free
mov dword[ebx + FILED.offset], 0
mov dword[ebx + FILED.offset + 4], 0
mov [ebx + FILED.buffer], edi
mov [ebx + FILED.size], 32*1024
.send_response_body:
; read 32 kib to file
push ebx
call FileRead
test eax, eax
jz @f
cmp eax, 6
jne .exit_free
@@:
; send this block data
push dword 0 ; flags
push 32*1024
push edi
push dword[esi + CONNECT_DATA.socket]
call netfunc_send
cmp eax, -1
je .exit_free
; check end file
mov ecx, [ebx + FILED.offset + 4]
cmp [ebx - 4], ecx
ja .add_offset
mov edx, [ebx + FILED.offset]
cmp [ebx - 8], edx
jbe .exit_free
.add_offset:
add [ebx + FILED.offset], 32*1024
adc [ebx + FILED.offset + 4], 0
jmp @b
.exit_free:
push edi
call Free
ret
.send_options:
; send standart options of file server
push dword 0 ; flags
push http_response_options.size
push http_response_options
push dword[esi + CONNECT_DATA.socket]
call netfunc_send
ret
.err_not_found_1:
push edi
call Free
.err_not_found:
; send error 404
push dword 0 ; flags
push http_response_err_404.size
push http_response_err_404
push dword[esi + CONNECT_DATA.socket]
call netfunc_send
ret
.err_http_501:
; send error 501
push dword 0 ; flags
push http_response_err_501.size
push http_response_err_501
push dword[esi + CONNECT_DATA.socket]
call netfunc_send
ret
; char* stdcall Get_MIME_Type(FILED* fd); //path is ASCIIZ string
Get_MIME_Type:
push esi edi
mov edx, [GLOBAL_DATA.MIME_types_arr]
mov esi, [esp + 4*2 + 4]
sub edx, 8
.next:
add edx, 8
mov ecx, [esi + FILED.end_path] ;pointer to \0 full path
cmp dword[edx], 0
jz .found
mov edi, [edx]
movzx eax, byte[edi]
sub ecx, eax
@@:
inc edi
mov al, [edi]
cmp byte[ecx], al
jne .next
inc ecx
test al, al
jne @b
.found:
mov eax, [edx + 4]
pop edi esi
ret 4

View File

@@ -7,15 +7,20 @@
; Version 0.0.1, 12 November 2023 ; ; Version 0.0.1, 12 November 2023 ;
; ; ; ;
;*****************************************************************************; ;*****************************************************************************;
use32 ;include "macros.inc"
org 0 include 'D:\kos\programs\macros.inc'
;include 'D:\kos\programs\network.inc'
use32
org 0
db 'MENUET01'
dd 1, START, I_END, MEM, STACKTOP, PATH, 0
;KOS_APP_START
include 'sys_func.inc' include 'sys_func.inc'
include 'settings.inc' include 'settings.inc'
;CODE
start: START:
mcall 68, 11 ; init heap mcall 68, 11 ; init heap
mcall 40, EVM_STACK ;set event bitmap mcall 40, EVM_STACK ;set event bitmap
@@ -30,7 +35,7 @@ start:
jnz .err_settings jnz .err_settings
;init server socket ;init server socket
push dword SO_NONBLOCK push dword SO_NONBLOCK ; IPPROTO_TCP
push dword SOCK_STREAM push dword SOCK_STREAM
push dword AF_INET4 push dword AF_INET4
call netfunc_socket; AF_INET4, SOCK_STREAM, SO_NONBLOCK ; we dont want to block on accept call netfunc_socket; AF_INET4, SOCK_STREAM, SO_NONBLOCK ; we dont want to block on accept
@@ -64,9 +69,9 @@ start:
.listen_err: .listen_err:
.bind_err: .bind_err:
push dword[srv_socket] push dword[srv_socket]
call close; [srv_socket] call netfunc_close; [srv_socket]
..err_settings: .err_settings:
.sock_err: .sock_err:
mcall -1 mcall -1
@@ -77,9 +82,12 @@ thread_connect:
mcall 40, EVM_STACK ; set event bitmap - network event mcall 40, EVM_STACK ; set event bitmap - network event
; ожидание подключения Accept, sockaddr находится на вершине стека нового потока ; ожидание подключения Accept, 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 dword 16 ; 16 byte - sockaddr length
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
@@ -119,8 +127,8 @@ 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], 0x8000 ; check end buffer
jb @b ; jb @b
@@: @@:
; после получения всего запроса(более или менее всего) выделяем озу для ; после получения всего запроса(более или менее всего) выделяем озу для
; ассоциативного массива заголовков и аргументов запроса ; ассоциативного массива заголовков и аргументов запроса
@@ -129,21 +137,26 @@ thread_connect:
; esp + 1024 .. esp + 2048 -> for URI args ; esp + 1024 .. esp + 2048 -> for URI args
sub esp, 2048 sub esp, 2048
; parse http message ; parse http message
call parse_http_query ; ecx - buffer edx - length data in buffer mov ecx, [esi + CONNECT_DATA.buffer_request]
call parse_http_query ; ecx - buffer
test eax, eax test eax, eax
jz .err_parse jz .err_parse
; вызов нужной функции из списка моделей ; вызов нужной функции из списка моделей
; TODO ; TODO
; if not found units, call file_server
call file_server ; esi - struct
;TEST SERVER, DELETE ON RELISE
; end work thread ; end work thread
jmp .end_work jmp .end_work
.err_parse: .err_parse:
; send error 501 call file_server.err_http_501
.end_work: .end_work:
add esp, 2048 add esp, 2048
; free OUT buffer ; free OUT buffer
@@ -167,14 +180,21 @@ thread_connect:
include 'parser.inc' include 'parser.inc'
include 'file_server.inc'
; DATA AND FUNCTION ; DATA AND FUNCTION
include 'httpd_lib.inc' include 'httpd_lib.inc'
default_ini_path: db 'httpd.ini',0
I_END:
;DATA
; DATA ; DATA
srv_backlog: dd 0 ; максимум одновременных подключений подключений ;UDATA
srv_socket: dd 0 srv_backlog: rd 1 ; максимум одновременных подключений подключений
srv_socket: rd 1
srv_sockaddr: srv_sockaddr:
dw AF_INET4 dw AF_INET4
@@ -184,9 +204,21 @@ srv_sockaddr:
.length = $ - srv_sockaddr .length = $ - srv_sockaddr
GLOBAL_DATA: GLOBAL_DATA:
.units dd 0 ; указатель на ассоциативный массив пути и указателя на функцию либы(см ниж) .units rd 1 ; указатель на ассоциативный массив пути и указателя на функцию либы(см ниж)
.unit_count dd 0 ; количество записей в массиве .unit_count rd 1 ; количество записей в массиве
.libs dd 0 ; указатель на массив указателей на ассоциативные массивы библиотек .libs rd 1 ; указатель на массив указателей на ассоциативные массивы библиотек
.work_dir rb 1024 ; max size path to work directory
.work_dir.size rd 1 ; length string
.unit_dir rb 1024
.unit_dir.size rd 1
.MIME_types_arr rd 1
;; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию) ;; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию)
PATH:
rb 256
; stack memory
rb 4096
STACKTOP:
MEM:
;KOS_APP_END

BIN
httpd.kex Normal file

Binary file not shown.

View File

@@ -83,27 +83,108 @@ http_err_response:
db 13, 10 db 13, 10
.size = $ - http_err_response .size = $ - http_err_response
http_response_err_501:
db 'HTTP/1.1 '
db '501 ',13, 10
db 'Server: simple-httpd/0.0.1', 13, 10
db 'Content-length: 91', 13, 10
db 'Content-type: text/plain', 13, 10;
db 'Connection: close', 13, 10
db 13, 10
db 'Error parsing your request message. The version is not supported or another error.'
.size = $ - http_response_err_501
http_response_err_404:
db 'HTTP/1.1 '
db '404 ',13, 10
db 'Server: simple-httpd/0.0.1', 13, 10
db 'Content-length: 45', 13, 10
db 'Content-type: text/plain', 13, 10;
db 'Connection: close', 13, 10
db 13, 10
db 'The server could not find the requested page.'
.size = $ - http_response_err_404
http_response_options:
db 'HTTP/1.1 '
db '204 ',13, 10
db 'Server: simple-httpd/0.0.1', 13, 10
db 'Allow: OPTIONS, GET, POST', 13, 10
db 'Connection: close', 13, 10
db 13, 10
.size = $ - http_response_options
base_response: base_response:
label response at 0 response:
db 'HTTP/1.0 ' db 'HTTP/1.0 '
.code: db '000 ',13, 10 .code = $ - response
db 'Server: httpd(kolibri os)/0.0.1', 13, 10 db '000 ',13, 10
db 'Server: simple-httpd/0.0.1', 13, 10 ; httpd(kolibri os)/0.0.1, 13, 10
db 'Cache-Control: no-cache', 13, 10 db 'Cache-Control: no-cache', 13, 10
db 'Content-Encoding: ' db 'Content-Encoding: '
.content_encod: db 'identity', 13, 10 .content_encod = $ - response
db 'Date: ' db 'identity', 13, 10
.date: db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10 ; db 'Date: '
;.date: db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10
db 'Content-length: ' db 'Content-length: '
.content_len: db ' ', 13, 10 ;.content_len: db ' ', 13, 10
.content_len = $ - response
db '0000000000000000000000', 13, 10
db 'Content-type: ' db 'Content-type: '
.content_type: db ' ', 13, 10; .content_type = $ - response
db ' ', 13, 10;
;'text/html; charset=utf-8' ;'text/html; charset=utf-8'
.end_headers: ;нужно, когда базового заголовка не хватает ;.end_headers: ;нужно, когда базового заголовка не хватает
.connection db 'Connection: close', 13, 10 .connection = $ - response
db 'Connection: close', 13, 10
db 13, 10 db 13, 10
.body: ; с этого оффсета уже писать данные .body = $ - response ; с этого оффсета уже писать данные
; min HTTP request size ; min HTTP request size
; "GET / HTTP/1.1" - 18 byte ; "GET / HTTP/1.1" - 18 byte
min_http_size = 18 min_http_size = 18
MIME_TYPES:
.html: db 'text/html',0
.css: db 'text/css',0
.js: db 'text/javascript',0
.txt: db 'text/plain',0
.json: db 'application/json',0
.pdf: db 'application/pdf',0
.png: db 'image/png',0
.mp3: db 'audio/mpeg',0
.mp4: db 'video/mp4',0
.other: db 'application/octet-stream',0 ; for unknow file - all file :)
MIME_FILE_FORMAT:
.html: db 5,'.html',0
.css: db 4,'.css',0
.js: db 3,'.js',0
.txt: db 4,'.txt',0
.pdf: db 4,'.pdf',0
.json: db 5,'.json',0
.png: db 4,'.png',0
.mp3: db 4,'.mp3',0
.mp4: db 4,'.mp4',0
STD_MIME_TYPE_ARR:
dd MIME_FILE_FORMAT.html, MIME_TYPES.html,\
MIME_FILE_FORMAT.css, MIME_TYPES.css,\
MIME_FILE_FORMAT.js, MIME_TYPES.js,\
MIME_FILE_FORMAT.txt, MIME_TYPES.txt,\
MIME_FILE_FORMAT.pdf, MIME_TYPES.pdf,\
MIME_FILE_FORMAT.json, MIME_TYPES.json,\
MIME_FILE_FORMAT.png, MIME_TYPES.png,\
MIME_FILE_FORMAT.mp3, MIME_TYPES.mp3,\
MIME_FILE_FORMAT.mp4, MIME_TYPES.mp4,\
0, MIME_TYPES.other
_DIV_10_: dd 10
_DIV_100_: dd 100
_DIV_1000_: dd 1000

View File

@@ -58,7 +58,7 @@ parse_url:
je .get_query je .get_query
cmp byte[ecx], '#' cmp byte[ecx], '#'
je get_fragment je .get_fragment
cmp byte[ecx], ' ' ; check end path cmp byte[ecx], ' ' ; check end path
jne @b jne @b
@@ -106,7 +106,7 @@ parse_url:
cmp byte[ecx], ' ' cmp byte[ecx], ' '
je .exit_2 je .exit_2
cmp byte[ecx] '&' cmp byte[ecx], '&'
jne @b jne @b
jmp .get_query_new_arg jmp .get_query_new_arg
@@ -122,7 +122,7 @@ parse_url:
inc ecx inc ecx
cmp byte[ecx - 1], ' ' cmp byte[ecx - 1], ' '
jne @b jne @b
mov [ecx - 1], 0 mov byte[ecx - 1], 0
.exit: .exit:
ret ret
@@ -138,17 +138,31 @@ parse_url:
parse_headers: parse_headers:
; init array ; init array
mov [esi + CONNECT_DATA.num_headers], 0 mov [esi + CONNECT_DATA.num_headers], 0
mov [esi + CONNECT_DATA.http_headers], BASE_ARRAY_HEADERS lea eax, [BASE_ARRAY_HEADERS]
mov [esi + CONNECT_DATA.http_headers], eax
xor edx, edx xor edx, edx
; for check size
mov eax, [esi + CONNECT_DATA.request_size]
add eax, [esi + CONNECT_DATA.buffer_request]
.new_str: .new_str:
cmp ecx, eax
jae .exit
cmp word[ecx], 0x0A0D ; \n cmp word[ecx], 0x0A0D ; \n
jnz .find_header jnz .find_header
.exit:
; end find heeaders ; end find heeaders
mov byte[ecx], 0
add ecx, 2 ; ecx = base for body message add ecx, 2 ; ecx = base for body message
ret ret
.find_header: .find_header:
; add new item in array headers ; add new item in array headers
cmp edx, 512 ; max count headers
jae .exit
inc edx inc edx
mov dword[esi + CONNECT_DATA.num_headers], edx mov dword[esi + CONNECT_DATA.num_headers], edx
; save pointer to name header ; save pointer to name header
@@ -157,6 +171,9 @@ parse_headers:
@@: @@:
inc ecx inc ecx
cmp ecx, eax
jae .exit
cmp byte[ecx], ':' cmp byte[ecx], ':'
jnz @b jnz @b
@@ -165,8 +182,11 @@ parse_headers:
; save pointer to value ; save pointer to value
mov dword[BASE_ARRAY_HEADERS + (edx-1)*8 + 4], ecx mov dword[BASE_ARRAY_HEADERS + (edx-1)*8 + 4], ecx
@@: @@:
cmp ecx, eax
jae .exit
inc ecx inc ecx
cmp byte[ecx - 1], 0x0A0D cmp word[ecx - 1], 0x0A0D
jnz @b jnz @b
mov byte[ecx - 1], 0 mov byte[ecx - 1], 0
inc ecx ; set offset on new string inc ecx ; set offset on new string

View File

@@ -30,18 +30,40 @@ ends
; OUT: eax - 0 or err_code ; OUT: eax - 0 or err_code
load_settings: load_settings:
; check file path ; check file path
sub esp, 40 ; size file info struct ;sub esp, 40 ; size file info struct
push esp ;push esp
push ecx ;push ecx
call FileInfo ;call FileInfo
lea esp, [esp + 40] ;lea esp, [esp + 40]
test eax, eax ;test eax, eax
jnz .err ;jnz .err
; TEST SERVER
mov word[srv_sockaddr], AF_INET4
mov word[srv_sockaddr.port], 0x5000 ; 80 port
mov dword[srv_sockaddr.ip], 0x1589A8C0 ; 192.168.137.21 or 0xc0a88915 ?
mov dword[srv_backlog], 10
push esi edi
mov edi, GLOBAL_DATA.work_dir
mov esi, test_workdir
mov ecx, test_workdir.size
rep movsb
pop edi esi
mov dword[GLOBAL_DATA.work_dir.size], test_workdir.size
mov dword[GLOBAL_DATA.MIME_types_arr], STD_MIME_TYPE_ARR
xor eax, eax
ret ret
.err: .err:
ret ret
test_workdir: db '/sys'
.size = $ - test_workdir
; Config format: ; Config format:
; Standart INI file: ; Standart INI file:
; - ";" or "#" comments ; - ";" or "#" comments

View File

@@ -1,5 +1,112 @@
; ABSTRACT SYSTEM FUNCTIONS ; ABSTRACT SYSTEM FUNCTIONS
;======== inclede network.inc ========
; Socket types
SOCK_STREAM = 1
SOCK_DGRAM = 2
SOCK_RAW = 3
; IP protocols
IPPROTO_IP = 0
IPPROTO_ICMP = 1
IPPROTO_TCP = 6
IPPROTO_UDP = 17
IPPROTO_RAW = 255
; IP options
IP_TTL = 2
; Address families
AF_UNSPEC = 0
AF_LOCAL = 1
AF_INET4 = 2 ; IPv4
AF_INET6 = 10 ; IPv6
PF_UNSPEC = AF_UNSPEC
PF_LOCAL = AF_LOCAL
PF_INET4 = AF_INET4
PF_INET6 = AF_INET6
; Flags for addrinfo
AI_PASSIVE = 1
AI_CANONNAME = 2
AI_NUMERICHOST = 4
AI_NUMERICSERV = 8
AI_ADDRCONFIG = 0x400
; internal definition
AI_SUPPORTED = 0x40F
; for system function 76
API_ETH = 0 shl 16
API_IPv4 = 1 shl 16
API_ICMP = 2 shl 16
API_UDP = 3 shl 16
API_TCP = 4 shl 16
API_ARP = 5 shl 16
API_PPPOE = 6 shl 16
; Socket flags for user calls
MSG_PEEK = 0x02
MSG_DONTWAIT = 0x40
; Socket levels
SOL_SOCKET = 0xffff
; Socket options
SO_BINDTODEVICE = 1 shl 9
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
ai_flags dd ? ; bitmask of AI_*
ai_family dd ? ; PF_*
ai_socktype dd ? ; SOCK_*
ai_protocol dd ? ; 0 or IPPROTO_*
ai_addrlen dd ? ; length of ai_addr
ai_canonname dd ? ; char*
ai_addr dd ? ; struct sockaddr*
ai_next dd ? ; struct addrinfo*
ends
EAI_ADDRFAMILY = 1
EAI_AGAIN = 2
EAI_BADFLAGS = 3
EAI_FAIL = 4
EAI_FAMILY = 5
EAI_MEMORY = 6
EAI_NONAME = 8
EAI_SERVICE = 9
EAI_SOCKTYPE = 10
EAI_BADHINTS = 12
EAI_PROTOCOL = 13
EAI_OVERFLOW = 14
; Socket error codes
; Error Codes
ENOBUFS = 1
EINPROGRESS = 2
EOPNOTSUPP = 4
EWOULDBLOCK = 6
ENOTCONN = 9
EALREADY = 10
EINVAL = 11
EMSGSIZE = 12
ENOMEM = 18
EADDRINUSE = 20
ECONNREFUSED = 61
ECONNRESET = 52
EISCONN = 56
ETIMEDOUT = 60
ECONNABORTED = 53
;======== End include========
; stdcall socket(uint32_t domain, type, proto) ; stdcall socket(uint32_t domain, type, proto)
netfunc_socket: netfunc_socket:
push ebx esi push ebx esi
@@ -11,7 +118,7 @@ netfunc_socket:
;stdcall close(uint32_t sock_number); ;stdcall close(uint32_t sock_number);
netfunc_close: netfunc_close:
push ebx push ebx
call 75, 1, [esp + 4 + 4] mcall 75, 1, [esp + 4 + 4]
pop ebx pop ebx
ret 4 ret 4
@@ -80,11 +187,31 @@ Free:
pop ebx pop ebx
ret 4 ret 4
;NTSTATUS stdcall FileInfo(const char* path, void* buff)
struct FILED
opcode rd 1
offset rd 2
size rd 1
buffer rd 1
rb 1
path rd 1
end_path rd 1
ends
;NTSTATUS stdcall FileInfo(FILED* file)
FileInfo: FileInfo:
push ebx
ret 8 mov ebx, [esp + 4*1 + 4]
;NTSATTUS stdcall FileRead(const char* path, void* buff, uint32_t size) mov dword[ebx], 5 ; file info
mov dword[ebx + FILED.offset + 4], 0 ; zero flag
mcall 70
pop ebx
ret 4
;NTSATTUS stdcall FileRead(FILED* file)
FileRead: FileRead:
push ebx
ret 12 mov ebx, [esp + 4*1 + 4]
mov dword[ebx], 0 ; read file
mcall 70
pop ebx
ret 4