Subversion Repositories Kolibri OS

Rev

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

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