Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2783 clevermous 1
restore_usa:
2
; Update Sequence Array restore
3
	mov	bx, [di+4]
4
	mov	cx, [di+6]
5
	inc	bx
6
	add	bx, di
7
	inc	bx
8
	add	di, 1feh
9
	dec	cx
10
@@:
11
	mov	ax, [bx]
12
	stosw
13
	inc	bx
14
	inc	bx
15
	add	di, 1feh
16
	loop	@b
17
	ret
18
 
19
find_attr:
20
; in: di->file record, ax=attribute
21
; out: di->attribute or di=0 if not found
22
	add	di, [di+14h]
23
.1:
24
; attributes codes are formally dwords, but all they fit in word
25
	cmp	word [di], -1
26
	jz	.notfound
27
	cmp	word [di], ax
28
	jnz	.continue
29
; for $DATA attribute, scan only unnamed
30
	cmp	ax, 80h
31
	jnz	.found
32
	cmp	byte [di+9], 0
33
	jz	.found
34
.continue:
35
	add	di, [di+4]
36
	jmp	.1
37
.notfound:
38
	xor	di, di
39
.found:
40
	ret
41
 
42
process_mcb_nonres:
43
; in: si->attribute, es:di->buffer
44
; out: di->buffer end
45
	add	si, [si+20h]
46
	xor	ebx, ebx
47
.loop:
48
	lodsb
49
	test	al, al
50
	jz	.done
51
	push	invalid_read_request_string
52
	movzx	cx, al
53
	shr	cx, 4
54
	jz	find_error_sp
55
	xchg	ax, dx
56
	and	dx, 0Fh
57
	jz	find_error_sp
58
	add	si, cx
59
	add	si, dx
60
	pop	ax
61
	push	si
62
	dec	si
63
	movsx	eax, byte [si]
64
	dec	cx
65
	jz	.l1e
66
.l1:
67
	dec	si
68
	shl	eax, 8
69
	mov	al, [si]
70
	loop	.l1
71
.l1e:
72
	xchg	ebp, eax
73
	dec	si
74
	movsx	eax, byte [si]
75
	mov	cx, dx
76
	dec	cx
77
	jz	.l2e
78
.l2:
79
	dec	si
80
	shl	eax, 8
81
	mov	al, byte [si]
82
	loop	.l2
83
.l2e:
84
	pop	si
85
	add	ebx, ebp
86
; eax=length, ebx=disk block
87
	stosd
88
	mov	eax, ebx
89
	stosd
90
	jmp	.loop
91
.done:
92
	xor	eax, eax
93
	stosd
94
	ret
95
 
96
load_attr:
97
; in: ax=attribute, es:bx->buffer, di->base record
98
; out: bx->buffer end; CF set if not found
99
	push	di
100
	push	ax
101
	mov	byte [es:bx], 1
102
	inc	bx
103
	push	bx
104
	mov	[ofs], bx
105
; scan for attrubute
106
	add	di, [di+14h]
107
@@:
108
	call	find_attr.1
109
	test	di, di
110
	jz	.notfound1
111
	cmp	byte [di+8], 0
112
	jnz	.nonresident
113
	jmp	.resident
114
.aux_resident:
115
	push	di
116
	popad
117
; resident attribute
118
.resident:
119
	mov	si, di
120
	pop	di
121
	dec	di
122
	mov	al, 0
123
	stosb
124
	mov	ax, [si+10h]
125
	stosw
126
	xchg	ax, cx
127
	add	si, [si+14h]
128
	rep	movsb
129
	mov	bx, di
130
	pop	ax
131
	pop	di
132
	ret
133
.nonresident:
134
; nonresident attribute
135
	cmp	dword [di+10h], 0
136
	jnz	@b
137
; read start of data
138
	mov	si, di
139
	pop	di
140
	call	process_mcb_nonres
141
	sub	di, 4
142
	push	di
143
.notfound1:
144
; $ATTRIBUTE_LIST is always in base file record
145
	cmp	word [esp+2], 20h
146
	jz	.nofragmented
147
; scan for $ATTRIBUTE_LIST = 20h
148
	mov	di, [esp+4]
149
	mov	ax, 20h
150
	call	find_attr
151
	test	di, di
152
	jz	.nofragmented
153
; load $ATTRIBUTE_LIST itself
154
	push	es
155
	mov	bx, 0C000h
156
	mov	di, [esp+6]
157
	push	bx
158
	push	[ofs]
159
	push	ds
160
	pop	es
161
	call	load_attr
162
	pop	[ofs]
163
	pop	si
164
	mov	bx, 8000h
165
	push	bx
166
	push	si
167
	call	read_attr_full
168
	pop	si
169
	pop	bx
170
	add	dx, bx
171
	mov	ax, [esp+4]
172
	pop	es
173
.1:
174
	cmp	[bx], ax
175
	jnz	.continue1
176
; only unnamed $DATA attributes!
177
	cmp	ax, 80h
178
	jnz	@f
179
	cmp	byte [bx+6], 0
180
	jnz	.continue1
181
@@:
182
	cmp	dword [bx+10h], 0
183
	jz	.continue1
184
	cmp	dword [bx+8], 0
185
	jnz	@f
186
	push	ax
187
	mov	ax, [esp+2]
188
	cmp	ax, [ofs]
189
	pop	ax
190
	jnz	.continue1
191
@@:
192
	pushad
193
	mov	eax, [bx+10h]
194
	mov	bx, dx
195
	push	[ofs]
196
	push	es
197
	push	ds
198
	pop	es
199
	call	read_file_record
200
	pop	es
201
	pop	[ofs]
202
	popad
203
	pushad
204
	pop	di
205
	mov	di, dx
206
	add	di, [di+14h]
207
.2:
208
	call	find_attr.1
209
	cmp	byte [di+8], 0
210
	jz	.aux_resident
211
	mov	eax, [bx+8]
212
	cmp	eax, [di+10h]
213
	jnz	.2
214
	mov	si, di
215
	mov	di, [esp+1Eh]
216
	call	process_mcb_nonres
217
	sub	di, 4
218
	mov	[esp+1Eh], di
219
	push	di
220
	popad
221
.continue1:
222
	add	bx, [bx+4]
223
	cmp	bx, dx
224
	jb	.1
225
.nofragmented:
226
	pop	bx
227
	pop	ax
228
	pop	di
229
	cmp	bx, [ofs]
230
	jnz	@f
231
	dec	bx
232
	stc
233
	ret
234
@@:
235
	add	bx, 4
236
	ret
237
 
238
read_attr_full:
239
; in: si->decoded attribute data, bx->buffer
240
; out: edx=length in bytes
241
	lodsb
242
	cmp	al, 0
243
	jnz	.nonresident
244
; resident
245
	lodsw
246
	movzx	edx, ax
247
	xchg	ax, cx
248
	mov	di, bx
249
	rep	movsb
250
	ret
251
.nonresident:
252
; nonresident :-)
253
	xor	edx, edx
254
.loop:
255
	lodsd
256
	xchg	ecx, eax
257
	jecxz	.loopend
258
	lodsd
259
	xchg	edi, eax
260
; read ecx clusters from cluster edi to es:bx
261
.intloop:
262
	push	ecx
263
; read 1 cluster from physical cluster edi to es:bx
264
	mov	ecx, [cluster_size]
265
	mov	eax, edi
266
	mul	ecx
267
	push	bx
268
	call	relative_read
269
	pop	bx
270
	pop	ecx
271
	inc	edi
272
	mov	eax, [cluster_size]
273
	add	edx, eax
274
	shr	eax, 4
275
	mov	bp, es
276
	add	bp, ax
277
	mov	es, bp
278
	loop	.intloop
279
	jmp	.loop
280
.loopend:
281
	mov	es, cx
282
	ret
283
 
284
read_file_record:
285
; in: eax=index of record, bx=buffer
286
	mov	si, 700h
287
	mov	ecx, [frs_size]
288
	mul	ecx
289
	push	bx
290
	push	[cur_obj]
291
	mov	[cur_obj], mft_string
292
	call	read_attr
293
	pop	[cur_obj]
294
	pop	di
295
	call	restore_usa
296
	ret
297
read_attr:
298
; in: edx:eax=offset in bytes, ecx=size in bytes, bx=buffer, si=attribute
299
	push	invalid_read_request_string
300
	cmp	byte [si], 0
301
	jnz	.nonresident
302
	test	edx, edx
303
	jnz	find_error_sp
304
	cmp	eax, 10000h
305
	jae	find_error_sp
306
	cmp	ecx, 10000h
307
	jae	find_error_sp
308
	cmp	ax, [si+2]
309
	jae	find_error_sp
310
	cmp	cx, [si+2]
311
	ja	find_error_sp
312
	add	si, 3
313
	add	si, ax
314
	mov	di, bx
315
	rep	movsb
316
	pop	ax
317
	ret
318
.nonresident:
319
	mov	edi, [cluster_size]
320
	div	edi
321
	mov	[ofs], dx
322
	add	cx, dx
323
	push	eax
324
	xchg	eax, ecx
325
	xor	edx, edx
326
	dec	eax
327
	div	edi
328
	inc	eax
329
	xchg	eax, ecx
330
	pop	eax
331
	add	si, 1
332
	xor	edx, edx
333
	push	bx
334
; eax=offset in clusters, ecx=size in clusters
335
.scan:
336
	mov	ebx, [si]
337
	test	ebx, ebx
338
	jz	.notfound
339
	add	edx, ebx
340
	add	si, 8
341
	cmp	eax, edx
342
	jae	.scan
343
	mov	edi, [si-4]
344
; now edx=end of block, ebx=length of block, edi=start of block on disk
345
; eax=required offset, ecx=required length
346
	push	edx
347
	push	edi
348
	sub	edx, eax
349
	add	edi, ebx
350
	sub	edi, edx
351
	cmp	edx, ecx
352
	jb	@f
353
	mov	edx, ecx
354
@@:
355
; read (edx) clusters from (edi=disk offset in clusters) to ([esp+8])
356
	cmp	[ofs], 0
357
	jnz	.ofs_read
358
.cont:
359
	pushad
360
	movzx	ebx, byte [50Dh]
361
;       xchg    eax, edx
362
;       mul     ebx
363
	xchg	ax, dx
364
	mul	bx
365
	xchg	cx, ax
366
	xchg	eax, edi
367
	mul	ebx
368
	mov	bx, [esp+8+20h]
369
	call	relative_read
370
	mov	[esp+8+20h], bx
371
	popad
372
.cont2:
373
	add	eax, edx
374
	sub	ecx, edx
375
.cont3:
376
	pop	edi
377
	pop	edx
378
	jnz	.scan
379
	pop	bx
380
	pop	ax
381
	ret
382
.ofs_read:
383
	push	ecx
384
	movzx	ecx, byte [50Dh]	; bpb_sects_per_clust
385
	mov	eax, edi
386
	push	edx
387
	mul	ecx
388
	push	1000h
389
	pop	es
390
	xor	bx, bx
391
	call	relative_read
392
	mov	cx, bx
393
	push	si
394
	push	di
395
	mov	si, [ofs]
396
	mov	di, [esp+8+12]
397
	sub	cx, si
398
	push	ds
399
	push	es
400
	pop	ds
401
	pop	es
402
	rep	movsb
403
	mov	[esp+8+12], di
404
	push	es
405
	pop	ds
406
	pop	di
407
	pop	si
408
	pop	edx
409
	pop	ecx
410
	inc	edi
411
	mov	[ofs], 0
412
	inc	eax
413
	dec	ecx
414
	jz	.cont3
415
	dec	edx
416
	jnz	.cont
417
	jmp	.cont2
418
.notfound:
419
	mov	si, invalid_read_request_string
420
	jmp	find_error_si
421
 
422
ntfs_parse_dir:
423
; in: eax=directory iRecord, [word sp+2]=filename
424
; out: si=$DATA attribute of file
425
	mov	bx, [free]
426
	mov	[dir], bx
427
	push	bx
428
	call	read_file_record
429
	mov	ax, word [frs_size]
430
	add	[free], ax
431
	pop	di
432
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
433
	mov	ax, 90h 	; $INDEX_ROOT
434
	push	di
435
	mov	bx, [free]
436
	mov	[index_root], bx
437
	call	load_attr
438
	mov	si, noindex_string
439
	jc	find_error_si
440
	mov	[free], bx
441
	pop	di
442
	mov	ax, 0A0h	; $INDEX_ALLOCATION
443
	mov	bx, [free]
444
	mov	[index_alloc], bx
445
	call	load_attr
446
	jnc	@f
447
	mov	[index_alloc], 0
448
@@:
449
	mov	[free], bx
450
; search for entry
451
	mov	si, [index_root]
452
	mov	bx, [free]
453
	call	read_attr_full
454
	mov	ebp, [bx+8]	; subnode_size
455
	add	bx, 10h
456
.scan_record:
457
	add	bx, [bx]
458
.scan:
459
	test	byte [bx+0Ch], 2
460
	jnz	.not_found
461
	mov	si, [esp+2]
462
	movzx	cx, byte [bx+50h]	; namelen
463
	lea	di, [bx+52h]		; name
464
	xor	ax, ax
465
@@:
466
	lodsb
467
	cmp	al, 'a'
468
	jb	.notletter
469
	cmp	al, 'z'
470
	ja	.notletter
471
	or	byte [di], 20h
472
.notletter:
473
	scasw
474
	loopz	@b
475
	jb	.not_found
476
	ja	@f
477
	cmp	byte [esi], 0
478
	jz	.file_found
479
@@:
480
	add	bx, [bx+8]
481
	jmp	.scan
482
.not_found:
483
	test	byte [bx+0Ch], 1
484
	jz	file_not_found
485
	cmp	[index_alloc], 0
486
	jz	file_not_found
487
	add	bx, [bx+8]
488
	mov	eax, [bx-8]
489
	mul	[cluster_size]
490
	mov	si, [index_alloc]
491
	mov	ecx, ebp
492
	mov	bx, [free]
493
	call	read_attr
494
	mov	di, [free]
495
	call	restore_usa
496
	mov	bx, [free]
497
	add	bx, 18h
498
	jmp	.scan_record
499
.file_found:
500
	mov	si, [esp+2]
501
	mov	[cur_obj], si
502
	cmp	byte [esp+4], 0
503
	jz	.need_file
504
	mov	si, notdir_string
505
	test	byte [bx+48h+3], 10h
506
	jz	find_error_si
507
	mov	eax, [bx]
508
	mov	bx, [dir]
509
	mov	[free], bx
510
	ret	2
511
.need_file:
512
	mov	si, directory_string
513
	test	byte [bx+48h+3], 10h	; directory?
514
	jnz	find_error_si
515
; read entry
516
	mov	eax, [bx]
517
	mov	bx, [dir]
518
	mov	[free], bx
519
	mov	bx, 4000h
520
	push	bx
521
	call	read_file_record
522
	pop	di
523
	mov	ax, 80h
524
	push	2000h
525
	pop	es
526
	xor	bx, bx
527
	call	load_attr
528
	mov	si, nodata_string
529
	jz	find_error_si
530
	mov	[free], bx
531
	ret	2