Subversion Repositories Kolibri OS

Rev

Rev 1635 | 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
3555 Serge 30
        push    bx
31
        lea     di, [bx+1feh]
32
        mov     cx, [bx+6]
33
        add     bx, [bx+4]
34
        dec     cx
1065 Lrz 35
@@:
3555 Serge 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
1065 Lrz 44
 
45
find_attr:
46
; in: ds:di->file record, ax=attribute
47
; out: ds:di->attribute or di=0 if not found
3555 Serge 48
        add     di, [di+14h]
1065 Lrz 49
.1:
50
; attributes' codes are formally dwords, but all of them fit in word
3555 Serge 51
        cmp     word [di], -1
52
        jz      .notfound
53
        cmp     word [di], ax
54
        jnz     .continue
1065 Lrz 55
; for $DATA attribute, scan only unnamed
3555 Serge 56
        cmp     ax, 80h
57
        jnz     .found
58
        cmp     byte [di+9], 0
59
        jz      .found
1065 Lrz 60
.continue:
3555 Serge 61
        add     di, [di+4]
62
        jmp     .1
1065 Lrz 63
.notfound:
3555 Serge 64
        xor     di, di
1065 Lrz 65
.found:
3555 Serge 66
        ret
1065 Lrz 67
 
68
process_mcb_nonres:
69
; in: ds:si->attribute, es:di->buffer
70
; out: es:di->buffer end
3555 Serge 71
        pushad
72
        pop     di
73
        add     si, [si+20h]
74
        xor     ebx, ebx
1065 Lrz 75
.loop:
3555 Serge 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
1065 Lrz 94
.l1:
3555 Serge 95
        dec     si
96
        shl     eax, 8
97
        mov     al, [si]
98
        loop    .l1
1065 Lrz 99
.l1e:
3555 Serge 100
        xchg    ebp, eax
101
        dec     si
102
        movsx   eax, byte [si]
103
        mov     cx, dx
104
        dec     cx
105
        jz      .l2e
1065 Lrz 106
.l2:
3555 Serge 107
        dec     si
108
        shl     eax, 8
109
        mov     al, byte [si]
110
        loop    .l2
1065 Lrz 111
.l2e:
3555 Serge 112
        pop     si
113
        add     ebx, ebp
1065 Lrz 114
; eax=length, ebx=disk block
3555 Serge 115
        stosd
116
        mov     eax, ebx
117
        stosd
118
        cmp     di, 0x8000 - 12
119
        jbe     .loop
1065 Lrz 120
..attr_overflow:
3555 Serge 121
        mov     si, fragmented_string
122
        jmp     find_error_si
1065 Lrz 123
.done:
3555 Serge 124
        xor     ax, ax
125
        stosw
126
        stosw
127
        push    di
128
        popad
129
        ret
1065 Lrz 130
 
131
load_attr:
132
; in: ax=attribute, ds:bx->base record
133
; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated,
3555 Serge 134
;       edx=size of attribute in bytes
1065 Lrz 135
; out: if not found: CF=1
3555 Serge 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
1065 Lrz 144
; scan for attribute
3555 Serge 145
        push    di
146
        mov     di, bx
147
        add     di, [di+14h]
1065 Lrz 148
@@:
3555 Serge 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
1065 Lrz 158
.aux_resident:
3555 Serge 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
1065 Lrz 166
; resident attribute
167
.resident:
3555 Serge 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
1065 Lrz 185
.nonresident:
186
; nonresident attribute
3555 Serge 187
        cmp     dword [di+10h], 0
188
        jnz     @b
1065 Lrz 189
; read start of data
3555 Serge 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
1065 Lrz 196
.notfound1:
3555 Serge 197
        pop     di
198
        push    edx
1065 Lrz 199
; $ATTRIBUTE_LIST is always in base file record
3555 Serge 200
        cmp     ax, 20h
201
        jz      .nofragmented
1065 Lrz 202
; try to load $ATTRIBUTE_LIST = 20h
3555 Serge 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
1065 Lrz 233
.1:
3555 Serge 234
        cmp     [bx], ax
235
        jnz     .continue1
1065 Lrz 236
; only unnamed $DATA attributes!
3555 Serge 237
        cmp     ax, 80h
238
        jnz     @f
239
        cmp     byte [bx+6], 0
240
        jnz     .continue1
1065 Lrz 241
@@:
3555 Serge 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
1065 Lrz 250
@@:
3555 Serge 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]
1065 Lrz 258
.2:
3555 Serge 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]
1065 Lrz 270
@@:
3555 Serge 271
        pop     di
272
        call    process_mcb_nonres
273
        sub     di, 4
274
        pop     ds
1065 Lrz 275
.continue1:
3555 Serge 276
        add     bx, [bx+4]
277
        cmp     bx, dx
278
        jb      .1
279
        pop     bx ds
1065 Lrz 280
.nofragmented:
3555 Serge 281
        pop     edx
282
        dec     di
283
        cmp     di, [bp + freeattr - dat]
284
        jnz     @f
285
        stc
286
        ret
1065 Lrz 287
@@:
3555 Serge 288
        inc     di
289
        xor     ax, ax
290
        stosw
291
        stosw
292
        mov     [bp + freeattr - dat], di
293
        ret
1065 Lrz 294
 
295
read_file_record:
296
; in: eax = index of record
297
; out: ds:0 -> record
298
; find place in cache
3555 Serge 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
1065 Lrz 312
; read file record  to ds:0
3555 Serge 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
1065 Lrz 329
; initialize cache for $INDEX_ALLOCATION for this record
3555 Serge 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
1065 Lrz 347
.noread:
3555 Serge 348
        ret
1065 Lrz 349
 
350
read_attr:
351
; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute
3555 Serge 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
1065 Lrz 369
.nonresident:
3555 Serge 370
        inc     si
1065 Lrz 371
.loop:
3555 Serge 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
1065 Lrz 385
@@:
3555 Serge 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
1065 Lrz 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)
3555 Serge 408
        push    es bx cx
409
        mov     eax, 5          ; root cluster
410
        mov     [bp + cur_obj - dat], root_string
1065 Lrz 411
.parse_dir_loop:
3555 Serge 412
        push    ds si
413
        call    read_file_record
1065 Lrz 414
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
3555 Serge 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
1065 Lrz 428
@@:
3555 Serge 429
        push    ds
1065 Lrz 430
; search for entry
3555 Serge 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
1065 Lrz 448
; calculate number of items in cache
3555 Serge 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
1065 Lrz 473
.scan_record:
3555 Serge 474
        add     bx, [bx]
1065 Lrz 475
.scan:
3555 Serge 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
1065 Lrz 485
.1:
3555 Serge 486
        lodsb
487
        cmp     al, '/'
488
        jnz     @f
489
        mov     al, 0
1065 Lrz 490
@@:
3555 Serge 491
        cmp     al, 'A'
492
        jb      .nocapital
493
        cmp     al, 'Z'
494
        ja      .nocapital
495
        or      al, 20h
1065 Lrz 496
.nocapital:
3555 Serge 497
        cmp     al, 'a'
498
        jb      .notletter
499
        cmp     al, 'z'
500
        ja      .notletter
501
        or      byte [es:di], 20h
1065 Lrz 502
.notletter:
3555 Serge 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
1065 Lrz 511
@@:
3555 Serge 512
        push    es
513
        pop     ds
514
        add     bx, [bx+8]
515
        jmp     .scan
1065 Lrz 516
.look_child:
3555 Serge 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
1065 Lrz 552
.noread:
3555 Serge 553
        push    es
554
        pop     ds
555
        add     bx, 18h
556
        jmp     .scan_record
1065 Lrz 557
.not_found:
3555 Serge 558
        pop     [bp + cur_obj - dat]
559
        mov     si, error_not_found
560
        jmp     find_error_si
1065 Lrz 561
.file_found:
3555 Serge 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
1065 Lrz 573
.regular_file:
3555 Serge 574
        cmp     byte [si], 0
575
        jnz     ..notdir_error
1065 Lrz 576
; read entry
3555 Serge 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