Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ; Copyright (c) 2008-2009, diamond
  2. ; All rights reserved.
  3. ;
  4. ; Redistribution and use in source and binary forms, with or without
  5. ; modification, are permitted provided that the following conditions are met:
  6. ;       * Redistributions of source code must retain the above copyright
  7. ;       notice, this list of conditions and the following disclaimer.
  8. ;       * Redistributions in binary form must reproduce the above copyright
  9. ;       notice, this list of conditions and the following disclaimer in the
  10. ;       documentation and/or other materials provided with the distribution.
  11. ;       * Neither the name of the <organization> nor the
  12. ;       names of its contributors may be used to endorse or promote products
  13. ;       derived from this software without specific prior written permission.
  14. ;
  15. ; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
  16. ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. ; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
  19. ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. ;*****************************************************************************
  26.  
  27. restore_usa:
  28. ; Update Sequence Array restore
  29. ; in: ds:bx -> USA-protected structure
  30.         push    bx
  31.         lea     di, [bx+1feh]
  32.         mov     cx, [bx+6]
  33.         add     bx, [bx+4]
  34.         dec     cx
  35. @@:
  36.         mov     ax, [bx+2]
  37.         mov     [di], ax
  38.         inc     bx
  39.         inc     bx
  40.         add     di, 200h
  41.         loop    @b
  42.         pop     bx
  43.         ret
  44.  
  45. find_attr:
  46. ; in: ds:di->file record, ax=attribute
  47. ; out: ds:di->attribute or di=0 if not found
  48.         add     di, [di+14h]
  49. .1:
  50. ; attributes' codes are formally dwords, but all of them fit in word
  51.         cmp     word [di], -1
  52.         jz      .notfound
  53.         cmp     word [di], ax
  54.         jnz     .continue
  55. ; for $DATA attribute, scan only unnamed
  56.         cmp     ax, 80h
  57.         jnz     .found
  58.         cmp     byte [di+9], 0
  59.         jz      .found
  60. .continue:
  61.         add     di, [di+4]
  62.         jmp     .1
  63. .notfound:
  64.         xor     di, di
  65. .found:
  66.         ret
  67.  
  68. process_mcb_nonres:
  69. ; in: ds:si->attribute, es:di->buffer
  70. ; out: es:di->buffer end
  71.         pushad
  72.         pop     di
  73.         add     si, [si+20h]
  74.         xor     ebx, ebx
  75. .loop:
  76.         lodsb
  77.         test    al, al
  78.         jz      .done
  79.         push    invalid_read_request_string
  80.         movzx   cx, al
  81.         shr     cx, 4
  82.         jz      find_error_sp
  83.         xchg    ax, dx
  84.         and     dx, 0Fh
  85.         jz      find_error_sp
  86.         add     si, cx
  87.         add     si, dx
  88.         pop     ax
  89.         push    si
  90.         dec     si
  91.         movsx   eax, byte [si]
  92.         dec     cx
  93.         jz      .l1e
  94. .l1:
  95.         dec     si
  96.         shl     eax, 8
  97.         mov     al, [si]
  98.         loop    .l1
  99. .l1e:
  100.         xchg    ebp, eax
  101.         dec     si
  102.         movsx   eax, byte [si]
  103.         mov     cx, dx
  104.         dec     cx
  105.         jz      .l2e
  106. .l2:
  107.         dec     si
  108.         shl     eax, 8
  109.         mov     al, byte [si]
  110.         loop    .l2
  111. .l2e:
  112.         pop     si
  113.         add     ebx, ebp
  114. ; eax=length, ebx=disk block
  115.         stosd
  116.         mov     eax, ebx
  117.         stosd
  118.         cmp     di, 0x8000 - 12
  119.         jbe     .loop
  120. ..attr_overflow:
  121.         mov     si, fragmented_string
  122.         jmp     find_error_si
  123. .done:
  124.         xor     ax, ax
  125.         stosw
  126.         stosw
  127.         push    di
  128.         popad
  129.         ret
  130.  
  131. load_attr:
  132. ; in: ax=attribute, ds:bx->base record
  133. ; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated,
  134. ;       edx=size of attribute in bytes
  135. ; out: if not found: CF=1
  136.         mov     di, [bp + freeattr - dat]
  137.         push    ss
  138.         pop     es
  139.         mov     byte [es:di], 1
  140.         inc     di
  141.         cmp     di, 0x8000 - 12
  142.         ja      ..attr_overflow
  143.         or      edx, -1         ; file size is not known yet
  144. ; scan for attribute
  145.         push    di
  146.         mov     di, bx
  147.         add     di, [di+14h]
  148. @@:
  149.         call    find_attr.1
  150.         test    di, di
  151.         jz      .notfound1
  152.         cmp     byte [di+8], 0
  153.         jnz     .nonresident
  154.         mov     si, di
  155.         pop     di
  156.         push    ds
  157.         jmp     .resident
  158. .aux_resident:
  159.         mov     ax, ds
  160.         mov     si, di
  161.         pop     di ds bx ds edx
  162.         push    ss
  163.         pop     es
  164.         push    ds
  165.         mov     ds, ax
  166. ; resident attribute
  167. .resident:
  168.         dec     di
  169.         mov     al, 0
  170.         stosb
  171.         mov     ax, [si+10h]
  172.         stosw
  173.         push    di
  174.         add     di, ax
  175.         cmp     di, 0x8000 - 12
  176.         pop     di
  177.         ja      ..attr_overflow
  178.         movzx   edx, ax         ; length of attribute
  179.         xchg    ax, cx
  180.         add     si, [si+14h]
  181.         rep     movsb
  182.         mov     [bp + freeattr - dat], di
  183.         pop     ds
  184.         ret
  185. .nonresident:
  186. ; nonresident attribute
  187.         cmp     dword [di+10h], 0
  188.         jnz     @b
  189. ; read start of data
  190.         mov     si, di
  191.         mov     edx, [di+30h]   ; size of attribute
  192.         pop     di
  193.         call    process_mcb_nonres
  194.         sub     di, 4
  195.         push    di
  196. .notfound1:
  197.         pop     di
  198.         push    edx
  199. ; $ATTRIBUTE_LIST is always in base file record
  200.         cmp     ax, 20h
  201.         jz      .nofragmented
  202. ; try to load $ATTRIBUTE_LIST = 20h
  203.         push    ax
  204.         mov     ax, 20h
  205.         push    [bp + freeattr - dat]
  206.         mov     [bp + freeattr - dat], di
  207.         push    di
  208.         call    load_attr
  209.         pop     di
  210.         pop     [bp + freeattr - dat]
  211.         pop     ax
  212.         jc      .nofragmented
  213.         push    ds bx
  214.         pusha
  215.         mov     si, di
  216.         push    ss
  217.         pop     ds
  218.         push    0x8100
  219.         pop     es
  220.         xor     ecx, ecx
  221.         mov     cl, 0x78
  222.         xor     bx, bx
  223.         push    es
  224.         call    read_file_chunk
  225.         pop     ds
  226.         jc      ..found_disk_error
  227.         test    cx, cx
  228.         jz      ..attr_overflow
  229.         popa
  230.         push    ss
  231.         pop     es
  232.         xor     bx, bx
  233. .1:
  234.         cmp     [bx], ax
  235.         jnz     .continue1
  236. ; only unnamed $DATA attributes!
  237.         cmp     ax, 80h
  238.         jnz     @f
  239.         cmp     byte [bx+6], 0
  240.         jnz     .continue1
  241. @@:
  242.         cmp     dword [bx+10h], 0
  243.         jz      .continue1
  244.         cmp     dword [bx+8], 0
  245.         jnz     @f
  246.         dec     di
  247.         cmp     di, [bp + freeattr - dat]
  248.         lea     di, [di+1]
  249.         jnz     .continue1
  250. @@:
  251.         push    ds di
  252.         push    ax
  253.         mov     eax, [bx+10h]
  254.         mov     ecx, [bx+8]
  255.         call    read_file_record
  256.         pop     ax
  257.         mov     di, [14h]
  258. .2:
  259.         call    find_attr.1
  260.         cmp     byte [di+8], 0
  261.         jz      .aux_resident
  262.         cmp     dword [di+10h], ecx
  263.         jnz     .2
  264.         mov     si, di
  265.         mov     di, sp
  266.         cmp     dword [ss:di+8], -1
  267.         jnz     @f
  268.         push    dword [si+30h]  ; size of attribute
  269.         pop     dword [ss:di+8]
  270. @@:
  271.         pop     di
  272.         call    process_mcb_nonres
  273.         sub     di, 4
  274.         pop     ds
  275. .continue1:
  276.         add     bx, [bx+4]
  277.         cmp     bx, dx
  278.         jb      .1
  279.         pop     bx ds
  280. .nofragmented:
  281.         pop     edx
  282.         dec     di
  283.         cmp     di, [bp + freeattr - dat]
  284.         jnz     @f
  285.         stc
  286.         ret
  287. @@:
  288.         inc     di
  289.         xor     ax, ax
  290.         stosw
  291.         stosw
  292.         mov     [bp + freeattr - dat], di
  293.         ret
  294.  
  295. read_file_record:
  296. ; in: eax = index of record
  297. ; out: ds:0 -> record
  298. ; find place in cache
  299.         push    di
  300.         push    si
  301.         mov     si, cache1head
  302.         call    cache_lookup
  303.         pop     si
  304.         pushf
  305.         sub     di, 3400h
  306.         shl     di, 10-3
  307.         add     di, 0x6000
  308.         mov     ds, di
  309.         popf
  310.         pop     di
  311.         jnc     .noread
  312. ; read file record <eax> to ds:0
  313.         pushad
  314.         push    ds
  315.         push    es
  316.         movzx   ecx, [bp + frs_size - dat]
  317.         shr     cx, 9
  318.         mul     ecx
  319.         push    ds
  320.         pop     es
  321.         push    ss
  322.         pop     ds
  323.         mov     si, 0x4000
  324.         xor     bx, bx
  325.         push    [bp + cur_obj - dat]
  326.         mov     [bp + cur_obj - dat], mft_string
  327.         push    es
  328.         call    read_attr
  329. ; initialize cache for $INDEX_ALLOCATION for this record
  330.         pop     si
  331.         push    si
  332.         sub     si, 0x6000
  333.         mov     ax, si
  334.         shr     si, 10-3
  335.         shr     ax, 2
  336.         add     si, 3480h
  337.         add     ax, 3500h
  338.         mov     [si], si
  339.         mov     [si+2], si
  340.         mov     [si+4], ax
  341.         pop     ds
  342.         call    restore_usa
  343.         pop     [bp + cur_obj - dat]
  344.         pop     es
  345.         pop     ds
  346.         popad
  347. .noread:
  348.         ret
  349.  
  350. read_attr:
  351. ; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute
  352.         push    invalid_read_request_string
  353.         cmp     byte [si], 0
  354.         jnz     .nonresident
  355.         cmp     eax, 10000h shr 9
  356.         jae     find_error_sp
  357.         shl     ax, 9
  358.         shl     cx, 9
  359.         cmp     ax, [si+2]
  360.         jae     find_error_sp
  361.         cmp     cx, [si+2]
  362.         ja      find_error_sp
  363.         add     si, 3
  364.         add     si, ax
  365.         mov     di, bx
  366.         rep     movsb
  367.         pop     ax
  368.         ret
  369. .nonresident:
  370.         inc     si
  371. .loop:
  372.         mov     edx, dword [si]
  373.         add     si, 8
  374.         test    edx, edx
  375.         jz      find_error_sp
  376.         imul    edx, [bp + sect_per_clust - dat]
  377.         sub     eax, edx
  378.         jnc     .loop
  379.         add     eax, edx
  380.         sub     edx, eax
  381.         push    cx
  382.         cmp     ecx, edx
  383.         jb      @f
  384.         mov     cx, dx
  385. @@:
  386.         push    bx
  387.         mov     ebx, [si-4]
  388.         imul    ebx, [bp + sect_per_clust - dat]
  389.         add     eax, ebx
  390.         pop     bx
  391.         call    read
  392.         jc      ..found_disk_error
  393.         mov     dx, cx
  394.         pop     cx
  395.         xor     eax, eax
  396.         sub     cx, dx
  397.         jnz     .loop
  398.         pop     ax
  399.         ret
  400.  
  401. load_file_ntfs:
  402. ; in: ss:bp = 0:dat
  403. ; in: es:bx = address to load file
  404. ; in: ds:si -> ASCIIZ name
  405. ; in: cx = limit in sectors
  406. ; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found
  407. ; out: dx:ax = file size (0xFFFFFFFF if file not found)
  408.         push    es bx cx
  409.         mov     eax, 5          ; root cluster
  410.         mov     [bp + cur_obj - dat], root_string
  411. .parse_dir_loop:
  412.         push    ds si
  413.         call    read_file_record
  414. ; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
  415.         mov     ax, [bp + freeattr - dat]
  416.         mov     [bp + index_root - dat], ax
  417.         mov     ax, 90h         ; $INDEX_ROOT
  418.         xor     bx, bx
  419.         call    load_attr
  420.         mov     si, noindex_string
  421.         jc      find_error_si
  422.         mov     ax, [bp + freeattr - dat]
  423.         mov     [bp + index_alloc - dat], ax
  424.         mov     ax, 0A0h        ; $INDEX_ALLOCATION
  425.         call    load_attr
  426.         jnc     @f
  427.         mov     [bp + index_alloc - dat], bx
  428. @@:
  429.         push    ds
  430. ; search for entry
  431.         mov     si, [bp + index_root - dat]
  432.         push    ss
  433.         pop     ds
  434.         push    0x8100
  435.         pop     es
  436.         xor     ecx, ecx
  437.         mov     cl, 0x78
  438.         xor     bx, bx
  439.         push    es
  440.         call    read_file_chunk
  441.         pop     ds
  442.         jc      ..found_disk_error
  443.         test    cx, cx
  444.         jz      ..attr_overflow
  445.         mov     si, invalid_read_request_string
  446.         cmp     word [bx+10], 0
  447.         jnz     find_error_si
  448. ; calculate number of items in cache
  449.         mov     di, [bx+8]      ; subnode_size
  450.         mov     ax, 0x4000
  451.         sub     ax, word [bp + frs_size - dat]
  452.         cwd
  453.         div     di
  454.         test    ax, ax
  455.         jz      find_error_si
  456.         mov     si, invalid_volume_msg
  457.         test    di, 0x1FF
  458.         jnz     find_error_si
  459.         pop     cx
  460.         mov     [bp + cur_index_seg - dat], cx
  461.         shl     ax, 3
  462.         sub     cx, 6000h
  463.         mov     si, cx
  464.         shr     cx, 2
  465.         shr     si, 10-3
  466.         add     cx, ax
  467.         add     si, 3480h
  468.         mov     [bp + cur_index_cache - dat], si
  469.         add     cx, 3500h
  470.         mov     [ss:si+6], cx
  471.         mov     dx, di
  472.         add     bx, 10h
  473. .scan_record:
  474.         add     bx, [bx]
  475. .scan:
  476.         test    byte [bx+0Ch], 2
  477.         jnz     .look_child
  478.         movzx   cx, byte [bx+50h]       ; namelen
  479.         lea     di, [bx+52h]            ; name
  480.         push    ds
  481.         pop     es
  482.         pop     si ds
  483.         push    ds si
  484.         xor     ax, ax
  485. .1:
  486.         lodsb
  487.         cmp     al, '/'
  488.         jnz     @f
  489.         mov     al, 0
  490. @@:
  491.         cmp     al, 'A'
  492.         jb      .nocapital
  493.         cmp     al, 'Z'
  494.         ja      .nocapital
  495.         or      al, 20h
  496. .nocapital:
  497.         cmp     al, 'a'
  498.         jb      .notletter
  499.         cmp     al, 'z'
  500.         ja      .notletter
  501.         or      byte [es:di], 20h
  502. .notletter:
  503.         scasw
  504.         loopz   .1
  505.         jb      .look_child
  506.         ja      @f
  507.         cmp     byte [si], 0
  508.         jz      .file_found
  509.         cmp     byte [si], '/'
  510.         jz      .file_found
  511. @@:
  512.         push    es
  513.         pop     ds
  514.         add     bx, [bx+8]
  515.         jmp     .scan
  516. .look_child:
  517.         push    es
  518.         pop     ds
  519.         test    byte [bx+0Ch], 1
  520.         jz      .not_found
  521.         mov     si, [bp + index_alloc - dat]
  522.         test    si, si
  523.         jz      .not_found
  524.         add     bx, [bx+8]
  525.         mov     eax, [bx-8]
  526.         mov     es, [bp + cur_index_seg - dat]
  527.         push    si
  528.         mov     si, [bp + cur_index_cache - dat]
  529.         call    cache_lookup
  530.         pop     si
  531.         pushf
  532.         mov     bx, di
  533.         mov     bh, 0
  534.         shr     bx, 3
  535.         imul    bx, dx
  536.         add     bx, [bp + frs_size - dat]
  537.         popf
  538.         jnc     .noread
  539.         push    es
  540.         push    dx
  541.         push    ss
  542.         pop     ds
  543.         movzx   ecx, dx
  544.         shr     cx, 9
  545.         mul     [bp + sect_per_clust - dat]
  546.         call    read_attr
  547.         pop     dx
  548.         pop     es
  549.         push    es
  550.         pop     ds
  551.         call    restore_usa
  552. .noread:
  553.         push    es
  554.         pop     ds
  555.         add     bx, 18h
  556.         jmp     .scan_record
  557. .not_found:
  558.         pop     [bp + cur_obj - dat]
  559.         mov     si, error_not_found
  560.         jmp     find_error_si
  561. .file_found:
  562.         pop     [bp + cur_obj - dat]
  563.         pop     cx
  564.         mov     ax, [bp + index_root - dat]
  565.         mov     [bp + freeattr - dat], ax
  566.         mov     eax, [es:bx]
  567.         test    byte [es:bx+48h+3], 10h
  568.         jz      .regular_file
  569.         cmp     byte [si], 0
  570.         jz      ..directory_error
  571.         inc     si
  572.         jmp     .parse_dir_loop
  573. .regular_file:
  574.         cmp     byte [si], 0
  575.         jnz     ..notdir_error
  576. ; read entry
  577.         call    read_file_record
  578.         xor     bx, bx
  579.         mov     ax, 80h
  580.         call    load_attr
  581.         mov     si, nodata_string
  582.         jc      find_error_si
  583.         mov     si, [bp + index_root - dat]
  584.         mov     [bp + freeattr - dat], si
  585.         push    ss
  586.         pop     ds
  587.         jmp     load_file_common_end
  588.