Subversion Repositories Kolibri OS

Rev

Rev 154 | 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,[CURRENT_TASK]
  27.     shl   eax,5
  28.     mov   eax,[eax+CURRENT_TASK+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. uglobal
  69. cd_status dd 0
  70. endg
  71.  
  72. ;----------------------------------------------------------------
  73. ;
  74. ;  fs_CdRead - LFN variant for reading CD disk
  75. ;
  76. ;  esi  points to filename /dir1/dir2/.../dirn/file,0
  77. ;  ebx  pointer to 64-bit number = first wanted byte, 0+
  78. ;       may be ebx=0 - start from first byte
  79. ;  ecx  number of bytes to read, 0+
  80. ;  edx  mem location to return data
  81. ;
  82. ;  ret ebx = bytes read or 0xffffffff file not found
  83. ;      eax = 0 ok read or other = errormsg
  84. ;
  85. ;--------------------------------------------------------------
  86. fs_CdRead:
  87.     push    edi
  88.     cmp    byte [esi], 0
  89.     jnz    @f
  90. .noaccess:
  91.     pop    edi
  92. .noaccess_2:
  93.     or    ebx, -1
  94.     mov    eax, ERROR_ACCESS_DENIED
  95.     ret
  96.  
  97. .noaccess_3:
  98.     pop     eax edx ecx edi
  99.     jmp  .noaccess_2
  100.  
  101. @@:
  102.     call    cd_find_lfn
  103.     jnc    .found
  104.     pop    edi
  105.     cmp   [DevErrorCode],0
  106.     jne   .noaccess_2
  107.     or    ebx, -1
  108.     mov    eax, ERROR_FILE_NOT_FOUND
  109.     ret
  110.  
  111. .found:
  112.     mov    edi,[cd_current_pointer_of_input]
  113.     test   byte [edi+25],10b    ; do not allow read directories
  114.     jnz    .noaccess
  115.     test    ebx, ebx
  116.     jz    .l1
  117.     cmp    dword [ebx+4], 0
  118.     jz    @f
  119.         xor     ebx, ebx
  120. .reteof:
  121.     mov    eax, 6 ; end of file
  122.     pop    edi
  123.     ret
  124. @@:
  125.     mov    ebx, [ebx]
  126. .l1:
  127.         push    ecx edx
  128.         push    0
  129.         mov     eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
  130.         sub     eax, ebx
  131.         jb      .eof
  132.         cmp     eax, ecx
  133.         jae     @f
  134.         mov     ecx, eax
  135.         mov     byte [esp], 6
  136. @@:
  137.      mov    eax,[edi+2]
  138.      mov    [CDSectorAddress],eax
  139. ; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
  140. .new_sector:
  141.     test    ecx, ecx
  142.     jz    .done
  143.     sub    ebx, 2048
  144.     jae    .next
  145.     add    ebx, 2048
  146.     jnz    .incomplete_sector
  147.     cmp    ecx, 2048
  148.     jb    .incomplete_sector
  149. ; we may read and memmove complete sector
  150.     mov  [CDDataBuf_pointer],edx
  151.     call ReadCDWRetr      ; ÷èòàåì ñåêòîð ôàéëà
  152.     cmp   [DevErrorCode],0
  153.     jne   .noaccess_3
  154.     add    edx, 2048
  155.     sub    ecx, 2048
  156. .next:
  157.     inc  dword [CDSectorAddress]
  158.     jmp    .new_sector
  159. .incomplete_sector:
  160. ; we must read and memmove incomplete sector
  161.     mov  [CDDataBuf_pointer],CDDataBuf
  162.     call ReadCDWRetr      ; ÷èòàåì ñåêòîð ôàéëà
  163.     cmp   [DevErrorCode],0
  164.     jne   .noaccess_3
  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.         lea     esi, [CDDataBuf + ebx]
  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    .next
  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.         ja      .read_to_buffer
  259.         mov     edi, [cd_counter_block]
  260.         mov     [edx+8], edi
  261.         mov     edi, [ebx]
  262.         sub     [edx+4], edi
  263.         xor     eax, eax
  264.         dec     ecx
  265.         js      @f
  266.         mov     al, ERROR_END_OF_FILE
  267. @@:
  268.         pop     ecx edi
  269.         mov     ebx, [edx+4]
  270.         ret
  271.  
  272. .get_names_from_buffer:
  273.     mov     [cd_current_pointer_of_input_2],CDDataBuf
  274.     push    eax esi edi edx
  275. .get_names_from_buffer_1:
  276.     call    cd_get_name
  277.     jc    .end_buffer
  278.     inc    dword [cd_counter_block]
  279.     mov    eax,[cd_counter_block]
  280.     cmp    [ebx],eax
  281.     jae     .get_names_from_buffer_1
  282.     test    ecx, ecx
  283.     jz    .get_names_from_buffer_1
  284.     mov   edi,[cd_counter_block]
  285.     mov   [edx+4],edi
  286.     dec     ecx
  287.     mov   esi,ebp
  288.     mov   edi,[cd_mem_location]
  289.     add   edi,40
  290.     test   dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
  291.     jnz    .unicode
  292. ;    jmp  .unicode
  293. .ansi:
  294.     cmp   [cd_counter_block],2
  295.     jbe   .ansi_parent_directory
  296.     cld
  297.     lodsw
  298.     xchg ah,al
  299.     call uni2ansi_char
  300.     cld
  301.     stosb
  302. ; ïðîâåðêà êîíöà ôàéëà
  303.     mov   ax,[esi]
  304.     cmp   ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
  305.     je   .cd_get_parameters_of_file_1
  306. ; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
  307.     movzx   eax,byte [ebp-33]
  308.     add   eax,ebp
  309.     sub   eax,34
  310.     cmp   esi,eax
  311.     je   .cd_get_parameters_of_file_1
  312. ; ïðîâåðêà êîíöà ïàïêè
  313.     movzx   eax,byte [ebp-1]
  314.     add   eax,ebp
  315.     cmp   esi,eax
  316.     jb   .ansi
  317. .cd_get_parameters_of_file_1:
  318.     mov   [edi],byte 0
  319.     call  cd_get_parameters_of_file
  320.     add   [cd_mem_location],304
  321.     jmp   .get_names_from_buffer_1
  322.  
  323. .ansi_parent_directory:
  324.     cmp   [cd_counter_block],2
  325.     je    @f
  326.     mov   [edi],byte '.'
  327.     inc   edi
  328.     jmp  .cd_get_parameters_of_file_1
  329. @@:
  330.     mov   [edi],word '..'
  331.     add   edi,2
  332.     jmp  .cd_get_parameters_of_file_1
  333.  
  334. .unicode:
  335.     cmp   [cd_counter_block],2
  336.     jbe   .unicode_parent_directory
  337.     cld
  338.     movsw
  339. ; ïðîâåðêà êîíöà ôàéëà
  340.     mov   ax,[esi]
  341.     cmp   ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
  342.     je   .cd_get_parameters_of_file_2
  343. ; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
  344.     movzx   eax,byte [ebp-33]
  345.     add   eax,ebp
  346.     sub   eax,34
  347.     cmp   esi,eax
  348.     je   .cd_get_parameters_of_file_2
  349. ; ïðîâåðêà êîíöà ïàïêè
  350.     movzx   eax,byte [ebp-1]
  351.     add   eax,ebp
  352.     cmp   esi,eax
  353.     jb   .unicode
  354. .cd_get_parameters_of_file_2:
  355.     mov   [edi],word 0
  356.     call  cd_get_parameters_of_file
  357.     add   [cd_mem_location],560
  358.     jmp   .get_names_from_buffer_1
  359.  
  360. .unicode_parent_directory:
  361.     cmp   [cd_counter_block],2
  362.     je    @f
  363.     mov   [edi],word 2E00h ; '.'
  364.     add   edi,2
  365.     jmp   .cd_get_parameters_of_file_2
  366. @@:
  367.     mov   [edi],dword 2E002E00h ; '..'
  368.     add   edi,4
  369.     jmp   .cd_get_parameters_of_file_2
  370.  
  371. .end_buffer:
  372.     pop   edx edi esi eax
  373.     ret
  374.  
  375. cd_get_parameters_of_file:
  376.     mov   edi,[cd_mem_location]
  377. cd_get_parameters_of_file_1:
  378. ; ïîëó÷àåì àòðèáóòû ôàéëà
  379.     xor   eax,eax
  380. ; ôàéë íå àðõèâèðîâàëñ
  381.     inc   al
  382.     shl   eax,1
  383. ; ýòî êàòàëîã?
  384.     test  [ebp-8],byte 2
  385.     jz    .file
  386.     inc   al
  387. .file:
  388. ; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
  389. ; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
  390.     shl   eax,3
  391. ; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
  392.     test  [ebp-8],byte 1
  393.     jz    .hidden
  394.     inc   al
  395. .hidden:
  396.     shl   eax,1
  397. ; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
  398.     inc   al
  399.     mov   [edi],eax
  400. ; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
  401. ;÷àñ
  402.     movzx eax,byte [ebp-12]
  403.     shl   eax,8
  404. ;ìèíóòà
  405.     mov   al,[ebp-11]
  406.     shl   eax,8
  407. ;ñåêóíäà
  408.     mov   al,[ebp-10]
  409. ;âðåìÿ ñîçäàíèÿ ôàéëà
  410.     mov   [edi+8],eax
  411. ;âðåìÿ ïîñëåäíåãî äîñòóïà
  412.     mov   [edi+16],eax
  413. ;âðåìÿ ïîñëåäíåé çàïèñè
  414.     mov   [edi+24],eax
  415. ; ïîëó÷àåì äàòó äëÿ ôàéëà
  416. ;ãîä
  417.     movzx eax,byte [ebp-15]
  418.     add   eax,1900
  419.     shl   eax,8
  420. ;ìåñÿö
  421.     mov   al,[ebp-14]
  422.     shl   eax,8
  423. ;äåíü
  424.     mov   al,[ebp-13]
  425. ;äàòà ñîçäàíèÿ ôàéëà
  426.     mov   [edi+12],eax
  427. ;âðåìÿ ïîñëåäíåãî äîñòóïà
  428.     mov   [edi+20],eax
  429. ;âðåìÿ ïîñëåäíåé çàïèñè
  430.     mov   [edi+28],eax
  431. ; ïîëó÷àåì òèï äàííûõ èìåíè
  432.     xor   eax,eax
  433.     test   dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
  434.     jnz    .unicode_1
  435.     mov    [edi+4],eax
  436.     jmp   @f
  437. .unicode_1:
  438.     inc    eax
  439.     mov    [edi+4],eax
  440. @@:
  441. ; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
  442.     xor   eax,eax
  443.     mov   [edi+32+4],eax
  444.     mov   eax,[ebp-23]
  445.     mov   [edi+32],eax
  446.     ret
  447.  
  448. ;----------------------------------------------------------------
  449. ;
  450. ;  fs_CdGetFileInfo - LFN variant for CD
  451. ;                     get file/directory attributes structure
  452. ;
  453. ;----------------------------------------------------------------
  454. fs_CdGetFileInfo:
  455.         cmp     byte [esi], 0
  456.         jnz     @f
  457.         mov     eax, 2
  458.         ret
  459. @@:
  460.         push    edi ebp
  461.         call    cd_find_lfn
  462.         pushfd
  463.         cmp     [DevErrorCode], 0
  464.         jz      @f
  465.         popfd
  466.         pop     ebp edi
  467.         mov     eax, 11
  468.         ret
  469. @@:
  470.         popfd
  471.         jnc     @f
  472.         pop     ebp edi
  473.         mov     eax, ERROR_FILE_NOT_FOUND
  474.         ret
  475. @@:
  476.  
  477.         mov     edi, edx
  478.         call    cd_get_parameters_of_file_1
  479.         and     dword [edi+4], 0
  480.         pop     ebp edi
  481.         xor     eax, eax
  482.         ret
  483.  
  484. ;----------------------------------------------------------------
  485. ;
  486. ;  fs_CdExecute - LFN variant for executing from CD
  487. ;
  488. ;  esi  points to hd filename (e.g. 'dir1/name')
  489. ;  ebp  points to full filename (e.g. '/hd0/1/dir1/name')
  490. ;  dword [ebx] = flags
  491. ;  dword [ebx+4] = cmdline
  492. ;
  493. ;  ret ebx,edx destroyed
  494. ;      eax > 0 - PID, < 0 - error
  495. ;
  496. ;--------------------------------------------------------------
  497. fs_CdExecute:
  498.         mov     edx, [ebx]
  499.         mov     ebx, [ebx+4]
  500.         test    ebx, ebx
  501.         jz      @f
  502.         add     ebx, std_application_base_address
  503. @@:
  504.  
  505. ;----------------------------------------------------------------
  506. ;
  507. ; fs_CdExecute.flags - second entry
  508. ;
  509. ;  esi  points to floppy filename (kernel address)
  510. ;  ebp  points to full filename
  511. ;  edx  flags
  512. ;  ebx  cmdline (kernel address)
  513. ;
  514. ;  ret  eax > 0 - PID, < 0 - error
  515. ;
  516. ;--------------------------------------------------------------
  517.  
  518. .flags:
  519.         cmp     byte [esi], 0
  520.         jnz     @f
  521. ; cannot execute root!
  522.         mov     eax, -ERROR_ACCESS_DENIED
  523.         ret
  524. @@:
  525.         push    edi
  526.         call    cd_find_lfn
  527.         jnc     .found
  528.         pop     edi
  529.         mov     eax, -ERROR_FILE_NOT_FOUND
  530.         cmp     [DevErrorCode], 0
  531.         jz      @f
  532.         mov     al, -11
  533. @@:
  534.         ret
  535. .found:
  536.         mov     edi,[cd_current_pointer_of_input]
  537.         mov    eax,[edi+2]
  538.         push    0
  539.         push    eax
  540.         push    dword [edi+10]          ; size
  541.         push    .DoRead
  542.         call    fs_execute
  543.         add     esp, 16
  544.         pop     edi
  545.         ret
  546.  
  547. .DoRead:
  548. ; read next block
  549. ; in: eax->parameters, edi->buffer
  550. ; out: eax = error code
  551.         pushad
  552.         cmp     dword [eax], 0  ; file size
  553.         jz      .eof
  554.         cmp     [eax+8],dword 0
  555.         jne     @f
  556.         mov     ecx,[eax+4]
  557.         inc     dword [eax+4]
  558.         mov     [CDSectorAddress],ecx
  559.         mov     [CDDataBuf_pointer],CDDataBuf  ;edi
  560.         call    ReadCDWRetr
  561.         cmp     [DevErrorCode], 0
  562.         jnz     .err
  563. @@:
  564.         push    esi edi ecx
  565.         mov     esi,512
  566.         imul    esi,[eax+8]
  567.         add     esi,CDDataBuf
  568.         mov     ecx,512/4
  569.         cld
  570.         rep     movsd
  571.         pop     ecx edi esi
  572.  
  573.         mov     eax, [esp+28]
  574.         mov     ecx, [eax]
  575.         sub     ecx, 512
  576.         jae     @f
  577.         lea     edi, [edi+ecx+512]
  578.         neg     ecx
  579.         push    eax
  580.         xor     eax, eax
  581.         rep     stosb
  582.         pop     eax
  583. @@:
  584.         mov     [eax], ecx
  585.         mov     edx, [eax+8]
  586.         inc     edx
  587.         cmp     edx, 4  ; 2048/512=4
  588.         jb      @f
  589.         xor     edx, edx
  590. @@:
  591.         mov     [eax+8], edx
  592.         popad
  593.         xor     eax, eax
  594.         ret
  595. .eof:
  596.         popad
  597.         mov     eax, 6
  598.         ret
  599. .err:
  600.         popad
  601.         mov     eax, 11
  602.         ret
  603.  
  604. cd_find_lfn:
  605. ; in: esi->name
  606. ; out: CF=1 - file not found
  607. ;      else CF=0 and [cd_current_pointer_of_input] direntry
  608.         push eax esi
  609. ; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
  610.         mov  [CDSectorAddress],dword 15
  611. .start:
  612.         inc  dword [CDSectorAddress]
  613.        mov  [CDDataBuf_pointer],CDDataBuf
  614.        call  ReadCDWRetr
  615.        cmp   [DevErrorCode],0
  616.        jne   .access_denied
  617. ; ïðîâåðêà íà âøèâîñòü
  618.         cmp  [CDDataBuf+1],dword 'CD00'
  619.         jne  .access_denied
  620.         cmp  [CDDataBuf+5],byte '1'
  621.         jne  .access_denied
  622. ; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
  623.         cmp  [CDDataBuf],byte 0xff
  624.         je  .access_denied
  625. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
  626.         cmp  [CDDataBuf],byte 0x2
  627.         jne  .start
  628. ; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
  629.         cmp  [CDDataBuf+6],byte 0x1
  630.         jne  .start
  631. ; ïàðàìåòðû root äèðåêòðîðèè
  632.         mov  eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
  633.         mov  [CDSectorAddress],eax
  634.         mov  eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
  635.         cmp    byte [esi], 0
  636.         jnz    @f
  637.         mov   [cd_current_pointer_of_input],CDDataBuf+0x9c
  638.         jmp   .done
  639. @@:
  640. ; íà÷èíàåì ïîèñê
  641. .mainloop:
  642.         dec  dword [CDSectorAddress]
  643. .read_to_buffer:
  644.         inc  dword [CDSectorAddress]
  645.         mov  [CDDataBuf_pointer],CDDataBuf
  646.         call ReadCDWRetr         ; ÷èòàåì ñåêòîð äèðåêòîðèè
  647.         cmp   [DevErrorCode],0
  648.         jne   .access_denied
  649.         call cd_find_name_in_buffer
  650.         jnc    .found
  651.         sub  eax,2048
  652. ; äèðåêòîðèÿ çàêîí÷èëàñü?
  653.         cmp  eax,0
  654.         ja   .read_to_buffer
  655. ; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
  656. .access_denied:
  657.         pop  esi eax
  658.         stc
  659.         ret
  660. ; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
  661.   .found:
  662. ; êîíåö ïóòè ôàéëà
  663.         cmp    byte [esi-1], 0
  664.         jz    .done
  665.         mov    eax,[cd_current_pointer_of_input]
  666.         push    dword [eax+2]
  667.         pop     dword [CDSectorAddress]       ; íà÷àëî äèðåêòîðèè
  668.         mov    eax,[eax+2+8]  ; ðàçìåð äèðåêòîðèè
  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.