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