Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1065 Lrz 1
; Copyright (c) 2008-2009, diamond
2
; All rights reserved.
3
;
4
; Redistribution and use in source and binary forms, with or without
5
; modification, are permitted provided that the following conditions are met:
6
;       * Redistributions of source code must retain the above copyright
7
;       notice, this list of conditions and the following disclaimer.
8
;       * Redistributions in binary form must reproduce the above copyright
9
;       notice, this list of conditions and the following disclaimer in the
10
;       documentation and/or other materials provided with the distribution.
11
;       * Neither the name of the  nor the
12
;       names of its contributors may be used to endorse or promote products
13
;       derived from this software without specific prior written permission.
14
;
15
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka  ''AS IS'' AND ANY
16
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
; DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
19
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
;*****************************************************************************
26
 
27
restore_usa:
28
; Update Sequence Array restore
29
; in: ds:bx -> USA-protected structure
30
	push	bx
31
	lea	di, [bx+1feh]
32
	mov	cx, [bx+6]
33
	add	bx, [bx+4]
34
	dec	cx
35
@@:
36
	mov	ax, [bx+2]
37
	mov	[di], ax
38
	inc	bx
39
	inc	bx
40
	add	di, 200h
41
	loop	@b
42
	pop	bx
43
	ret
44
 
45
find_attr:
46
; in: ds:di->file record, ax=attribute
47
; out: ds:di->attribute or di=0 if not found
48
	add	di, [di+14h]
49
.1:
50
; attributes' codes are formally dwords, but all of them fit in word
51
	cmp	word [di], -1
52
	jz	.notfound
53
	cmp	word [di], ax
54
	jnz	.continue
55
; for $DATA attribute, scan only unnamed
56
	cmp	ax, 80h
57
	jnz	.found
58
	cmp	byte [di+9], 0
59
	jz	.found
60
.continue:
61
	add	di, [di+4]
62
	jmp	.1
63
.notfound:
64
	xor	di, di
65
.found:
66
	ret
67
 
68
process_mcb_nonres:
69
; in: ds:si->attribute, es:di->buffer
70
; out: es:di->buffer end
71
	pushad
72
	pop	di
73
	add	si, [si+20h]
74
	xor	ebx, ebx
75
.loop:
76
	lodsb
77
	test	al, al
78
	jz	.done
79
	push	invalid_read_request_string
80
	movzx	cx, al
81
	shr	cx, 4
82
	jz	find_error_sp
83
	xchg	ax, dx
84
	and	dx, 0Fh
85
	jz	find_error_sp
86
	add	si, cx
87
	add	si, dx
88
	pop	ax
89
	push	si
90
	dec	si
91
	movsx	eax, byte [si]
92
	dec	cx
93
	jz	.l1e
94
.l1:
95
	dec	si
96
	shl	eax, 8
97
	mov	al, [si]
98
	loop	.l1
99
.l1e:
100
	xchg	ebp, eax
101
	dec	si
102
	movsx	eax, byte [si]
103
	mov	cx, dx
104
	dec	cx
105
	jz	.l2e
106
.l2:
107
	dec	si
108
	shl	eax, 8
109
	mov	al, byte [si]
110
	loop	.l2
111
.l2e:
112
	pop	si
113
	add	ebx, ebp
114
; eax=length, ebx=disk block
115
	stosd
116
	mov	eax, ebx
117
	stosd
118
	cmp	di, 0x8000 - 12
119
	jbe	.loop
120
..attr_overflow:
121
	mov	si, fragmented_string
122
	jmp	find_error_si
123
.done:
124
	xor	ax, ax
125
	stosw
126
	stosw
127
	push	di
128
	popad
129
	ret
130
 
131
load_attr:
132
; in: ax=attribute, ds:bx->base record
133
; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated,
134
;	edx=size of attribute in bytes
135
; out: if not found: CF=1
136
	mov	di, [bp + freeattr - dat]
137
	push	ss
138
	pop	es
139
	mov	byte [es:di], 1
140
	inc	di
141
	cmp	di, 0x8000 - 12
142
	ja	..attr_overflow
143
	or	edx, -1		; file size is not known yet
144
; scan for attribute
145
	push	di
146
	mov	di, bx
147
	add	di, [di+14h]
148
@@:
149
	call	find_attr.1
150
	test	di, di
151
	jz	.notfound1
152
	cmp	byte [di+8], 0
153
	jnz	.nonresident
154
	mov	si, di
155
	pop	di
156
	push	ds
157
	jmp	.resident
158
.aux_resident:
159
	mov	ax, ds
160
	mov	si, di
161
	pop	di ds bx ds edx
162
	push	ss
163
	pop	es
164
	push	ds
165
	mov	ds, ax
166
; resident attribute
167
.resident:
168
	dec	di
169
	mov	al, 0
170
	stosb
171
	mov	ax, [si+10h]
172
	stosw
173
	push	di
174
	add	di, ax
175
	cmp	di, 0x8000 - 12
176
	pop	di
177
	ja	..attr_overflow
178
	movzx	edx, ax		; length of attribute
179
	xchg	ax, cx
180
	add	si, [si+14h]
181
	rep	movsb
182
	mov	[bp + freeattr - dat], di
183
	pop	ds
184
	ret
185
.nonresident:
186
; nonresident attribute
187
	cmp	dword [di+10h], 0
188
	jnz	@b
189
; read start of data
190
	mov	si, di
191
	mov	edx, [di+30h]	; size of attribute
192
	pop	di
193
	call	process_mcb_nonres
194
	sub	di, 4
195
	push	di
196
.notfound1:
197
	pop	di
198
	push	edx
199
; $ATTRIBUTE_LIST is always in base file record
200
	cmp	ax, 20h
201
	jz	.nofragmented
202
; try to load $ATTRIBUTE_LIST = 20h
203
	push	ax
204
	mov	ax, 20h
205
	push	[bp + freeattr - dat]
206
	mov	[bp + freeattr - dat], di
207
	push	di
208
	call	load_attr
209
	pop	di
210
	pop	[bp + freeattr - dat]
211
	pop	ax
212
	jc	.nofragmented
213
	push	ds bx
214
	pusha
215
	mov	si, di
216
	push	ss
217
	pop	ds
218
	push	0x8100
219
	pop	es
220
	xor	ecx, ecx
221
	mov	cl, 0x78
222
	xor	bx, bx
223
	push	es
224
	call	read_file_chunk
225
	pop	ds
226
	jc	..found_disk_error
227
	test	cx, cx
228
	jz	..attr_overflow
229
	popa
230
	push	ss
231
	pop	es
232
	xor	bx, bx
233
.1:
234
	cmp	[bx], ax
235
	jnz	.continue1
236
; only unnamed $DATA attributes!
237
	cmp	ax, 80h
238
	jnz	@f
239
	cmp	byte [bx+6], 0
240
	jnz	.continue1
241
@@:
242
	cmp	dword [bx+10h], 0
243
	jz	.continue1
244
	cmp	dword [bx+8], 0
245
	jnz	@f
246
	dec	di
247
	cmp	di, [bp + freeattr - dat]
248
	lea	di, [di+1]
249
	jnz	.continue1
250
@@:
251
	push	ds di
252
	push	ax
253
	mov	eax, [bx+10h]
254
	mov	ecx, [bx+8]
255
	call	read_file_record
256
	pop	ax
257
	mov	di, [14h]
258
.2:
259
	call	find_attr.1
260
	cmp	byte [di+8], 0
261
	jz	.aux_resident
262
	cmp	dword [di+10h], ecx
263
	jnz	.2
264
	mov	si, di
265
	mov	di, sp
266
	cmp	dword [ss:di+8], -1
267
	jnz	@f
268
	push	dword [si+30h]	; size of attribute
269
	pop	dword [ss:di+8]
270
@@:
271
	pop	di
272
	call	process_mcb_nonres
273
	sub	di, 4
274
	pop	ds
275
.continue1:
276
	add	bx, [bx+4]
277
	cmp	bx, dx
278
	jb	.1
279
	pop	bx ds
280
.nofragmented:
281
	pop	edx
282
	dec	di
283
	cmp	di, [bp + freeattr - dat]
284
	jnz	@f
285
	stc
286
	ret
287
@@:
288
	inc	di
289
	xor	ax, ax
290
	stosw
291
	stosw
292
	mov	[bp + freeattr - dat], di
293
	ret
294
 
295
read_file_record:
296
; in: eax = index of record
297
; out: ds:0 -> record
298
; find place in cache
299
	push	di
300
	push	si
301
	mov	si, cache1head
302
	call	cache_lookup
303
	pop	si
304
	pushf
305
	sub	di, 3400h
306
	shl	di, 10-3
307
	add	di, 0x6000
308
	mov	ds, di
309
	popf
310
	pop	di
311
	jnc	.noread
312
; read file record  to ds:0
313
	pushad
314
	push	ds
315
	push	es
316
	movzx	ecx, [bp + frs_size - dat]
317
	shr	cx, 9
318
	mul	ecx
319
	push	ds
320
	pop	es
321
	push	ss
322
	pop	ds
323
	mov	si, 0x4000
324
	xor	bx, bx
325
	push	[bp + cur_obj - dat]
326
	mov	[bp + cur_obj - dat], mft_string
327
	push	es
328
	call	read_attr
329
; initialize cache for $INDEX_ALLOCATION for this record
330
	pop	si
331
	push	si
332
	sub	si, 0x6000
333
	mov	ax, si
334
	shr	si, 10-3
335
	shr	ax, 2
336
	add	si, 3480h
337
	add	ax, 3500h
338
	mov	[si], si
339
	mov	[si+2], si
340
	mov	[si+4], ax
341
	pop	ds
342
	call	restore_usa
343
	pop	[bp + cur_obj - dat]
344
	pop	es
345
	pop	ds
346
	popad
347
.noread:
348
	ret
349
 
350
read_attr:
351
; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute
352
	push	invalid_read_request_string
353
	cmp	byte [si], 0
354
	jnz	.nonresident
355
	cmp	eax, 10000h shr 9
356
	jae	find_error_sp
357
	shl	ax, 9
358
	shl	cx, 9
359
	cmp	ax, [si+2]
360
	jae	find_error_sp
361
	cmp	cx, [si+2]
362
	ja	find_error_sp
363
	add	si, 3
364
	add	si, ax
365
	mov	di, bx
366
	rep	movsb
367
	pop	ax
368
	ret
369
.nonresident:
370
	inc	si
371
.loop:
372
	mov	edx, dword [si]
373
	add	si, 8
374
	test	edx, edx
375
	jz	find_error_sp
376
	imul	edx, [bp + sect_per_clust - dat]
377
	sub	eax, edx
378
	jnc	.loop
379
	add	eax, edx
380
	sub	edx, eax
381
	push	cx
382
	cmp	ecx, edx
383
	jb	@f
384
	mov	cx, dx
385
@@:
386
	push	bx
387
	mov	ebx, [si-4]
388
	imul	ebx, [bp + sect_per_clust - dat]
389
	add	eax, ebx
390
	pop	bx
391
	call	read
392
	jc	..found_disk_error
393
	mov	dx, cx
394
	pop	cx
395
	xor	eax, eax
396
	sub	cx, dx
397
	jnz	.loop
398
	pop	ax
399
	ret
400
 
401
load_file_ntfs:
402
; in: ss:bp = 0:dat
403
; in: es:bx = address to load file
404
; in: ds:si -> ASCIIZ name
405
; in: cx = limit in sectors
406
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found
407
; out: dx:ax = file size (0xFFFFFFFF if file not found)
408
	push	es bx cx
409
	mov	eax, 5		; root cluster
410
	mov	[bp + cur_obj - dat], root_string
411
.parse_dir_loop:
412
	push	ds si
413
	call	read_file_record
414
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
415
	mov	ax, [bp + freeattr - dat]
416
	mov	[bp + index_root - dat], ax
417
	mov	ax, 90h		; $INDEX_ROOT
418
	xor	bx, bx
419
	call	load_attr
420
	mov	si, noindex_string
421
	jc	find_error_si
422
	mov	ax, [bp + freeattr - dat]
423
	mov	[bp + index_alloc - dat], ax
424
	mov	ax, 0A0h	; $INDEX_ALLOCATION
425
	call	load_attr
426
	jnc	@f
427
	mov	[bp + index_alloc - dat], bx
428
@@:
429
	push	ds
430
; search for entry
431
	mov	si, [bp + index_root - dat]
432
	push	ss
433
	pop	ds
434
	push	0x8100
435
	pop	es
436
	xor	ecx, ecx
437
	mov	cl, 0x78
438
	xor	bx, bx
439
	push	es
440
	call	read_file_chunk
441
	pop	ds
442
	jc	..found_disk_error
443
	test	cx, cx
444
	jz	..attr_overflow
445
	mov	si, invalid_read_request_string
446
	cmp	word [bx+10], 0
447
	jnz	find_error_si
448
; calculate number of items in cache
449
	mov	di, [bx+8]	; subnode_size
450
	mov	ax, 0x4000
451
	sub	ax, word [bp + frs_size - dat]
452
	cwd
453
	div	di
454
	test	ax, ax
455
	jz	find_error_si
456
	mov	si, invalid_volume_msg
457
	test	di, 0x1FF
458
	jnz	find_error_si
459
	pop	cx
460
	mov	[bp + cur_index_seg - dat], cx
461
	shl	ax, 3
462
	sub	cx, 6000h
463
	mov	si, cx
464
	shr	cx, 2
465
	shr	si, 10-3
466
	add	cx, ax
467
	add	si, 3480h
468
	mov	[bp + cur_index_cache - dat], si
469
	add	cx, 3500h
470
	mov	[ss:si+6], cx
471
	mov	dx, di
472
	add	bx, 10h
473
.scan_record:
474
	add	bx, [bx]
475
.scan:
476
	test	byte [bx+0Ch], 2
477
	jnz	.look_child
478
	movzx	cx, byte [bx+50h]	; namelen
479
	lea	di, [bx+52h]		; name
480
	push	ds
481
	pop	es
482
	pop	si ds
483
	push	ds si
484
	xor	ax, ax
485
.1:
486
	lodsb
487
	cmp	al, '/'
488
	jnz	@f
489
	mov	al, 0
490
@@:
491
	cmp	al, 'A'
492
	jb	.nocapital
493
	cmp	al, 'Z'
494
	ja	.nocapital
495
	or	al, 20h
496
.nocapital:
497
	cmp	al, 'a'
498
	jb	.notletter
499
	cmp	al, 'z'
500
	ja	.notletter
501
	or	byte [es:di], 20h
502
.notletter:
503
	scasw
504
	loopz	.1
505
	jb	.look_child
506
	ja	@f
507
	cmp	byte [si], 0
508
	jz	.file_found
509
	cmp	byte [si], '/'
510
	jz	.file_found
511
@@:
512
	push	es
513
	pop	ds
514
	add	bx, [bx+8]
515
	jmp	.scan
516
.look_child:
517
	push	es
518
	pop	ds
519
	test	byte [bx+0Ch], 1
520
	jz	.not_found
521
	mov	si, [bp + index_alloc - dat]
522
	test	si, si
523
	jz	.not_found
524
	add	bx, [bx+8]
525
	mov	eax, [bx-8]
526
	mov	es, [bp + cur_index_seg - dat]
527
	push	si
528
	mov	si, [bp + cur_index_cache - dat]
529
	call	cache_lookup
530
	pop	si
531
	pushf
532
	mov	bx, di
533
	mov	bh, 0
534
	shr	bx, 3
535
	imul	bx, dx
536
	add	bx, [bp + frs_size - dat]
537
	popf
538
	jnc	.noread
539
	push	es
540
	push	dx
541
	push	ss
542
	pop	ds
543
	movzx	ecx, dx
544
	shr	cx, 9
545
	mul	[bp + sect_per_clust - dat]
546
	call	read_attr
547
	pop	dx
548
	pop	es
549
	push	es
550
	pop	ds
551
	call	restore_usa
552
.noread:
553
	push	es
554
	pop	ds
555
	add	bx, 18h
556
	jmp	.scan_record
557
.not_found:
558
	pop	[bp + cur_obj - dat]
559
	mov	si, error_not_found
560
	jmp	find_error_si
561
.file_found:
562
	pop	[bp + cur_obj - dat]
563
	pop	cx
564
	mov	ax, [bp + index_root - dat]
565
	mov	[bp + freeattr - dat], ax
566
	mov	eax, [es:bx]
567
	test	byte [es:bx+48h+3], 10h
568
	jz	.regular_file
569
	cmp	byte [si], 0
570
	jz	..directory_error
571
	inc	si
572
	jmp	.parse_dir_loop
573
.regular_file:
574
	cmp	byte [si], 0
575
	jnz	..notdir_error
576
; read entry
577
	call	read_file_record
578
	xor	bx, bx
579
	mov	ax, 80h
580
	call	load_attr
581
	mov	si, nodata_string
582
	jc	find_error_si
583
	mov	si, [bp + index_root - dat]
584
	mov	[bp + freeattr - dat], si
585
	push	ss
586
	pop	ds
587
	jmp	load_file_common_end