Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 593 $
  9.  
  10.  
  11. uglobal
  12. cd_current_pointer_of_input    dd  0
  13. cd_current_pointer_of_input_2  dd  0
  14. cd_mem_location                dd  0
  15. cd_counter_block               dd  0
  16. IDE_Channel_1                  db  0
  17. IDE_Channel_2                  db  0
  18. endg
  19.  
  20. reserve_cd:
  21.  
  22.     cli
  23.     cmp   [cd_status],0
  24.     je    reserve_ok2
  25.  
  26.     sti
  27.     call  change_task
  28.     jmp   reserve_cd
  29.  
  30.   reserve_ok2:
  31.  
  32.     push  eax
  33.     mov   eax,[CURRENT_TASK]
  34.     shl   eax,5
  35.     mov   eax,[eax+CURRENT_TASK+TASKDATA.pid]
  36.     mov   [cd_status],eax
  37.     pop   eax
  38.     sti
  39.     ret
  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
  47.     je    .reserve_ok_1
  48.     sti
  49.     call  change_task
  50.     jmp   .IDE_Channel_1
  51. .IDE_Channel_2:
  52.     cli
  53.     cmp   [IDE_Channel_2],0
  54.     je    .reserve_ok_2
  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:
  69.     mov [IDE_Channel_1],0
  70.     ret
  71. .IDE_Channel_2:
  72.     mov [IDE_Channel_2],0
  73.     ret
  74.  
  75. uglobal
  76. cd_status dd 0
  77. endg
  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:
  100.     or    ebx, -1
  101.     mov    eax, ERROR_ACCESS_DENIED
  102.     ret
  103.  
  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
  114.     or    ebx, -1
  115.     mov    eax, ERROR_FILE_NOT_FOUND
  116.     ret
  117.  
  118. .found:
  119.     mov    edi,[cd_current_pointer_of_input]
  120.     test   byte [edi+25],10b    ; do not allow read directories
  121.     jnz    .noaccess
  122.     test    ebx, ebx
  123.     jz    .l1
  124.     cmp    dword [ebx+4], 0
  125.     jz    @f
  126.         xor     ebx, ebx
  127. .reteof:
  128.     mov    eax, 6 ; end of file
  129.     pop    edi
  130.     ret
  131. @@:
  132.     mov    ebx, [ebx]
  133. .l1:
  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
  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
  149.     jz    .done
  150.     sub    ebx, 2048
  151.     jae    .next
  152.     add    ebx, 2048
  153.     jnz    .incomplete_sector
  154.     cmp    ecx, 2048
  155.     jb    .incomplete_sector
  156. ; we may read and memmove complete sector
  157.     mov  [CDDataBuf_pointer],edx
  158.     call ReadCDWRetr      ; ÷èòàåì ñåêòîð ôàéëà
  159.     cmp   [DevErrorCode],0
  160.     jne   .noaccess_3
  161.     add    edx, 2048
  162.     sub    ecx, 2048
  163. .next:
  164.     inc  dword [CDSectorAddress]
  165.     jmp    .new_sector
  166. .incomplete_sector:
  167. ; we must read and memmove incomplete sector
  168.     mov  [CDDataBuf_pointer],CDDataBuf
  169.     call ReadCDWRetr      ; ÷èòàåì ñåêòîð ôàéëà
  170.     cmp   [DevErrorCode],0
  171.     jne   .noaccess_3
  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
  181.         lea     esi, [CDDataBuf + ebx]
  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
  189.     jmp    .next
  190.  
  191. .done:
  192.         mov     ebx, edx
  193.         pop     eax edx ecx edi
  194.         sub     ebx, edx
  195.         ret
  196. .eof:
  197.         mov     ebx, edx
  198.         pop     eax edx ecx
  199.         sub     ebx, edx
  200.         jmp     .reteof
  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:
  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
  227. .found:
  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
  232. .noaccess_1:
  233.         or      ebx, -1
  234.         mov     eax, ERROR_ACCESS_DENIED
  235.         ret
  236. .found_dir:
  237.         mov     eax, [edi+2]    ; eax=cluster
  238.         mov     [CDSectorAddress], eax
  239.         mov     eax, [edi+10]   ; ðàçìåð äèðåêòðîðèè
  240. .doit:
  241. ; init header
  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
  251. ; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ
  252. ;.mainloop:
  253.         mov     [cd_counter_block], dword 0
  254.         dec     dword [CDSectorAddress]
  255.         push    ecx
  256. .read_to_buffer:
  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
  264. ; äèðåêòîðèÿ çàêîí÷èëàñü?
  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
  274. @@:
  275.         pop     ecx edi
  276.         mov     ebx, [edx+4]
  277.         ret
  278.  
  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
  284.     jc    .end_buffer
  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
  290.     jz    .get_names_from_buffer_1
  291.     mov   edi,[cd_counter_block]
  292.     mov   [edx+4],edi
  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. ; ïðîâåðêà êîíöà ôàéëà
  310.     mov   ax,[esi]
  311.     cmp   ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
  312.     je   .cd_get_parameters_of_file_1
  313. ; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
  314.     movzx   eax,byte [ebp-33]
  315.     add   eax,ebp
  316.     sub   eax,34
  317.     cmp   esi,eax
  318.     je   .cd_get_parameters_of_file_1
  319. ; ïðîâåðêà êîíöà ïàïêè
  320.     movzx   eax,byte [ebp-1]
  321.     add   eax,ebp
  322.     cmp   esi,eax
  323.     jb   .ansi
  324. .cd_get_parameters_of_file_1:
  325.     mov   [edi],byte 0
  326.     call  cd_get_parameters_of_file
  327.     add   [cd_mem_location],304
  328.     jmp   .get_names_from_buffer_1
  329.  
  330. .ansi_parent_directory:
  331.     cmp   [cd_counter_block],2
  332.     je    @f
  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 ; ñåïàðàòîð êîíöà ôàéëà ';'
  349.     je   .cd_get_parameters_of_file_2
  350. ; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
  351.     movzx   eax,byte [ebp-33]
  352.     add   eax,ebp
  353.     sub   eax,34
  354.     cmp   esi,eax
  355.     je   .cd_get_parameters_of_file_2
  356. ; ïðîâåðêà êîíöà ïàïêè
  357.     movzx   eax,byte [ebp-1]
  358.     add   eax,ebp
  359.     cmp   esi,eax
  360.     jb   .unicode
  361. .cd_get_parameters_of_file_2:
  362.     mov   [edi],word 0
  363.     call  cd_get_parameters_of_file
  364.     add   [cd_mem_location],560
  365.     jmp   .get_names_from_buffer_1
  366.  
  367. .unicode_parent_directory:
  368.     cmp   [cd_counter_block],2
  369.     je    @f
  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.  
  378. .end_buffer:
  379.     pop   edx edi esi eax
  380.     ret
  381.  
  382. cd_get_parameters_of_file:
  383.     mov   edi,[cd_mem_location]
  384. cd_get_parameters_of_file_1:
  385. ; ïîëó÷àåì àòðèáóòû ôàéëà
  386.     xor   eax,eax
  387. ; ôàéë íå àðõèâèðîâàëñÿ
  388.     inc   eax
  389.     shl   eax,1
  390. ; ýòî êàòàëîã?
  391.     test  [ebp-8],byte 2
  392.     jz    .file
  393.     inc   eax
  394. .file:
  395. ; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
  396. ; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
  397.     shl   eax,3
  398. ; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
  399.     test  [ebp-8],byte 1
  400.     jz    .hidden
  401.     inc   eax
  402. .hidden:
  403.     shl   eax,1
  404. ; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
  405.     inc   eax
  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.  
  455. ;----------------------------------------------------------------
  456. ;
  457. ;  fs_CdGetFileInfo - LFN variant for CD
  458. ;                     get file/directory attributes structure
  459. ;
  460. ;----------------------------------------------------------------
  461. fs_CdGetFileInfo:
  462.         cmp     byte [esi], 0
  463.         jnz     @f
  464.         mov     eax, 2
  465.         ret
  466. @@:
  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
  476. @@:
  477.         popfd
  478.         jnc     @f
  479.         pop     edi
  480.         mov     eax, ERROR_FILE_NOT_FOUND
  481.         ret
  482. @@:
  483.  
  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
  494.  
  495. cd_find_lfn:
  496.        mov   [cd_appl_data],0
  497. ; in: esi+ebp -> name
  498. ; out: CF=1 - file not found
  499. ;      else CF=0 and [cd_current_pointer_of_input] direntry
  500.         push eax esi
  501. ; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
  502.         mov  [CDSectorAddress],dword 15
  503.        mov  [CDDataBuf_pointer],CDDataBuf
  504.        call  prevent_medium_removal
  505. .start:
  506.         inc  dword [CDSectorAddress]
  507.        call  ReadCDWRetr    ;_1
  508.        cmp   [DevErrorCode],0
  509.        jne   .access_denied
  510. ; ïðîâåðêà íà âøèâîñòü
  511.         cmp  [CDDataBuf+1],dword 'CD00'
  512.         jne  .access_denied
  513.         cmp  [CDDataBuf+5],byte '1'
  514.         jne  .access_denied
  515. ; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
  516.         cmp  [CDDataBuf],byte 0xff
  517.         je  .access_denied
  518. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
  519.         cmp  [CDDataBuf],byte 0x2
  520.         jne  .start
  521. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
  522.         cmp  [CDDataBuf+6],byte 0x1
  523.         jne  .start
  524. ; ïàðàìåòðû root äèðåêòðîðèè
  525.         mov  eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
  526.         mov  [CDSectorAddress],eax
  527.         mov  eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
  528.         cmp    byte [esi], 0
  529.         jnz    @f
  530.         mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
  531.         jmp   .done
  532. @@:
  533. ; íà÷èíàåì ïîèñê
  534. .mainloop:
  535.         dec  dword [CDSectorAddress]
  536. .read_to_buffer:
  537.         inc  dword [CDSectorAddress]
  538.         mov  [CDDataBuf_pointer],CDDataBuf
  539.         call ReadCDWRetr         ; ÷èòàåì ñåêòîð äèðåêòîðèè
  540.         cmp   [DevErrorCode],0
  541.         jne   .access_denied
  542.         push    ebp
  543.         call    cd_find_name_in_buffer
  544.         pop     ebp
  545.         jnc     .found
  546.         sub  eax,2048
  547. ; äèðåêòîðèÿ çàêîí÷èëàñü?
  548.         cmp  eax,0
  549.         ja   .read_to_buffer
  550. ; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
  551. .access_denied:
  552.         pop  esi eax
  553.         mov   [cd_appl_data],1
  554.         stc
  555.         ret
  556. ; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
  557.   .found:
  558. ; êîíåö ïóòè ôàéëà
  559.         cmp    byte [esi-1], 0
  560.         jz    .done
  561.   .nested:
  562.         mov    eax,[cd_current_pointer_of_input]
  563.         push    dword [eax+2]
  564.         pop     dword [CDSectorAddress]       ; íà÷àëî äèðåêòîðèè
  565.         mov    eax,[eax+2+8]  ; ðàçìåð äèðåêòîðèè
  566.         jmp    .mainloop
  567. ; óêàçàòåëü ôàéëà íàéäåí
  568.    .done:
  569.         test    ebp, ebp
  570.         jz      @f
  571.         mov     esi, ebp
  572.         xor     ebp, ebp
  573.         jmp     .nested
  574. @@:
  575.         pop  esi eax
  576.         mov   [cd_appl_data],1
  577.         clc
  578.         ret
  579.  
  580. cd_find_name_in_buffer:
  581.         mov     [cd_current_pointer_of_input_2],CDDataBuf
  582. .start:
  583.         call    cd_get_name
  584.         jc      .not_found
  585.         call    cd_compare_name
  586.         jc      .start
  587. .found:
  588.         clc
  589.         ret
  590. .not_found:
  591.         stc
  592.         ret
  593.  
  594. cd_get_name:
  595.         push eax
  596.         mov   ebp,[cd_current_pointer_of_input_2]
  597.         mov   [cd_current_pointer_of_input],ebp
  598.         mov   eax,[ebp]
  599.         cmp   eax,0   ; âõîäû çàêîí÷èëèñü?
  600.         je    .next_sector
  601.         cmp   ebp,CDDataBuf+2048     ; áóôåð çàêîí÷èëñÿ?
  602.         jae   .next_sector
  603.         movzx eax, byte [ebp]
  604.         add   [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
  605.         add   ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
  606.         pop   eax
  607.         clc
  608.         ret
  609. .next_sector:
  610.         pop  eax
  611.         stc
  612.         ret
  613.  
  614. cd_compare_name:
  615. ; compares ASCIIZ-names, case-insensitive (cp866 encoding)
  616. ; in: esi->name, ebp->name
  617. ; out: if names match: ZF=1 and esi->next component of name
  618. ;      else: ZF=0, esi is not changed
  619. ; destroys eax
  620.     push    esi eax edi
  621.     mov     edi,ebp
  622. .loop:
  623.     cld
  624.     lodsb
  625.     push eax
  626.     call char_todown
  627.     call ansi2uni_char
  628.     xchg ah,al
  629.     scasw
  630.     pop  eax
  631.     je    .coincides
  632.     call char_toupper
  633.     call ansi2uni_char
  634.     xchg ah,al
  635.     sub  edi,2
  636.     scasw
  637.     jne   .name_not_coincide
  638. .coincides:
  639.     cmp   [esi],byte '/'  ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
  640.     je   .done
  641.     cmp   [esi],byte 0  ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
  642.     je   .done
  643.     jmp   .loop
  644. .name_not_coincide:
  645.     pop    edi eax esi
  646.     stc
  647.     ret
  648. .done:
  649. ; ïðîâåðêà êîíöà ôàéëà
  650.     cmp   [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
  651.     je   .done_1
  652. ; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
  653.     movzx   eax,byte [ebp-33]
  654.     add   eax,ebp
  655.     sub   eax,34
  656.     cmp   edi,eax
  657.     je   .done_1
  658. ; ïðîâåðêà êîíöà ïàïêè
  659.     movzx   eax,byte [ebp-1]
  660.     add   eax,ebp
  661.     cmp   edi,eax
  662.     jne   .name_not_coincide
  663. .done_1:
  664.     pop   edi eax
  665.     add   esp,4
  666.     inc   esi
  667.     clc
  668.     ret
  669.  
  670. char_todown:
  671. ; convert character to uppercase, using cp866 encoding
  672. ; in: al=symbol
  673. ; out: al=converted symbol
  674.         cmp     al, 'A'
  675.         jb      .ret
  676.         cmp     al, 'Z'
  677.         jbe     .az
  678.         cmp     al, '€'
  679.         jb      .ret
  680.         cmp     al, ''
  681.         jb      .rus1
  682.         cmp     al, 'Ÿ'
  683.         ja      .ret
  684. ; 0x90-0x9F -> 0xE0-0xEF
  685.         add     al, 'à'-''
  686. .ret:
  687.         ret
  688. .rus1:
  689. ; 0x80-0x8F -> 0xA0-0xAF
  690. .az:
  691.         add     al, 0x20
  692.         ret
  693.  
  694. uni2ansi_char:
  695. ; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
  696. ; in: ax=UNICODE character
  697. ; out: al=converted ANSI character
  698.         cmp     ax, 0x80
  699.         jb      .ascii
  700.         cmp     ax, 0x401
  701.         jz      .yo1
  702.         cmp     ax, 0x451
  703.         jz      .yo2
  704.         cmp     ax, 0x410
  705.         jb      .unk
  706.         cmp     ax, 0x440
  707.         jb      .rus1
  708.         cmp     ax, 0x450
  709.         jb      .rus2
  710. .unk:
  711.         mov     al, '_'
  712.         jmp     .doit
  713. .yo1:
  714.         mov     al, 'ð'
  715.         jmp     .doit
  716. .yo2:
  717.         mov     al, 'ñ'
  718.         jmp     .doit
  719. .rus1:
  720. ; 0x410-0x43F -> 0x80-0xAF
  721.         add     al, 0x70
  722.         jmp     .doit
  723. .rus2:
  724. ; 0x440-0x44F -> 0xE0-0xEF
  725.         add     al, 0xA0
  726. .ascii:
  727. .doit:
  728.         ret
  729.