Subversion Repositories Kolibri OS

Rev

Rev 533 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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