Subversion Repositories Kolibri OS

Rev

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