Subversion Repositories Kolibri OS

Rev

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

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