Subversion Repositories Kolibri OS

Rev

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