Subversion Repositories Kolibri OS

Rev

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

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