Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 533 $
  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   al
  387.     shl   eax,1
  388. ; ýòî êàòàëîã?
  389.     test  [ebp-8],byte 2
  390.     jz    .file
  391.     inc   al
  392. .file:
  393. ; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
  394. ; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
  395.     shl   eax,3
  396. ; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
  397.     test  [ebp-8],byte 1
  398.     jz    .hidden
  399.     inc   al
  400. .hidden:
  401.     shl   eax,1
  402. ; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
  403.     inc   al
  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 ebp
  466.         call    cd_find_lfn
  467.         pushfd
  468.         cmp     [DevErrorCode], 0
  469.         jz      @f
  470.         popfd
  471.         pop     ebp edi
  472.         mov     eax, 11
  473.         ret
  474. @@:
  475.         popfd
  476.         jnc     @f
  477.         pop     ebp edi
  478.         mov     eax, ERROR_FILE_NOT_FOUND
  479.         ret
  480. @@:
  481.  
  482.         mov     edi, edx
  483.         call    cd_get_parameters_of_file_1
  484.         and     dword [edi+4], 0
  485.         pop     ebp edi
  486.         xor     eax, eax
  487.         ret
  488.  
  489. cd_find_lfn:
  490. ; in: esi+ebp -> name
  491. ; out: CF=1 - file not found
  492. ;      else CF=0 and [cd_current_pointer_of_input] direntry
  493.         push eax esi
  494. ; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
  495.         mov  [CDSectorAddress],dword 15
  496. .start:
  497.         inc  dword [CDSectorAddress]
  498.        mov  [CDDataBuf_pointer],CDDataBuf
  499.        call  ReadCDWRetr
  500.        cmp   [DevErrorCode],0
  501.        jne   .access_denied
  502. ; ïðîâåðêà íà âøèâîñòü
  503.         cmp  [CDDataBuf+1],dword 'CD00'
  504.         jne  .access_denied
  505.         cmp  [CDDataBuf+5],byte '1'
  506.         jne  .access_denied
  507. ; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
  508.         cmp  [CDDataBuf],byte 0xff
  509.         je  .access_denied
  510. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
  511.         cmp  [CDDataBuf],byte 0x2
  512.         jne  .start
  513. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
  514.         cmp  [CDDataBuf+6],byte 0x1
  515.         jne  .start
  516. ; ïàðàìåòðû root äèðåêòðîðèè
  517.         mov  eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
  518.         mov  [CDSectorAddress],eax
  519.         mov  eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
  520.         cmp    byte [esi], 0
  521.         jnz    @f
  522.         mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
  523.         jmp   .done
  524. @@:
  525. ; íà÷èíàåì ïîèñê
  526. .mainloop:
  527.         dec  dword [CDSectorAddress]
  528. .read_to_buffer:
  529.         inc  dword [CDSectorAddress]
  530.         mov  [CDDataBuf_pointer],CDDataBuf
  531.         call ReadCDWRetr         ; ÷èòàåì ñåêòîð äèðåêòîðèè
  532.         cmp   [DevErrorCode],0
  533.         jne   .access_denied
  534.         push    ebp
  535.         call    cd_find_name_in_buffer
  536.         pop     ebp
  537.         jnc     .found
  538.         sub  eax,2048
  539. ; äèðåêòîðèÿ çàêîí÷èëàñü?
  540.         cmp  eax,0
  541.         ja   .read_to_buffer
  542. ; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
  543. .access_denied:
  544.         pop  esi eax
  545.         stc
  546.         ret
  547. ; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
  548.   .found:
  549. ; êîíåö ïóòè ôàéëà
  550.         cmp    byte [esi-1], 0
  551.         jz    .done
  552.   .nested:
  553.         mov    eax,[cd_current_pointer_of_input]
  554.         push    dword [eax+2]
  555.         pop     dword [CDSectorAddress]       ; íà÷àëî äèðåêòîðèè
  556.         mov    eax,[eax+2+8]  ; ðàçìåð äèðåêòîðèè
  557.         jmp    .mainloop
  558. ; óêàçàòåëü ôàéëà íàéäåí
  559.    .done:
  560.         test    ebp, ebp
  561.         jz      @f
  562.         mov     esi, ebp
  563.         xor     ebp, ebp
  564.         jmp     .nested
  565. @@:
  566.         pop  esi eax
  567.         clc
  568.         ret
  569.  
  570. cd_find_name_in_buffer:
  571.         mov     [cd_current_pointer_of_input_2],CDDataBuf
  572. .start:
  573.         call    cd_get_name
  574.         jc      .not_found
  575.         call    cd_compare_name
  576.         jc      .start
  577. .found:
  578.         clc
  579.         ret
  580. .not_found:
  581.         stc
  582.         ret
  583.  
  584. cd_get_name:
  585.         push eax
  586.         mov   ebp,[cd_current_pointer_of_input_2]
  587.         mov   [cd_current_pointer_of_input],ebp
  588.         mov   eax,[ebp]
  589.         cmp   eax,0   ; âõîäû çàêîí÷èëèñü?
  590.         je    .next_sector
  591.         cmp   ebp,CDDataBuf+2048     ; áóôåð çàêîí÷èëñÿ?
  592.         jae   .next_sector
  593.         movzx eax, byte [ebp]
  594.         add   [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
  595.         add   ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
  596.         pop   eax
  597.         clc
  598.         ret
  599. .next_sector:
  600.         pop  eax
  601.         stc
  602.         ret
  603.  
  604. cd_compare_name:
  605. ; compares ASCIIZ-names, case-insensitive (cp866 encoding)
  606. ; in: esi->name, ebp->name
  607. ; out: if names match: ZF=1 and esi->next component of name
  608. ;      else: ZF=0, esi is not changed
  609. ; destroys eax
  610.     push    esi eax edi
  611.     mov     edi,ebp
  612. .loop:
  613.     cld
  614.     lodsb
  615.     push ax
  616.     call char_todown
  617.     call ansi2uni_char
  618.     xchg ah,al
  619.     cld
  620.     scasw
  621.     pop  ax
  622.     je    .coincides
  623.     call char_toupper
  624.     call ansi2uni_char
  625.     xchg ah,al
  626.     cld
  627.     sub  edi,2
  628.     scasw
  629.     jne   .name_not_coincide
  630. .coincides:
  631.     cmp   [esi],byte '/'  ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
  632.     je   .done
  633.     cmp   [esi],byte 0  ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
  634.     je   .done
  635.     jmp   .loop
  636. .name_not_coincide:
  637.     pop    edi eax esi
  638.     stc
  639.     ret
  640. .done:
  641. ; ïðîâåðêà êîíöà ôàéëà
  642.     cmp   [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
  643.     je   .done_1
  644. ; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
  645.     movzx   eax,byte [ebp-33]
  646.     add   eax,ebp
  647.     sub   eax,34
  648.     cmp   edi,eax
  649.     je   .done_1
  650. ; ïðîâåðêà êîíöà ïàïêè
  651.     movzx   eax,byte [ebp-1]
  652.     add   eax,ebp
  653.     cmp   edi,eax
  654.     jne   .name_not_coincide
  655. .done_1:
  656.     pop   edi eax
  657.     add   esp,4
  658.     inc   esi
  659.     clc
  660.     ret
  661.  
  662. char_todown:
  663. ; convert character to uppercase, using cp866 encoding
  664. ; in: al=symbol
  665. ; out: al=converted symbol
  666.         cmp     al, 'A'
  667.         jb      .ret
  668.         cmp     al, 'Z'
  669.         jbe     .az
  670.         cmp     al, '€'
  671.         jb      .ret
  672.         cmp     al, ''
  673.         jb      .rus1
  674.         cmp     al, 'Ÿ'
  675.         ja      .ret
  676. ; 0x90-0x9F -> 0xE0-0xEF
  677.         add     al, 'à'-''
  678. .ret:
  679.         ret
  680. .rus1:
  681. ; 0x80-0x8F -> 0xA0-0xAF
  682. .az:
  683.         add     al, 0x20
  684.         ret
  685.  
  686. uni2ansi_char:
  687. ; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
  688. ; in: ax=UNICODE character
  689. ; out: al=converted ANSI character
  690.         cmp     ax, 0x80
  691.         jb      .ascii
  692.         cmp     ax, 0x401
  693.         jz      .yo1
  694.         cmp     ax, 0x451
  695.         jz      .yo2
  696.         cmp     ax, 0x410
  697.         jb      .unk
  698.         cmp     ax, 0x440
  699.         jb      .rus1
  700.         cmp     ax, 0x450
  701.         jb      .rus2
  702. .unk:
  703.         mov     al, '_'
  704.         jmp     .doit
  705. .yo1:
  706.         mov     al, 'ð'
  707.         jmp     .doit
  708. .yo2:
  709.         mov     al, 'ñ'
  710.         jmp     .doit
  711. .rus1:
  712. ; 0x410-0x43F -> 0x80-0xAF
  713.         add     al, 0x70
  714.         jmp     .doit
  715. .rus2:
  716. ; 0x440-0x44F -> 0xE0-0xEF
  717.         add     al, 0xA0
  718. .ascii:
  719. .doit:
  720.         ret
  721.