Subversion Repositories Kolibri OS

Rev

Rev 87 | Rev 90 | 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
279
    call  .cd_get_parameters_of_file
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
316
    call  .cd_get_parameters_of_file
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
 
331
.cd_get_parameters_of_file:
332
    mov   edi,[cd_mem_location]
333
; получаем атрибуты файла
334
    xor   eax,eax
335
; файл не архивировался
336
    inc   al
337
    shl   eax,1
338
; это каталог?
339
    test  [ebp-8],byte 2
340
    jz    .file
341
    inc   al
342
.file:
343
; метка тома не как в FAT, в этом виде отсутсвует
344
; файл не является системным
345
    shl   eax,3
346
; файл является скрытым? (атрибут существование)
347
    test  [ebp-8],byte 1
348
    jz    .hidden
349
    inc   al
350
.hidden:
351
    shl   eax,1
352
; файл всегда только для чтения, так как это CD
353
    inc   al
354
    mov   [edi],eax
355
; получаем время для файла
356
;час
357
    movzx eax,byte [ebp-12]
358
    shl   eax,8
359
;минута
360
    mov   al,[ebp-11]
361
    shl   eax,8
362
;секунда
363
    mov   al,[ebp-10]
364
;время создания файла
365
    mov   [edi+8],eax
366
;время последнего доступа
367
    mov   [edi+16],eax
368
;время последней записи
369
    mov   [edi+24],eax
370
; получаем дату для файла
371
;год
372
    movzx eax,byte [ebp-15]
373
    add   eax,1900
374
    shl   eax,8
375
;месяц
376
    mov   al,[ebp-14]
377
    shl   eax,8
378
;день
379
    mov   al,[ebp-13]
380
;дата создания файла
381
    mov   [edi+12],eax
382
;время последнего доступа
383
    mov   [edi+20],eax
384
;время последней записи
385
    mov   [edi+28],eax
386
; получаем тип данных имени
387
    xor   eax,eax
388
    test   dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
389
    jnz    .unicode_1
390
    mov    [edi+4],eax
391
    jmp   @f
392
.unicode_1:
393
    inc    eax
394
    mov    [edi+4],eax
395
@@:
396
; получаем размер файла в байтах
397
    xor   eax,eax
398
    mov   [edi+32+4],eax
399
    mov   eax,[ebp-23]
400
    mov   [edi+32],eax
401
    ret
402
 
403
.end_buffer:
404
    pop   edx edi esi eax
405
    ret
406
 
407
cd_find_lfn:
408
; in: esi->name
409
; out: CF=1 - file not found
410
;      else CF=0 and [cd_current_pointer_of_input] direntry
411
        push eax esi
412
; 16 сектор начало набора дескрипторов томов
413
        mov  [CDSectorAddress],dword 15
414
.start:
415
        inc  dword [CDSectorAddress]
416
       mov  [CDDataBuf_pointer],CDDataBuf
417
       call  ReadCDWRetr
418
       cmp   [DevErrorCode],0
419
       jne   .access_denied
420
; проверка на вшивость
421
        cmp  [CDDataBuf+1],dword 'CD00'
422
        jne  .access_denied
423
        cmp  [CDDataBuf+5],byte '1'
424
        jne  .access_denied
425
; сектор является терминатором набор дескрипторов томов?
426
        cmp  [CDDataBuf],byte 0xff
427
        je  .access_denied
428
; сектор является дополнительным и улучшенным дескриптором тома?
429
        cmp  [CDDataBuf],byte 0x2
430
        jne  .start
431
; сектор является дополнительным дескриптором тома?
432
        cmp  [CDDataBuf+6],byte 0x1
433
        jne  .start
434
; параметры root директрории
435
        mov  eax,[CDDataBuf+0x9c+2] ; начало root директрории
436
        mov  [CDSectorAddress],eax
437
        mov  eax,[CDDataBuf+0x9c+10] ; размер root директрории
438
        cmp    byte [esi], 0
439
        jnz    @f
440
        mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
441
        jmp   .done
442
@@:
443
; начинаем поиск
444
.mainloop:
445
        dec  dword [CDSectorAddress]
446
.read_to_buffer:
447
        inc  dword [CDSectorAddress]
448
        mov  [CDDataBuf_pointer],CDDataBuf
449
        call ReadCDWRetr         ; читаем сектор директории
450
        cmp   [DevErrorCode],0
451
        jne   .access_denied
452
        call cd_find_name_in_buffer
453
        jnc    .found
454
        sub  eax,2048
455
; директория закончилась?
456
        cmp  eax,0
457
        jg   .read_to_buffer
458
; нет искомого элемента цепочки
459
.access_denied:
460
        pop  esi eax
461
        stc
462
        ret
463
; искомый элемент цепочки найден
464
  .found:
465
; конец пути файла
466
        cmp    byte [esi], 0
467
        jz    .done
468
        mov    eax,[cd_current_pointer_of_input]
469
        add    eax,2
470
        mov    eax,[eax]
471
        mov    [CDSectorAddress],eax ; начало директории
472
        add    eax,8
473
        mov    eax,[eax]  ; размер директории
474
        jmp    .mainloop
475
; указатель файла найден
476
   .done:
477
        pop  esi eax
478
        clc
479
        ret
480
 
481
cd_find_name_in_buffer:
482
        mov     [cd_current_pointer_of_input_2],CDDataBuf
483
.start:
484
        call    cd_get_name
485
        jc    .not_found
486
        call    cd_compare_name
487
        jc    .start
488
.found:
489
        clc
490
        ret
491
.not_found:
492
        stc
493
        ret
494
 
495
cd_get_name:
496
        push eax
497
        mov   ebp,[cd_current_pointer_of_input_2]
498
        mov   [cd_current_pointer_of_input],ebp
499
        mov   eax,[ebp]
500
        cmp   eax,0   ; входы закончились?
501
        je    .next_sector
502
        cmp   ebp,CDDataBuf+2048     ; буфер закончился?
503
        jae   .next_sector
504
        movzx eax, byte [ebp]
505
        add   [cd_current_pointer_of_input_2],eax ; следующий вход каталога
506
        add   ebp,33 ; указатель установлен на начало имени
507
        pop   eax
508
        clc
509
        ret
510
.next_sector:
511
        pop  eax
512
        stc
513
        ret
514
 
515
cd_compare_name:
516
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
517
; in: esi->name, ebp->name
518
; out: if names match: ZF=1 and esi->next component of name
519
;      else: ZF=0, esi is not changed
520
; destroys eax
521
    push    esi eax edi
522
    mov     edi,ebp
523
.loop:
524
    cld
525
    lodsb
526
    push ax
527
    call char_toupper
528
    call ansi2uni_char
529
    xchg ah,al
530
    cld
531
    scasw
532
    pop  ax
533
    je    .coincides
534
    call char_todown
535
    call ansi2uni_char
536
    xchg ah,al
537
    cld
538
    sub  edi,2
539
    scasw
540
    jne   .name_not_coincide
541
.coincides:
542
    cmp   [esi],byte '/'  ; разделитель пути, конец имени текущего элемента
543
    je   .done
544
    cmp   [esi],byte 0  ; разделитель пути, конец имени текущего элемента
545
    je   .done
546
    jmp   .loop
547
.name_not_coincide:
548
    pop    edi eax esi
549
    stc
550
    ret
551
.done:
552
; проверка конца файла
553
    cmp   [edi],word 3B00h ; сепаратор конца файла ';'
554
    je   .done_1
555
; проверка для файлов не заканчивающихся сепаратором
556
    movzx   eax,byte [ebp-33]
557
    add   eax,ebp
558
    sub   eax,34
559
    cmp   edi,eax
560
    je   .done_1
561
; проверка конца папки
562
    movzx   eax,byte [ebp-1]
563
    add   eax,ebp
564
    cmp   edi,eax
565
    jne   .name_not_coincide
566
.done_1:
567
    pop   edi eax
568
    add   esp,4
569
    inc   esi
570
    clc
571
    ret
572
 
573
char_todown:
574
; convert character to uppercase, using cp866 encoding
575
; in: al=symbol
576
; out: al=converted symbol
577
        cmp     al, 'A'
578
        jb      .ret
579
        cmp     al, 'Z'
580
        jbe     .az
581
        cmp     al, 'Ђ'
582
        jb      .ret
583
        cmp     al, 'ђ'
584
        jb      .rus1
585
        cmp     al, 'џ'
586
        ja      .ret
587
; 0x90-0x9F -> 0xE0-0xEF
588
        add     al, 'а'-'ђ'
589
.ret:
590
        ret
591
.rus1:
592
; 0x80-0x8F -> 0xA0-0xAF
593
.az:
594
        add     al, 0x20
595
        ret
596
 
597
uni2ansi_char:
598
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
599
; in: ax=UNICODE character
600
; out: al=converted ANSI character
601
        cmp     ax, 0x80
602
        jb      .ascii
603
        cmp     ax, 0x401
604
        jz      .yo1
605
        cmp     ax, 0x451
606
        jz      .yo2
607
        cmp     ax, 0x410
608
        jb      .unk
609
        cmp     ax, 0x440
610
        jb      .rus1
611
        cmp     ax, 0x450
612
        jb      .rus2
613
.unk:
614
        mov     al, '_'
615
        jmp     .doit
616
.yo1:
617
        mov     al, 'р'
618
        jmp     .doit
619
.yo2:
620
        mov     al, 'с'
621
        jmp     .doit
622
.rus1:
623
; 0x410-0x43F -> 0x80-0xAF
624
        add     al, 0x70
625
        jmp     .doit
626
.rus2:
627
; 0x440-0x44F -> 0xE0-0xEF
628
        add     al, 0xA0
629
.ascii:
630
.doit:
631
        ret