Subversion Repositories Kolibri OS

Rev

Rev 837 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2971 Serge 3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
94 mario79 7
 
593 mikedld 8
$Revision: 2971 $
9
 
10
 
87 mario79 11
uglobal
12
cd_current_pointer_of_input    dd  0
13
cd_current_pointer_of_input_2  dd  0
585 mario79 14
cd_mem_location 	       dd  0
15
cd_counter_block	       dd  0
16
IDE_Channel_1		       db  0
17
IDE_Channel_2		       db  0
87 mario79 18
endg
19
 
20
reserve_cd:
21
 
22
    cli
23
    cmp   [cd_status],0
585 mario79 24
    je	  reserve_ok2
87 mario79 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
585 mario79 47
    je	  .reserve_ok_1
95 mario79 48
    sti
49
    call  change_task
50
    jmp   .IDE_Channel_1
51
.IDE_Channel_2:
52
    cli
53
    cmp   [IDE_Channel_2],0
585 mario79 54
    je	  .reserve_ok_2
95 mario79 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:
585 mario79 100
    or	  ebx, -1
87 mario79 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
585 mario79 114
    or	  ebx, -1
87 mario79 115
    mov    eax, ERROR_FILE_NOT_FOUND
116
    ret
117
 
118
.found:
119
    mov    edi,[cd_current_pointer_of_input]
585 mario79 120
    test   byte [edi+25],10b	; do not allow read directories
87 mario79 121
    jnz    .noaccess
122
    test    ebx, ebx
585 mario79 123
    jz	  .l1
87 mario79 124
    cmp    dword [ebx+4], 0
585 mario79 125
    jz	  @f
126
	xor	ebx, ebx
87 mario79 127
.reteof:
128
    mov    eax, 6 ; end of file
129
    pop    edi
130
    ret
131
@@:
132
    mov    ebx, [ebx]
133
.l1:
585 mario79 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
87 mario79 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
585 mario79 149
    jz	  .done
87 mario79 150
    sub    ebx, 2048
154 diamond 151
    jae    .next
87 mario79 152
    add    ebx, 2048
153
    jnz    .incomplete_sector
154
    cmp    ecx, 2048
585 mario79 155
    jb	  .incomplete_sector
87 mario79 156
; we may read and memmove complete sector
157
    mov  [CDDataBuf_pointer],edx
585 mario79 158
    call ReadCDWRetr	  ; читаем сектор файла
87 mario79 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
585 mario79 169
    call ReadCDWRetr	  ; читаем сектор файла
87 mario79 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
585 mario79 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:
585 mario79 192
	mov	ebx, edx
193
	pop	eax edx ecx edi
194
	sub	ebx, edx
195
	ret
87 mario79 196
.eof:
585 mario79 197
	mov	ebx, edx
198
	pop	eax edx ecx
199
	sub	ebx, edx
200
	jmp	.reteof
87 mario79 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:
585 mario79 218
	push	edi
219
	call	cd_find_lfn
220
	jnc	.found
221
	pop	edi
222
	cmp	[DevErrorCode], 0
223
	jne	.noaccess_1
224
	or	ebx, -1
225
	mov	eax, ERROR_FILE_NOT_FOUND
226
	ret
87 mario79 227
.found:
585 mario79 228
	mov	edi, [cd_current_pointer_of_input]
229
	test	byte [edi+25], 10b    ; do not allow read directories
230
	jnz	.found_dir
231
	pop	edi
87 mario79 232
.noaccess_1:
585 mario79 233
	or	ebx, -1
234
	mov	eax, ERROR_ACCESS_DENIED
235
	ret
87 mario79 236
.found_dir:
585 mario79 237
	mov	eax, [edi+2]	; eax=cluster
238
	mov	[CDSectorAddress], eax
239
	mov	eax, [edi+10]	; размер директрории
87 mario79 240
.doit:
241
; init header
585 mario79 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
249
	mov	[cd_mem_location], edx
250
	add	[cd_mem_location], 32
87 mario79 251
; начинаем переброску БДВК в УСВК
252
;.mainloop:
585 mario79 253
	mov	[cd_counter_block], dword 0
254
	dec	dword [CDSectorAddress]
255
	push	ecx
87 mario79 256
.read_to_buffer:
585 mario79 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
; директория закончилась?
585 mario79 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
364 diamond 274
@@:
585 mario79 275
	pop	ecx edi
276
	mov	ebx, [edx+4]
277
	ret
364 diamond 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
585 mario79 284
    jc	  .end_buffer
87 mario79 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
585 mario79 290
    jz	  .get_names_from_buffer_1
87 mario79 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 ; сепаратор конца файла ';'
585 mario79 312
    je	 .cd_get_parameters_of_file_1
87 mario79 313
; проверка для файлов не заканчивающихся сепаратором
314
    movzx   eax,byte [ebp-33]
315
    add   eax,ebp
316
    sub   eax,34
317
    cmp   esi,eax
585 mario79 318
    je	 .cd_get_parameters_of_file_1
87 mario79 319
; проверка конца папки
320
    movzx   eax,byte [ebp-1]
321
    add   eax,ebp
322
    cmp   esi,eax
585 mario79 323
    jb	 .ansi
87 mario79 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
585 mario79 332
    je	  @f
87 mario79 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 ; сепаратор конца файла ';'
585 mario79 349
    je	 .cd_get_parameters_of_file_2
87 mario79 350
; проверка для файлов не заканчивающихся сепаратором
351
    movzx   eax,byte [ebp-33]
352
    add   eax,ebp
353
    sub   eax,34
354
    cmp   esi,eax
585 mario79 355
    je	 .cd_get_parameters_of_file_2
87 mario79 356
; проверка конца папки
357
    movzx   eax,byte [ebp-1]
358
    add   eax,ebp
359
    cmp   esi,eax
585 mario79 360
    jb	 .unicode
87 mario79 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
585 mario79 369
    je	  @f
87 mario79 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
536 diamond 387
; файл не архивировался
388
    inc   eax
87 mario79 389
    shl   eax,1
390
; это каталог?
391
    test  [ebp-8],byte 2
585 mario79 392
    jz	  .file
536 diamond 393
    inc   eax
87 mario79 394
.file:
395
; метка тома не как в FAT, в этом виде отсутсвует
396
; файл не является системным
397
    shl   eax,3
398
; файл является скрытым? (атрибут существование)
399
    test  [ebp-8],byte 1
585 mario79 400
    jz	  .hidden
536 diamond 401
    inc   eax
87 mario79 402
.hidden:
403
    shl   eax,1
404
; файл всегда только для чтения, так как это CD
536 diamond 405
    inc   eax
87 mario79 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:
585 mario79 462
	cmp	byte [esi], 0
463
	jnz	@f
464
	mov	eax, 2
465
	ret
90 mario79 466
@@:
585 mario79 467
	push	edi
468
	call	cd_find_lfn
469
	pushfd
470
	cmp	[DevErrorCode], 0
471
	jz	@f
472
	popfd
473
	pop	edi
474
	mov	eax, 11
475
	ret
90 mario79 476
@@:
585 mario79 477
	popfd
478
	jnc	@f
479
	pop	edi
480
	mov	eax, ERROR_FILE_NOT_FOUND
481
	ret
90 mario79 482
@@:
483
 
585 mario79 484
	mov	edi, edx
485
	push	ebp
486
	mov	ebp, [cd_current_pointer_of_input]
487
	add	ebp, 33
488
	call	cd_get_parameters_of_file_1
489
	pop	ebp
490
	and	dword [edi+4], 0
491
	pop	edi
492
	xor	eax, eax
493
	ret
90 mario79 494
 
628 mario79 495
;----------------------------------------------------------------
87 mario79 496
cd_find_lfn:
758 mario79 497
  mov	[cd_appl_data],0
521 diamond 498
; in: esi+ebp -> name
87 mario79 499
; out: CF=1 - file not found
758 mario79 500
; else CF=0 and [cd_current_pointer_of_input] direntry
585 mario79 501
	push eax esi
87 mario79 502
; 16 сектор начало набора дескрипторов томов
758 mario79 503
 
504
  call	WaitUnitReady
505
  cmp	[DevErrorCode],0
506
  jne	.access_denied
507
 
508
  call	prevent_medium_removal
509
; тестовое чтение
510
  mov  [CDSectorAddress],dword 16
800 diamond 511
  mov  [CDDataBuf_pointer],CDDataBuf
758 mario79 512
  call	ReadCDWRetr    ;_1
513
   cmp	 [DevErrorCode],0
514
  jne	.access_denied
515
 
516
; вычисление последней сессии
517
  call WaitUnitReady
518
  cmp	[DevErrorCode],0
519
  jne	.access_denied
520
  call Read_TOC
521
  mov  ah,[CDDataBuf+4+4]
522
  mov  al,[CDDataBuf+4+5]
523
  shl  eax,16
524
  mov  ah,[CDDataBuf+4+6]
525
  mov  al,[CDDataBuf+4+7]
526
  add  eax,15
527
  mov  [CDSectorAddress],eax
528
;  mov  [CDSectorAddress],dword 15
529
  mov  [CDDataBuf_pointer],CDDataBuf
530
 
87 mario79 531
.start:
585 mario79 532
	inc  dword [CDSectorAddress]
758 mario79 533
  call	ReadCDWRetr    ;_1
534
   cmp	 [DevErrorCode],0
535
  jne	.access_denied
536
 
537
.start_check:
87 mario79 538
; проверка на вшивость
585 mario79 539
	cmp  [CDDataBuf+1],dword 'CD00'
540
	jne  .access_denied
541
	cmp  [CDDataBuf+5],byte '1'
542
	jne  .access_denied
87 mario79 543
; сектор является терминатором набор дескрипторов томов?
585 mario79 544
	cmp  [CDDataBuf],byte 0xff
545
	je  .access_denied
87 mario79 546
; сектор является дополнительным и улучшенным дескриптором тома?
585 mario79 547
	cmp  [CDDataBuf],byte 0x2
548
	jne  .start
87 mario79 549
; сектор является дополнительным дескриптором тома?
585 mario79 550
	cmp  [CDDataBuf+6],byte 0x1
551
	jne  .start
758 mario79 552
 
87 mario79 553
; параметры root директрории
585 mario79 554
	mov  eax,[CDDataBuf+0x9c+2] ; начало root директрории
555
	mov  [CDSectorAddress],eax
556
	mov  eax,[CDDataBuf+0x9c+10] ; размер root директрории
557
	cmp    byte [esi], 0
558
	jnz    @f
559
	mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
560
	jmp   .done
87 mario79 561
@@:
562
; начинаем поиск
563
.mainloop:
585 mario79 564
	dec  dword [CDSectorAddress]
87 mario79 565
.read_to_buffer:
585 mario79 566
	inc  dword [CDSectorAddress]
567
	mov  [CDDataBuf_pointer],CDDataBuf
568
	call ReadCDWRetr	 ; читаем сектор директории
569
	cmp   [DevErrorCode],0
570
	jne   .access_denied
571
	push	ebp
572
	call	cd_find_name_in_buffer
573
	pop	ebp
574
	jnc	.found
575
	sub  eax,2048
87 mario79 576
; директория закончилась?
585 mario79 577
	cmp  eax,0
578
	ja   .read_to_buffer
87 mario79 579
; нет искомого элемента цепочки
580
.access_denied:
585 mario79 581
	pop  esi eax
582
	mov   [cd_appl_data],1
583
	stc
584
	ret
87 mario79 585
; искомый элемент цепочки найден
586
  .found:
587
; конец пути файла
585 mario79 588
	cmp    byte [esi-1], 0
589
	jz    .done
521 diamond 590
  .nested:
585 mario79 591
	mov    eax,[cd_current_pointer_of_input]
592
	push	dword [eax+2]
593
	pop	dword [CDSectorAddress]       ; начало директории
594
	mov    eax,[eax+2+8]  ; размер директории
595
	jmp    .mainloop
87 mario79 596
; указатель файла найден
597
   .done:
585 mario79 598
	test	ebp, ebp
599
	jz	@f
600
	mov	esi, ebp
601
	xor	ebp, ebp
602
	jmp	.nested
521 diamond 603
@@:
585 mario79 604
	pop  esi eax
605
	mov   [cd_appl_data],1
606
	clc
607
	ret
379 serge 608
 
87 mario79 609
cd_find_name_in_buffer:
585 mario79 610
	mov	[cd_current_pointer_of_input_2],CDDataBuf
87 mario79 611
.start:
585 mario79 612
	call	cd_get_name
613
	jc	.not_found
614
	call	cd_compare_name
615
	jc	.start
379 serge 616
.found:
585 mario79 617
	clc
618
	ret
87 mario79 619
.not_found:
585 mario79 620
	stc
621
	ret
87 mario79 622
 
623
cd_get_name:
585 mario79 624
	push eax
625
	mov   ebp,[cd_current_pointer_of_input_2]
626
	mov   [cd_current_pointer_of_input],ebp
627
	mov   eax,[ebp]
628
	cmp   eax,0   ; входы закончились?
629
	je    .next_sector
630
	cmp   ebp,CDDataBuf+2048     ; буфер закончился?
631
	jae   .next_sector
632
	movzx eax, byte [ebp]
633
	add   [cd_current_pointer_of_input_2],eax ; следующий вход каталога
634
	add   ebp,33 ; указатель установлен на начало имени
635
	pop   eax
636
	clc
637
	ret
87 mario79 638
.next_sector:
585 mario79 639
	pop  eax
640
	stc
641
	ret
87 mario79 642
 
643
cd_compare_name:
644
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
645
; in: esi->name, ebp->name
646
; out: if names match: ZF=1 and esi->next component of name
647
;      else: ZF=0, esi is not changed
648
; destroys eax
379 serge 649
    push    esi eax edi
87 mario79 650
    mov     edi,ebp
651
.loop:
652
    cld
653
    lodsb
536 diamond 654
    push eax
99 mario79 655
    call char_todown
87 mario79 656
    call ansi2uni_char
657
    xchg ah,al
658
    scasw
536 diamond 659
    pop  eax
585 mario79 660
    je	  .coincides
99 mario79 661
    call char_toupper
87 mario79 662
    call ansi2uni_char
663
    xchg ah,al
664
    sub  edi,2
665
    scasw
666
    jne   .name_not_coincide
667
.coincides:
668
    cmp   [esi],byte '/'  ; разделитель пути, конец имени текущего элемента
585 mario79 669
    je	 .done
670
    cmp   [esi],byte 0	; разделитель пути, конец имени текущего элемента
671
    je	 .done
87 mario79 672
    jmp   .loop
673
.name_not_coincide:
674
    pop    edi eax esi
675
    stc
676
    ret
677
.done:
678
; проверка конца файла
679
    cmp   [edi],word 3B00h ; сепаратор конца файла ';'
585 mario79 680
    je	 .done_1
87 mario79 681
; проверка для файлов не заканчивающихся сепаратором
682
    movzx   eax,byte [ebp-33]
683
    add   eax,ebp
684
    sub   eax,34
685
    cmp   edi,eax
585 mario79 686
    je	 .done_1
87 mario79 687
; проверка конца папки
688
    movzx   eax,byte [ebp-1]
689
    add   eax,ebp
690
    cmp   edi,eax
691
    jne   .name_not_coincide
692
.done_1:
693
    pop   edi eax
694
    add   esp,4
695
    inc   esi
696
    clc
697
    ret
379 serge 698
 
87 mario79 699
char_todown:
700
; convert character to uppercase, using cp866 encoding
701
; in: al=symbol
702
; out: al=converted symbol
585 mario79 703
	cmp	al, 'A'
704
	jb	.ret
705
	cmp	al, 'Z'
706
	jbe	.az
707
	cmp	al, 'Ђ'
708
	jb	.ret
709
	cmp	al, 'ђ'
710
	jb	.rus1
711
	cmp	al, 'џ'
712
	ja	.ret
87 mario79 713
; 0x90-0x9F -> 0xE0-0xEF
585 mario79 714
	add	al, 'а'-'ђ'
87 mario79 715
.ret:
585 mario79 716
	ret
87 mario79 717
.rus1:
718
; 0x80-0x8F -> 0xA0-0xAF
719
.az:
585 mario79 720
	add	al, 0x20
721
	ret
379 serge 722
 
87 mario79 723
uni2ansi_char:
724
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
725
; in: ax=UNICODE character
726
; out: al=converted ANSI character
585 mario79 727
	cmp	ax, 0x80
728
	jb	.ascii
729
	cmp	ax, 0x401
730
	jz	.yo1
731
	cmp	ax, 0x451
732
	jz	.yo2
733
	cmp	ax, 0x410
734
	jb	.unk
735
	cmp	ax, 0x440
736
	jb	.rus1
737
	cmp	ax, 0x450
738
	jb	.rus2
87 mario79 739
.unk:
585 mario79 740
	mov	al, '_'
741
	jmp	.doit
87 mario79 742
.yo1:
585 mario79 743
	mov	al, 'р'
744
	jmp	.doit
87 mario79 745
.yo2:
585 mario79 746
	mov	al, 'с'
747
	jmp	.doit
87 mario79 748
.rus1:
749
; 0x410-0x43F -> 0x80-0xAF
585 mario79 750
	add	al, 0x70
751
	jmp	.doit
87 mario79 752
.rus2:
753
; 0x440-0x44F -> 0xE0-0xEF
585 mario79 754
	add	al, 0xA0
87 mario79 755
.ascii:
756
.doit:
585 mario79 757
	ret