Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
87 mario79 1
uglobal
2
cd_current_pointer_of_input    dd  0
3
cd_current_pointer_of_input_2  dd  0
4
cd_mem_location                dd  0
5
cd_counter_block               dd  0
6
endg
7
 
8
CDDataBuf equ 0x7000
9
 
10
reserve_cd:
11
 
12
    cli
13
    cmp   [cd_status],0
14
    je    reserve_ok2
15
 
16
    sti
17
    call  change_task
18
    jmp   reserve_hd1
19
 
20
  reserve_ok2:
21
 
22
    push  eax
23
    mov   eax,[0x3000]
24
    shl   eax,5
25
    mov   eax,[eax+0x3000+4]
26
    mov   [cd_status],eax
27
    pop   eax
28
    sti
29
    ret
30
 
31
cd_status dd 0
32
 
33
;----------------------------------------------------------------
34
;
35
;  fs_CdRead - LFN variant for reading CD disk
36
;
37
;  esi  points to filename /dir1/dir2/.../dirn/file,0
38
;  ebx  pointer to 64-bit number = first wanted byte, 0+
39
;       may be ebx=0 - start from first byte
40
;  ecx  number of bytes to read, 0+
41
;  edx  mem location to return data
42
;
43
;  ret ebx = bytes read or 0xffffffff file not found
44
;      eax = 0 ok read or other = errormsg
45
;
46
;--------------------------------------------------------------
47
fs_CdRead:
48
    push    edi
49
    cmp    byte [esi], 0
50
    jnz    @f
51
.noaccess:
52
    pop    edi
53
.noaccess_2:
54
    or    ebx, -1
55
    mov    eax, ERROR_ACCESS_DENIED
56
    ret
57
 
58
.noaccess_3:
59
    pop     eax edx ecx edi
60
    jmp  .noaccess_2
61
 
62
@@:
63
    call    cd_find_lfn
64
    jnc    .found
65
    pop    edi
66
    cmp   [DevErrorCode],0
67
    jne   .noaccess_2
68
    or    ebx, -1
69
    mov    eax, ERROR_FILE_NOT_FOUND
70
    ret
71
 
72
.found:
73
    mov    edi,[cd_current_pointer_of_input]
74
    test   byte [edi+25],10b    ; do not allow read directories
75
    jnz    .noaccess
76
    test    ebx, ebx
77
    jz    .l1
78
    cmp    dword [ebx+4], 0
79
    jz    @f
80
        xor     ebx, ebx
81
.reteof:
82
    mov    eax, 6 ; end of file
83
    pop    edi
84
    ret
85
@@:
86
    mov    ebx, [ebx]
87
.l1:
88
        push    ecx edx
89
        push    0
90
        mov     eax, [edi+10] ; реальный размер файловой секции
91
        sub     eax, ebx
92
        jb      .eof
93
        cmp     eax, ecx
94
        jae     @f
95
        mov     ecx, eax
96
        mov     byte [esp], 6
97
@@:
98
     mov    eax,[edi+2]
99
     mov    [CDSectorAddress],eax
100
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
101
.new_sector:
102
    test    ecx, ecx
103
    jz    .done
104
    sub    ebx, 2048
105
    jae    .new_sector
106
    add    ebx, 2048
107
    jnz    .incomplete_sector
108
    cmp    ecx, 2048
109
    jb    .incomplete_sector
110
; we may read and memmove complete sector
111
    mov  [CDDataBuf_pointer],edx
112
    call ReadCDWRetr      ; читаем сектор файла
113
    cmp   [DevErrorCode],0
114
    jne   .noaccess_3
115
    inc  dword [CDSectorAddress]
116
    add    edx, 2048
117
    sub    ecx, 2048
118
    jmp    .new_sector
119
.incomplete_sector:
120
; we must read and memmove incomplete sector
121
    mov  [CDDataBuf_pointer],CDDataBuf
122
    call ReadCDWRetr      ; читаем сектор файла
123
    cmp   [DevErrorCode],0
124
    jne   .noaccess_3
125
    inc  dword [CDSectorAddress]
126
    mov    eax,CDDataBuf
127
    add    eax, ebx
128
    push    ecx
129
    add    ecx, ebx
130
    cmp    ecx, 2048
131
    jbe    @f
132
    mov    ecx, 2048
133
@@:
134
    sub    ecx, ebx
135
     push edi esi ecx
136
     mov edi,edx
137
     mov esi,eax ;0x7000   ; CD data buffer
138
     cld
139
     rep movsb
140
     pop ecx esi edi
141
    add    edx, ecx
142
    sub    [esp], ecx
143
    pop    ecx
144
    xor    ebx, ebx
145
    jmp    .new_sector
146
 
147
.done:
148
        mov     ebx, edx
149
        pop     eax edx ecx edi
150
        sub     ebx, edx
151
        ret
152
.eof:
153
        mov     ebx, edx
154
        pop     eax edx ecx
155
        sub     ebx, edx
156
        jmp     .reteof
157
 
158
;----------------------------------------------------------------
159
;
160
;  fs_CdReadFolder - LFN variant for reading CD disk folder
161
;
162
;  esi  points to filename  /dir1/dir2/.../dirn/file,0
163
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
164
;                          & flags (bitfields)
165
; flags: bit 0: 0=ANSI names, 1=UNICODE names
166
;  ecx  number of blocks to read, 0+
167
;  edx  mem location to return data
168
;
169
;  ret ebx = blocks read or 0xffffffff folder not found
170
;      eax = 0 ok read or other = errormsg
171
;
172
;--------------------------------------------------------------
173
fs_CdReadFolder:
174
        push    edi
175
        call    cd_find_lfn
176
        jnc     .found
177
        pop     edi
178
        cmp   [DevErrorCode],0
179
        jne     .noaccess_1
180
        or      ebx, -1
181
        mov     eax, ERROR_FILE_NOT_FOUND
182
        ret
183
.found:
184
        mov    edi,[cd_current_pointer_of_input]
185
        test   byte [edi+25],10b    ; do not allow read directories
186
        jnz     .found_dir
187
        pop     edi
188
.noaccess_1:
189
        or      ebx, -1
190
        mov     eax, ERROR_ACCESS_DENIED
191
        ret
192
.found_dir:
193
        mov    eax,[edi+2]    ; eax=cluster
194
        mov    [CDSectorAddress],eax
195
        mov    eax,[edi+10] ; размер директрории
196
.doit:
197
; init header
198
        push    eax ecx
199
        mov     edi, edx
200
        mov     ecx, 32/4
201
        xor     eax, eax
202
        rep     stosd
203
        pop     ecx eax
204
        mov     byte [edx], 1   ; version
205
        mov     [cd_mem_location],edx
206
        add     [cd_mem_location],32
207
; начинаем переброску БДВК в УСВК
208
;.mainloop:
209
        mov  [cd_counter_block],dword 0
210
        dec  dword [CDSectorAddress]
211
        push ecx
212
.read_to_buffer:
213
        inc  dword [CDSectorAddress]
214
        mov  [CDDataBuf_pointer],CDDataBuf
215
        call ReadCDWRetr         ; читаем сектор директории
216
        cmp   [DevErrorCode],0
217
        jne   .noaccess_1
218
        call .get_names_from_buffer
219
        sub  eax,2048
220
; директория закончилась?
221
        cmp  eax,0
222
        jg   .read_to_buffer
223
        mov   edi,[cd_counter_block]
224
        mov   [edx+8],edi
225
        mov   edi,[ebx]
226
        sub   [edx+4],edi
227
        pop     ecx edi
89 diamond 228
        mov     ebx, [edx+4]
87 mario79 229
        mov     eax,ERROR_SUCCESS
230
        ret
231
 
232
.get_names_from_buffer:
233
    mov     [cd_current_pointer_of_input_2],CDDataBuf
234
    push    eax esi edi edx
235
.get_names_from_buffer_1:
236
    call    cd_get_name
237
    jc    .end_buffer
238
    inc    dword [cd_counter_block]
239
    mov    eax,[cd_counter_block]
240
    cmp    [ebx],eax
241
    jae     .get_names_from_buffer_1
242
    test    ecx, ecx
243
    jz    .get_names_from_buffer_1
244
    mov   edi,[cd_counter_block]
245
    mov   [edx+4],edi
246
    dec     ecx
247
    mov   esi,ebp
248
    mov   edi,[cd_mem_location]
249
    add   edi,40
250
    test   dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
251
    jnz    .unicode
252
;    jmp  .unicode
253
.ansi:
254
    cmp   [cd_counter_block],2
255
    jbe   .ansi_parent_directory
256
    cld
257
    lodsw
258
    xchg ah,al
259
    call uni2ansi_char
260
    cld
261
    stosb
262
; проверка конца файла
263
    mov   al,[esi+1]
264
    cmp   al,byte 3Bh ; сепаратор конца файла ';'
265
    je   .cd_get_parameters_of_file_1
266
; проверка для файлов не заканчивающихся сепаратором
267
    movzx   eax,byte [ebp-33]
268
    add   eax,ebp
269
    sub   eax,34
270
    cmp   esi,eax
271
    je   .cd_get_parameters_of_file_1
272
; проверка конца папки
273
    movzx   eax,byte [ebp-1]
274
    add   eax,ebp
275
    cmp   esi,eax
276
    jb   .ansi
277
.cd_get_parameters_of_file_1:
278
    mov   [edi],byte 0
90 mario79 279
    call  cd_get_parameters_of_file
87 mario79 280
    add   [cd_mem_location],304
281
    jmp   .get_names_from_buffer_1
282
 
283
.ansi_parent_directory:
284
    cmp   [cd_counter_block],2
285
    je    @f
286
    mov   [edi],byte '.'
287
    inc   edi
288
    jmp  .cd_get_parameters_of_file_1
289
@@:
290
    mov   [edi],word '..'
291
    add   edi,2
292
    jmp  .cd_get_parameters_of_file_1
293
 
294
.unicode:
295
    cmp   [cd_counter_block],2
296
    jbe   .unicode_parent_directory
297
    cld
298
    movsw
299
; проверка конца файла
300
    mov   ax,[esi]
301
    cmp   ax,word 3B00h ; сепаратор конца файла ';'
302
    je   .cd_get_parameters_of_file_2
303
; проверка для файлов не заканчивающихся сепаратором
304
    movzx   eax,byte [ebp-33]
305
    add   eax,ebp
306
    sub   eax,34
307
    cmp   esi,eax
308
    je   .cd_get_parameters_of_file_2
309
; проверка конца папки
310
    movzx   eax,byte [ebp-1]
311
    add   eax,ebp
312
    cmp   esi,eax
313
    jb   .unicode
314
.cd_get_parameters_of_file_2:
315
    mov   [edi],word 0
90 mario79 316
    call  cd_get_parameters_of_file
87 mario79 317
    add   [cd_mem_location],560
318
    jmp   .get_names_from_buffer_1
319
 
320
.unicode_parent_directory:
321
    cmp   [cd_counter_block],2
322
    je    @f
323
    mov   [edi],word 2E00h ; '.'
324
    add   edi,2
325
    jmp   .cd_get_parameters_of_file_2
326
@@:
327
    mov   [edi],dword 2E002E00h ; '..'
328
    add   edi,4
329
    jmp   .cd_get_parameters_of_file_2
330
 
90 mario79 331
.end_buffer:
332
    pop   edx edi esi eax
333
    ret
334
 
335
cd_get_parameters_of_file:
87 mario79 336
    mov   edi,[cd_mem_location]
90 mario79 337
cd_get_parameters_of_file_1:
87 mario79 338
; получаем атрибуты файла
339
    xor   eax,eax
340
; файл не архивировался
341
    inc   al
342
    shl   eax,1
343
; это каталог?
344
    test  [ebp-8],byte 2
345
    jz    .file
346
    inc   al
347
.file:
348
; метка тома не как в FAT, в этом виде отсутсвует
349
; файл не является системным
350
    shl   eax,3
351
; файл является скрытым? (атрибут существование)
352
    test  [ebp-8],byte 1
353
    jz    .hidden
354
    inc   al
355
.hidden:
356
    shl   eax,1
357
; файл всегда только для чтения, так как это CD
358
    inc   al
359
    mov   [edi],eax
360
; получаем время для файла
361
;час
362
    movzx eax,byte [ebp-12]
363
    shl   eax,8
364
;минута
365
    mov   al,[ebp-11]
366
    shl   eax,8
367
;секунда
368
    mov   al,[ebp-10]
369
;время создания файла
370
    mov   [edi+8],eax
371
;время последнего доступа
372
    mov   [edi+16],eax
373
;время последней записи
374
    mov   [edi+24],eax
375
; получаем дату для файла
376
;год
377
    movzx eax,byte [ebp-15]
378
    add   eax,1900
379
    shl   eax,8
380
;месяц
381
    mov   al,[ebp-14]
382
    shl   eax,8
383
;день
384
    mov   al,[ebp-13]
385
;дата создания файла
386
    mov   [edi+12],eax
387
;время последнего доступа
388
    mov   [edi+20],eax
389
;время последней записи
390
    mov   [edi+28],eax
391
; получаем тип данных имени
392
    xor   eax,eax
393
    test   dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
394
    jnz    .unicode_1
395
    mov    [edi+4],eax
396
    jmp   @f
397
.unicode_1:
398
    inc    eax
399
    mov    [edi+4],eax
400
@@:
401
; получаем размер файла в байтах
402
    xor   eax,eax
403
    mov   [edi+32+4],eax
404
    mov   eax,[ebp-23]
405
    mov   [edi+32],eax
406
    ret
407
 
90 mario79 408
;----------------------------------------------------------------
409
;
410
;  fs_CdGetFileInfo - LFN variant for CD
411
;                     get file/directory attributes structure
412
;
413
;----------------------------------------------------------------
414
fs_CdGetFileInfo:
415
        cmp     byte [esi], 0
416
        jnz     @f
417
        mov     eax, 2
418
        ret
419
@@:
420
        push    edi ebp
421
        call    cd_find_lfn
422
        pushfd
423
        cmp     [DevErrorCode], 0
424
        jz      @f
425
        popfd
426
        pop     ebp edi
427
        mov     eax, 11
428
        ret
429
@@:
430
        popfd
431
        jnc     @f
432
        pop     ebp edi
433
        mov     eax, ERROR_FILE_NOT_FOUND
434
        ret
435
@@:
436
 
437
        mov     edi, edx
438
        call    cd_get_parameters_of_file_1
439
        and     dword [edi+4], 0
440
        pop     ebp
441
        pop     ebp edi
442
        xor     eax, eax
443
        ret
444
 
87 mario79 445
cd_find_lfn:
446
; in: esi->name
447
; out: CF=1 - file not found
448
;      else CF=0 and [cd_current_pointer_of_input] direntry
449
        push eax esi
450
; 16 сектор начало набора дескрипторов томов
451
        mov  [CDSectorAddress],dword 15
452
.start:
453
        inc  dword [CDSectorAddress]
454
       mov  [CDDataBuf_pointer],CDDataBuf
455
       call  ReadCDWRetr
456
       cmp   [DevErrorCode],0
457
       jne   .access_denied
458
; проверка на вшивость
459
        cmp  [CDDataBuf+1],dword 'CD00'
460
        jne  .access_denied
461
        cmp  [CDDataBuf+5],byte '1'
462
        jne  .access_denied
463
; сектор является терминатором набор дескрипторов томов?
464
        cmp  [CDDataBuf],byte 0xff
465
        je  .access_denied
466
; сектор является дополнительным и улучшенным дескриптором тома?
467
        cmp  [CDDataBuf],byte 0x2
468
        jne  .start
469
; сектор является дополнительным дескриптором тома?
470
        cmp  [CDDataBuf+6],byte 0x1
471
        jne  .start
472
; параметры root директрории
473
        mov  eax,[CDDataBuf+0x9c+2] ; начало root директрории
474
        mov  [CDSectorAddress],eax
475
        mov  eax,[CDDataBuf+0x9c+10] ; размер root директрории
476
        cmp    byte [esi], 0
477
        jnz    @f
478
        mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
479
        jmp   .done
480
@@:
481
; начинаем поиск
482
.mainloop:
483
        dec  dword [CDSectorAddress]
484
.read_to_buffer:
485
        inc  dword [CDSectorAddress]
486
        mov  [CDDataBuf_pointer],CDDataBuf
487
        call ReadCDWRetr         ; читаем сектор директории
488
        cmp   [DevErrorCode],0
489
        jne   .access_denied
490
        call cd_find_name_in_buffer
491
        jnc    .found
492
        sub  eax,2048
493
; директория закончилась?
494
        cmp  eax,0
495
        jg   .read_to_buffer
496
; нет искомого элемента цепочки
497
.access_denied:
498
        pop  esi eax
499
        stc
500
        ret
501
; искомый элемент цепочки найден
502
  .found:
503
; конец пути файла
504
        cmp    byte [esi], 0
505
        jz    .done
506
        mov    eax,[cd_current_pointer_of_input]
507
        add    eax,2
508
        mov    eax,[eax]
509
        mov    [CDSectorAddress],eax ; начало директории
510
        add    eax,8
511
        mov    eax,[eax]  ; размер директории
512
        jmp    .mainloop
513
; указатель файла найден
514
   .done:
515
        pop  esi eax
516
        clc
517
        ret
518
 
519
cd_find_name_in_buffer:
520
        mov     [cd_current_pointer_of_input_2],CDDataBuf
521
.start:
522
        call    cd_get_name
523
        jc    .not_found
524
        call    cd_compare_name
525
        jc    .start
526
.found:
527
        clc
528
        ret
529
.not_found:
530
        stc
531
        ret
532
 
533
cd_get_name:
534
        push eax
535
        mov   ebp,[cd_current_pointer_of_input_2]
536
        mov   [cd_current_pointer_of_input],ebp
537
        mov   eax,[ebp]
538
        cmp   eax,0   ; входы закончились?
539
        je    .next_sector
540
        cmp   ebp,CDDataBuf+2048     ; буфер закончился?
541
        jae   .next_sector
542
        movzx eax, byte [ebp]
543
        add   [cd_current_pointer_of_input_2],eax ; следующий вход каталога
544
        add   ebp,33 ; указатель установлен на начало имени
545
        pop   eax
546
        clc
547
        ret
548
.next_sector:
549
        pop  eax
550
        stc
551
        ret
552
 
553
cd_compare_name:
554
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
555
; in: esi->name, ebp->name
556
; out: if names match: ZF=1 and esi->next component of name
557
;      else: ZF=0, esi is not changed
558
; destroys eax
559
    push    esi eax edi
560
    mov     edi,ebp
561
.loop:
562
    cld
563
    lodsb
564
    push ax
565
    call char_toupper
566
    call ansi2uni_char
567
    xchg ah,al
568
    cld
569
    scasw
570
    pop  ax
571
    je    .coincides
572
    call char_todown
573
    call ansi2uni_char
574
    xchg ah,al
575
    cld
576
    sub  edi,2
577
    scasw
578
    jne   .name_not_coincide
579
.coincides:
580
    cmp   [esi],byte '/'  ; разделитель пути, конец имени текущего элемента
581
    je   .done
582
    cmp   [esi],byte 0  ; разделитель пути, конец имени текущего элемента
583
    je   .done
584
    jmp   .loop
585
.name_not_coincide:
586
    pop    edi eax esi
587
    stc
588
    ret
589
.done:
590
; проверка конца файла
591
    cmp   [edi],word 3B00h ; сепаратор конца файла ';'
592
    je   .done_1
593
; проверка для файлов не заканчивающихся сепаратором
594
    movzx   eax,byte [ebp-33]
595
    add   eax,ebp
596
    sub   eax,34
597
    cmp   edi,eax
598
    je   .done_1
599
; проверка конца папки
600
    movzx   eax,byte [ebp-1]
601
    add   eax,ebp
602
    cmp   edi,eax
603
    jne   .name_not_coincide
604
.done_1:
605
    pop   edi eax
606
    add   esp,4
607
    inc   esi
608
    clc
609
    ret
610
 
611
char_todown:
612
; convert character to uppercase, using cp866 encoding
613
; in: al=symbol
614
; out: al=converted symbol
615
        cmp     al, 'A'
616
        jb      .ret
617
        cmp     al, 'Z'
618
        jbe     .az
619
        cmp     al, 'Ђ'
620
        jb      .ret
621
        cmp     al, 'ђ'
622
        jb      .rus1
623
        cmp     al, 'џ'
624
        ja      .ret
625
; 0x90-0x9F -> 0xE0-0xEF
626
        add     al, 'а'-'ђ'
627
.ret:
628
        ret
629
.rus1:
630
; 0x80-0x8F -> 0xA0-0xAF
631
.az:
632
        add     al, 0x20
633
        ret
634
 
635
uni2ansi_char:
636
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
637
; in: ax=UNICODE character
638
; out: al=converted ANSI character
639
        cmp     ax, 0x80
640
        jb      .ascii
641
        cmp     ax, 0x401
642
        jz      .yo1
643
        cmp     ax, 0x451
644
        jz      .yo2
645
        cmp     ax, 0x410
646
        jb      .unk
647
        cmp     ax, 0x440
648
        jb      .rus1
649
        cmp     ax, 0x450
650
        jb      .rus2
651
.unk:
652
        mov     al, '_'
653
        jmp     .doit
654
.yo1:
655
        mov     al, 'р'
656
        jmp     .doit
657
.yo2:
658
        mov     al, 'с'
659
        jmp     .doit
660
.rus1:
661
; 0x410-0x43F -> 0x80-0xAF
662
        add     al, 0x70
663
        jmp     .doit
664
.rus2:
665
; 0x440-0x44F -> 0xE0-0xEF
666
        add     al, 0xA0
667
.ascii:
668
.doit:
669
        ret