Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
94 mario79 7
 
593 mikedld 8
$Revision: 758 $
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
511
  call	ReadCDWRetr    ;_1
512
   cmp	 [DevErrorCode],0
513
  jne	.access_denied
514
 
515
; вычисление последней сессии
516
  call WaitUnitReady
517
  cmp	[DevErrorCode],0
518
  jne	.access_denied
519
  call Read_TOC
520
  mov  ah,[CDDataBuf+4+4]
521
  mov  al,[CDDataBuf+4+5]
522
  shl  eax,16
523
  mov  ah,[CDDataBuf+4+6]
524
  mov  al,[CDDataBuf+4+7]
525
  add  eax,15
526
  mov  [CDSectorAddress],eax
527
;  mov  [CDSectorAddress],dword 15
528
  mov  [CDDataBuf_pointer],CDDataBuf
529
 
87 mario79 530
.start:
585 mario79 531
	inc  dword [CDSectorAddress]
758 mario79 532
  call	ReadCDWRetr    ;_1
533
   cmp	 [DevErrorCode],0
534
  jne	.access_denied
535
 
536
.start_check:
87 mario79 537
; проверка на вшивость
585 mario79 538
	cmp  [CDDataBuf+1],dword 'CD00'
539
	jne  .access_denied
540
	cmp  [CDDataBuf+5],byte '1'
541
	jne  .access_denied
87 mario79 542
; сектор является терминатором набор дескрипторов томов?
585 mario79 543
	cmp  [CDDataBuf],byte 0xff
544
	je  .access_denied
87 mario79 545
; сектор является дополнительным и улучшенным дескриптором тома?
585 mario79 546
	cmp  [CDDataBuf],byte 0x2
547
	jne  .start
87 mario79 548
; сектор является дополнительным дескриптором тома?
585 mario79 549
	cmp  [CDDataBuf+6],byte 0x1
550
	jne  .start
758 mario79 551
 
87 mario79 552
; параметры root директрории
585 mario79 553
	mov  eax,[CDDataBuf+0x9c+2] ; начало root директрории
554
	mov  [CDSectorAddress],eax
555
	mov  eax,[CDDataBuf+0x9c+10] ; размер root директрории
556
	cmp    byte [esi], 0
557
	jnz    @f
558
	mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
559
	jmp   .done
87 mario79 560
@@:
561
; начинаем поиск
562
.mainloop:
585 mario79 563
	dec  dword [CDSectorAddress]
87 mario79 564
.read_to_buffer:
585 mario79 565
	inc  dword [CDSectorAddress]
566
	mov  [CDDataBuf_pointer],CDDataBuf
567
	call ReadCDWRetr	 ; читаем сектор директории
568
	cmp   [DevErrorCode],0
569
	jne   .access_denied
570
	push	ebp
571
	call	cd_find_name_in_buffer
572
	pop	ebp
573
	jnc	.found
574
	sub  eax,2048
87 mario79 575
; директория закончилась?
585 mario79 576
	cmp  eax,0
577
	ja   .read_to_buffer
87 mario79 578
; нет искомого элемента цепочки
579
.access_denied:
585 mario79 580
	pop  esi eax
581
	mov   [cd_appl_data],1
582
	stc
583
	ret
87 mario79 584
; искомый элемент цепочки найден
585
  .found:
586
; конец пути файла
585 mario79 587
	cmp    byte [esi-1], 0
588
	jz    .done
521 diamond 589
  .nested:
585 mario79 590
	mov    eax,[cd_current_pointer_of_input]
591
	push	dword [eax+2]
592
	pop	dword [CDSectorAddress]       ; начало директории
593
	mov    eax,[eax+2+8]  ; размер директории
594
	jmp    .mainloop
87 mario79 595
; указатель файла найден
596
   .done:
585 mario79 597
	test	ebp, ebp
598
	jz	@f
599
	mov	esi, ebp
600
	xor	ebp, ebp
601
	jmp	.nested
521 diamond 602
@@:
585 mario79 603
	pop  esi eax
604
	mov   [cd_appl_data],1
605
	clc
606
	ret
379 serge 607
 
87 mario79 608
cd_find_name_in_buffer:
585 mario79 609
	mov	[cd_current_pointer_of_input_2],CDDataBuf
87 mario79 610
.start:
585 mario79 611
	call	cd_get_name
612
	jc	.not_found
613
	call	cd_compare_name
614
	jc	.start
379 serge 615
.found:
585 mario79 616
	clc
617
	ret
87 mario79 618
.not_found:
585 mario79 619
	stc
620
	ret
87 mario79 621
 
622
cd_get_name:
585 mario79 623
	push eax
624
	mov   ebp,[cd_current_pointer_of_input_2]
625
	mov   [cd_current_pointer_of_input],ebp
626
	mov   eax,[ebp]
627
	cmp   eax,0   ; входы закончились?
628
	je    .next_sector
629
	cmp   ebp,CDDataBuf+2048     ; буфер закончился?
630
	jae   .next_sector
631
	movzx eax, byte [ebp]
632
	add   [cd_current_pointer_of_input_2],eax ; следующий вход каталога
633
	add   ebp,33 ; указатель установлен на начало имени
634
	pop   eax
635
	clc
636
	ret
87 mario79 637
.next_sector:
585 mario79 638
	pop  eax
639
	stc
640
	ret
87 mario79 641
 
642
cd_compare_name:
643
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
644
; in: esi->name, ebp->name
645
; out: if names match: ZF=1 and esi->next component of name
646
;      else: ZF=0, esi is not changed
647
; destroys eax
379 serge 648
    push    esi eax edi
87 mario79 649
    mov     edi,ebp
650
.loop:
651
    cld
652
    lodsb
536 diamond 653
    push eax
99 mario79 654
    call char_todown
87 mario79 655
    call ansi2uni_char
656
    xchg ah,al
657
    scasw
536 diamond 658
    pop  eax
585 mario79 659
    je	  .coincides
99 mario79 660
    call char_toupper
87 mario79 661
    call ansi2uni_char
662
    xchg ah,al
663
    sub  edi,2
664
    scasw
665
    jne   .name_not_coincide
666
.coincides:
667
    cmp   [esi],byte '/'  ; разделитель пути, конец имени текущего элемента
585 mario79 668
    je	 .done
669
    cmp   [esi],byte 0	; разделитель пути, конец имени текущего элемента
670
    je	 .done
87 mario79 671
    jmp   .loop
672
.name_not_coincide:
673
    pop    edi eax esi
674
    stc
675
    ret
676
.done:
677
; проверка конца файла
678
    cmp   [edi],word 3B00h ; сепаратор конца файла ';'
585 mario79 679
    je	 .done_1
87 mario79 680
; проверка для файлов не заканчивающихся сепаратором
681
    movzx   eax,byte [ebp-33]
682
    add   eax,ebp
683
    sub   eax,34
684
    cmp   edi,eax
585 mario79 685
    je	 .done_1
87 mario79 686
; проверка конца папки
687
    movzx   eax,byte [ebp-1]
688
    add   eax,ebp
689
    cmp   edi,eax
690
    jne   .name_not_coincide
691
.done_1:
692
    pop   edi eax
693
    add   esp,4
694
    inc   esi
695
    clc
696
    ret
379 serge 697
 
87 mario79 698
char_todown:
699
; convert character to uppercase, using cp866 encoding
700
; in: al=symbol
701
; out: al=converted symbol
585 mario79 702
	cmp	al, 'A'
703
	jb	.ret
704
	cmp	al, 'Z'
705
	jbe	.az
706
	cmp	al, 'Ђ'
707
	jb	.ret
708
	cmp	al, 'ђ'
709
	jb	.rus1
710
	cmp	al, 'џ'
711
	ja	.ret
87 mario79 712
; 0x90-0x9F -> 0xE0-0xEF
585 mario79 713
	add	al, 'а'-'ђ'
87 mario79 714
.ret:
585 mario79 715
	ret
87 mario79 716
.rus1:
717
; 0x80-0x8F -> 0xA0-0xAF
718
.az:
585 mario79 719
	add	al, 0x20
720
	ret
379 serge 721
 
87 mario79 722
uni2ansi_char:
723
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
724
; in: ax=UNICODE character
725
; out: al=converted ANSI character
585 mario79 726
	cmp	ax, 0x80
727
	jb	.ascii
728
	cmp	ax, 0x401
729
	jz	.yo1
730
	cmp	ax, 0x451
731
	jz	.yo2
732
	cmp	ax, 0x410
733
	jb	.unk
734
	cmp	ax, 0x440
735
	jb	.rus1
736
	cmp	ax, 0x450
737
	jb	.rus2
87 mario79 738
.unk:
585 mario79 739
	mov	al, '_'
740
	jmp	.doit
87 mario79 741
.yo1:
585 mario79 742
	mov	al, 'р'
743
	jmp	.doit
87 mario79 744
.yo2:
585 mario79 745
	mov	al, 'с'
746
	jmp	.doit
87 mario79 747
.rus1:
748
; 0x410-0x43F -> 0x80-0xAF
585 mario79 749
	add	al, 0x70
750
	jmp	.doit
87 mario79 751
.rus2:
752
; 0x440-0x44F -> 0xE0-0xEF
585 mario79 753
	add	al, 0xA0
87 mario79 754
.ascii:
755
.doit:
585 mario79 756
	ret