Subversion Repositories Kolibri OS

Rev

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