Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | 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
  478.         pop     ebp edi
  479.         xor     eax, eax
  480.         ret
  481.  
  482. ;----------------------------------------------------------------
  483. ;
  484. ;  fs_CdExecute - LFN variant for executing from CD
  485. ;
  486. ;  esi  points to hd filename (e.g. 'dir1/name')
  487. ;  ebp  points to full filename (e.g. '/hd0/1/dir1/name')
  488. ;  dword [ebx] = flags
  489. ;  dword [ebx+4] = cmdline
  490. ;
  491. ;  ret ebx,edx destroyed
  492. ;      eax > 0 - PID, < 0 - error
  493. ;
  494. ;--------------------------------------------------------------
  495. fs_CdExecute:
  496.         mov     edx, [ebx]
  497.         mov     ebx, [ebx+4]
  498.         test    ebx, ebx
  499.         jz      @f
  500.         add     ebx, std_application_base_address
  501. @@:
  502.  
  503. ;----------------------------------------------------------------
  504. ;
  505. ; fs_CdExecute.flags - second entry
  506. ;
  507. ;  esi  points to floppy filename (kernel address)
  508. ;  ebp  points to full filename
  509. ;  edx  flags
  510. ;  ebx  cmdline (kernel address)
  511. ;
  512. ;  ret  eax > 0 - PID, < 0 - error
  513. ;
  514. ;--------------------------------------------------------------
  515.  
  516. .flags:
  517.         cmp     byte [esi], 0
  518.         jnz     @f
  519. ; cannot execute root!
  520.         mov     eax, -ERROR_ACCESS_DENIED
  521.         ret
  522. @@:
  523.         push    edi
  524.         call    cd_find_lfn
  525.         jnc     .found
  526.         pop     edi
  527.         mov     eax, -ERROR_FILE_NOT_FOUND
  528.         cmp     [DevErrorCode], 0
  529.         jz      @f
  530.         mov     al, -11
  531. @@:
  532.         ret
  533. .found:
  534.         mov     edi,[cd_current_pointer_of_input]
  535.         mov    eax,[edi+2]
  536.         push    0
  537.         push    eax
  538.         push    dword [edi+10]          ; size
  539.         push    .DoRead
  540.         call    fs_execute
  541.         add     esp, 16
  542.         pop     edi
  543.         ret
  544.  
  545. .DoRead:
  546. ; read next block
  547. ; in: eax->parameters, edi->buffer
  548. ; out: eax = error code
  549.         pushad
  550.         cmp     dword [eax], 0  ; file size
  551.         jz      .eof
  552.         cmp     [eax+8],dword 0
  553.         jne     @f
  554.         mov     ecx,[eax+4]
  555.         inc     dword [eax+4]
  556.         mov     [CDSectorAddress],ecx
  557.         mov     [CDDataBuf_pointer],CDDataBuf  ;edi
  558.         call    ReadCDWRetr
  559.         cmp     [DevErrorCode], 0
  560.         jnz     .err
  561. @@:
  562.         push    esi edi ecx
  563.         mov     esi,512
  564.         imul    esi,[eax+8]
  565.         add     esi,CDDataBuf  
  566.         mov     ecx,512/4
  567.         cld
  568.         rep     movsd
  569.         pop     ecx edi esi
  570.  
  571.         mov     eax, [esp+28]
  572.         mov     ecx, [eax]
  573.         sub     ecx, 512
  574.         jae     @f
  575.         lea     edi, [edi+ecx+512]
  576.         neg     ecx
  577.         push    eax
  578.         xor     eax, eax
  579.         rep     stosb
  580.         pop     eax
  581. @@:
  582.         mov     [eax], ecx
  583.         mov     edx, [eax+8]
  584.         inc     edx
  585.         cmp     edx, 4  ; 2048/512=4
  586.         jb      @f
  587.         xor     edx, edx
  588. @@:
  589.         mov     [eax+8], edx
  590.         popad
  591.         xor     eax, eax
  592.         ret
  593. .eof:
  594.         popad
  595.         mov     eax, 6
  596.         ret
  597. .err:
  598.         popad
  599.         mov     eax, 11
  600.         ret        
  601.  
  602. cd_find_lfn:
  603. ; in: esi->name
  604. ; out: CF=1 - file not found
  605. ;      else CF=0 and [cd_current_pointer_of_input] direntry
  606.         push eax esi
  607. ; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
  608.         mov  [CDSectorAddress],dword 15
  609. .start:
  610.         inc  dword [CDSectorAddress]
  611.        mov  [CDDataBuf_pointer],CDDataBuf
  612.        call  ReadCDWRetr
  613.        cmp   [DevErrorCode],0
  614.        jne   .access_denied
  615. ; ïðîâåðêà íà âøèâîñòü
  616.         cmp  [CDDataBuf+1],dword 'CD00'
  617.         jne  .access_denied
  618.         cmp  [CDDataBuf+5],byte '1'
  619.         jne  .access_denied
  620. ; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
  621.         cmp  [CDDataBuf],byte 0xff
  622.         je  .access_denied        
  623. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
  624.         cmp  [CDDataBuf],byte 0x2
  625.         jne  .start
  626. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
  627.         cmp  [CDDataBuf+6],byte 0x1
  628.         jne  .start
  629. ; ïàðàìåòðû root äèðåêòðîðèè
  630.         mov  eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
  631.         mov  [CDSectorAddress],eax
  632.         mov  eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
  633.         cmp    byte [esi], 0
  634.         jnz    @f
  635.         mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
  636.         jmp   .done
  637. @@:
  638. ; íà÷èíàåì ïîèñê
  639. .mainloop:
  640.         dec  dword [CDSectorAddress]
  641. .read_to_buffer:
  642.         inc  dword [CDSectorAddress]
  643.         mov  [CDDataBuf_pointer],CDDataBuf
  644.         call ReadCDWRetr         ; ÷èòàåì ñåêòîð äèðåêòîðèè
  645.         cmp   [DevErrorCode],0
  646.         jne   .access_denied
  647.         call cd_find_name_in_buffer
  648.         jnc    .found
  649.         sub  eax,2048
  650. ; äèðåêòîðèÿ çàêîí÷èëàñü?
  651.         cmp  eax,0
  652.         ja   .read_to_buffer
  653. ; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
  654. .access_denied:
  655.         pop  esi eax
  656.         stc
  657.         ret
  658. ; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
  659.   .found:
  660. ; êîíåö ïóòè ôàéëà
  661.         cmp    byte [esi-1], 0
  662.         jz    .done
  663.         mov    eax,[cd_current_pointer_of_input]
  664.         add    eax,2
  665.         mov    eax,[eax]
  666.         mov    [CDSectorAddress],eax ; íà÷àëî äèðåêòîðèè
  667.         add    eax,8
  668.         mov    eax,[eax]  ; ðàçìåð äèðåêòîðèè
  669.         jmp    .mainloop
  670. ; óêàçàòåëü ôàéëà íàéäåí
  671.    .done:
  672.         pop  esi eax
  673.         clc
  674.         ret
  675.        
  676. cd_find_name_in_buffer:
  677.         mov     [cd_current_pointer_of_input_2],CDDataBuf
  678. .start:
  679.         call    cd_get_name
  680.         jc    .not_found
  681.         call    cd_compare_name
  682.         jc    .start
  683. .found:
  684.         clc
  685.         ret  
  686. .not_found:
  687.         stc
  688.         ret
  689.  
  690. cd_get_name:
  691.         push eax
  692.         mov   ebp,[cd_current_pointer_of_input_2]
  693.         mov   [cd_current_pointer_of_input],ebp
  694.         mov   eax,[ebp]
  695.         cmp   eax,0   ; âõîäû çàêîí÷èëèñü?
  696.         je    .next_sector
  697.         cmp   ebp,CDDataBuf+2048     ; áóôåð çàêîí÷èëñÿ?
  698.         jae   .next_sector
  699.         movzx eax, byte [ebp]
  700.         add   [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
  701.         add   ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
  702.         pop   eax
  703.         clc
  704.         ret
  705. .next_sector:
  706.         pop  eax
  707.         stc
  708.         ret
  709.  
  710. cd_compare_name:
  711. ; compares ASCIIZ-names, case-insensitive (cp866 encoding)
  712. ; in: esi->name, ebp->name
  713. ; out: if names match: ZF=1 and esi->next component of name
  714. ;      else: ZF=0, esi is not changed
  715. ; destroys eax
  716.     push    esi eax edi
  717.     mov     edi,ebp
  718. .loop:
  719.     cld
  720.     lodsb
  721.     push ax
  722.     call char_todown
  723.     call ansi2uni_char
  724.     xchg ah,al
  725.     cld
  726.     scasw
  727.     pop  ax
  728.     je    .coincides
  729.     call char_toupper
  730.     call ansi2uni_char
  731.     xchg ah,al
  732.     cld  
  733.     sub  edi,2
  734.     scasw
  735.     jne   .name_not_coincide
  736. .coincides:
  737.     cmp   [esi],byte '/'  ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
  738.     je   .done
  739.     cmp   [esi],byte 0  ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
  740.     je   .done
  741.     jmp   .loop
  742. .name_not_coincide:
  743.     pop    edi eax esi
  744.     stc
  745.     ret
  746. .done:
  747. ; ïðîâåðêà êîíöà ôàéëà
  748.     cmp   [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
  749.     je   .done_1
  750. ; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
  751.     movzx   eax,byte [ebp-33]
  752.     add   eax,ebp
  753.     sub   eax,34
  754.     cmp   edi,eax
  755.     je   .done_1
  756. ; ïðîâåðêà êîíöà ïàïêè
  757.     movzx   eax,byte [ebp-1]
  758.     add   eax,ebp
  759.     cmp   edi,eax
  760.     jne   .name_not_coincide
  761. .done_1:
  762.     pop   edi eax
  763.     add   esp,4
  764.     inc   esi
  765.     clc
  766.     ret
  767.    
  768. char_todown:
  769. ; convert character to uppercase, using cp866 encoding
  770. ; in: al=symbol
  771. ; out: al=converted symbol
  772.         cmp     al, 'A'
  773.         jb      .ret
  774.         cmp     al, 'Z'
  775.         jbe     .az
  776.         cmp     al, '€'
  777.         jb      .ret
  778.         cmp     al, ''
  779.         jb      .rus1
  780.         cmp     al, 'Ÿ'
  781.         ja      .ret
  782. ; 0x90-0x9F -> 0xE0-0xEF
  783.         add     al, 'à'-''
  784. .ret:
  785.         ret
  786. .rus1:
  787. ; 0x80-0x8F -> 0xA0-0xAF
  788. .az:
  789.         add     al, 0x20
  790.         ret
  791.        
  792. uni2ansi_char:
  793. ; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
  794. ; in: ax=UNICODE character
  795. ; out: al=converted ANSI character
  796.         cmp     ax, 0x80
  797.         jb      .ascii
  798.         cmp     ax, 0x401
  799.         jz      .yo1
  800.         cmp     ax, 0x451
  801.         jz      .yo2
  802.         cmp     ax, 0x410
  803.         jb      .unk
  804.         cmp     ax, 0x440
  805.         jb      .rus1
  806.         cmp     ax, 0x450
  807.         jb      .rus2
  808. .unk:
  809.         mov     al, '_'
  810.         jmp     .doit
  811. .yo1:
  812.         mov     al, 'ð'
  813.         jmp     .doit
  814. .yo2:
  815.         mov     al, 'ñ'
  816.         jmp     .doit
  817. .rus1:
  818. ; 0x410-0x43F -> 0x80-0xAF
  819.         add     al, 0x70
  820.         jmp     .doit
  821. .rus2:
  822. ; 0x440-0x44F -> 0xE0-0xEF
  823.         add     al, 0xA0
  824. .ascii:
  825. .doit:
  826.         ret
  827.