Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. restore_usa:
  2. ; Update Sequence Array restore
  3.         mov     bx, [di+4]
  4.         mov     cx, [di+6]
  5.         inc     bx
  6.         add     bx, di
  7.         inc     bx
  8.         add     di, 1feh
  9.         dec     cx
  10. @@:
  11.         mov     ax, [bx]
  12.         stosw
  13.         inc     bx
  14.         inc     bx
  15.         add     di, 1feh
  16.         loop    @b
  17.         ret
  18.  
  19. find_attr:
  20. ; in: di->file record, ax=attribute
  21. ; out: di->attribute or di=0 if not found
  22.         add     di, [di+14h]
  23. .1:
  24. ; attributes codes are formally dwords, but all they fit in word
  25.         cmp     word [di], -1
  26.         jz      .notfound
  27.         cmp     word [di], ax
  28.         jnz     .continue
  29. ; for $DATA attribute, scan only unnamed
  30.         cmp     ax, 80h
  31.         jnz     .found
  32.         cmp     byte [di+9], 0
  33.         jz      .found
  34. .continue:
  35.         add     di, [di+4]
  36.         jmp     .1
  37. .notfound:
  38.         xor     di, di
  39. .found:
  40.         ret
  41.  
  42. process_mcb_nonres:
  43. ; in: si->attribute, es:di->buffer
  44. ; out: di->buffer end
  45.         add     si, [si+20h]
  46.         xor     ebx, ebx
  47. .loop:
  48.         lodsb
  49.         test    al, al
  50.         jz      .done
  51.         push    invalid_read_request_string
  52.         movzx   cx, al
  53.         shr     cx, 4
  54.         jz      find_error_sp
  55.         xchg    ax, dx
  56.         and     dx, 0Fh
  57.         jz      find_error_sp
  58.         add     si, cx
  59.         add     si, dx
  60.         pop     ax
  61.         push    si
  62.         dec     si
  63.         movsx   eax, byte [si]
  64.         dec     cx
  65.         jz      .l1e
  66. .l1:
  67.         dec     si
  68.         shl     eax, 8
  69.         mov     al, [si]
  70.         loop    .l1
  71. .l1e:
  72.         xchg    ebp, eax
  73.         dec     si
  74.         movsx   eax, byte [si]
  75.         mov     cx, dx
  76.         dec     cx
  77.         jz      .l2e
  78. .l2:
  79.         dec     si
  80.         shl     eax, 8
  81.         mov     al, byte [si]
  82.         loop    .l2
  83. .l2e:
  84.         pop     si
  85.         add     ebx, ebp
  86. ; eax=length, ebx=disk block
  87.         stosd
  88.         mov     eax, ebx
  89.         stosd
  90.         jmp     .loop
  91. .done:
  92.         xor     eax, eax
  93.         stosd
  94.         ret
  95.  
  96. load_attr:
  97. ; in: ax=attribute, es:bx->buffer, di->base record
  98. ; out: bx->buffer end; CF set if not found
  99.         push    di
  100.         push    ax
  101.         mov     byte [es:bx], 1
  102.         inc     bx
  103.         push    bx
  104.         mov     [ofs], bx
  105. ; scan for attrubute
  106.         add     di, [di+14h]
  107. @@:
  108.         call    find_attr.1
  109.         test    di, di
  110.         jz      .notfound1
  111.         cmp     byte [di+8], 0
  112.         jnz     .nonresident
  113.         jmp     .resident
  114. .aux_resident:
  115.         push    di
  116.         popad
  117. ; resident attribute
  118. .resident:
  119.         mov     si, di
  120.         pop     di
  121.         dec     di
  122.         mov     al, 0
  123.         stosb
  124.         mov     ax, [si+10h]
  125.         stosw
  126.         xchg    ax, cx
  127.         add     si, [si+14h]
  128.         rep     movsb
  129.         mov     bx, di
  130.         pop     ax
  131.         pop     di
  132.         ret
  133. .nonresident:
  134. ; nonresident attribute
  135.         cmp     dword [di+10h], 0
  136.         jnz     @b
  137. ; read start of data
  138.         mov     si, di
  139.         pop     di
  140.         call    process_mcb_nonres
  141.         sub     di, 4
  142.         push    di
  143. .notfound1:
  144. ; $ATTRIBUTE_LIST is always in base file record
  145.         cmp     word [esp+2], 20h
  146.         jz      .nofragmented
  147. ; scan for $ATTRIBUTE_LIST = 20h
  148.         mov     di, [esp+4]
  149.         mov     ax, 20h
  150.         call    find_attr
  151.         test    di, di
  152.         jz      .nofragmented
  153. ; load $ATTRIBUTE_LIST itself
  154.         push    es
  155.         mov     bx, 0C000h
  156.         mov     di, [esp+6]
  157.         push    bx
  158.         push    [ofs]
  159.         push    ds
  160.         pop     es
  161.         call    load_attr
  162.         pop     [ofs]
  163.         pop     si
  164.         mov     bx, 8000h
  165.         push    bx
  166.         push    si
  167.         call    read_attr_full
  168.         pop     si
  169.         pop     bx
  170.         add     dx, bx
  171.         mov     ax, [esp+4]
  172.         pop     es
  173. .1:
  174.         cmp     [bx], ax
  175.         jnz     .continue1
  176. ; only unnamed $DATA attributes!
  177.         cmp     ax, 80h
  178.         jnz     @f
  179.         cmp     byte [bx+6], 0
  180.         jnz     .continue1
  181. @@:
  182.         cmp     dword [bx+10h], 0
  183.         jz      .continue1
  184.         cmp     dword [bx+8], 0
  185.         jnz     @f
  186.         push    ax
  187.         mov     ax, [esp+2]
  188.         cmp     ax, [ofs]
  189.         pop     ax
  190.         jnz     .continue1
  191. @@:
  192.         pushad
  193.         mov     eax, [bx+10h]
  194.         mov     bx, dx
  195.         push    [ofs]
  196.         push    es
  197.         push    ds
  198.         pop     es
  199.         call    read_file_record
  200.         pop     es
  201.         pop     [ofs]
  202.         popad
  203.         pushad
  204.         pop     di
  205.         mov     di, dx
  206.         add     di, [di+14h]
  207. .2:
  208.         call    find_attr.1
  209.         cmp     byte [di+8], 0
  210.         jz      .aux_resident
  211.         mov     eax, [bx+8]
  212.         cmp     eax, [di+10h]
  213.         jnz     .2
  214.         mov     si, di
  215.         mov     di, [esp+1Eh]
  216.         call    process_mcb_nonres
  217.         sub     di, 4
  218.         mov     [esp+1Eh], di
  219.         push    di
  220.         popad
  221. .continue1:
  222.         add     bx, [bx+4]
  223.         cmp     bx, dx
  224.         jb      .1
  225. .nofragmented:
  226.         pop     bx
  227.         pop     ax
  228.         pop     di
  229.         cmp     bx, [ofs]
  230.         jnz     @f
  231.         dec     bx
  232.         stc
  233.         ret
  234. @@:
  235.         add     bx, 4
  236.         ret
  237.  
  238. read_attr_full:
  239. ; in: si->decoded attribute data, bx->buffer
  240. ; out: edx=length in bytes
  241.         lodsb
  242.         cmp     al, 0
  243.         jnz     .nonresident
  244. ; resident
  245.         lodsw
  246.         movzx   edx, ax
  247.         xchg    ax, cx
  248.         mov     di, bx
  249.         rep     movsb
  250.         ret
  251. .nonresident:
  252. ; nonresident :-)
  253.         xor     edx, edx
  254. .loop:
  255.         lodsd
  256.         xchg    ecx, eax
  257.         jecxz   .loopend
  258.         lodsd
  259.         xchg    edi, eax
  260. ; read ecx clusters from cluster edi to es:bx
  261. .intloop:
  262.         push    ecx
  263. ; read 1 cluster from physical cluster edi to es:bx
  264.         mov     ecx, [cluster_size]
  265.         mov     eax, edi
  266.         mul     ecx
  267.         push    bx
  268.         call    relative_read
  269.         pop     bx
  270.         pop     ecx
  271.         inc     edi
  272.         mov     eax, [cluster_size]
  273.         add     edx, eax
  274.         shr     eax, 4
  275.         mov     bp, es
  276.         add     bp, ax
  277.         mov     es, bp
  278.         loop    .intloop
  279.         jmp     .loop
  280. .loopend:
  281.         mov     es, cx
  282.         ret
  283.  
  284. read_file_record:
  285. ; in: eax=index of record, bx=buffer
  286.         mov     si, 700h
  287.         mov     ecx, [frs_size]
  288.         mul     ecx
  289.         push    bx
  290.         push    [cur_obj]
  291.         mov     [cur_obj], mft_string
  292.         call    read_attr
  293.         pop     [cur_obj]
  294.         pop     di
  295.         call    restore_usa
  296.         ret
  297. read_attr:
  298. ; in: edx:eax=offset in bytes, ecx=size in bytes, bx=buffer, si=attribute
  299.         push    invalid_read_request_string
  300.         cmp     byte [si], 0
  301.         jnz     .nonresident
  302.         test    edx, edx
  303.         jnz     find_error_sp
  304.         cmp     eax, 10000h
  305.         jae     find_error_sp
  306.         cmp     ecx, 10000h
  307.         jae     find_error_sp
  308.         cmp     ax, [si+2]
  309.         jae     find_error_sp
  310.         cmp     cx, [si+2]
  311.         ja      find_error_sp
  312.         add     si, 3
  313.         add     si, ax
  314.         mov     di, bx
  315.         rep     movsb
  316.         pop     ax
  317.         ret
  318. .nonresident:
  319.         mov     edi, [cluster_size]
  320.         div     edi
  321.         mov     [ofs], dx
  322.         add     cx, dx
  323.         push    eax
  324.         xchg    eax, ecx
  325.         xor     edx, edx
  326.         dec     eax
  327.         div     edi
  328.         inc     eax
  329.         xchg    eax, ecx
  330.         pop     eax
  331.         add     si, 1
  332.         xor     edx, edx
  333.         push    bx
  334. ; eax=offset in clusters, ecx=size in clusters
  335. .scan:
  336.         mov     ebx, [si]
  337.         test    ebx, ebx
  338.         jz      .notfound
  339.         add     edx, ebx
  340.         add     si, 8
  341.         cmp     eax, edx
  342.         jae     .scan
  343.         mov     edi, [si-4]
  344. ; now edx=end of block, ebx=length of block, edi=start of block on disk
  345. ; eax=required offset, ecx=required length
  346.         push    edx
  347.         push    edi
  348.         sub     edx, eax
  349.         add     edi, ebx
  350.         sub     edi, edx
  351.         cmp     edx, ecx
  352.         jb      @f
  353.         mov     edx, ecx
  354. @@:
  355. ; read (edx) clusters from (edi=disk offset in clusters) to ([esp+8])
  356.         cmp     [ofs], 0
  357.         jnz     .ofs_read
  358. .cont:
  359.         pushad
  360.         movzx   ebx, byte [50Dh]
  361. ;       xchg    eax, edx
  362. ;       mul     ebx
  363.         xchg    ax, dx
  364.         mul     bx
  365.         xchg    cx, ax
  366.         xchg    eax, edi
  367.         mul     ebx
  368.         mov     bx, [esp+8+20h]
  369.         call    relative_read
  370.         mov     [esp+8+20h], bx
  371.         popad
  372. .cont2:
  373.         add     eax, edx
  374.         sub     ecx, edx
  375. .cont3:
  376.         pop     edi
  377.         pop     edx
  378.         jnz     .scan
  379.         pop     bx
  380.         pop     ax
  381.         ret
  382. .ofs_read:
  383.         push    ecx
  384.         movzx   ecx, byte [50Dh]        ; bpb_sects_per_clust
  385.         mov     eax, edi
  386.         push    edx
  387.         mul     ecx
  388.         push    1000h
  389.         pop     es
  390.         xor     bx, bx
  391.         call    relative_read
  392.         mov     cx, bx
  393.         push    si
  394.         push    di
  395.         mov     si, [ofs]
  396.         mov     di, [esp+8+12]
  397.         sub     cx, si
  398.         push    ds
  399.         push    es
  400.         pop     ds
  401.         pop     es
  402.         rep     movsb
  403.         mov     [esp+8+12], di
  404.         push    es
  405.         pop     ds
  406.         pop     di
  407.         pop     si
  408.         pop     edx
  409.         pop     ecx
  410.         inc     edi
  411.         mov     [ofs], 0
  412.         inc     eax
  413.         dec     ecx
  414.         jz      .cont3
  415.         dec     edx
  416.         jnz     .cont
  417.         jmp     .cont2
  418. .notfound:
  419.         mov     si, invalid_read_request_string
  420.         jmp     find_error_si
  421.  
  422. ntfs_parse_dir:
  423. ; in: eax=directory iRecord, [word sp+2]=filename
  424. ; out: si=$DATA attribute of file
  425.         mov     bx, [free]
  426.         mov     [dir], bx
  427.         push    bx
  428.         call    read_file_record
  429.         mov     ax, word [frs_size]
  430.         add     [free], ax
  431.         pop     di
  432. ; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
  433.         mov     ax, 90h         ; $INDEX_ROOT
  434.         push    di
  435.         mov     bx, [free]
  436.         mov     [index_root], bx
  437.         call    load_attr
  438.         mov     si, noindex_string
  439.         jc      find_error_si
  440.         mov     [free], bx
  441.         pop     di
  442.         mov     ax, 0A0h        ; $INDEX_ALLOCATION
  443.         mov     bx, [free]
  444.         mov     [index_alloc], bx
  445.         call    load_attr
  446.         jnc     @f
  447.         mov     [index_alloc], 0
  448. @@:
  449.         mov     [free], bx
  450. ; search for entry
  451.         mov     si, [index_root]
  452.         mov     bx, [free]
  453.         call    read_attr_full
  454.         mov     ebp, [bx+8]     ; subnode_size
  455.         add     bx, 10h
  456. .scan_record:
  457.         add     bx, [bx]
  458. .scan:
  459.         test    byte [bx+0Ch], 2
  460.         jnz     .not_found
  461.         mov     si, [esp+2]
  462.         movzx   cx, byte [bx+50h]       ; namelen
  463.         lea     di, [bx+52h]            ; name
  464.         xor     ax, ax
  465. @@:
  466.         lodsb
  467.         cmp     al, 'a'
  468.         jb      .notletter
  469.         cmp     al, 'z'
  470.         ja      .notletter
  471.         or      byte [di], 20h
  472. .notletter:
  473.         scasw
  474.         loopz   @b
  475.         jb      .not_found
  476.         ja      @f
  477.         cmp     byte [esi], 0
  478.         jz      .file_found
  479. @@:
  480.         add     bx, [bx+8]
  481.         jmp     .scan
  482. .not_found:
  483.         test    byte [bx+0Ch], 1
  484.         jz      file_not_found
  485.         cmp     [index_alloc], 0
  486.         jz      file_not_found
  487.         add     bx, [bx+8]
  488.         mov     eax, [bx-8]
  489.         mul     [cluster_size]
  490.         mov     si, [index_alloc]
  491.         mov     ecx, ebp
  492.         mov     bx, [free]
  493.         call    read_attr
  494.         mov     di, [free]
  495.         call    restore_usa
  496.         mov     bx, [free]
  497.         add     bx, 18h
  498.         jmp     .scan_record
  499. .file_found:
  500.         mov     si, [esp+2]
  501.         mov     [cur_obj], si
  502.         cmp     byte [esp+4], 0
  503.         jz      .need_file
  504.         mov     si, notdir_string
  505.         test    byte [bx+48h+3], 10h
  506.         jz      find_error_si
  507.         mov     eax, [bx]
  508.         mov     bx, [dir]
  509.         mov     [free], bx
  510.         ret     2
  511. .need_file:
  512.         mov     si, directory_string
  513.         test    byte [bx+48h+3], 10h    ; directory?
  514.         jnz     find_error_si
  515. ; read entry
  516.         mov     eax, [bx]
  517.         mov     bx, [dir]
  518.         mov     [free], bx
  519.         mov     bx, 4000h
  520.         push    bx
  521.         call    read_file_record
  522.         pop     di
  523.         mov     ax, 80h
  524.         push    2000h
  525.         pop     es
  526.         xor     bx, bx
  527.         call    load_attr
  528.         mov     si, nodata_string
  529.         jz      find_error_si
  530.         mov     [free], bx
  531.         ret     2
  532.