Subversion Repositories Kolibri OS

Rev

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

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