Subversion Repositories Kolibri OS

Rev

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