From b9e8e3f7350998a27574e3bb57fcce05ad544e0e Mon Sep 17 00:00:00 2001 From: IgorA Date: Fri, 20 Nov 2020 19:47:45 +0000 Subject: [PATCH] add new version 'load_lib.mac', 'animage' use new macros 'load_lib.mac' git-svn-id: svn://kolibrios.org@8227 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/dll.inc | 2 + programs/load_lib.mac | 534 ++++++++++++++++++++++ programs/media/animage/trunk/animage.asm | 6 +- programs/media/animage/trunk/lib_data.inc | 22 +- 4 files changed, 543 insertions(+), 21 deletions(-) create mode 100644 programs/load_lib.mac diff --git a/programs/dll.inc b/programs/dll.inc index 9d47ec790d..151c374e7b 100644 --- a/programs/dll.inc +++ b/programs/dll.inc @@ -125,9 +125,11 @@ proc strcmp, str1:dword, str2:dword ret endp ;----------------------------------------------------------------------------- +if defined dll.Load s_libdir: db '/sys/lib/' .fname rb 32 +end if ;----------------------------------------------------------------------------- proc mem.Alloc, size push ebx ecx diff --git a/programs/load_lib.mac b/programs/load_lib.mac new file mode 100644 index 0000000000..303523fff9 --- /dev/null +++ b/programs/load_lib.mac @@ -0,0 +1,534 @@ +; The macros for load any library/libraries: +; Copyright (c) 2009, +; 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 +arrea_xx dd 0 +file_name db '/sys/@notify',0 + +if lang eq 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 + 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 + +@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] + +;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 + +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 + + 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_boxlib 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: +} +;--------------------------------------------------------------------- + +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 + 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_boxlib 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: +;--------------------------------------------------------------------- +} + +;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_boxlib 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_boxlib 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 или указатель на имя функции которую не удалось загрузить +macro import_boxlib 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 + + mov edx, eax + mov esi,myimport +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 - указатель на имя экспортируемой функции (в пользовательской программе) +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: +} +;--------------------------------------------------------------------- + +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 +; +} diff --git a/programs/media/animage/trunk/animage.asm b/programs/media/animage/trunk/animage.asm index 291ce6f89b..b58fb0d71c 100644 --- a/programs/media/animage/trunk/animage.asm +++ b/programs/media/animage/trunk/animage.asm @@ -35,7 +35,7 @@ ; design by golus use32 -org 0x0 +org 0 db 'MENUET01' dd 1, START, IM_END, I_END dd stacktop, file_path, cur_dir_path @@ -44,13 +44,13 @@ include '../../../config.inc' ;for nightbuild include '../../../macros.inc' include '../../../proc32.inc' include '../../../KOSfuncs.inc' -include '../../../develop/libraries/box_lib/load_lib.mac' +include '../../../load_lib.mac' include '../../../dll.inc' include '../../../develop/libraries/libs-dev/libio/libio.inc' include '../../../develop/libraries/libs-dev/libimg/libimg.inc' ;include '../../../debug.inc' -@use_library_mem mem.Alloc,mem.Free,mem.ReAlloc,dll.Load +@use_library mem.Alloc,mem.Free,mem.ReAlloc,dll.Load ;--------------------------------------------------------- ; *** константы для интерфейса *** diff --git a/programs/media/animage/trunk/lib_data.inc b/programs/media/animage/trunk/lib_data.inc index 424e90b7c6..22af7db7c6 100644 --- a/programs/media/animage/trunk/lib_data.inc +++ b/programs/media/animage/trunk/lib_data.inc @@ -1,27 +1,13 @@ ;--------------------------------------------------------------------- -head_f_i: -head_f_l db 'System error',0 -;--------------------------------------------------------------------- system_dir_1: db '/sys/lib/libimg.obj',0 -err_message_found_lib_1 db 39,'libimg.obj',39,' - Not found!',0 -err_message_import_1 db 39,'libimg.obj',39,' - Wrong import!',0 - -system_dir_ProcLib db '/sys/lib/proc_lib.obj',0 -err_message_found_lib2 db 39,'proc_lib.obj',39,' - Not found!',0 -err_message_import2 db 39,'proc_lib.obj',39,' - Wrong import!',0 - +system_dir_2 db '/sys/lib/proc_lib.obj',0 system_dir_3: db '/sys/lib/kmenu.obj',0 -err_message_found_lib_3 db 39,'kmenu.obj',39,' - Not found!',0 -err_message_import_3 db 39,'kmenu.obj',39,' - Wrong import!',0 ;--------------------------------------------------------------------- align 4 l_libs_start: - lib1 l_libs system_dir_1+9, cur_dir_path, library_path, system_dir_1,\ - err_message_found_lib_1, head_f_l, import_libimg, err_message_import_1, head_f_i - lib2 l_libs system_dir_ProcLib+9, cur_dir_path, library_path, system_dir_ProcLib, \ - err_message_found_lib2, head_f_l, ProcLib_import, err_message_import2, head_f_i - lib3 l_libs system_dir_3+9, cur_dir_path, library_path, system_dir_3,\ - err_message_found_lib_3, head_f_l, import_libkmenu, err_message_import_3, head_f_i + lib1 l_libs system_dir_1+9, library_path, system_dir_1, import_libimg + lib2 l_libs system_dir_2+9, library_path, system_dir_2, ProcLib_import + lib3 l_libs system_dir_3+9, library_path, system_dir_3, import_libkmenu end_l_libs: ;--------------------------------------------------------------------- align 4