Rev 9976 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2288 | clevermous | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
10051 | ace_dent | 3 | ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;; |
6502 | pathoswith | 4 | ;; Distributed under terms of the GNU General Public License. ;; |
2288 | clevermous | 5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
7 | |||
8 | |||
7136 | dunkaist | 9 | DRV_COMPAT = 5 ;minimal required drivers version |
10 | DRV_CURRENT = 6 ;current drivers model version |
||
2288 | clevermous | 11 | |
7136 | dunkaist | 12 | DRV_VERSION = (DRV_COMPAT shl 16) or DRV_CURRENT |
13 | PID_KERNEL = 1 ;os_idle thread |
||
2288 | clevermous | 14 | |
15 | |||
16 | |||
17 | align 4 |
||
18 | proc get_notify stdcall, p_ev:dword |
||
19 | |||
20 | .wait: |
||
21 | mov ebx, [current_slot] |
||
9715 | Doczom | 22 | test dword [ebx + APPDATA.event_mask], EVENT_NOTIFY |
2288 | clevermous | 23 | jz @f |
9715 | Doczom | 24 | and dword [ebx + APPDATA.event_mask], not EVENT_NOTIFY |
2288 | clevermous | 25 | mov edi, [p_ev] |
26 | mov dword [edi], EV_INTR |
||
9715 | Doczom | 27 | mov eax, [ebx + APPDATA.event] |
2288 | clevermous | 28 | mov dword [edi+4], eax |
29 | ret |
||
30 | @@: |
||
31 | call change_task |
||
32 | jmp .wait |
||
33 | endp |
||
34 | |||
35 | |||
36 | |||
37 | handle equ IOCTL.handle |
||
38 | io_code equ IOCTL.io_code |
||
39 | input equ IOCTL.input |
||
40 | inp_size equ IOCTL.inp_size |
||
41 | output equ IOCTL.output |
||
42 | out_size equ IOCTL.out_size |
||
43 | |||
44 | |||
45 | align 4 |
||
46 | proc srv_handler stdcall, ioctl:dword |
||
47 | mov esi, [ioctl] |
||
48 | test esi, esi |
||
49 | jz .err |
||
50 | |||
9715 | Doczom | 51 | mov edi, [esi + handle] |
52 | cmp [edi + SRV.magic], ' SRV' |
||
2288 | clevermous | 53 | jne .fail |
54 | |||
9715 | Doczom | 55 | cmp [edi + SRV.size], sizeof.SRV |
2288 | clevermous | 56 | jne .fail |
57 | |||
3520 | clevermous | 58 | ; stdcall [edi+SRV.srv_proc], esi |
9715 | Doczom | 59 | mov eax, [edi + SRV.srv_proc] |
3520 | clevermous | 60 | test eax, eax |
61 | jz .fail |
||
62 | stdcall eax, esi |
||
2288 | clevermous | 63 | ret |
64 | .fail: |
||
65 | xor eax, eax |
||
66 | not eax |
||
9715 | Doczom | 67 | mov [esi + output], eax |
68 | mov [esi + out_size], 4 |
||
2288 | clevermous | 69 | ret |
70 | .err: |
||
71 | xor eax, eax |
||
72 | not eax |
||
73 | ret |
||
74 | endp |
||
75 | |||
76 | ; param |
||
77 | ; ecx= io_control |
||
78 | ; |
||
79 | ; retval |
||
80 | ; eax= error code |
||
81 | |||
82 | align 4 |
||
83 | srv_handlerEx: |
||
84 | cmp ecx, OS_BASE |
||
85 | jae .fail |
||
86 | |||
9715 | Doczom | 87 | mov eax, [ecx + handle] |
9430 | Doczom | 88 | |
89 | cmp eax, OS_BASE |
||
9440 | Doczom | 90 | jbe .fail |
9430 | Doczom | 91 | |
9715 | Doczom | 92 | cmp [eax + SRV.magic], ' SRV' |
2288 | clevermous | 93 | jne .fail |
94 | |||
9715 | Doczom | 95 | cmp [eax + SRV.size], sizeof.SRV |
2288 | clevermous | 96 | jne .fail |
97 | |||
3520 | clevermous | 98 | ; stdcall [eax+SRV.srv_proc], ecx |
9715 | Doczom | 99 | mov eax, [eax + SRV.srv_proc] |
3520 | clevermous | 100 | test eax, eax |
101 | jz .fail |
||
102 | stdcall eax, ecx |
||
2288 | clevermous | 103 | ret |
104 | .fail: |
||
105 | or eax, -1 |
||
106 | ret |
||
107 | |||
108 | restore handle |
||
109 | restore io_code |
||
110 | restore input |
||
111 | restore inp_size |
||
112 | restore output |
||
113 | restore out_size |
||
114 | |||
115 | align 4 |
||
116 | proc get_service stdcall, sz_name:dword |
||
117 | mov eax, [sz_name] |
||
118 | test eax, eax |
||
119 | jnz @F |
||
120 | ret |
||
121 | @@: |
||
122 | mov edx, [srv.fd] |
||
123 | @@: |
||
9715 | Doczom | 124 | cmp edx, srv.fd - SRV.fd |
2288 | clevermous | 125 | je .not_load |
126 | |||
127 | stdcall strncmp, edx, [sz_name], 16 |
||
128 | test eax, eax |
||
5088 | clevermous | 129 | mov eax, edx |
130 | je .nothing |
||
2288 | clevermous | 131 | |
9715 | Doczom | 132 | mov edx, [edx + SRV.fd] |
2288 | clevermous | 133 | jmp @B |
134 | .not_load: |
||
4418 | clevermous | 135 | mov eax, [sz_name] |
136 | push edi |
||
137 | sub esp, 36 |
||
138 | mov edi, esp |
||
139 | mov dword [edi], '/sys' |
||
140 | mov dword [edi+4], '/dri' |
||
141 | mov dword [edi+8], 'vers' |
||
142 | mov byte [edi+12], '/' |
||
143 | @@: |
||
144 | mov dl, [eax] |
||
145 | mov [edi+13], dl |
||
146 | inc eax |
||
147 | inc edi |
||
148 | test dl, dl |
||
149 | jnz @b |
||
150 | mov dword [edi+12], '.sys' |
||
151 | mov byte [edi+16], 0 |
||
152 | mov edi, esp |
||
153 | stdcall load_pe_driver, edi, 0 |
||
154 | add esp, 36 |
||
155 | pop edi |
||
156 | .nothing: |
||
2288 | clevermous | 157 | ret |
158 | endp |
||
159 | |||
3520 | clevermous | 160 | reg_service: |
161 | xor eax, eax |
||
162 | mov ecx, [esp+8] |
||
9872 | Doczom | 163 | ;jecxz .nothing |
3520 | clevermous | 164 | push sizeof.SRV |
165 | push ecx |
||
166 | pushd [esp+12] |
||
167 | call reg_service_ex |
||
168 | .nothing: |
||
169 | ret 8 |
||
2288 | clevermous | 170 | |
3520 | clevermous | 171 | reg_usb_driver: |
172 | push sizeof.USBSRV |
||
173 | pushd [esp+12] |
||
174 | pushd [esp+12] |
||
175 | call reg_service_ex |
||
176 | test eax, eax |
||
177 | jz .nothing |
||
178 | mov ecx, [esp+12] |
||
179 | mov [eax+USBSRV.usb_func], ecx |
||
180 | .nothing: |
||
181 | ret 12 |
||
182 | |||
183 | proc reg_service_ex stdcall, name:dword, handler:dword, srvsize:dword |
||
184 | |||
2288 | clevermous | 185 | push ebx |
186 | |||
187 | xor eax, eax |
||
188 | |||
189 | cmp [name], eax |
||
190 | je .fail |
||
191 | |||
3520 | clevermous | 192 | ; cmp [handler], eax |
193 | ; je .fail |
||
2288 | clevermous | 194 | |
3520 | clevermous | 195 | mov eax, [srvsize] |
2288 | clevermous | 196 | call malloc |
197 | test eax, eax |
||
198 | jz .fail |
||
199 | |||
200 | push esi |
||
201 | push edi |
||
202 | mov edi, eax |
||
203 | mov esi, [name] |
||
204 | movsd |
||
205 | movsd |
||
206 | movsd |
||
207 | movsd |
||
208 | pop edi |
||
209 | pop esi |
||
210 | |||
9715 | Doczom | 211 | mov [eax + SRV.magic], ' SRV' |
212 | mov [eax + SRV.size], sizeof.SRV |
||
2288 | clevermous | 213 | |
9715 | Doczom | 214 | mov ebx, srv.fd - SRV.fd |
215 | mov edx, [ebx + SRV.fd] |
||
216 | mov [eax + SRV.fd], edx |
||
217 | mov [eax + SRV.bk], ebx |
||
218 | mov [ebx + SRV.fd], eax |
||
219 | mov [edx + SRV.bk], eax |
||
2288 | clevermous | 220 | |
221 | mov ecx, [handler] |
||
9715 | Doczom | 222 | mov [eax + SRV.srv_proc], ecx |
9440 | Doczom | 223 | ;dec [count_services] |
2288 | clevermous | 224 | pop ebx |
225 | ret |
||
226 | .fail: |
||
227 | xor eax, eax |
||
228 | pop ebx |
||
229 | ret |
||
230 | endp |
||
231 | |||
232 | align 4 |
||
9567 | Doczom | 233 | stop_all_services: ;used in shutdown system |
234 | push ebp |
||
235 | mov edx, [srv.fd] |
||
236 | .next: |
||
9715 | Doczom | 237 | cmp edx, srv.fd - SRV.fd |
9567 | Doczom | 238 | je .done |
9715 | Doczom | 239 | cmp [edx + SRV.magic], ' SRV' |
9567 | Doczom | 240 | jne .next |
9715 | Doczom | 241 | cmp [edx + SRV.size], sizeof.SRV |
9567 | Doczom | 242 | jne .next |
243 | |||
9715 | Doczom | 244 | mov ebx, [edx + SRV.entry] |
245 | mov edx, [edx + SRV.fd] |
||
9567 | Doczom | 246 | test ebx, ebx |
247 | jz .next |
||
248 | |||
249 | push edx |
||
250 | mov ebp, esp |
||
251 | push 0 |
||
252 | push DRV_EXIT |
||
253 | call ebx ;stdcall |
||
254 | mov esp, ebp |
||
255 | pop edx |
||
256 | jmp .next |
||
257 | .done: |
||
258 | pop ebp |
||
259 | ret |
||
260 | |||
261 | align 4 |
||
2288 | clevermous | 262 | proc get_proc stdcall, exp:dword, sz_name:dword |
263 | |||
264 | mov edx, [exp] |
||
265 | .next: |
||
266 | mov eax, [edx] |
||
267 | test eax, eax |
||
268 | jz .end |
||
269 | |||
270 | push edx |
||
271 | stdcall strncmp, eax, [sz_name], 16 |
||
272 | pop edx |
||
273 | test eax, eax |
||
274 | jz .ok |
||
275 | |||
276 | add edx, 8 |
||
277 | jmp .next |
||
278 | .ok: |
||
279 | mov eax, [edx+4] |
||
280 | .end: |
||
281 | ret |
||
282 | endp |
||
283 | |||
284 | align 4 |
||
285 | proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword |
||
286 | |||
287 | @@: |
||
9823 | dunkaist | 288 | stdcall strncmp, [pSym], [sz_sym], sizeof.COFF_SYM.Name |
2288 | clevermous | 289 | test eax, eax |
290 | jz .ok |
||
9823 | dunkaist | 291 | add [pSym], sizeof.COFF_SYM |
2288 | clevermous | 292 | dec [count] |
293 | jnz @b |
||
294 | xor eax, eax |
||
295 | ret |
||
296 | .ok: |
||
297 | mov eax, [pSym] |
||
9823 | dunkaist | 298 | mov eax, [eax+COFF_SYM.Value] |
2288 | clevermous | 299 | ret |
300 | endp |
||
301 | |||
302 | |||
303 | align 4 |
||
304 | proc get_fileinfo stdcall, file_name:dword, info:dword |
||
305 | locals |
||
306 | cmd dd ? |
||
307 | offset dd ? |
||
308 | dd ? |
||
309 | count dd ? |
||
310 | buff dd ? |
||
311 | db ? |
||
312 | name dd ? |
||
313 | endl |
||
314 | |||
315 | xor eax, eax |
||
316 | mov ebx, [file_name] |
||
317 | mov ecx, [info] |
||
318 | |||
319 | mov [cmd], 5 |
||
320 | mov [offset], eax |
||
321 | mov [offset+4], eax |
||
322 | mov [count], eax |
||
323 | mov [buff], ecx |
||
324 | mov byte [buff+4], al |
||
325 | mov [name], ebx |
||
326 | |||
327 | mov eax, 70 |
||
328 | lea ebx, [cmd] |
||
8680 | rgimad | 329 | pushad |
330 | cld |
||
331 | call protect_from_terminate |
||
332 | call file_system_lfn |
||
333 | call unprotect_from_terminate |
||
334 | popad |
||
2288 | clevermous | 335 | ret |
336 | endp |
||
337 | |||
338 | align 4 |
||
339 | proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\ |
||
340 | bytes:dword |
||
341 | locals |
||
342 | cmd dd ? |
||
343 | offset dd ? |
||
344 | dd ? |
||
345 | count dd ? |
||
346 | buff dd ? |
||
347 | db ? |
||
348 | name dd ? |
||
349 | endl |
||
350 | |||
351 | xor eax, eax |
||
352 | mov ebx, [file_name] |
||
353 | mov ecx, [off] |
||
354 | mov edx, [bytes] |
||
355 | mov esi, [buffer] |
||
356 | |||
357 | mov [cmd], eax |
||
358 | mov [offset], ecx |
||
359 | mov [offset+4], eax |
||
360 | mov [count], edx |
||
361 | mov [buff], esi |
||
362 | mov byte [buff+4], al |
||
363 | mov [name], ebx |
||
364 | |||
365 | pushad |
||
366 | lea ebx, [cmd] |
||
3296 | clevermous | 367 | call file_system_lfn_protected |
2288 | clevermous | 368 | popad |
369 | ret |
||
370 | endp |
||
371 | |||
9034 | Boppan | 372 | align 4 |
373 | ; @brief Allocate kernel memory and loads the specified file |
||
2288 | clevermous | 374 | ; |
9034 | Boppan | 375 | ; @param file_name Path to file |
2288 | clevermous | 376 | ; |
9034 | Boppan | 377 | ; @returns File image in kernel memory in `eax` and size of file in `ebx` |
2288 | clevermous | 378 | ; |
9034 | Boppan | 379 | ; @warning You must call kernel_free() to delete each file loaded by the |
380 | ; load_file() function |
||
2288 | clevermous | 381 | proc load_file stdcall, file_name:dword |
382 | locals |
||
383 | attr dd ? |
||
384 | flags dd ? |
||
385 | cr_time dd ? |
||
386 | cr_date dd ? |
||
387 | acc_time dd ? |
||
388 | acc_date dd ? |
||
389 | mod_time dd ? |
||
390 | mod_date dd ? |
||
391 | file_size dd ? |
||
392 | |||
393 | file dd ? |
||
394 | file2 dd ? |
||
395 | endl |
||
396 | |||
397 | push esi |
||
398 | push edi |
||
399 | |||
400 | lea eax, [attr] |
||
401 | stdcall get_fileinfo, [file_name], eax |
||
402 | test eax, eax |
||
403 | jnz .fail |
||
404 | |||
405 | mov eax, [file_size] |
||
406 | cmp eax, 1024*1024*16 |
||
407 | ja .fail |
||
408 | |||
409 | stdcall kernel_alloc, [file_size] |
||
410 | mov [file], eax |
||
411 | test eax, eax |
||
412 | jz .fail |
||
413 | |||
414 | stdcall read_file, [file_name], eax, dword 0, [file_size] |
||
415 | cmp ebx, [file_size] |
||
416 | jne .cleanup |
||
417 | |||
418 | mov eax, [file] |
||
7122 | dunkaist | 419 | cmp dword [eax], 'KPCK' |
2288 | clevermous | 420 | jne .exit |
421 | mov ebx, [eax+4] |
||
422 | mov [file_size], ebx |
||
423 | stdcall kernel_alloc, ebx |
||
424 | |||
425 | test eax, eax |
||
426 | jz .cleanup |
||
427 | |||
428 | mov [file2], eax |
||
2486 | mario79 | 429 | |
2500 | mario79 | 430 | pushad |
2489 | mario79 | 431 | mov ecx, unpack_mutex |
432 | call mutex_lock |
||
2500 | mario79 | 433 | popad |
2486 | mario79 | 434 | |
2288 | clevermous | 435 | stdcall unpack, [file], eax |
2486 | mario79 | 436 | |
2500 | mario79 | 437 | pushad |
438 | mov ecx, unpack_mutex |
||
2489 | mario79 | 439 | call mutex_unlock |
2500 | mario79 | 440 | popad |
2486 | mario79 | 441 | |
2288 | clevermous | 442 | stdcall kernel_free, [file] |
443 | mov eax, [file2] |
||
444 | mov ebx, [file_size] |
||
445 | .exit: |
||
446 | push eax |
||
447 | lea edi, [eax+ebx] ;cleanup remain space |
||
448 | mov ecx, 4096 ;from file end |
||
449 | and ebx, 4095 |
||
450 | jz @f |
||
451 | sub ecx, ebx |
||
452 | xor eax, eax |
||
453 | cld |
||
454 | rep stosb |
||
455 | @@: |
||
456 | mov ebx, [file_size] |
||
457 | pop eax |
||
458 | pop edi |
||
459 | pop esi |
||
460 | ret |
||
461 | .cleanup: |
||
462 | stdcall kernel_free, [file] |
||
463 | .fail: |
||
464 | xor eax, eax |
||
465 | xor ebx, ebx |
||
466 | pop edi |
||
467 | pop esi |
||
468 | ret |
||
469 | endp |
||
470 | |||
3786 | Serge | 471 | ; description |
472 | ; allocate user memory and loads the specified file |
||
473 | ; |
||
474 | ; param |
||
475 | ; file_name= path to file |
||
476 | ; |
||
477 | ; retval |
||
478 | ; eax= file image in user memory |
||
479 | ; ebx= size of file |
||
480 | ; |
||
481 | ; warging |
||
482 | ; You mast call kernel_free() to delete each file |
||
483 | ; loaded by the load_file() function |
||
484 | |||
485 | align 4 |
||
486 | proc load_file_umode stdcall, file_name:dword |
||
487 | locals |
||
488 | attr dd ? |
||
489 | flags dd ? |
||
490 | cr_time dd ? |
||
491 | cr_date dd ? |
||
492 | acc_time dd ? |
||
493 | acc_date dd ? |
||
494 | mod_time dd ? |
||
495 | mod_date dd ? |
||
496 | file_size dd ? |
||
497 | |||
498 | km_file dd ? |
||
499 | um_file dd ? |
||
500 | endl |
||
501 | |||
502 | push esi |
||
503 | push edi |
||
504 | push ebx |
||
505 | |||
506 | lea eax, [attr] |
||
507 | stdcall get_fileinfo, [file_name], eax ;find file and get info |
||
508 | test eax, eax |
||
509 | jnz .err_1 |
||
510 | |||
511 | mov eax, [file_size] |
||
9976 | Jurgen | 512 | cmp eax, 1024*1024*1024 ;to be enough for anybody 1Gbt(c) |
3786 | Serge | 513 | ja .err_1 |
514 | ;it is very likely that the file is packed |
||
515 | stdcall kernel_alloc, [file_size] ;with kpack, so allocate memory from kernel heap |
||
516 | mov [km_file], eax |
||
517 | test eax, eax |
||
518 | jz .err_1 |
||
519 | |||
520 | stdcall read_file, [file_name], eax, dword 0, [file_size] |
||
521 | cmp ebx, [file_size] |
||
522 | |||
523 | jne .err_2 |
||
524 | |||
525 | mov eax, [km_file] |
||
7122 | dunkaist | 526 | cmp dword [eax], 'KPCK' ; check kpack signature |
3786 | Serge | 527 | jne .raw_file |
528 | |||
529 | mov ebx, [eax+4] ;get real size of file |
||
530 | mov [file_size], ebx |
||
4237 | Serge | 531 | stdcall user_alloc, ebx ;and allocate space from user heap |
3786 | Serge | 532 | mov [um_file], eax |
533 | test eax, eax |
||
534 | jz .err_2 |
||
535 | |||
4237 | Serge | 536 | mov edx, [file_size] ;preallocate page memory |
537 | shr eax, 10 |
||
9715 | Doczom | 538 | lea edi, [page_tabs + eax] |
4237 | Serge | 539 | add edx, 4095 |
540 | shr edx, 12 |
||
541 | @@: |
||
542 | call alloc_page |
||
543 | test eax, eax |
||
544 | jz .err_3 |
||
545 | |||
5356 | serge | 546 | or eax, PG_UWR |
4237 | Serge | 547 | stosd |
548 | dec edx |
||
549 | jnz @B |
||
550 | |||
3786 | Serge | 551 | pushad |
552 | mov ecx, unpack_mutex |
||
553 | call mutex_lock |
||
554 | |||
555 | stdcall unpack, [km_file], [um_file] |
||
556 | |||
557 | mov ecx, unpack_mutex |
||
558 | call mutex_unlock |
||
559 | popad |
||
560 | |||
561 | stdcall kernel_free, [km_file] ;we don't need packed file anymore |
||
562 | .exit: |
||
4237 | Serge | 563 | |
564 | mov edi, [um_file] |
||
565 | mov esi, [um_file] |
||
566 | mov eax, [file_size] |
||
567 | mov edx, eax |
||
568 | |||
569 | add edi, eax ;cleanup remain space |
||
570 | mov ecx, 4096 ;from file end |
||
571 | and eax, 4095 |
||
572 | jz @f |
||
573 | sub ecx, eax |
||
574 | xor eax, eax |
||
575 | cld |
||
576 | rep stosb |
||
577 | @@: |
||
3786 | Serge | 578 | mov eax, [um_file] |
579 | |||
580 | pop ebx |
||
581 | pop edi |
||
582 | pop esi |
||
583 | ret |
||
584 | |||
585 | .raw_file: ; sometimes we load unpacked file |
||
586 | stdcall user_alloc, ebx ; allocate space from user heap |
||
587 | mov [um_file], eax |
||
588 | |||
589 | test eax, eax |
||
590 | jz .err_2 |
||
591 | |||
592 | shr eax, 10 ; and remap pages. |
||
593 | |||
594 | mov ecx, [file_size] |
||
595 | add ecx, 4095 |
||
596 | shr ecx, 12 |
||
597 | |||
598 | mov esi, [km_file] |
||
599 | shr esi, 10 |
||
600 | add esi, page_tabs |
||
601 | |||
602 | lea edi, [page_tabs+eax] |
||
603 | |||
604 | cld |
||
605 | @@: |
||
606 | lodsd |
||
607 | and eax, 0xFFFFF000 |
||
5356 | serge | 608 | or eax, PG_UWR |
3786 | Serge | 609 | stosd |
610 | loop @B |
||
611 | |||
612 | stdcall free_kernel_space, [km_file] ; release allocated kernel space |
||
613 | jmp .exit ; physical pages still in use |
||
4237 | Serge | 614 | .err_3: |
615 | stdcall user_free, [um_file] |
||
3786 | Serge | 616 | .err_2: |
617 | stdcall kernel_free, [km_file] |
||
618 | .err_1: |
||
619 | xor eax, eax |
||
620 | xor edx, edx |
||
621 | |||
622 | pop ebx |
||
623 | pop edi |
||
624 | pop esi |
||
625 | ret |
||
626 | endp |
||
627 | |||
628 | |||
2489 | mario79 | 629 | uglobal |
2288 | clevermous | 630 | align 4 |
2489 | mario79 | 631 | unpack_mutex MUTEX |
2486 | mario79 | 632 | endg |
633 | |||
634 | align 4 |
||
3761 | clevermous | 635 | proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword |
636 | mov ebx, [imports] |
||
637 | test ebx, ebx |
||
638 | jz .end |
||
639 | xor esi, esi |
||
2288 | clevermous | 640 | .look_up: |
641 | |||
3761 | clevermous | 642 | mov eax, [ebx+32] |
9715 | Doczom | 643 | mov eax, [OS_BASE + eax + esi*4] |
3761 | clevermous | 644 | add eax, OS_BASE |
2288 | clevermous | 645 | stdcall strncmp, eax, [proc_name], 256 |
646 | test eax, eax |
||
647 | jz .ok |
||
648 | |||
3761 | clevermous | 649 | inc esi |
650 | cmp esi, [ebx+24] |
||
651 | jb .look_up |
||
2288 | clevermous | 652 | .end: |
653 | xor eax, eax |
||
654 | ret |
||
3761 | clevermous | 655 | .ok: |
656 | mov eax, [ebx+28] |
||
9715 | Doczom | 657 | mov eax, [OS_BASE + eax + esi*4] |
3761 | clevermous | 658 | add eax, OS_BASE |
659 | ret |
||
2288 | clevermous | 660 | endp |
661 | |||
662 | align 4 |
||
663 | proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\ |
||
664 | sym_count:dword, strings:dword, imports:dword |
||
665 | locals |
||
666 | retval dd ? |
||
667 | endl |
||
668 | |||
669 | mov edi, [symbols] |
||
670 | mov [retval], 1 |
||
671 | .fix: |
||
9715 | Doczom | 672 | movzx ebx, [edi + COFF_SYM.SectionNumber] |
2288 | clevermous | 673 | test ebx, ebx |
674 | jnz .internal |
||
9715 | Doczom | 675 | mov eax, dword [edi + COFF_SYM.Name] |
2288 | clevermous | 676 | test eax, eax |
677 | jnz @F |
||
678 | |||
679 | mov edi, [edi+4] |
||
680 | add edi, [strings] |
||
681 | @@: |
||
682 | push edi |
||
683 | stdcall get_proc_ex, edi, [imports] |
||
684 | pop edi |
||
685 | |||
686 | xor ebx, ebx |
||
687 | test eax, eax |
||
688 | jnz @F |
||
689 | |||
5998 | veliant | 690 | ; disable debug msg |
691 | ;mov esi, msg_unresolved |
||
692 | ;call sys_msg_board_str |
||
693 | ;mov esi, edi |
||
694 | ;call sys_msg_board_str |
||
695 | ;mov esi, msg_CR |
||
696 | ;call sys_msg_board_str |
||
2288 | clevermous | 697 | |
698 | mov [retval], 0 |
||
699 | @@: |
||
700 | mov edi, [symbols] |
||
9715 | Doczom | 701 | mov [edi + COFF_SYM.Value], eax |
2288 | clevermous | 702 | jmp .next |
703 | .internal: |
||
704 | cmp bx, -1 |
||
705 | je .next |
||
706 | cmp bx, -2 |
||
707 | je .next |
||
708 | |||
709 | dec ebx |
||
710 | shl ebx, 3 |
||
9715 | Doczom | 711 | lea ebx, [ebx + ebx*4] |
2288 | clevermous | 712 | add ebx, [sec] |
713 | |||
9715 | Doczom | 714 | mov eax, [ebx + COFF_SECTION.VirtualAddress] |
715 | add [edi + COFF_SYM.Value], eax |
||
2288 | clevermous | 716 | .next: |
2384 | hidnplayr | 717 | add edi, sizeof.COFF_SYM |
2288 | clevermous | 718 | mov [symbols], edi |
719 | dec [sym_count] |
||
720 | jnz .fix |
||
721 | mov eax, [retval] |
||
722 | ret |
||
723 | endp |
||
724 | |||
725 | align 4 |
||
726 | proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \ |
||
727 | delta:dword |
||
728 | locals |
||
729 | n_sec dd ? |
||
730 | endl |
||
731 | |||
732 | mov eax, [coff] |
||
9715 | Doczom | 733 | movzx ebx, [eax + COFF_HEADER.nSections] |
2288 | clevermous | 734 | mov [n_sec], ebx |
735 | lea esi, [eax+20] |
||
736 | .fix_sec: |
||
9715 | Doczom | 737 | mov edi, [esi + COFF_SECTION.PtrReloc] |
2288 | clevermous | 738 | add edi, [coff] |
739 | |||
9715 | Doczom | 740 | movzx ecx, [esi + COFF_SECTION.NumReloc] |
2288 | clevermous | 741 | test ecx, ecx |
742 | jz .next |
||
743 | .reloc_loop: |
||
9715 | Doczom | 744 | mov ebx, [edi + COFF_RELOC.SymIndex] |
2288 | clevermous | 745 | add ebx, ebx |
746 | lea ebx, [ebx+ebx*8] |
||
747 | add ebx, [sym] |
||
748 | |||
9715 | Doczom | 749 | mov edx, [ebx + COFF_SYM.Value] |
2288 | clevermous | 750 | |
9715 | Doczom | 751 | cmp [edi + COFF_RELOC.Type], 6 |
2288 | clevermous | 752 | je .dir_32 |
753 | |||
9715 | Doczom | 754 | cmp [edi + COFF_RELOC.Type], 20 |
2288 | clevermous | 755 | jne .next_reloc |
756 | .rel_32: |
||
9715 | Doczom | 757 | mov eax, [edi + COFF_RELOC.VirtualAddress] |
758 | add eax, [esi + COFF_SECTION.VirtualAddress] |
||
2288 | clevermous | 759 | sub edx, eax |
760 | sub edx, 4 |
||
761 | jmp .fix |
||
762 | .dir_32: |
||
9715 | Doczom | 763 | mov eax, [edi + COFF_RELOC.VirtualAddress] |
764 | add eax, [esi + COFF_SECTION.VirtualAddress] |
||
2288 | clevermous | 765 | .fix: |
766 | add eax, [delta] |
||
767 | add [eax], edx |
||
768 | .next_reloc: |
||
769 | add edi, 10 |
||
770 | dec ecx |
||
771 | jnz .reloc_loop |
||
772 | .next: |
||
2384 | hidnplayr | 773 | add esi, sizeof.COFF_SECTION |
2288 | clevermous | 774 | dec [n_sec] |
775 | jnz .fix_sec |
||
776 | .exit: |
||
777 | ret |
||
778 | endp |
||
779 | |||
780 | align 4 |
||
781 | proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \ |
||
782 | delta:dword |
||
783 | locals |
||
784 | n_sec dd ? |
||
785 | endl |
||
786 | |||
787 | mov eax, [coff] |
||
9715 | Doczom | 788 | movzx ebx, [eax + COFF_HEADER.nSections] |
2288 | clevermous | 789 | mov [n_sec], ebx |
790 | lea esi, [eax+20] |
||
791 | mov edx, [delta] |
||
792 | .fix_sec: |
||
9715 | Doczom | 793 | mov edi, [esi + COFF_SECTION.PtrReloc] |
2288 | clevermous | 794 | add edi, [coff] |
795 | |||
9715 | Doczom | 796 | movzx ecx, [esi + COFF_SECTION.NumReloc] |
2288 | clevermous | 797 | test ecx, ecx |
798 | jz .next |
||
799 | .reloc_loop: |
||
9715 | Doczom | 800 | cmp [edi + COFF_RELOC.Type], 6 |
2288 | clevermous | 801 | jne .next_reloc |
802 | .dir_32: |
||
9715 | Doczom | 803 | mov eax, [edi + COFF_RELOC.VirtualAddress] |
804 | add eax, [esi + COFF_SECTION.VirtualAddress] |
||
805 | add [eax + edx], edx |
||
2288 | clevermous | 806 | .next_reloc: |
807 | add edi, 10 |
||
808 | dec ecx |
||
809 | jnz .reloc_loop |
||
810 | .next: |
||
2384 | hidnplayr | 811 | add esi, sizeof.COFF_SECTION |
2288 | clevermous | 812 | dec [n_sec] |
813 | jnz .fix_sec |
||
814 | .exit: |
||
815 | ret |
||
816 | endp |
||
817 | |||
818 | ; in: edx -> COFF_SECTION struct |
||
819 | ; out: eax = alignment as mask for bits to drop |
||
820 | coff_get_align: |
||
821 | ; Rules: |
||
822 | ; - if alignment is not given, use default = 4K; |
||
823 | ; - if alignment is given and is no more than 4K, use it; |
||
824 | ; - if alignment is more than 4K, revert to 4K. |
||
825 | push ecx |
||
9715 | Doczom | 826 | mov cl, byte [edx + COFF_SECTION.Characteristics+2] |
2288 | clevermous | 827 | mov eax, 1 |
828 | shr cl, 4 |
||
829 | dec cl |
||
830 | js .default |
||
831 | cmp cl, 12 |
||
832 | jbe @f |
||
833 | .default: |
||
834 | mov cl, 12 |
||
835 | @@: |
||
836 | shl eax, cl |
||
837 | pop ecx |
||
838 | dec eax |
||
839 | ret |
||
840 | |||
841 | align 4 |
||
6792 | pathoswith | 842 | proc load_library stdcall, file_name:dword, encoding:dword |
6502 | pathoswith | 843 | locals |
844 | fullname dd ? |
||
845 | fileinfo rb 40 |
||
846 | coff dd ? |
||
847 | img_base dd ? |
||
848 | endl |
||
2288 | clevermous | 849 | |
850 | ; resolve file name |
||
6502 | pathoswith | 851 | stdcall kernel_alloc, maxPathLength |
852 | mov [fullname], eax |
||
6792 | pathoswith | 853 | mov edi, eax |
854 | mov esi, [file_name] |
||
855 | mov eax, [encoding] |
||
856 | push ebp |
||
857 | call getFullPath |
||
858 | pop ebp |
||
6502 | pathoswith | 859 | test eax, eax |
2288 | clevermous | 860 | jz .fail |
861 | ; scan for required DLL in list of already loaded for this process, |
||
862 | ; ignore timestamp |
||
3827 | clevermous | 863 | cli |
5130 | serge | 864 | mov esi, [current_process] |
6502 | pathoswith | 865 | mov edi, [fullname] |
9715 | Doczom | 866 | mov ebx, [esi + PROC.dlls_list_ptr] |
2288 | clevermous | 867 | test ebx, ebx |
868 | jz .not_in_process |
||
9715 | Doczom | 869 | mov esi, [ebx + HDLL.fd] |
2288 | clevermous | 870 | .scan_in_process: |
871 | cmp esi, ebx |
||
872 | jz .not_in_process |
||
9715 | Doczom | 873 | mov eax, [esi + HDLL.parent] |
2288 | clevermous | 874 | add eax, DLLDESCR.name |
875 | stdcall strncmp, eax, edi, -1 |
||
876 | test eax, eax |
||
877 | jnz .next_in_process |
||
878 | ; simple variant: load DLL which is already loaded in this process |
||
879 | ; just increment reference counters and return address of exports table |
||
9715 | Doczom | 880 | inc [esi + HDLL.refcount] |
881 | mov ecx, [esi + HDLL.parent] |
||
882 | inc [ecx + DLLDESCR.refcount] |
||
883 | mov eax, [ecx + DLLDESCR.exports] |
||
884 | sub eax, [ecx + DLLDESCR.defaultbase] |
||
885 | add eax, [esi + HDLL.base] |
||
3827 | clevermous | 886 | sti |
6502 | pathoswith | 887 | push eax |
888 | stdcall kernel_free, [fullname] |
||
889 | pop eax |
||
2288 | clevermous | 890 | ret |
6502 | pathoswith | 891 | |
2288 | clevermous | 892 | .next_in_process: |
9715 | Doczom | 893 | mov esi, [esi + HDLL.fd] |
2288 | clevermous | 894 | jmp .scan_in_process |
6502 | pathoswith | 895 | |
2288 | clevermous | 896 | .not_in_process: |
897 | ; scan in full list, compare timestamp |
||
3827 | clevermous | 898 | sti |
2288 | clevermous | 899 | lea eax, [fileinfo] |
900 | stdcall get_fileinfo, edi, eax |
||
901 | test eax, eax |
||
902 | jnz .fail |
||
3827 | clevermous | 903 | cli |
2288 | clevermous | 904 | mov esi, [dll_list.fd] |
905 | .scan_for_dlls: |
||
906 | cmp esi, dll_list |
||
907 | jz .load_new |
||
9715 | Doczom | 908 | lea eax, [esi + DLLDESCR.name] |
2288 | clevermous | 909 | stdcall strncmp, eax, edi, -1 |
910 | test eax, eax |
||
911 | jnz .continue_scan |
||
912 | .test_prev_dll: |
||
913 | mov eax, dword [fileinfo+24]; last modified time |
||
914 | mov edx, dword [fileinfo+28]; last modified date |
||
9715 | Doczom | 915 | cmp dword [esi + DLLDESCR.timestamp], eax |
2288 | clevermous | 916 | jnz .continue_scan |
9715 | Doczom | 917 | cmp dword [esi + DLLDESCR.timestamp+4], edx |
2288 | clevermous | 918 | jz .dll_already_loaded |
919 | .continue_scan: |
||
9715 | Doczom | 920 | mov esi, [esi + DLLDESCR.fd] |
2288 | clevermous | 921 | jmp .scan_for_dlls |
922 | |||
923 | ; new DLL |
||
924 | .load_new: |
||
3827 | clevermous | 925 | sti |
2288 | clevermous | 926 | ; load file |
927 | stdcall load_file, edi |
||
928 | test eax, eax |
||
929 | jz .fail |
||
930 | mov [coff], eax |
||
931 | mov dword [fileinfo+32], ebx |
||
932 | |||
933 | ; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name |
||
934 | mov esi, edi |
||
935 | mov ecx, -1 |
||
936 | xor eax, eax |
||
937 | repnz scasb |
||
938 | not ecx |
||
9715 | Doczom | 939 | lea eax, [ecx + sizeof.DLLDESCR] |
2288 | clevermous | 940 | push ecx |
941 | call malloc |
||
942 | pop ecx |
||
943 | test eax, eax |
||
944 | jz .fail_and_free_coff |
||
945 | ; save timestamp |
||
9715 | Doczom | 946 | lea edi, [eax + DLLDESCR.name] |
2288 | clevermous | 947 | rep movsb |
948 | mov esi, eax |
||
949 | mov eax, dword [fileinfo+24] |
||
9715 | Doczom | 950 | mov dword [esi + DLLDESCR.timestamp], eax |
2288 | clevermous | 951 | mov eax, dword [fileinfo+28] |
9715 | Doczom | 952 | mov dword [esi + DLLDESCR.timestamp+4], eax |
2288 | clevermous | 953 | |
954 | ; calculate size of loaded DLL |
||
955 | mov edx, [coff] |
||
9715 | Doczom | 956 | movzx ecx, [edx + COFF_HEADER.nSections] |
2288 | clevermous | 957 | xor ebx, ebx |
958 | |||
9823 | dunkaist | 959 | add edx, sizeof.COFF_HEADER |
2288 | clevermous | 960 | @@: |
961 | call coff_get_align |
||
962 | add ebx, eax |
||
963 | not eax |
||
964 | and ebx, eax |
||
9715 | Doczom | 965 | add ebx, [edx + COFF_SECTION.SizeOfRawData] |
2384 | hidnplayr | 966 | add edx, sizeof.COFF_SECTION |
2288 | clevermous | 967 | dec ecx |
968 | jnz @B |
||
969 | ; it must be nonzero and not too big |
||
9715 | Doczom | 970 | mov [esi + DLLDESCR.size], ebx |
2288 | clevermous | 971 | test ebx, ebx |
972 | jz .fail_and_free_dll |
||
973 | cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR |
||
974 | ja .fail_and_free_dll |
||
975 | ; allocate memory for kernel-side image |
||
976 | stdcall kernel_alloc, ebx |
||
977 | test eax, eax |
||
978 | jz .fail_and_free_dll |
||
9715 | Doczom | 979 | mov [esi + DLLDESCR.data], eax |
2288 | clevermous | 980 | ; calculate preferred base address |
981 | add ebx, 0x1FFF |
||
982 | and ebx, not 0xFFF |
||
983 | mov ecx, [dll_cur_addr] |
||
9715 | Doczom | 984 | lea edx, [ecx + ebx] |
2288 | clevermous | 985 | cmp edx, MAX_DEFAULT_DLL_ADDR |
986 | jb @f |
||
987 | mov ecx, MIN_DEFAULT_DLL_ADDR |
||
9715 | Doczom | 988 | lea edx, [ecx + ebx] |
2288 | clevermous | 989 | @@: |
9715 | Doczom | 990 | mov [esi + DLLDESCR.defaultbase], ecx |
2288 | clevermous | 991 | mov [dll_cur_addr], edx |
992 | |||
993 | ; copy sections and set correct values for VirtualAddress'es in headers |
||
994 | push esi |
||
995 | mov edx, [coff] |
||
9715 | Doczom | 996 | movzx ebx, [edx + COFF_HEADER.nSections] |
2288 | clevermous | 997 | mov edi, eax |
998 | add edx, 20 |
||
999 | cld |
||
1000 | @@: |
||
1001 | call coff_get_align |
||
1002 | add ecx, eax |
||
1003 | add edi, eax |
||
1004 | not eax |
||
1005 | and ecx, eax |
||
1006 | and edi, eax |
||
9715 | Doczom | 1007 | mov [edx + COFF_SECTION.VirtualAddress], ecx |
1008 | add ecx, [edx + COFF_SECTION.SizeOfRawData] |
||
1009 | mov esi, [edx + COFF_SECTION.PtrRawData] |
||
2288 | clevermous | 1010 | push ecx |
9715 | Doczom | 1011 | mov ecx, [edx + COFF_SECTION.SizeOfRawData] |
2288 | clevermous | 1012 | test esi, esi |
1013 | jnz .copy |
||
1014 | xor eax, eax |
||
1015 | rep stosb |
||
1016 | jmp .next |
||
1017 | .copy: |
||
1018 | add esi, [coff] |
||
1019 | rep movsb |
||
1020 | .next: |
||
1021 | pop ecx |
||
2384 | hidnplayr | 1022 | add edx, sizeof.COFF_SECTION |
2288 | clevermous | 1023 | dec ebx |
1024 | jnz @B |
||
1025 | pop esi |
||
1026 | |||
1027 | ; save some additional data from COFF file |
||
1028 | ; later we will use COFF header, headers for sections and symbol table |
||
1029 | ; and also relocations table for all sections |
||
1030 | mov edx, [coff] |
||
9715 | Doczom | 1031 | mov ebx, [edx + COFF_HEADER.pSymTable] |
2288 | clevermous | 1032 | mov edi, dword [fileinfo+32] |
1033 | sub edi, ebx |
||
1034 | jc .fail_and_free_data |
||
9715 | Doczom | 1035 | mov [esi + DLLDESCR.symbols_lim], edi |
2288 | clevermous | 1036 | add ebx, edx |
9715 | Doczom | 1037 | movzx ecx, [edx + COFF_HEADER.nSections] |
2288 | clevermous | 1038 | lea ecx, [ecx*5] |
9715 | Doczom | 1039 | lea edi, [edi + ecx*8+20] |
9823 | dunkaist | 1040 | add edx, sizeof.COFF_HEADER |
2288 | clevermous | 1041 | @@: |
9715 | Doczom | 1042 | movzx eax, [edx + COFF_SECTION.NumReloc] |
2288 | clevermous | 1043 | lea eax, [eax*5] |
9715 | Doczom | 1044 | lea edi, [edi + eax*2] |
2384 | hidnplayr | 1045 | add edx, sizeof.COFF_SECTION |
2288 | clevermous | 1046 | sub ecx, 5 |
1047 | jnz @b |
||
1048 | stdcall kernel_alloc, edi |
||
1049 | test eax, eax |
||
1050 | jz .fail_and_free_data |
||
1051 | mov edx, [coff] |
||
9715 | Doczom | 1052 | movzx ecx, [edx + COFF_HEADER.nSections] |
2288 | clevermous | 1053 | lea ecx, [ecx*5] |
1054 | lea ecx, [ecx*2+5] |
||
9715 | Doczom | 1055 | mov [esi + DLLDESCR.coff_hdr], eax |
2288 | clevermous | 1056 | push esi |
1057 | mov esi, edx |
||
1058 | mov edi, eax |
||
1059 | rep movsd |
||
1060 | pop esi |
||
9715 | Doczom | 1061 | mov [esi + DLLDESCR.symbols_ptr], edi |
2288 | clevermous | 1062 | push esi |
2384 | hidnplayr | 1063 | mov ecx, [edx+COFF_HEADER.nSymbols] |
9715 | Doczom | 1064 | mov [esi + DLLDESCR.symbols_num], ecx |
1065 | mov ecx, [esi + DLLDESCR.symbols_lim] |
||
2288 | clevermous | 1066 | mov esi, ebx |
1067 | rep movsb |
||
1068 | pop esi |
||
9715 | Doczom | 1069 | mov ebx, [esi + DLLDESCR.coff_hdr] |
2288 | clevermous | 1070 | push esi |
9715 | Doczom | 1071 | movzx eax, [edx + COFF_HEADER.nSections] |
2288 | clevermous | 1072 | lea edx, [ebx+20] |
1073 | @@: |
||
9715 | Doczom | 1074 | movzx ecx, [edx + COFF_SECTION.NumReloc] |
2288 | clevermous | 1075 | lea ecx, [ecx*5] |
9715 | Doczom | 1076 | mov esi, [edx + COFF_SECTION.PtrReloc] |
1077 | mov [edx + COFF_SECTION.PtrReloc], edi |
||
1078 | sub [edx + COFF_SECTION.PtrReloc], ebx |
||
2288 | clevermous | 1079 | add esi, [coff] |
1080 | shr ecx, 1 |
||
1081 | rep movsd |
||
1082 | adc ecx, ecx |
||
1083 | rep movsw |
||
2384 | hidnplayr | 1084 | add edx, sizeof.COFF_SECTION |
2288 | clevermous | 1085 | dec eax |
1086 | jnz @b |
||
1087 | pop esi |
||
1088 | |||
1089 | ; fixup symbols |
||
1090 | mov edx, ebx |
||
9715 | Doczom | 1091 | mov eax, [ebx + COFF_HEADER.nSymbols] |
9823 | dunkaist | 1092 | add edx, sizeof.COFF_HEADER |
9715 | Doczom | 1093 | mov ecx, [esi + DLLDESCR.symbols_num] |
2288 | clevermous | 1094 | lea ecx, [ecx*9] |
1095 | add ecx, ecx |
||
9715 | Doczom | 1096 | add ecx, [esi + DLLDESCR.symbols_ptr] |
2288 | clevermous | 1097 | |
9715 | Doczom | 1098 | stdcall fix_coff_symbols, edx, [esi + DLLDESCR.symbols_ptr], eax, \ |
2288 | clevermous | 1099 | ecx, 0 |
1100 | ; test eax, eax |
||
1101 | ; jnz @F |
||
1102 | ; |
||
1103 | ;@@: |
||
1104 | |||
9715 | Doczom | 1105 | stdcall get_coff_sym, [esi + DLLDESCR.symbols_ptr], [ebx + COFF_HEADER.nSymbols], szEXPORTS |
2288 | clevermous | 1106 | test eax, eax |
1107 | jnz @F |
||
1108 | |||
9715 | Doczom | 1109 | stdcall get_coff_sym, [esi + DLLDESCR.symbols_ptr], [ebx + COFF_HEADER.nSymbols], sz_EXPORTS |
2288 | clevermous | 1110 | @@: |
9715 | Doczom | 1111 | mov [esi + DLLDESCR.exports], eax |
2288 | clevermous | 1112 | |
1113 | ; fix relocs in the hidden copy in kernel memory to default address |
||
1114 | ; it is first fix; usually this will be enough, but second fix |
||
1115 | ; can be necessary if real load address will not equal assumption |
||
9715 | Doczom | 1116 | mov eax, [esi + DLLDESCR.data] |
1117 | sub eax, [esi + DLLDESCR.defaultbase] |
||
1118 | stdcall fix_coff_relocs, ebx, [esi + DLLDESCR.symbols_ptr], eax |
||
2288 | clevermous | 1119 | |
1120 | stdcall kernel_free, [coff] |
||
1121 | |||
3827 | clevermous | 1122 | cli |
1123 | ; initialize DLLDESCR struct |
||
9715 | Doczom | 1124 | and dword [esi + DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented |
1125 | mov [esi + DLLDESCR.fd], dll_list |
||
3827 | clevermous | 1126 | mov eax, [dll_list.bk] |
1127 | mov [dll_list.bk], esi |
||
9715 | Doczom | 1128 | mov [esi + DLLDESCR.bk], eax |
1129 | mov [eax + DLLDESCR.fd], esi |
||
2288 | clevermous | 1130 | .dll_already_loaded: |
6502 | pathoswith | 1131 | stdcall kernel_free, [fullname] |
9715 | Doczom | 1132 | inc [esi + DLLDESCR.refcount] |
2288 | clevermous | 1133 | push esi |
1134 | call init_heap |
||
1135 | pop esi |
||
9715 | Doczom | 1136 | mov edi, [esi + DLLDESCR.size] |
1137 | stdcall user_alloc_at, [esi + DLLDESCR.defaultbase], edi |
||
2288 | clevermous | 1138 | test eax, eax |
1139 | jnz @f |
||
1140 | stdcall user_alloc, edi |
||
1141 | test eax, eax |
||
1142 | jz .fail_and_dereference |
||
1143 | @@: |
||
1144 | mov [img_base], eax |
||
2384 | hidnplayr | 1145 | mov eax, sizeof.HDLL |
2288 | clevermous | 1146 | call malloc |
1147 | test eax, eax |
||
1148 | jz .fail_and_free_user |
||
9828 | Doczom | 1149 | mov ebx, [current_slot] |
1150 | mov edx, [ebx + APPDATA.tid] |
||
9715 | Doczom | 1151 | mov [eax + HDLL.pid], edx |
2288 | clevermous | 1152 | push eax |
1153 | call init_dlls_in_thread |
||
1154 | pop ebx |
||
1155 | test eax, eax |
||
1156 | jz .fail_and_free_user |
||
9715 | Doczom | 1157 | mov edx, [eax + HDLL.fd] |
1158 | mov [ebx + HDLL.fd], edx |
||
1159 | mov [ebx + HDLL.bk], eax |
||
1160 | mov [eax + HDLL.fd], ebx |
||
1161 | mov [edx + HDLL.bk], ebx |
||
2288 | clevermous | 1162 | mov eax, ebx |
1163 | mov ebx, [img_base] |
||
9715 | Doczom | 1164 | mov [eax + HDLL.base], ebx |
1165 | mov [eax + HDLL.size], edi |
||
1166 | mov [eax + HDLL.refcount], 1 |
||
1167 | mov [eax + HDLL.parent], esi |
||
2288 | clevermous | 1168 | mov edx, ebx |
1169 | shr edx, 12 |
||
9715 | Doczom | 1170 | or dword [page_tabs + (edx-1)*4], MEM_BLOCK_DONT_FREE |
2288 | clevermous | 1171 | ; copy entries of page table from kernel-side image to usermode |
1172 | ; use copy-on-write for user-mode image, so map as readonly |
||
1173 | xor edi, edi |
||
9715 | Doczom | 1174 | mov ecx, [esi + DLLDESCR.data] |
2288 | clevermous | 1175 | shr ecx, 12 |
1176 | .map_pages_loop: |
||
9715 | Doczom | 1177 | mov eax, [page_tabs + ecx*4] |
9823 | dunkaist | 1178 | and eax, -PAGE_SIZE |
5356 | serge | 1179 | or al, PG_UR |
9715 | Doczom | 1180 | xchg eax, [page_tabs + edx*4] |
2288 | clevermous | 1181 | test al, 1 |
1182 | jz @f |
||
1183 | call free_page |
||
1184 | @@: |
||
1185 | invlpg [ebx+edi] |
||
1186 | inc ecx |
||
1187 | inc edx |
||
9823 | dunkaist | 1188 | add edi, PAGE_SIZE |
9715 | Doczom | 1189 | cmp edi, [esi + DLLDESCR.size] |
2288 | clevermous | 1190 | jb .map_pages_loop |
1191 | |||
1192 | ; if real user-mode base is not equal to preferred base, relocate image |
||
9715 | Doczom | 1193 | sub ebx, [esi + DLLDESCR.defaultbase] |
2288 | clevermous | 1194 | jz @f |
9715 | Doczom | 1195 | stdcall rebase_coff, [esi + DLLDESCR.coff_hdr], [esi + DLLDESCR.symbols_ptr], ebx |
2288 | clevermous | 1196 | @@: |
1197 | |||
9715 | Doczom | 1198 | mov eax, [esi + DLLDESCR.exports] |
1199 | sub eax, [esi + DLLDESCR.defaultbase] |
||
2288 | clevermous | 1200 | add eax, [img_base] |
3827 | clevermous | 1201 | sti |
2288 | clevermous | 1202 | ret |
6502 | pathoswith | 1203 | |
2288 | clevermous | 1204 | .fail_and_free_data: |
9715 | Doczom | 1205 | stdcall kernel_free, [esi + DLLDESCR.data] |
2288 | clevermous | 1206 | .fail_and_free_dll: |
1207 | mov eax, esi |
||
1208 | call free |
||
1209 | .fail_and_free_coff: |
||
1210 | stdcall kernel_free, [coff] |
||
1211 | .fail: |
||
6502 | pathoswith | 1212 | stdcall kernel_free, [fullname] |
2288 | clevermous | 1213 | xor eax, eax |
1214 | ret |
||
6502 | pathoswith | 1215 | |
2288 | clevermous | 1216 | .fail_and_free_user: |
1217 | stdcall user_free, [img_base] |
||
1218 | .fail_and_dereference: |
||
1219 | mov eax, 1 ; delete 1 reference |
||
1220 | call dereference_dll |
||
3827 | clevermous | 1221 | sti |
2288 | clevermous | 1222 | xor eax, eax |
1223 | ret |
||
1224 | endp |
||
1225 | |||
1226 | ; initialize [APPDATA.dlls_list_ptr] for given thread |
||
1227 | ; DLL is per-process object, so APPDATA.dlls_list_ptr must be |
||
1228 | ; kept in sync for all threads of one process. |
||
1229 | ; out: eax = APPDATA.dlls_list_ptr if all is OK, |
||
1230 | ; NULL if memory allocation failed |
||
1231 | init_dlls_in_thread: |
||
5130 | serge | 1232 | mov ebx, [current_process] |
9715 | Doczom | 1233 | mov eax, [ebx + PROC.dlls_list_ptr] |
2288 | clevermous | 1234 | test eax, eax |
1235 | jnz .ret |
||
5130 | serge | 1236 | |
2288 | clevermous | 1237 | mov eax, 8 |
5130 | serge | 1238 | call malloc ; FIXME |
2288 | clevermous | 1239 | test eax, eax |
1240 | jz .ret |
||
5130 | serge | 1241 | |
2288 | clevermous | 1242 | mov [eax], eax |
1243 | mov [eax+4], eax |
||
5130 | serge | 1244 | |
1245 | mov ebx, [current_process] |
||
9715 | Doczom | 1246 | mov [ebx + PROC.dlls_list_ptr], eax |
2288 | clevermous | 1247 | .ret: |
1248 | ret |
||
1249 | |||
1250 | ; in: eax = number of references to delete, esi -> DLLDESCR struc |
||
1251 | dereference_dll: |
||
9715 | Doczom | 1252 | sub [esi + DLLDESCR.refcount], eax |
2288 | clevermous | 1253 | jnz .ret |
9715 | Doczom | 1254 | mov eax, [esi + DLLDESCR.fd] |
1255 | mov edx, [esi + DLLDESCR.bk] |
||
1256 | mov [eax + DLLDESCR.bk], edx |
||
1257 | mov [edx + DLLDESCR.fd], eax |
||
1258 | stdcall kernel_free, [esi + DLLDESCR.coff_hdr] |
||
1259 | stdcall kernel_free, [esi + DLLDESCR.data] |
||
2288 | clevermous | 1260 | mov eax, esi |
1261 | call free |
||
1262 | .ret: |
||
1263 | ret |
||
1264 | |||
1265 | destroy_hdll: |
||
1266 | push ebx ecx esi edi |
||
9715 | Doczom | 1267 | mov ebx, [eax + HDLL.base] |
1268 | mov esi, [eax + HDLL.parent] |
||
1269 | mov edx, [esi + DLLDESCR.size] |
||
5130 | serge | 1270 | |
2288 | clevermous | 1271 | push eax |
9715 | Doczom | 1272 | mov esi, [eax + HDLL.parent] |
1273 | mov eax, [eax + HDLL.refcount] |
||
2288 | clevermous | 1274 | call dereference_dll |
1275 | pop eax |
||
9715 | Doczom | 1276 | mov edx, [eax + HDLL.bk] |
1277 | mov ebx, [eax + HDLL.fd] |
||
1278 | mov [ebx + HDLL.bk], edx |
||
1279 | mov [edx + HDLL.fd], ebx |
||
2288 | clevermous | 1280 | call free |
1281 | pop edi esi ecx ebx |
||
1282 | ret |
||
1283 | |||
1284 | ; ecx -> APPDATA for slot, esi = dlls_list_ptr |
||
1285 | destroy_all_hdlls: |
||
1286 | test esi, esi |
||
1287 | jz .ret |
||
1288 | .loop: |
||
9715 | Doczom | 1289 | mov eax, [esi + HDLL.fd] |
2288 | clevermous | 1290 | cmp eax, esi |
1291 | jz free |
||
1292 | call destroy_hdll |
||
1293 | jmp .loop |
||
1294 | .ret: |
||
1295 | ret |
||
1296 | |||
1297 | ; param |
||
1298 | ; eax= size |
||
1299 | ; ebx= pid |
||
1300 | |||
1301 | align 4 |
||
1302 | create_kernel_object: |
||
1303 | |||
1304 | push ebx |
||
1305 | call malloc |
||
1306 | pop ebx |
||
1307 | test eax, eax |
||
1308 | jz .fail |
||
1309 | |||
1310 | mov ecx, [current_slot] |
||
1311 | add ecx, APP_OBJ_OFFSET |
||
1312 | |||
1313 | pushfd |
||
1314 | cli |
||
9715 | Doczom | 1315 | mov edx, [ecx + APPOBJ.fd] |
1316 | mov [eax + APPOBJ.fd], edx |
||
1317 | mov [eax + APPOBJ.bk], ecx |
||
1318 | mov [eax + APPOBJ.pid], ebx |
||
2288 | clevermous | 1319 | |
9715 | Doczom | 1320 | mov [ecx + APPOBJ.fd], eax |
1321 | mov [edx + APPOBJ.bk], eax |
||
2288 | clevermous | 1322 | popfd |
1323 | .fail: |
||
1324 | ret |
||
1325 | |||
1326 | ; param |
||
1327 | ; eax= object |
||
1328 | |||
1329 | align 4 |
||
1330 | destroy_kernel_object: |
||
1331 | |||
1332 | pushfd |
||
1333 | cli |
||
9715 | Doczom | 1334 | mov ebx, [eax + APPOBJ.fd] |
1335 | mov ecx, [eax + APPOBJ.bk] |
||
1336 | mov [ebx + APPOBJ.bk], ecx |
||
1337 | mov [ecx + APPOBJ.fd], ebx |
||
2288 | clevermous | 1338 | popfd |
1339 | |||
1340 | xor edx, edx ;clear common header |
||
1341 | mov [eax], edx |
||
1342 | mov [eax+4], edx |
||
1343 | mov [eax+8], edx |
||
1344 | mov [eax+12], edx |
||
1345 | mov [eax+16], edx |
||
1346 | |||
1347 | call free ;release object memory |
||
1348 | ret |
||
5595 | serge | 1349 | |
6926 | serge | 1350 | |
1351 | ;void* __fastcall create_object(size_t size) |
||
5595 | serge | 1352 | ; param |
1353 | ; ecx= size |
||
1354 | |||
1355 | align 4 |
||
1356 | create_object: |
||
1357 | |||
1358 | push esi |
||
1359 | push edi |
||
1360 | pushfd |
||
1361 | cli |
||
1362 | |||
1363 | mov esi, [current_process] |
||
9715 | Doczom | 1364 | mov eax, [esi + PROC.ht_free] |
1365 | mov edi, [esi + PROC.ht_next] |
||
5595 | serge | 1366 | dec eax |
1367 | js .err0 |
||
1368 | |||
9715 | Doczom | 1369 | mov [esi + PROC.ht_free], eax |
1370 | mov eax, [esi + PROC.htab + edi*4] |
||
1371 | mov [esi + PROC.ht_next], eax |
||
5595 | serge | 1372 | popfd |
1373 | |||
1374 | mov eax, ecx |
||
1375 | call malloc |
||
1376 | test eax, eax |
||
1377 | jz .err1 |
||
1378 | |||
9715 | Doczom | 1379 | mov [eax + FUTEX.handle], edi |
1380 | mov [esi + PROC.htab+edi*4], eax |
||
5595 | serge | 1381 | pop edi |
1382 | pop esi |
||
1383 | ret |
||
1384 | |||
1385 | .err1: |
||
1386 | pushfd |
||
1387 | cli |
||
1388 | |||
9715 | Doczom | 1389 | mov eax, [esi + PROC.ht_next] |
1390 | mov [esi + PROC.htab+edi*4], eax |
||
1391 | mov [esi + PROC.ht_next], edi |
||
1392 | inc [esi + PROC.ht_free] |
||
5595 | serge | 1393 | .err0: |
1394 | popfd |
||
1395 | pop edi |
||
1396 | pop esi |
||
1397 | xor eax, eax |
||
1398 | ret |
||
1399 | |||
6926 | serge | 1400 | |
1401 | ;int __fastcall destroy_object(struct object *obj) |
||
1402 | |||
1403 | align 4 |
||
1404 | destroy_object: |
||
1405 | push esi |
||
1406 | mov esi, [current_process] |
||
9715 | Doczom | 1407 | mov edx, [ecx + FUTEX.handle] |
6926 | serge | 1408 | |
1409 | pushfd |
||
1410 | cli |
||
1411 | |||
9715 | Doczom | 1412 | mov eax, [esi + PROC.ht_next] |
1413 | mov [esi + PROC.htab + edx*4], eax |
||
1414 | mov [esi + PROC.ht_next], edx |
||
1415 | inc [esi + PROC.ht_free] |
||
6926 | serge | 1416 | |
1417 | popfd |
||
1418 | pop esi |
||
1419 | |||
1420 | mov eax, ecx |
||
1421 | call free |
||
1422 | xor eax, eax |
||
1423 | ret |
||
1424 | .fail: |
||
1425 | popfd |
||
1426 | pop esi |
||
1427 | mov eax, -1 |
||
1428 | ret |
||
1429 |