Subversion Repositories Kolibri OS

Rev

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