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