Subversion Repositories Kolibri OS

Rev

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

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