Subversion Repositories Kolibri OS

Rev

Rev 8227 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8227 IgorA 1
; The macros for load any library/libraries:
2
; Copyright (c) 2009, 
3
; All rights reserved.
4
 
5
 
6
 
7
macro @use_library mem_alloc,mem_free,mem_realloc,dll_load
8
{
9
local lp1
10
local lp2
11
local lp3
12
local lp4
13
local lp5
14
local lp6
15
local file_name
16
local l_lib_m1
17
local l_lib_m2
18
local l_lib_m3
19
local l_lib_m4
20
 
21
library_fun_memory_alloc equ mem_alloc
22
library_fun_memory_free equ mem_free
23
library_fun_memory_realloc equ mem_realloc
24
library_fun_dll_load equ dll_load
25
 
26
align 4
27
arrea_xx dd 0
28
file_name db '/sys/@notify',0
29
 
30
if lang eq ru
31
	l_lib_m1 db '"Системная ошибка',13,10,'Не найдена библиотека ',39,0
32
	l_lib_m2 db '"Системная ошибка',13,10,'Ошибка при импорте библиотеки ',39,0
33
	l_lib_m3 db 39,13,10,'не найдена функция ',39,0
34
	l_lib_m4 db 39,'" -tE',0
35
else
36
	l_lib_m1 db '"System error',13,10,'Sorry I cannot found library ',39,0
37
	l_lib_m2 db '"System error',13,10,'Error on load import library ',39,0
38
	l_lib_m3 db 39,13,10,'cannot found function ',39,0
39
	l_lib_m4 db 39,'" -tE',0
40
end if
41
 
42
align 4
43
run_notify_struct:
44
	.Function dd 7
45
	.Position dd 0
46
	.Flags dd ?
47
	.Count dd 0
48
	.Buffer dd 0
49
		db 0
50
	.FileName dd file_name
51
 
52
@library_name     equ    dword [esp+16]
53
@cur_dir_path     equ    dword [esp+12]
54
@library_path     equ    dword [esp+8]
55
@point_dir_name   equ    dword [esp+4]
56
 
57
;description:
58
; готовим текст для показа через @notify:
59
; 1) выделяем память в [arrea_xx] но не больше одного раза
60
; 2) копируем заголовок (если есть имя функции то добавляем его к заголовку) и текст сообщения в [arrea_xx]
61
;input:
62
; ebp+8  - library name
63
; ebp+12 - 0 или имя функции, которую не удалось экспортировать
64
;output:
65
; eax = -1
66
align 4
67
l_lib_init_error_window:
68
	push ebp
69
	mov ebp,esp
70
	cmp dword[arrea_xx],0
71
	jne .no_msg ;если раньше было создано другое сообщение
72
	pushad
73
 
74
	mcall SF_SYS_MISC,SSF_HEAP_INIT
75
	mcall SF_SYS_MISC,SSF_MEM_ALLOC,4096
76
	mov [arrea_xx],eax
77
 
78
	mov edi,eax
79
	mov esi,l_lib_m2 ;сообщение если не удалось импортировать функцию
80
	cmp dword[ebp+12],0
81
	je @f
82
	mov esi,l_lib_m1 ;сообщение если не удалось загрузить библиотеку
83
align 4
84
@@:
85
	movsb
86
	cmp byte[esi],0
87
	jne @b
88
	;добавляем имя библиотеки
89
	mov esi,[ebp+8]
90
align 4
91
@@:
92
	movsb
93
	cmp byte[esi],0
94
	jne @b
95
 
96
	cmp dword[ebp+12],0
97
	je .lp1
98
	;добавляем середину сообщения
99
	mov esi,l_lib_m3
100
align 4
101
@@:
102
	movsb
103
	cmp byte[esi],0
104
	jne @b
105
	;добавляем имя функции
106
	mov esi,[ebp+12]
107
align 4
108
@@:
109
	movsb
110
	cmp byte[esi],0
111
	jne @b
112
 
113
	.lp1: ;сообщение если не удалось загрузить библиотеку
114
	;добавляем конец сообщения
115
	mov esi,l_lib_m4
116
align 4
117
@@:
118
	movsb
119
	cmp byte[esi],0
120
	jne @b
121
	mov byte[edi],0
122
 
123
	popad
124
	.no_msg:
125
	or eax,-1
126
	pop ebp
127
	ret 8
128
 
129
align 4
130
@copy_path:
131
	mov     esi,@cur_dir_path
132
	mov     edi,@library_path
133
	xor     eax,eax
134
	cld
135
align 4
136
.lp1:
137
	lodsb
138
	stosb
139
	test    eax,eax
140
	jnz     .lp1
141
	mov     esi,edi
142
	dec     esi ;переход на символ конца строки @cur_dir_path
143
	std
144
align 4
145
.lp2:
146
	lodsb
147
	cmp     al,'/'
148
	jnz     .lp2
149
	mov     edi,esi
150
	add     edi,2
151
	cld
152
	mov     esi,@point_dir_name
153
	test    esi,esi
154
	jz      .str_lp4
155
 
156
	;проверка относительных путей c двумя точками '../'
157
	cmp word[esi],'..'
158
	jne .lp3
159
	dec edi ;для перехода на '/'
160
.lp6:
161
		add esi,3 ;пропускаем одно поднятие '../'
162
.lp5:
163
		dec edi ;идем по папкам
164
		cmp byte[edi],'/'
165
		jnz .lp5
166
	cmp word[esi],'..'
167
	je .lp6
168
	inc edi ;для перехода на '/'
169
 
170
	;копирование относительного пути
171
align 4
172
.lp3:
173
	lodsb
174
	stosb
175
	test    eax,eax
176
	jnz     .lp3
177
	dec     edi
178
.str_lp4:
179
	mov     esi,@library_name
180
align 4
181
.lp4:
182
	lodsb
183
	stosb
184
	test    eax,eax
185
	jnz     .lp4
186
	ret
187
}
188
;---------------------------------------------------------------------
189
 
190
macro sys_load_library library_name__, library_path__, system_path__, myimport, point_dir_name__
191
{
192
local i_begin
193
local i_error
194
local i_exit
8236 IgorA 195
	push ebx
8227 IgorA 196
	mcall	SF_SYS_MISC,SSF_LOAD_DLL,system_path__   ; load of sys directory
197
	test	eax,eax
198
	jnz		i_begin
199
 
200
if point_dir_name__ eq
201
		copy_path   library_name__, [32], library_path__,0
202
else
203
		;the macros making way /current path a program/ + name system library
204
		copy_path   library_name__, [32], library_path__,point_dir_name__
205
end if
206
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
207
		test	eax,eax
208
		jnz		i_begin
209
		jmp		i_error
210
align 4
211
	i_begin:
212
		import_boxlib myimport
213
		test	eax,eax
214
		jz		i_exit
215
	i_error:
216
		push	eax
217
		push	dword library_name__
218
		call	l_lib_init_error_window
219
		notify_window_run [arrea_xx] ; создаем окно @notify
220
	i_exit:
8236 IgorA 221
	pop ebx
8227 IgorA 222
}
223
;---------------------------------------------------------------------
224
 
8236 IgorA 225
;output:
226
; eax - если удачно то 0
8227 IgorA 227
macro load_library library_name__, library_path__, system_path__, myimport, point_dir_name__
228
{
229
local i_begin
230
local i_error
231
local i_exit
8236 IgorA 232
	push ebx
8227 IgorA 233
if point_dir_name__ eq
234
		copy_path   library_name__, [32], library_path__,0
235
else
236
		;the macros making way /current path a program/ + name system library
237
		copy_path   library_name__, [32], library_path__,point_dir_name__
238
end if
239
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
240
		test	eax,eax
241
		jnz		i_begin
242
 
243
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,system_path__ ; load of sys directory
244
		test	eax,eax
245
		jnz		i_begin
246
		jmp		i_error
247
align 4
248
	i_begin:
249
		import_boxlib myimport
250
		test	eax,eax
251
		jz		i_exit
252
	i_error:
253
		push	eax
254
		push	dword library_name__
255
		call	l_lib_init_error_window
256
		notify_window_run [arrea_xx] ; создаем окно @notify
257
	i_exit:
8236 IgorA 258
	pop ebx
8227 IgorA 259
;---------------------------------------------------------------------
260
}
261
 
262
;description:
263
; макрос загрузки библиотек из системной папки, если библиотека не найдена
264
; тогда поиск идет в текущей папке с программой
265
macro sys_load_libraries _start,_end
266
{
267
local cycle0
268
local end_steep
269
local cycle0n
270
local cycle1
271
local cycle1n
272
local cycle1e
273
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
274
library_name__            equ [ebp]
275
library_path__            equ [ebp+4]
276
system_path__             equ [ebp+8]
277
my_import                 equ [ebp+12]
278
point_dir_name__          equ [ebp+16]
279
adr_load_lib              equ dword [ebp+20]
280
status_lib                equ dword [ebp+24]
281
 
282
	mov	ebp,_start
283
	mov	ecx,(_end-_start)/ll_struc_size
284
align 4
285
	cycle0:
286
		push	ecx
287
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,system_path__   ; load of sys directory
288
        test    eax,eax
289
        jnz     end_steep
290
 
291
        ;the macros making way /current path a program/ + name system library
292
		copy_path  library_name__, [32], library_path__,point_dir_name__
293
 
294
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
295
        test    eax,eax
296
        jnz     end_steep
297
        or      status_lib,1          ; status of code - enable error - not found library
298
 
299
		push	eax
300
		push	dword library_name__
301
		call	l_lib_init_error_window
302
        jmp		cycle0n
303
 
304
align 4
305
	end_steep:
306
		mov		adr_load_lib,eax        ;save adr lib in memory
307
		import_boxlib my_import
308
		test	eax,eax
309
		jz		cycle0n
310
		or		status_lib,2          ; status of code - enable error - import error
311
		push	eax
312
		push	dword library_name__
313
		call	l_lib_init_error_window
314
	cycle0n:
315
		pop     ecx
316
		add     ebp,ll_struc_size
317
		dec     ecx
318
		jnz     cycle0
319
 
320
	;вывод сообщения об ошибке при загрузке
321
	mov     ebp,_start
322
	mov     ecx,(_end-_start)/ll_struc_size
323
align 4
324
	cycle1:
325
		mov     eax,status_lib
326
		test    eax,eax
327
		jz      cycle1n
328
		notify_window_run [arrea_xx] ; создаем окно @notify
329
		mov		eax,-1
330
		jmp		cycle1e
331
align 4
332
		cycle1n:
333
		add     ebp,ll_struc_size
334
		dec     ecx
335
		jnz     cycle1
336
	cycle1e:
337
}
338
 
339
;description:
340
; макрос загрузки библиотек из текущей папки с программой, если библиотека не найдена
341
; тогда поиск идет в системной папке
342
macro load_libraries _start,_end
343
{
344
local cycle0
345
local end_steep
346
local cycle0n
347
local cycle1
348
local cycle1n
349
local cycle1e
350
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
351
library_name__            equ [ebp]
352
library_path__            equ [ebp+4]
353
system_path__             equ [ebp+8]
354
my_import                 equ [ebp+12]
355
point_dir_name__          equ [ebp+16]
356
adr_load_lib              equ dword [ebp+20]
357
status_lib                equ dword [ebp+24]
358
 
359
	mov	ebp,_start
360
	mov	ecx,(_end-_start)/ll_struc_size
361
align 4
362
	cycle0:
363
		push	ecx
364
 
365
		;the macros making way /current path a program/ + name system library
366
		copy_path    library_name__, [32], library_path__,point_dir_name__
367
 
368
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,library_path__  ; load of alternative
369
		test	eax,eax
370
		jnz		end_steep
371
 
372
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,system_path__   ; load of sys directory
373
		test	eax,eax
374
		jnz		end_steep
375
		or		status_lib,1          ; status of code - enable error - not found library
376
 
377
		push	eax
378
		push	dword library_name__
379
		call	l_lib_init_error_window
380
		jmp		cycle0n
381
 
382
align 4
383
	end_steep:
384
		mov		adr_load_lib,eax        ;save adr lib in memory
385
		import_boxlib my_import
386
		test	eax,eax
387
		jz		cycle0n
388
		or		status_lib,2          ; status of code - enable error - import error
389
		push	eax
390
		push	dword library_name__
391
		call	l_lib_init_error_window
392
	cycle0n:
393
		pop     ecx
394
		add     ebp,ll_struc_size
395
		dec     ecx
396
		jnz     cycle0
397
 
398
	;вывод сообщения об ошибке при загрузке
399
	mov     ebp,_start
400
	mov     ecx,(_end-_start)/ll_struc_size
401
align 4
402
	cycle1:
403
		mov     eax,status_lib
404
		test    eax,eax
405
		jz      cycle1n
406
		notify_window_run [arrea_xx] ; создаем окно @notify
407
		mov		eax,-1
408
		jmp		cycle1e
409
align 4
410
		cycle1n:
411
		add     ebp,ll_struc_size
412
		dec     ecx
413
		jnz     cycle1
414
	cycle1e:
415
}
416
 
417
 
418
macro copy_path lib_name,dir_path,lib_path,point_dir_name
419
{
420
pushad  ;save all registers
421
	push dword lib_name
422
	push dword dir_path
423
	push dword lib_path
424
	push dword point_dir_name
425
	call @copy_path
426
 
427
	add  esp,16
428
	;notify_window_run lib_path ;unblok for test load path
429
popad   ;restore all registers
430
}
431
 
432
; включаем показ сообщения через @notify:
433
macro notify_window_run message
434
{
435
push eax ebx
436
	mov eax,message ;параметры для командной строки
437
	mov [run_notify_struct.Flags],eax
438
	mcall SF_FILE,run_notify_struct
439
pop ebx eax
440
}
441
 
442
 
443
;input:
444
; eax - адрес библиотеки в памяти
445
; myimport - импортируемые функции
446
;output:
447
; eax - если удачно то 0 или указатель на имя функции которую не удалось загрузить
8236 IgorA 448
; ebx - разрушается
8227 IgorA 449
macro import_boxlib myimport
450
{
451
local import_loop
452
local import_find
453
local lp
454
local import_find_next
455
local import_found
456
local import_done
457
local exit
458
local import_not_found
459
; initialize import
8236 IgorA 460
	push esi
8227 IgorA 461
        mov     edx, eax
8236 IgorA 462
        mov     esi, myimport
463
		cld
8227 IgorA 464
import_loop:
465
        lodsd	;mov eax,dword[esi] ;add esi,4 ;получаем в eax указатель на имя импортируемой функции
466
        test    eax, eax
467
        jz      import_done ;если указатель на имя функции = 0 (в пользовательской программе)
468
        push    edx ;сохраняем начало библиотечных указателей на функции
469
import_find:
470
        mov     ebx, [edx]
471
        test    ebx, ebx
472
        jz      import_not_found ;если указатель на имя функции = 0 (в библиотеке)
473
        push    eax ;eax - указатель на имя экспортируемой функции (в пользовательской программе)
8236 IgorA 474
align 4
8227 IgorA 475
lp:
476
        mov     cl, [eax]
477
        cmp     cl, [ebx] ;сравниваем имена функций в библиотеке и в пользовательской программе
478
        jnz     import_find_next ;если названия не совпали
479
        test    cl, cl
480
        jz      import_found ;если названия совпали, и уже конец строки (cl=0)
481
        inc     eax
482
        inc     ebx
483
        jmp     lp
484
import_find_next:
485
        pop     eax
486
        add     edx, 8 ;8 = 4 байта указатель на название и 4 байта указатель на функцию
487
        jmp     import_find
488
import_found:
489
        pop     ebx ;востанавливаем указатель на имя функции (который был в eax) и освобождаем стек
490
        mov     eax, [edx+4] ;eax = указатель на функцию (в библиотеке)
491
        mov     [esi-4], eax ;копируем указатель (на функцию) в программу, -4 ставим потому что esi было сдвинуто командой lodsd
492
        pop     edx ;устанавливаем edx на начало библиотечных функций
493
;--- проверяем совпадает ли имя экспортированной функции с 'lib_init'
494
if library_fun_memory_alloc eq
495
else
496
		cmp dword[ebx],'lib_'
497
		jne		import_loop
498
		cmp dword[ebx+4],'init'
499
		jne		import_loop
500
		;cmp  byte[ebx+8],0
501
		;jne		import_loop
502
;--- если имя функции совпало с 'lib_init' попадаем сюда
503
		;подключение функций для работы с памятью
504
		;push eax
505
		;call dll.Init
506
		pushad
507
		mov esi,eax
508
		mov	eax,library_fun_memory_alloc
509
		mov	ebx,library_fun_memory_free
510
		mov	ecx,library_fun_memory_realloc
511
		mov	edx,library_fun_dll_load
512
		call dword esi
513
		popad
514
end if
515
        jmp     import_loop
516
import_not_found:
517
        add     esp,4
518
        jmp     exit
519
import_done:
520
        xor     eax,eax ;=0 все загрузилось удачно
521
exit:
8236 IgorA 522
	pop esi
8227 IgorA 523
}
524
;---------------------------------------------------------------------
525
 
526
ll_struc_size = 28;($-library_name__)    ; constant   size of struct
527
struc l_libs library_name__, library_path__, system_path__, my_import, point_dir_name; struct for loading libraries
528
{
529
.library_name__           dd library_name__        ; имя загружаемой библиотеки
530
 
531
.library_path__           dd library_path__        ; указатель на буфер в котором будет софоримирован путь к библиотеки, если нужно вычислить путь до либы с места запуска программы, обычно нужно, в случаях, если либа расположена в той же папке
532
.complete_path            dd system_path__         ; путь который четко содержит путь
533
.my_import                dd my_import
534
if point_dir_name eq
535
.point_dir_name__	dd 0
536
else
537
.point_dir_name__	dd point_dir_name	   ; имя вложенной дирректории в кторой храняться подгружаемые модули.
538
end if
539
.adr_load_lib           dd 0
540
.status_lib             dd 0          ;status of load library
541
;
542
}