Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 5363 $
  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. endg
  17. ;-----------------------------------------------------------------------------
  18. reserve_cd:
  19.         cli
  20.         cmp     [cd_status], 0
  21.         je      reserve_ok2
  22.  
  23.         sti
  24.         call    change_task
  25.         jmp     reserve_cd
  26. ;-----------------------------------------------------------------------------
  27. reserve_ok2:
  28.         push    eax
  29.         mov     eax, [CURRENT_TASK]
  30.         shl     eax, 5
  31.         mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
  32.         mov     [cd_status], eax
  33.         pop     eax
  34.         sti
  35.         ret
  36. ;-----------------------------------------------------------------------------
  37. reserve_cd_channel:
  38.         pushad
  39.         mov     eax, [cdpos]
  40.         dec     eax
  41.         shr     eax, 2
  42.  
  43.         test    eax, eax
  44.         jnz     .1
  45.  
  46.         cmp     [ChannelNumber], 1
  47.         jne     @f
  48.  
  49.         mov     ecx, ide_channel1_mutex
  50.         jmp     .mutex_lock
  51. ;--------------------------------------
  52. @@:
  53.         mov     ecx, ide_channel2_mutex
  54.         jmp     .mutex_lock
  55. ;--------------------------------------
  56. .1:
  57.         dec     eax
  58.         jnz     .2
  59.  
  60.         cmp     [ChannelNumber], 1
  61.         jne     @f
  62.  
  63.         mov     ecx, ide_channel3_mutex
  64.         jmp     .mutex_lock
  65. ;--------------------------------------
  66. @@:
  67.         mov     ecx, ide_channel4_mutex
  68.         jmp     .mutex_lock
  69. ;--------------------------------------
  70. .2:
  71.         cmp     [ChannelNumber], 1
  72.         jne     @f
  73.  
  74.         mov     ecx, ide_channel5_mutex
  75.         jmp     .mutex_lock
  76. ;--------------------------------------
  77. @@:
  78.         mov     ecx, ide_channel6_mutex
  79. .mutex_lock:
  80.         call    mutex_lock
  81.         popad
  82.         ret
  83. ;-----------------------------------------------------------------------------
  84. free_cd_channel:
  85.         pushad
  86.         mov     eax, [cdpos]
  87.         dec     eax
  88.         shr     eax, 2
  89.  
  90.         test    eax, eax
  91.         jnz     .1
  92.  
  93.         cmp     [ChannelNumber], 1
  94.         jne     @f
  95.  
  96.         mov     ecx, ide_channel1_mutex
  97.         jmp     .mutex_unlock
  98. ;--------------------------------------
  99. @@:
  100.         mov     ecx, ide_channel2_mutex
  101.         jmp     .mutex_unlock
  102. ;--------------------------------------
  103. .1:
  104.         dec     eax
  105.         jnz     .2
  106.  
  107.         cmp     [ChannelNumber], 1
  108.         jne     @f
  109.  
  110.         mov     ecx, ide_channel3_mutex
  111.         jmp     .mutex_unlock
  112. ;--------------------------------------
  113. @@:
  114.         mov     ecx, ide_channel4_mutex
  115.         jmp     .mutex_unlock
  116. ;--------------------------------------
  117. .2:
  118.         cmp     [ChannelNumber], 1
  119.         jne     @f
  120.  
  121.         mov     ecx, ide_channel5_mutex
  122.         jmp     .mutex_unlock
  123. ;--------------------------------------
  124. @@:
  125.         mov     ecx, ide_channel6_mutex
  126. .mutex_unlock:
  127.         call    mutex_unlock
  128.         popad
  129.         ret
  130. ;-----------------------------------------------------------------------------
  131. uglobal
  132. cd_status dd 0
  133. endg
  134. ;-----------------------------------------------------------------------------
  135. ;
  136. ;  fs_CdRead - LFN variant for reading CD disk
  137. ;
  138. ;  esi  points to filename /dir1/dir2/.../dirn/file,0
  139. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  140. ;       may be ebx=0 - start from first byte
  141. ;  ecx  number of bytes to read, 0+
  142. ;  edx  mem location to return data
  143. ;
  144. ;  ret ebx = bytes read or 0xffffffff file not found
  145. ;      eax = 0 ok read or other = errormsg
  146. ;
  147. ;-----------------------------------------------------------------------------
  148. fs_CdRead:
  149.         push    edi
  150.         cmp     byte [esi], 0
  151.         jnz     @f
  152. ;--------------------------------------
  153. .noaccess:
  154.         pop     edi
  155. ;--------------------------------------
  156. .noaccess_2:
  157.         or      ebx, -1
  158.         mov     eax, ERROR_ACCESS_DENIED
  159.         ret
  160. ;--------------------------------------
  161. .noaccess_3:
  162.         pop     eax edx ecx edi
  163.         jmp     .noaccess_2
  164. ;--------------------------------------
  165. @@:
  166.         call    cd_find_lfn
  167.         jnc     .found
  168.  
  169.         pop     edi
  170.         cmp     [DevErrorCode], 0
  171.         jne     .noaccess_2
  172.  
  173.         or      ebx, -1
  174.         mov     eax, ERROR_FILE_NOT_FOUND
  175.         ret
  176. ;--------------------------------------
  177. .found:
  178.         mov     edi, [cd_current_pointer_of_input]
  179.         test    byte [edi+25], 10b; do not allow read directories
  180.         jnz     .noaccess
  181.  
  182.         test    ebx, ebx
  183.         jz      .l1
  184.  
  185.         cmp     dword [ebx+4], 0
  186.         jz      @f
  187.  
  188.         xor     ebx, ebx
  189. ;--------------------------------------
  190. .reteof:
  191.         mov     eax, 6; end of file
  192.         pop     edi
  193.         ret
  194. ;--------------------------------------
  195. @@:
  196.         mov     ebx, [ebx]
  197. ;--------------------------------------
  198. .l1:
  199.         push    ecx edx
  200.         push    0
  201.         mov     eax, [edi+10] ; real size of the file section
  202.         sub     eax, ebx
  203.         jb      .eof
  204.  
  205.         cmp     eax, ecx
  206.         jae     @f
  207.  
  208.         mov     ecx, eax
  209.         mov     byte [esp], 6
  210. ;--------------------------------------
  211. @@:
  212.         mov     eax, [edi+2]
  213.         mov     [CDSectorAddress], eax
  214. ;--------------------------------------
  215. ; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
  216. .new_sector:
  217.         test    ecx, ecx
  218.         jz      .done
  219.  
  220.         sub     ebx, 2048
  221.         jae     .next
  222.  
  223.         add     ebx, 2048
  224.         jnz     .incomplete_sector
  225.  
  226.         cmp     ecx, 2048
  227.         jb      .incomplete_sector
  228. ; we may read and memmove complete sector
  229.         mov     [CDDataBuf_pointer], edx
  230.         call    ReadCDWRetr ; read sector of file
  231.         cmp     [DevErrorCode], 0
  232.         jne     .noaccess_3
  233.  
  234.         add     edx, 2048
  235.         sub     ecx, 2048
  236. ;--------------------------------------
  237. .next:
  238.         inc     dword [CDSectorAddress]
  239.         jmp     .new_sector
  240. ;--------------------------------------
  241. .incomplete_sector:
  242. ; we must read and memmove incomplete sector
  243.         mov     [CDDataBuf_pointer], CDDataBuf
  244.         call    ReadCDWRetr ; read sector of file
  245.         cmp     [DevErrorCode], 0
  246.         jne     .noaccess_3
  247.  
  248.         push    ecx
  249.         add     ecx, ebx
  250.         cmp     ecx, 2048
  251.         jbe     @f
  252.  
  253.         mov     ecx, 2048
  254. ;--------------------------------------
  255. @@:
  256.         sub     ecx, ebx
  257.         push    edi esi ecx
  258.         mov     edi, edx
  259.         lea     esi, [CDDataBuf + ebx]
  260.         cld
  261.         rep movsb
  262.         pop     ecx esi edi
  263.         add     edx, ecx
  264.         sub     [esp], ecx
  265.         pop     ecx
  266.         xor     ebx, ebx
  267.         jmp     .next
  268. ;--------------------------------------
  269. .done:
  270.         mov     ebx, edx
  271.         pop     eax edx ecx edi
  272.         sub     ebx, edx
  273.         ret
  274. ;--------------------------------------
  275. .eof:
  276.         mov     ebx, edx
  277.         pop     eax edx ecx
  278.         sub     ebx, edx
  279.         jmp     .reteof
  280. ;-----------------------------------------------------------------------------
  281. ;
  282. ;  fs_CdReadFolder - LFN variant for reading CD disk folder
  283. ;
  284. ;  esi  points to filename  /dir1/dir2/.../dirn/file,0
  285. ;  ebx  pointer to structure 32-bit number = first wanted block, 0+
  286. ;                          & flags (bitfields)
  287. ; flags: bit 0: 0=ANSI names, 1=UNICODE names
  288. ;  ecx  number of blocks to read, 0+
  289. ;  edx  mem location to return data
  290. ;
  291. ;  ret ebx = blocks read or 0xffffffff folder not found
  292. ;      eax = 0 ok read or other = errormsg
  293. ;
  294. ;-----------------------------------------------------------------------------
  295. fs_CdReadFolder:
  296.         push    edi
  297.         call    cd_find_lfn
  298.         jnc     .found
  299.  
  300.         pop     edi
  301.         cmp     [DevErrorCode], 0
  302.         jne     .noaccess_1
  303.  
  304.         or      ebx, -1
  305.         mov     eax, ERROR_FILE_NOT_FOUND
  306.         ret
  307. ;--------------------------------------
  308. .found:
  309.         mov     edi, [cd_current_pointer_of_input]
  310.         test    byte [edi+25], 10b    ; do not allow read directories
  311.         jnz     .found_dir
  312.  
  313.         pop     edi
  314. ;--------------------------------------
  315. .noaccess_1:
  316.         or      ebx, -1
  317.         mov     eax, ERROR_ACCESS_DENIED
  318.         ret
  319. ;--------------------------------------
  320. .found_dir:
  321.         mov     eax, [edi+2]    ; eax=cluster
  322.         mov     [CDSectorAddress], eax
  323.         mov     eax, [edi+10]   ; directory size
  324. ;--------------------------------------
  325. .doit:
  326. ; init header
  327.         push    eax ecx
  328.         mov     edi, edx
  329.         mov     ecx, 32/4
  330.         xor     eax, eax
  331.         rep stosd
  332.         pop     ecx eax
  333.         mov     byte [edx], 1   ; version
  334.         mov     [cd_mem_location], edx
  335.         add     [cd_mem_location], 32
  336. ;.mainloop:
  337.         mov     [cd_counter_block], dword 0
  338.         dec     dword [CDSectorAddress]
  339.         push    ecx
  340. ;--------------------------------------
  341. .read_to_buffer:
  342.         inc     dword [CDSectorAddress]
  343.         mov     [CDDataBuf_pointer], CDDataBuf
  344.         call    ReadCDWRetr         ; read sector of directory
  345.         cmp     [DevErrorCode], 0
  346.         jne     .noaccess_1
  347.  
  348.         call    .get_names_from_buffer
  349.         sub     eax, 2048
  350. ; directory is over?
  351.         ja      .read_to_buffer
  352.  
  353.         mov     edi, [cd_counter_block]
  354.         mov     [edx+8], edi
  355.         mov     edi, [ebx]
  356.         sub     [edx+4], edi
  357.         xor     eax, eax
  358.         dec     ecx
  359.         js      @f
  360.  
  361.         mov     al, ERROR_END_OF_FILE
  362. ;--------------------------------------
  363. @@:
  364.         pop     ecx edi
  365.         mov     ebx, [edx+4]
  366.         ret
  367. ;--------------------------------------
  368. .get_names_from_buffer:
  369.         mov     [cd_current_pointer_of_input_2], CDDataBuf
  370.         push    eax esi edi edx
  371. ;--------------------------------------
  372. .get_names_from_buffer_1:
  373.         call    cd_get_name
  374.         jc      .end_buffer
  375.  
  376.         inc     dword [cd_counter_block]
  377.         mov     eax, [cd_counter_block]
  378.         cmp     [ebx], eax
  379.         jae     .get_names_from_buffer_1
  380.  
  381.         test    ecx, ecx
  382.         jz      .get_names_from_buffer_1
  383.  
  384.         mov     edi, [cd_counter_block]
  385.         mov     [edx+4], edi
  386.         dec     ecx
  387.         mov     esi, ebp
  388.         mov     edi, [cd_mem_location]
  389.         add     edi, 40
  390.         test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
  391.         jnz     .unicode
  392. ;--------------------------------------
  393. .ansi:
  394.         cmp     [cd_counter_block], 2
  395.         jbe     .ansi_parent_directory
  396.  
  397.         cld
  398.         lodsw
  399.         xchg    ah, al
  400.         call    uni2ansi_char
  401.         cld
  402.         stosb
  403. ; check end of file
  404.         mov     ax, [esi]
  405.         cmp     ax, word 3B00h ; separator end of file ';'
  406.         je      .cd_get_parameters_of_file_1
  407. ; check for files not ending with separator
  408.         movzx   eax, byte [ebp-33]
  409.         add     eax, ebp
  410.         sub     eax, 34
  411.         cmp     esi, eax
  412.         je      .cd_get_parameters_of_file_1
  413. ; check the end of the directory
  414.         movzx   eax, byte [ebp-1]
  415.         add     eax, ebp
  416.         cmp     esi, eax
  417.         jb      .ansi
  418. ;--------------------------------------
  419. .cd_get_parameters_of_file_1:
  420.         mov     [edi], byte 0
  421.         call    cd_get_parameters_of_file
  422.         add     [cd_mem_location], 304
  423.         jmp     .get_names_from_buffer_1
  424. ;--------------------------------------
  425. .ansi_parent_directory:
  426.         cmp     [cd_counter_block], 2
  427.         je      @f
  428.  
  429.         mov     [edi], byte '.'
  430.         inc     edi
  431.         jmp     .cd_get_parameters_of_file_1
  432. ;--------------------------------------
  433. @@:
  434.         mov     [edi], word '..'
  435.         add     edi, 2
  436.         jmp     .cd_get_parameters_of_file_1
  437. ;--------------------------------------
  438. .unicode:
  439.         cmp     [cd_counter_block], 2
  440.         jbe     .unicode_parent_directory
  441.  
  442.         cld
  443.         movsw
  444. ; check end of file
  445.         mov     ax, [esi]
  446.         cmp     ax, word 3B00h; separator end of file ';'
  447.         je      .cd_get_parameters_of_file_2
  448. ; check for files not ending with separator
  449.         movzx   eax, byte [ebp-33]
  450.         add     eax, ebp
  451.         sub     eax, 34
  452.         cmp     esi, eax
  453.         je      .cd_get_parameters_of_file_2
  454. ; check the end of the directory
  455.         movzx   eax, byte [ebp-1]
  456.         add     eax, ebp
  457.         cmp     esi, eax
  458.         jb      .unicode
  459. ;--------------------------------------
  460. .cd_get_parameters_of_file_2:
  461.         mov     [edi], word 0
  462.         call    cd_get_parameters_of_file
  463.         add     [cd_mem_location], 560
  464.         jmp     .get_names_from_buffer_1
  465. ;--------------------------------------
  466. .unicode_parent_directory:
  467.         cmp     [cd_counter_block], 2
  468.         je      @f
  469.  
  470.         mov     [edi], word 2E00h; '.'
  471.         add     edi, 2
  472.         jmp     .cd_get_parameters_of_file_2
  473. ;--------------------------------------
  474. @@:
  475.         mov     [edi], dword 2E002E00h; '..'
  476.         add     edi, 4
  477.         jmp     .cd_get_parameters_of_file_2
  478. ;--------------------------------------
  479. .end_buffer:
  480.         pop     edx edi esi eax
  481.         ret
  482. ;-----------------------------------------------------------------------------
  483. cd_get_parameters_of_file:
  484.         mov     edi, [cd_mem_location]
  485. cd_get_parameters_of_file_1:
  486. ; get file attributes
  487.         xor     eax, eax
  488. ; file is not archived
  489.         inc     eax
  490.         shl     eax, 1
  491. ; is a directory?
  492.         test    [ebp-8], byte 2
  493.         jz      .file
  494.  
  495.         inc     eax
  496. ;--------------------------------------
  497. .file:
  498. ; not as a volume label in the FAT, in this form not available
  499. ; file is not a system
  500.         shl     eax, 3
  501. ; file is hidden? (attribute of existence)
  502.         test    [ebp-8], byte 1
  503.         jz      .hidden
  504.  
  505.         inc     eax
  506. ;--------------------------------------
  507. .hidden:
  508.         shl     eax, 1
  509. ; file is always read-only, as this CD
  510.         inc     eax
  511.         mov     [edi], eax
  512. ; get the time to file
  513. ; hour
  514.         movzx   eax, byte [ebp-12]
  515.         shl     eax, 8
  516. ; minute
  517.         mov     al, [ebp-11]
  518.         shl     eax, 8
  519. ; second
  520.         mov     al, [ebp-10]
  521. ; file creation time
  522.         mov     [edi+8], eax
  523. ; last access time
  524.         mov     [edi+16], eax
  525. ; last write time
  526.         mov     [edi+24], eax
  527. ; get date for file
  528. ; year
  529.         movzx   eax, byte [ebp-15]
  530.         add     eax, 1900
  531.         shl     eax, 8
  532. ; month
  533.         mov     al, [ebp-14]
  534.         shl     eax, 8
  535. ; day
  536.         mov     al, [ebp-13]
  537. ; file creation date
  538.         mov     [edi+12], eax
  539. ; last access date
  540.         mov     [edi+20], eax
  541. ; last write date
  542.         mov     [edi+28], eax
  543. ; get the data type of name
  544.         xor     eax, eax
  545.         test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
  546.         jnz     .unicode_1
  547.  
  548.         mov     [edi+4], eax
  549.         jmp     @f
  550. ;--------------------------------------
  551. .unicode_1:
  552.         inc     eax
  553.         mov     [edi+4], eax
  554. ;--------------------------------------
  555. @@:
  556. ; get the file size in bytes
  557.         xor     eax, eax
  558.         mov     [edi+32+4], eax
  559.         mov     eax, [ebp-23]
  560.         mov     [edi+32], eax
  561.         ret
  562. ;-----------------------------------------------------------------------------
  563. ;
  564. ;  fs_CdGetFileInfo - LFN variant for CD
  565. ;                     get file/directory attributes structure
  566. ;
  567. ;-----------------------------------------------------------------------------
  568. fs_CdGetFileInfo:
  569.         cmp     byte [esi], 0
  570.         jnz     @f
  571.  
  572.         mov     eax, 2
  573.         ret
  574. ;--------------------------------------
  575. @@:
  576.         push    edi
  577.         call    cd_find_lfn
  578.         pushfd
  579.         cmp     [DevErrorCode], 0
  580.         jz      @f
  581.  
  582.         popfd
  583.         pop     edi
  584.         mov     eax, 11
  585.         ret
  586. ;--------------------------------------
  587. @@:
  588.         popfd
  589.         jnc     @f
  590.  
  591.         pop     edi
  592.         mov     eax, ERROR_FILE_NOT_FOUND
  593.         ret
  594. ;--------------------------------------
  595. @@:
  596.  
  597.         mov     edi, edx
  598.         push    ebp
  599.         mov     ebp, [cd_current_pointer_of_input]
  600.         add     ebp, 33
  601.         call    cd_get_parameters_of_file_1
  602.         pop     ebp
  603.         and     dword [edi+4], 0
  604.         pop     edi
  605.         xor     eax, eax
  606.         ret
  607. ;-----------------------------------------------------------------------------
  608. cd_find_lfn:
  609.         mov     [cd_appl_data], 0
  610. ; in: esi+ebp -> name
  611. ; out: CF=1 - file not found
  612. ; else CF=0 and [cd_current_pointer_of_input] direntry
  613.         push    eax esi
  614. ; Sector 16 - start set of volume descriptors
  615.         call    WaitUnitReady
  616.         cmp     [DevErrorCode], 0
  617.         jne     .access_denied
  618.  
  619.         call    prevent_medium_removal
  620. ; testing of reading
  621.         mov     [CDSectorAddress], dword 16
  622.         mov     [CDDataBuf_pointer], CDDataBuf
  623.         call    ReadCDWRetr;_1
  624.         cmp     [DevErrorCode], 0
  625.         jne     .access_denied
  626.  
  627. ; calculation of the last session
  628.         call    WaitUnitReady
  629.         cmp     [DevErrorCode], 0
  630.         jne     .access_denied
  631.  
  632.         call    Read_TOC
  633.         mov     ah, [CDDataBuf+4+4]
  634.         mov     al, [CDDataBuf+4+5]
  635.         shl     eax, 16
  636.         mov     ah, [CDDataBuf+4+6]
  637.         mov     al, [CDDataBuf+4+7]
  638.         add     eax, 15
  639.         mov     [CDSectorAddress], eax
  640. ;  mov  [CDSectorAddress],dword 15
  641.         mov     [CDDataBuf_pointer], CDDataBuf
  642. ;--------------------------------------
  643. .start:
  644.         inc     dword [CDSectorAddress]
  645.         call    ReadCDWRetr;_1
  646.         cmp     [DevErrorCode], 0
  647.         jne     .access_denied
  648.  
  649. .start_check:
  650. ; checking for "lice"
  651.         cmp     [CDDataBuf+1], dword 'CD00'
  652.         jne     .access_denied
  653.  
  654.         cmp     [CDDataBuf+5], byte '1'
  655.         jne     .access_denied
  656. ; sector is the terminator of set of descriptors volumes?
  657.         cmp     [CDDataBuf], byte 0xff
  658.         je      .access_denied
  659. ; sector is an additional and improved descriptor of volume?
  660.         cmp     [CDDataBuf], byte 0x2
  661.         jne     .start
  662. ; sector is an additional descriptor of volume?
  663.         cmp     [CDDataBuf+6], byte 0x1
  664.         jne     .start
  665.  
  666. ; parameters of root directory
  667.         mov     eax, [CDDataBuf+0x9c+2]; start of root directory
  668.         mov     [CDSectorAddress], eax
  669.         mov     eax, [CDDataBuf+0x9c+10]; size of root directory
  670.         cmp     byte [esi], 0
  671.         jnz     @f
  672.  
  673.         mov     [cd_current_pointer_of_input], CDDataBuf+0x9c
  674.         jmp     .done
  675. ;--------------------------------------
  676. @@:
  677. ; start the search
  678. .mainloop:
  679.         dec     dword [CDSectorAddress]
  680. ;--------------------------------------
  681. .read_to_buffer:
  682.         inc     dword [CDSectorAddress]
  683.         mov     [CDDataBuf_pointer], CDDataBuf
  684.         call    ReadCDWRetr      ; read sector of directory
  685.         cmp     [DevErrorCode], 0
  686.         jne     .access_denied
  687.  
  688.         push    ebp
  689.         call    cd_find_name_in_buffer
  690.         pop     ebp
  691.         jnc     .found
  692.  
  693.         sub     eax, 2048
  694. ; directory is over?
  695.         cmp     eax, 0
  696.         ja      .read_to_buffer
  697. ; desired element of chain is not found
  698. .access_denied:
  699.         pop     esi eax
  700.         mov     [cd_appl_data], 1
  701.         stc
  702.         ret
  703. ;--------------------------------------
  704. ; desired element of chain found
  705. .found:
  706. ; the end of the file path
  707.         cmp     byte [esi-1], 0
  708.         jz      .done
  709.   .nested:
  710.         mov     eax, [cd_current_pointer_of_input]
  711.         push    dword [eax+2]
  712.         pop     dword [CDSectorAddress] ; beginning of the directory
  713.         mov     eax, [eax+2+8] ; size of directory
  714.         jmp     .mainloop
  715. ;--------------------------------------
  716. ; file pointer found
  717. .done:
  718.         test    ebp, ebp
  719.         jz      @f
  720.  
  721.         mov     esi, ebp
  722.         xor     ebp, ebp
  723.         jmp     .nested
  724. ;--------------------------------------
  725. @@:
  726.         pop     esi eax
  727.         mov     [cd_appl_data], 1
  728.         clc
  729.         ret
  730. ;-----------------------------------------------------------------------------
  731. cd_find_name_in_buffer:
  732.         mov     [cd_current_pointer_of_input_2], CDDataBuf
  733. ;--------------------------------------
  734. .start:
  735.         call    cd_get_name
  736.         jc      .not_found
  737.  
  738.         call    cd_compare_name
  739.         jc      .start
  740. ;--------------------------------------
  741. .found:
  742.         clc
  743.         ret
  744. ;--------------------------------------
  745. .not_found:
  746.         stc
  747.         ret
  748. ;-----------------------------------------------------------------------------
  749. cd_get_name:
  750.         push    eax
  751.         mov     ebp, [cd_current_pointer_of_input_2]
  752.         mov     [cd_current_pointer_of_input], ebp
  753.         mov     eax, [ebp]
  754.         test    eax, eax ; entry's is over?
  755.         jz      .next_sector
  756.  
  757.         cmp     ebp, CDDataBuf+2048  ; buffer is over?
  758.         jae     .next_sector
  759.  
  760.         movzx   eax, byte [ebp]
  761.         add     [cd_current_pointer_of_input_2], eax ; next entry of directory
  762.         add     ebp, 33; pointer is set to the beginning of the name
  763.         pop     eax
  764.         clc
  765.         ret
  766. ;--------------------------------------
  767. .next_sector:
  768.         pop     eax
  769.         stc
  770.         ret
  771. ;-----------------------------------------------------------------------------
  772. cd_compare_name:
  773. ; compares ASCIIZ-names, case-insensitive (cp866 encoding)
  774. ; in: esi->name, ebp->name
  775. ; out: if names match: ZF=1 and esi->next component of name
  776. ;      else: ZF=0, esi is not changed
  777. ; destroys eax
  778.         push    esi eax edi
  779.         mov     edi, ebp
  780. ;--------------------------------------
  781. .loop:
  782.         cld
  783.         lodsb
  784.         push    eax
  785.         call    char_todown
  786.         call    ansi2uni_char
  787.         xchg    ah, al
  788.         scasw
  789.         pop     eax
  790.         je      .coincides
  791.         call    char_toupper
  792.         call    ansi2uni_char
  793.         xchg    ah, al
  794.         sub     edi, 2
  795.         scasw
  796.         jne     .name_not_coincide
  797. ;--------------------------------------
  798. .coincides:
  799.         cmp     [esi], byte '/' ; path separator is end of current element
  800.         je      .done
  801.  
  802.         cmp     [esi], byte 0 ; path separator end of name
  803.         je      .done
  804.  
  805.         jmp     .loop
  806. ;--------------------------------------
  807. .name_not_coincide:
  808.         pop     edi eax esi
  809.         stc
  810.         ret
  811. ;--------------------------------------
  812. .done:
  813. ; check end of file
  814.         cmp     [edi], word 3B00h; separator end of file ';'
  815.         je      .done_1
  816. ; check for files not ending with separator
  817.         movzx   eax, byte [ebp-33]
  818.         add     eax, ebp
  819.         sub     eax, 34
  820.         cmp     edi, eax
  821.         je      .done_1
  822. ; check the end of directory
  823.         movzx   eax, byte [ebp-1]
  824.         add     eax, ebp
  825.         cmp     edi, eax
  826.         jne     .name_not_coincide
  827. ;--------------------------------------
  828. .done_1:
  829.         pop     edi eax
  830.         add     esp, 4
  831.         inc     esi
  832.         clc
  833.         ret
  834. ;-----------------------------------------------------------------------------
  835. char_todown:
  836. ; convert character to uppercase, using cp866 encoding
  837. ; in: al=symbol
  838. ; out: al=converted symbol
  839.         cmp     al, 'A'
  840.         jb      .ret
  841.  
  842.         cmp     al, 'Z'
  843.         jbe     .az
  844.  
  845.         cmp     al, 0x80 ; 'А'
  846.         jb      .ret
  847.  
  848.         cmp     al, 0x90 ; 'Р'
  849.         jb      .rus1
  850.  
  851.         cmp     al, 0x9F ; 'Я'
  852.         ja      .ret
  853. ; 0x90-0x9F -> 0xE0-0xEF
  854.         add     al, 0xE0-0x90
  855. ;--------------------------------------
  856. .ret:
  857.         ret
  858. ;--------------------------------------
  859. .rus1:
  860. ; 0x80-0x8F -> 0xA0-0xAF
  861. .az:
  862.         add     al, 0x20
  863.         ret
  864. ;-----------------------------------------------------------------------------
  865. uni2ansi_char:
  866. ; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
  867. ; in: ax=UNICODE character
  868. ; out: al=converted ANSI character
  869.         cmp     ax, 0x80
  870.         jb      .ascii
  871.  
  872.         cmp     ax, 0x401
  873.         jz      .yo1
  874.  
  875.         cmp     ax, 0x451
  876.         jz      .yo2
  877.  
  878.         cmp     ax, 0x410
  879.         jb      .unk
  880.  
  881.         cmp     ax, 0x440
  882.         jb      .rus1
  883.  
  884.         cmp     ax, 0x450
  885.         jb      .rus2
  886. ;--------------------------------------
  887. .unk:
  888.         mov     al, '_'
  889.         jmp     .doit
  890. ;--------------------------------------
  891. .yo1:
  892.         mov     al, 0xF0 ; 'Ё' in cp866
  893.         jmp     .doit
  894. ;--------------------------------------
  895. .yo2:
  896.         mov     al, 0xF1 ; 'ё' in cp866
  897.         jmp     .doit
  898. ;--------------------------------------
  899. .rus1:
  900. ; 0x410-0x43F -> 0x80-0xAF
  901.         add     al, 0x70
  902.         jmp     .doit
  903. ;--------------------------------------
  904. .rus2:
  905. ; 0x440-0x44F -> 0xE0-0xEF
  906.         add     al, 0xA0
  907. ;--------------------------------------
  908. .ascii:
  909. .doit:
  910.         ret
  911. ;-----------------------------------------------------------------------------
  912.