Subversion Repositories Kolibri OS

Rev

Rev 8236 | Go to most recent revision | Details | 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
195
 
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:
221
}
222
;---------------------------------------------------------------------
223
 
224
macro load_library library_name__, library_path__, system_path__, myimport, point_dir_name__
225
{
226
local i_begin
227
local i_error
228
local i_exit
229
 
230
if point_dir_name__ eq
231
		copy_path   library_name__, [32], library_path__,0
232
else
233
		;the macros making way /current path a program/ + name system library
234
		copy_path   library_name__, [32], library_path__,point_dir_name__
235
end if
236
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
237
		test	eax,eax
238
		jnz		i_begin
239
 
240
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,system_path__ ; load of sys directory
241
		test	eax,eax
242
		jnz		i_begin
243
		jmp		i_error
244
align 4
245
	i_begin:
246
		import_boxlib myimport
247
		test	eax,eax
248
		jz		i_exit
249
	i_error:
250
		push	eax
251
		push	dword library_name__
252
		call	l_lib_init_error_window
253
		notify_window_run [arrea_xx] ; создаем окно @notify
254
	i_exit:
255
;---------------------------------------------------------------------
256
}
257
 
258
;description:
259
; макрос загрузки библиотек из системной папки, если библиотека не найдена
260
; тогда поиск идет в текущей папке с программой
261
macro sys_load_libraries _start,_end
262
{
263
local cycle0
264
local end_steep
265
local cycle0n
266
local cycle1
267
local cycle1n
268
local cycle1e
269
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
270
library_name__            equ [ebp]
271
library_path__            equ [ebp+4]
272
system_path__             equ [ebp+8]
273
my_import                 equ [ebp+12]
274
point_dir_name__          equ [ebp+16]
275
adr_load_lib              equ dword [ebp+20]
276
status_lib                equ dword [ebp+24]
277
 
278
	mov	ebp,_start
279
	mov	ecx,(_end-_start)/ll_struc_size
280
align 4
281
	cycle0:
282
		push	ecx
283
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,system_path__   ; load of sys directory
284
        test    eax,eax
285
        jnz     end_steep
286
 
287
        ;the macros making way /current path a program/ + name system library
288
		copy_path  library_name__, [32], library_path__,point_dir_name__
289
 
290
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,library_path__ ; load of alternative
291
        test    eax,eax
292
        jnz     end_steep
293
        or      status_lib,1          ; status of code - enable error - not found library
294
 
295
		push	eax
296
		push	dword library_name__
297
		call	l_lib_init_error_window
298
        jmp		cycle0n
299
 
300
align 4
301
	end_steep:
302
		mov		adr_load_lib,eax        ;save adr lib in memory
303
		import_boxlib my_import
304
		test	eax,eax
305
		jz		cycle0n
306
		or		status_lib,2          ; status of code - enable error - import error
307
		push	eax
308
		push	dword library_name__
309
		call	l_lib_init_error_window
310
	cycle0n:
311
		pop     ecx
312
		add     ebp,ll_struc_size
313
		dec     ecx
314
		jnz     cycle0
315
 
316
	;вывод сообщения об ошибке при загрузке
317
	mov     ebp,_start
318
	mov     ecx,(_end-_start)/ll_struc_size
319
align 4
320
	cycle1:
321
		mov     eax,status_lib
322
		test    eax,eax
323
		jz      cycle1n
324
		notify_window_run [arrea_xx] ; создаем окно @notify
325
		mov		eax,-1
326
		jmp		cycle1e
327
align 4
328
		cycle1n:
329
		add     ebp,ll_struc_size
330
		dec     ecx
331
		jnz     cycle1
332
	cycle1e:
333
}
334
 
335
;description:
336
; макрос загрузки библиотек из текущей папки с программой, если библиотека не найдена
337
; тогда поиск идет в системной папке
338
macro load_libraries _start,_end
339
{
340
local cycle0
341
local end_steep
342
local cycle0n
343
local cycle1
344
local cycle1n
345
local cycle1e
346
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
347
library_name__            equ [ebp]
348
library_path__            equ [ebp+4]
349
system_path__             equ [ebp+8]
350
my_import                 equ [ebp+12]
351
point_dir_name__          equ [ebp+16]
352
adr_load_lib              equ dword [ebp+20]
353
status_lib                equ dword [ebp+24]
354
 
355
	mov	ebp,_start
356
	mov	ecx,(_end-_start)/ll_struc_size
357
align 4
358
	cycle0:
359
		push	ecx
360
 
361
		;the macros making way /current path a program/ + name system library
362
		copy_path    library_name__, [32], library_path__,point_dir_name__
363
 
364
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,library_path__  ; load of alternative
365
		test	eax,eax
366
		jnz		end_steep
367
 
368
		mcall	SF_SYS_MISC,SSF_LOAD_DLL,system_path__   ; load of sys directory
369
		test	eax,eax
370
		jnz		end_steep
371
		or		status_lib,1          ; status of code - enable error - not found library
372
 
373
		push	eax
374
		push	dword library_name__
375
		call	l_lib_init_error_window
376
		jmp		cycle0n
377
 
378
align 4
379
	end_steep:
380
		mov		adr_load_lib,eax        ;save adr lib in memory
381
		import_boxlib my_import
382
		test	eax,eax
383
		jz		cycle0n
384
		or		status_lib,2          ; status of code - enable error - import error
385
		push	eax
386
		push	dword library_name__
387
		call	l_lib_init_error_window
388
	cycle0n:
389
		pop     ecx
390
		add     ebp,ll_struc_size
391
		dec     ecx
392
		jnz     cycle0
393
 
394
	;вывод сообщения об ошибке при загрузке
395
	mov     ebp,_start
396
	mov     ecx,(_end-_start)/ll_struc_size
397
align 4
398
	cycle1:
399
		mov     eax,status_lib
400
		test    eax,eax
401
		jz      cycle1n
402
		notify_window_run [arrea_xx] ; создаем окно @notify
403
		mov		eax,-1
404
		jmp		cycle1e
405
align 4
406
		cycle1n:
407
		add     ebp,ll_struc_size
408
		dec     ecx
409
		jnz     cycle1
410
	cycle1e:
411
}
412
 
413
 
414
macro copy_path lib_name,dir_path,lib_path,point_dir_name
415
{
416
pushad  ;save all registers
417
	push dword lib_name
418
	push dword dir_path
419
	push dword lib_path
420
	push dword point_dir_name
421
	call @copy_path
422
 
423
	add  esp,16
424
	;notify_window_run lib_path ;unblok for test load path
425
popad   ;restore all registers
426
}
427
 
428
; включаем показ сообщения через @notify:
429
macro notify_window_run message
430
{
431
push eax ebx
432
	mov eax,message ;параметры для командной строки
433
	mov [run_notify_struct.Flags],eax
434
	mcall SF_FILE,run_notify_struct
435
pop ebx eax
436
}
437
 
438
 
439
;input:
440
; eax - адрес библиотеки в памяти
441
; myimport - импортируемые функции
442
;output:
443
; eax - если удачно то 0 или указатель на имя функции которую не удалось загрузить
444
macro import_boxlib myimport
445
{
446
local import_loop
447
local import_find
448
local lp
449
local import_find_next
450
local import_found
451
local import_done
452
local exit
453
local import_not_found
454
; initialize import
455
 
456
        mov     edx, eax
457
        mov     esi,myimport
458
import_loop:
459
        lodsd	;mov eax,dword[esi] ;add esi,4 ;получаем в eax указатель на имя импортируемой функции
460
        test    eax, eax
461
        jz      import_done ;если указатель на имя функции = 0 (в пользовательской программе)
462
        push    edx ;сохраняем начало библиотечных указателей на функции
463
import_find:
464
        mov     ebx, [edx]
465
        test    ebx, ebx
466
        jz      import_not_found ;если указатель на имя функции = 0 (в библиотеке)
467
        push    eax ;eax - указатель на имя экспортируемой функции (в пользовательской программе)
468
lp:
469
        mov     cl, [eax]
470
        cmp     cl, [ebx] ;сравниваем имена функций в библиотеке и в пользовательской программе
471
        jnz     import_find_next ;если названия не совпали
472
        test    cl, cl
473
        jz      import_found ;если названия совпали, и уже конец строки (cl=0)
474
        inc     eax
475
        inc     ebx
476
        jmp     lp
477
import_find_next:
478
        pop     eax
479
        add     edx, 8 ;8 = 4 байта указатель на название и 4 байта указатель на функцию
480
        jmp     import_find
481
import_found:
482
        pop     ebx ;востанавливаем указатель на имя функции (который был в eax) и освобождаем стек
483
        mov     eax, [edx+4] ;eax = указатель на функцию (в библиотеке)
484
        mov     [esi-4], eax ;копируем указатель (на функцию) в программу, -4 ставим потому что esi было сдвинуто командой lodsd
485
        pop     edx ;устанавливаем edx на начало библиотечных функций
486
;--- проверяем совпадает ли имя экспортированной функции с 'lib_init'
487
if library_fun_memory_alloc eq
488
else
489
		cmp dword[ebx],'lib_'
490
		jne		import_loop
491
		cmp dword[ebx+4],'init'
492
		jne		import_loop
493
		;cmp  byte[ebx+8],0
494
		;jne		import_loop
495
;--- если имя функции совпало с 'lib_init' попадаем сюда
496
		;подключение функций для работы с памятью
497
		;push eax
498
		;call dll.Init
499
		pushad
500
		mov esi,eax
501
		mov	eax,library_fun_memory_alloc
502
		mov	ebx,library_fun_memory_free
503
		mov	ecx,library_fun_memory_realloc
504
		mov	edx,library_fun_dll_load
505
		call dword esi
506
		popad
507
end if
508
        jmp     import_loop
509
import_not_found:
510
        add     esp,4
511
        jmp     exit
512
import_done:
513
        xor     eax,eax ;=0 все загрузилось удачно
514
exit:
515
}
516
;---------------------------------------------------------------------
517
 
518
ll_struc_size = 28;($-library_name__)    ; constant   size of struct
519
struc l_libs library_name__, library_path__, system_path__, my_import, point_dir_name; struct for loading libraries
520
{
521
.library_name__           dd library_name__        ; имя загружаемой библиотеки
522
 
523
.library_path__           dd library_path__        ; указатель на буфер в котором будет софоримирован путь к библиотеки, если нужно вычислить путь до либы с места запуска программы, обычно нужно, в случаях, если либа расположена в той же папке
524
.complete_path            dd system_path__         ; путь который четко содержит путь
525
.my_import                dd my_import
526
if point_dir_name eq
527
.point_dir_name__	dd 0
528
else
529
.point_dir_name__	dd point_dir_name	   ; имя вложенной дирректории в кторой храняться подгружаемые модули.
530
end if
531
.adr_load_lib           dd 0
532
.status_lib             dd 0          ;status of load library
533
;
534
}