Subversion Repositories Kolibri OS

Rev

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

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