1483ec8462
Libraries (box_lib, buf2d, libimg, tinygl): optimize function import Programs updated: - gears, test3, test_glu1, test_glu2, - test_array1, textures0, textures1, textures2, - ctrldemo, editbox_ex, crypt_files, img_transform, - scrshoot, t_edit, cnc_control, cnc_editor Reviewed-on: #231 Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com> Reviewed-by: Ivan B <dunkaist@noreply.localhost> Co-authored-by: IgorA <aie85playm@gmail.com> Co-committed-by: IgorA <aie85playm@gmail.com>
551 lines
14 KiB
Plaintext
551 lines
14 KiB
Plaintext
; The macros for load any library/libraries:
|
|
; Copyright (c) 2009, <Lrz>
|
|
; All rights reserved.
|
|
|
|
|
|
|
|
macro @use_library mem_alloc,mem_free,mem_realloc,dll_load
|
|
{
|
|
local lp1
|
|
local lp2
|
|
local lp3
|
|
local lp4
|
|
local lp5
|
|
local lp6
|
|
local file_name
|
|
local l_lib_m1
|
|
local l_lib_m2
|
|
local l_lib_m3
|
|
local l_lib_m4
|
|
|
|
library_fun_memory_alloc equ mem_alloc
|
|
library_fun_memory_free equ mem_free
|
|
library_fun_memory_realloc equ mem_realloc
|
|
library_fun_dll_load equ dll_load
|
|
|
|
align 4
|
|
strz_lib_init db 'lib_init',0
|
|
|
|
align 4
|
|
arrea_xx dd 0
|
|
file_name db '/sys/@notify',0
|
|
|
|
if lang eq ru_RU
|
|
l_lib_m1 db '"Системная ошибка',13,10,'Не найдена библиотека ',39,0
|
|
l_lib_m2 db '"Системная ошибка',13,10,'Ошибка при импорте библиотеки ',39,0
|
|
l_lib_m3 db 39,13,10,'не найдена функция ',39,0
|
|
l_lib_m4 db 39,'" -tE',0
|
|
else if lang eq it_IT
|
|
l_lib_m1 db '"Errore di sistema',13,10,'Non trovato ',39,0
|
|
l_lib_m2 db '"Errore di sistema',13,10,'Import errato ',39,0
|
|
l_lib_m3 db 39,13,10,'funzione non trovata ',39,0
|
|
l_lib_m4 db 39,'" -tE',0
|
|
else
|
|
l_lib_m1 db '"System error',13,10,'Sorry I cannot found library ',39,0
|
|
l_lib_m2 db '"System error',13,10,'Error on load import library ',39,0
|
|
l_lib_m3 db 39,13,10,'cannot found function ',39,0
|
|
l_lib_m4 db 39,'" -tE',0
|
|
end if
|
|
|
|
align 4
|
|
run_notify_struct:
|
|
.Function dd 7
|
|
.Position dd 0
|
|
.Flags dd ?
|
|
.Count dd 0
|
|
.Buffer dd 0
|
|
db 0
|
|
.FileName dd file_name
|
|
|
|
;description:
|
|
; готовим текст для показа через @notify:
|
|
; 1) выделяем память в [arrea_xx] но не больше одного раза
|
|
; 2) копируем заголовок (если есть имя функции то добавляем его к заголовку) и текст сообщения в [arrea_xx]
|
|
;input:
|
|
; ebp+8 - library name
|
|
; ebp+12 - 0 или имя функции, которую не удалось экспортировать
|
|
;output:
|
|
; eax = -1
|
|
align 4
|
|
l_lib_init_error_window:
|
|
push ebp
|
|
mov ebp,esp
|
|
cmp dword[arrea_xx],0
|
|
jne .no_msg ;если раньше было создано другое сообщение
|
|
pushad
|
|
|
|
mcall SF_SYS_MISC,SSF_HEAP_INIT
|
|
mcall SF_SYS_MISC,SSF_MEM_ALLOC,4096
|
|
mov [arrea_xx],eax
|
|
|
|
mov edi,eax
|
|
mov esi,l_lib_m2 ;сообщение если не удалось импортировать функцию
|
|
cmp dword[ebp+12],0
|
|
je @f
|
|
mov esi,l_lib_m1 ;сообщение если не удалось загрузить библиотеку
|
|
align 4
|
|
@@:
|
|
movsb
|
|
cmp byte[esi],0
|
|
jne @b
|
|
;добавляем имя библиотеки
|
|
mov esi,[ebp+8]
|
|
align 4
|
|
@@:
|
|
movsb
|
|
cmp byte[esi],0
|
|
jne @b
|
|
|
|
cmp dword[ebp+12],0
|
|
je .lp1
|
|
;добавляем середину сообщения
|
|
mov esi,l_lib_m3
|
|
align 4
|
|
@@:
|
|
movsb
|
|
cmp byte[esi],0
|
|
jne @b
|
|
;добавляем имя функции
|
|
mov esi,[ebp+12]
|
|
align 4
|
|
@@:
|
|
movsb
|
|
cmp byte[esi],0
|
|
jne @b
|
|
|
|
.lp1: ;сообщение если не удалось загрузить библиотеку
|
|
;добавляем конец сообщения
|
|
mov esi,l_lib_m4
|
|
align 4
|
|
@@:
|
|
movsb
|
|
cmp byte[esi],0
|
|
jne @b
|
|
mov byte[edi],0
|
|
|
|
popad
|
|
.no_msg:
|
|
or eax,-1
|
|
pop ebp
|
|
ret 8
|
|
|
|
@library_name equ dword [esp+16]
|
|
@cur_dir_path equ dword [esp+12]
|
|
@library_path equ dword [esp+8]
|
|
@point_dir_name equ dword [esp+4]
|
|
|
|
align 4
|
|
@copy_path:
|
|
mov esi,@cur_dir_path
|
|
mov edi,@library_path
|
|
xor eax,eax
|
|
cld
|
|
align 4
|
|
.lp1:
|
|
lodsb
|
|
stosb
|
|
test eax,eax
|
|
jnz .lp1
|
|
mov esi,edi
|
|
dec esi ;переход на символ конца строки @cur_dir_path
|
|
std
|
|
align 4
|
|
.lp2:
|
|
lodsb
|
|
cmp al,'/'
|
|
jnz .lp2
|
|
mov edi,esi
|
|
add edi,2
|
|
cld
|
|
mov esi,@point_dir_name
|
|
test esi,esi
|
|
jz .str_lp4
|
|
|
|
;проверка относительных путей c двумя точками '../'
|
|
cmp word[esi],'..'
|
|
jne .lp3
|
|
dec edi ;для перехода на '/'
|
|
.lp6:
|
|
add esi,3 ;пропускаем одно поднятие '../'
|
|
.lp5:
|
|
dec edi ;идем по папкам
|
|
cmp byte[edi],'/'
|
|
jnz .lp5
|
|
cmp word[esi],'..'
|
|
je .lp6
|
|
inc edi ;для перехода на '/'
|
|
|
|
;копирование относительного пути
|
|
align 4
|
|
.lp3:
|
|
lodsb
|
|
stosb
|
|
test eax,eax
|
|
jnz .lp3
|
|
dec edi
|
|
.str_lp4:
|
|
mov esi,@library_name
|
|
align 4
|
|
.lp4:
|
|
lodsb
|
|
stosb
|
|
test eax,eax
|
|
jnz .lp4
|
|
ret
|
|
}
|
|
;---------------------------------------------------------------------
|
|
|
|
macro sys_load_library library_name__, library_path__, system_path__, myimport, point_dir_name__
|
|
{
|
|
local i_begin
|
|
local i_error
|
|
local i_exit
|
|
push ebx
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,system_path__ ; load of sys directory
|
|
test eax,eax
|
|
jnz i_begin
|
|
|
|
if point_dir_name__ eq
|
|
copy_path library_name__, [32], library_path__,0
|
|
else
|
|
;the macros making way /current path a program/ + name system library
|
|
copy_path library_name__, [32], library_path__,point_dir_name__
|
|
end if
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
|
|
test eax,eax
|
|
jnz i_begin
|
|
jmp i_error
|
|
align 4
|
|
i_begin:
|
|
import_some_library myimport
|
|
test eax,eax
|
|
jz i_exit
|
|
i_error:
|
|
push eax
|
|
push dword library_name__
|
|
call l_lib_init_error_window
|
|
notify_window_run [arrea_xx] ; создаем окно @notify
|
|
i_exit:
|
|
pop ebx
|
|
}
|
|
;---------------------------------------------------------------------
|
|
|
|
;output:
|
|
; eax - если удачно то 0
|
|
macro load_library library_name__, library_path__, system_path__, myimport, point_dir_name__
|
|
{
|
|
local i_begin
|
|
local i_error
|
|
local i_exit
|
|
if point_dir_name__ eq
|
|
copy_path library_name__, [32], library_path__,0
|
|
else
|
|
;the macros making way /current path a program/ + name system library
|
|
copy_path library_name__, [32], library_path__,point_dir_name__
|
|
end if
|
|
push ebx
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
|
|
test eax,eax
|
|
jnz i_begin
|
|
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,system_path__ ; load of sys directory
|
|
test eax,eax
|
|
jnz i_begin
|
|
jmp i_error
|
|
align 4
|
|
i_begin:
|
|
import_some_library myimport
|
|
test eax,eax
|
|
jz i_exit
|
|
i_error:
|
|
push eax
|
|
push dword library_name__
|
|
call l_lib_init_error_window
|
|
notify_window_run [arrea_xx] ; создаем окно @notify
|
|
i_exit:
|
|
pop ebx
|
|
;---------------------------------------------------------------------
|
|
}
|
|
|
|
;description:
|
|
; макрос загрузки библиотек из системной папки, если библиотека не найдена
|
|
; тогда поиск идет в текущей папке с программой
|
|
macro sys_load_libraries _start,_end
|
|
{
|
|
local cycle0
|
|
local end_steep
|
|
local cycle0n
|
|
local cycle1
|
|
local cycle1n
|
|
local cycle1e
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
library_name__ equ [ebp]
|
|
library_path__ equ [ebp+4]
|
|
system_path__ equ [ebp+8]
|
|
my_import equ [ebp+12]
|
|
point_dir_name__ equ [ebp+16]
|
|
adr_load_lib equ dword [ebp+20]
|
|
status_lib equ dword [ebp+24]
|
|
|
|
mov ebp,_start
|
|
mov ecx,(_end-_start)/ll_struc_size
|
|
align 4
|
|
cycle0:
|
|
push ecx
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,system_path__ ; load of sys directory
|
|
test eax,eax
|
|
jnz end_steep
|
|
|
|
;the macros making way /current path a program/ + name system library
|
|
copy_path library_name__, [32], library_path__,point_dir_name__
|
|
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
|
|
test eax,eax
|
|
jnz end_steep
|
|
or status_lib,1 ; status of code - enable error - not found library
|
|
|
|
push eax
|
|
push dword library_name__
|
|
call l_lib_init_error_window
|
|
jmp cycle0n
|
|
|
|
align 4
|
|
end_steep:
|
|
mov adr_load_lib,eax ;save adr lib in memory
|
|
import_some_library my_import
|
|
test eax,eax
|
|
jz cycle0n
|
|
or status_lib,2 ; status of code - enable error - import error
|
|
push eax
|
|
push dword library_name__
|
|
call l_lib_init_error_window
|
|
cycle0n:
|
|
pop ecx
|
|
add ebp,ll_struc_size
|
|
dec ecx
|
|
jnz cycle0
|
|
|
|
;вывод сообщения об ошибке при загрузке
|
|
mov ebp,_start
|
|
mov ecx,(_end-_start)/ll_struc_size
|
|
align 4
|
|
cycle1:
|
|
mov eax,status_lib
|
|
test eax,eax
|
|
jz cycle1n
|
|
notify_window_run [arrea_xx] ; создаем окно @notify
|
|
mov eax,-1
|
|
jmp cycle1e
|
|
align 4
|
|
cycle1n:
|
|
add ebp,ll_struc_size
|
|
dec ecx
|
|
jnz cycle1
|
|
cycle1e:
|
|
}
|
|
|
|
;description:
|
|
; макрос загрузки библиотек из текущей папки с программой, если библиотека не найдена
|
|
; тогда поиск идет в системной папке
|
|
macro load_libraries _start,_end
|
|
{
|
|
local cycle0
|
|
local end_steep
|
|
local cycle0n
|
|
local cycle1
|
|
local cycle1n
|
|
local cycle1e
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
library_name__ equ [ebp]
|
|
library_path__ equ [ebp+4]
|
|
system_path__ equ [ebp+8]
|
|
my_import equ [ebp+12]
|
|
point_dir_name__ equ [ebp+16]
|
|
adr_load_lib equ dword [ebp+20]
|
|
status_lib equ dword [ebp+24]
|
|
|
|
mov ebp,_start
|
|
mov ecx,(_end-_start)/ll_struc_size
|
|
align 4
|
|
cycle0:
|
|
push ecx
|
|
|
|
;the macros making way /current path a program/ + name system library
|
|
copy_path library_name__, [32], library_path__,point_dir_name__
|
|
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
|
|
test eax,eax
|
|
jnz end_steep
|
|
|
|
mcall SF_SYS_MISC,SSF_LOAD_DLL,system_path__ ; load of sys directory
|
|
test eax,eax
|
|
jnz end_steep
|
|
or status_lib,1 ; status of code - enable error - not found library
|
|
|
|
push eax
|
|
push dword library_name__
|
|
call l_lib_init_error_window
|
|
jmp cycle0n
|
|
|
|
align 4
|
|
end_steep:
|
|
mov adr_load_lib,eax ;save adr lib in memory
|
|
import_some_library my_import
|
|
test eax,eax
|
|
jz cycle0n
|
|
or status_lib,2 ; status of code - enable error - import error
|
|
push eax
|
|
push dword library_name__
|
|
call l_lib_init_error_window
|
|
cycle0n:
|
|
pop ecx
|
|
add ebp,ll_struc_size
|
|
dec ecx
|
|
jnz cycle0
|
|
|
|
;вывод сообщения об ошибке при загрузке
|
|
mov ebp,_start
|
|
mov ecx,(_end-_start)/ll_struc_size
|
|
align 4
|
|
cycle1:
|
|
mov eax,status_lib
|
|
test eax,eax
|
|
jz cycle1n
|
|
notify_window_run [arrea_xx] ; создаем окно @notify
|
|
mov eax,-1
|
|
jmp cycle1e
|
|
align 4
|
|
cycle1n:
|
|
add ebp,ll_struc_size
|
|
dec ecx
|
|
jnz cycle1
|
|
cycle1e:
|
|
}
|
|
|
|
|
|
macro copy_path lib_name,dir_path,lib_path,point_dir_name
|
|
{
|
|
pushad ;save all registers
|
|
push dword lib_name
|
|
push dword dir_path
|
|
push dword lib_path
|
|
push dword point_dir_name
|
|
call @copy_path
|
|
|
|
add esp,16
|
|
;notify_window_run lib_path ;unblok for test load path
|
|
popad ;restore all registers
|
|
}
|
|
|
|
; включаем показ сообщения через @notify:
|
|
macro notify_window_run message
|
|
{
|
|
push eax ebx
|
|
mov eax,message ;параметры для командной строки
|
|
mov [run_notify_struct.Flags],eax
|
|
mcall SF_FILE,run_notify_struct
|
|
pop ebx eax
|
|
}
|
|
|
|
|
|
;input:
|
|
; eax - адрес библиотеки в памяти
|
|
; myimport - импортируемые функции
|
|
;output:
|
|
; eax - если удачно то 0 или указатель на имя функции которую не удалось загрузить
|
|
; ebx - разрушается
|
|
macro import_some_library myimport
|
|
{
|
|
local import_loop
|
|
local import_find
|
|
local lp
|
|
local import_find_next
|
|
local import_found
|
|
local import_done
|
|
local exit
|
|
local import_not_found
|
|
; initialize import
|
|
push esi
|
|
mov edx, eax
|
|
mov esi, myimport
|
|
cld
|
|
import_loop:
|
|
lodsd ;mov eax,dword[esi] ;add esi,4 ;получаем в eax указатель на имя импортируемой функции
|
|
test eax, eax
|
|
jz import_done ;если указатель на имя функции = 0 (в пользовательской программе)
|
|
push edx ;сохраняем начало библиотечных указателей на функции
|
|
import_find:
|
|
mov ebx, [edx]
|
|
test ebx, ebx
|
|
jz import_not_found ;если указатель на имя функции = 0 (в библиотеке)
|
|
push eax ;eax - указатель на имя экспортируемой функции (в пользовательской программе)
|
|
align 4
|
|
lp:
|
|
mov cl, [eax]
|
|
cmp cl, [ebx] ;сравниваем имена функций в библиотеке и в пользовательской программе
|
|
jnz import_find_next ;если названия не совпали
|
|
test cl, cl
|
|
jz import_found ;если названия совпали, и уже конец строки (cl=0)
|
|
inc eax
|
|
inc ebx
|
|
jmp lp
|
|
import_find_next:
|
|
pop eax
|
|
add edx, 8 ;8 = 4 байта указатель на название и 4 байта указатель на функцию
|
|
jmp import_find
|
|
import_found:
|
|
pop ebx ;востанавливаем указатель на имя функции (который был в eax) и освобождаем стек
|
|
mov eax, [edx+4] ;eax = указатель на функцию (в библиотеке)
|
|
mov [esi-4], eax ;копируем указатель (на функцию) в программу, -4 ставим потому что esi было сдвинуто командой lodsd
|
|
pop edx ;устанавливаем edx на начало библиотечных функций
|
|
;--- проверяем совпадает ли имя экспортированной функции с 'lib_init'
|
|
if library_fun_memory_alloc eq
|
|
else
|
|
cmp dword[ebx],'lib_'
|
|
jne import_loop
|
|
cmp dword[ebx+4],'init'
|
|
jne import_loop
|
|
;cmp byte[ebx+8],0
|
|
;jne import_loop
|
|
;--- если имя функции совпало с 'lib_init' попадаем сюда
|
|
;подключение функций для работы с памятью
|
|
;push eax
|
|
;call dll.Init
|
|
pushad
|
|
mov esi,eax
|
|
mov eax,library_fun_memory_alloc
|
|
mov ebx,library_fun_memory_free
|
|
mov ecx,library_fun_memory_realloc
|
|
mov edx,library_fun_dll_load
|
|
call dword esi
|
|
popad
|
|
end if
|
|
jmp import_loop
|
|
import_not_found:
|
|
add esp,4
|
|
jmp exit
|
|
import_done:
|
|
xor eax,eax ;=0 все загрузилось удачно
|
|
exit:
|
|
pop esi
|
|
}
|
|
;---------------------------------------------------------------------
|
|
|
|
ll_struc_size = 28;($-library_name__) ; constant size of struct
|
|
struc l_libs library_name__, library_path__, system_path__, my_import, point_dir_name; struct for loading libraries
|
|
{
|
|
.library_name__ dd library_name__ ; имя загружаемой библиотеки
|
|
|
|
.library_path__ dd library_path__ ; указатель на буфер в котором будет софоримирован путь к библиотеки, если нужно вычислить путь до либы с места запуска программы, обычно нужно, в случаях, если либа расположена в той же папке
|
|
.complete_path dd system_path__ ; путь который четко содержит путь
|
|
.my_import dd my_import
|
|
if point_dir_name eq
|
|
.point_dir_name__ dd 0
|
|
else
|
|
.point_dir_name__ dd point_dir_name ; имя вложенной дирректории в кторой храняться подгружаемые модули.
|
|
end if
|
|
.adr_load_lib dd 0
|
|
.status_lib dd 0 ;status of load library
|
|
;
|
|
}
|