Subversion Repositories Kolibri OS

Rev

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

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