Subversion Repositories Kolibri OS

Rev

Rev 6462 | Rev 9889 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6462 Rev 7736
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2013-2016. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2013-2020. All rights reserved. ;;
4
;;  Distributed under terms of the GNU General Public License.  ;;
4
;;  Distributed under terms of the GNU General Public License   ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 7... Line 7...
7
 
7
 
-
 
8
$Revision: 7736 $
-
 
9
 
-
 
10
 
-
 
11
include 'xfs.inc'
-
 
12
 
-
 
13
macro omit_frame_pointer_prologue procname,flag,parmbytes,localbytes,reglist {
-
 
14
  local loc
-
 
15
  loc = (localbytes+3) and (not 3)
-
 
16
  if localbytes
-
 
17
        sub     esp, loc
-
 
18
  end if
-
 
19
  irps reg, reglist \{ push reg \}
-
 
20
  counter = 0
-
 
21
  irps reg, reglist \{counter = counter+1 \}
-
 
22
  parmbase@proc equ esp+counter*4+loc+4
-
 
23
  localbase@proc equ esp
-
 
24
}
-
 
25
 
-
 
26
macro omit_frame_pointer_epilogue procname,flag,parmbytes,localbytes,reglist {
-
 
27
  local loc
-
 
28
  loc = (localbytes+3) and (not 3)
-
 
29
  irps reg, reglist \{ reverse pop reg \}
-
 
30
  if localbytes
-
 
31
        lea     esp, [esp+loc]
-
 
32
  end if
-
 
33
  if flag and 10000b
-
 
34
        retn
-
 
35
  else
-
 
36
        retn    parmbytes
-
 
37
  end if
-
 
38
}
-
 
39
 
-
 
40
prologue@proc equ omit_frame_pointer_prologue
-
 
41
epilogue@proc equ omit_frame_pointer_epilogue
-
 
42
 
-
 
43
macro movbe reg, arg {
-
 
44
 if CPUID_MOVBE eq Y
-
 
45
        movbe   reg, arg
-
 
46
 else
-
 
47
        mov     reg, arg
-
 
48
  if reg in 
-
 
49
        bswap   reg
-
 
50
  else if ax eq reg
-
 
51
        xchg    al, ah
-
 
52
  else if bx eq reg
-
 
53
        xchg    bl, bh
-
 
54
  else if cx eq reg
-
 
55
        xchg    cl, ch
-
 
56
  else if dx eq reg
-
 
57
        xchg    dl, dh
-
 
58
  else
-
 
59
   err
-
 
60
  end if
-
 
61
 end if
-
 
62
}
-
 
63
 
-
 
64
;
-
 
65
; This file contains XFS related code.
-
 
66
; For more information on XFS check links and source below.
-
 
67
;
-
 
68
; 1. https://xfs.wiki.kernel.org/
-
 
69
;
-
 
70
; 2. XFS Algorithms & Data Structures:
-
 
71
;    git://git.kernel.org/pub/scm/fs/xfs/xfs-documentation.git
-
 
72
;    https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf
-
 
73
;
-
 
74
; 3. Linux source at https://www.kernel.org/
-
 
75
;    git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
-
 
76
;    /fs/xfs
Line 8... Line -...
8
$Revision: 6462 $
-
 
9
 
-
 
10
; XFS external functions
-
 
11
;   in:
-
 
12
; ebx -> parameter structure of sysfunc 70
-
 
13
; ebp -> XFS structure
-
 
14
; [esi]+[[esp+4]] = name
-
 
15
;   out:
77
;
16
; eax, ebx = return values for sysfunc 70
78
 
17
iglobal
79
iglobal
18
align 4
80
align 4
19
xfs_user_functions:
81
xfs._.user_functions:
20
        dd      xfs_free
82
        dd      xfs._.free
21
        dd      (xfs_user_functions_end - xfs_user_functions - 4) / 4
83
        dd      (xfs._.user_functions_end-xfs._.user_functions-4)/4
22
        dd      xfs_ReadFile
84
        dd      xfs_Read
23
        dd      xfs_ReadFolder
85
        dd      xfs_ReadFolder
24
        dd      0;xfs_CreateFile
86
        dd      0;xfs_Rewrite
25
        dd      0;xfs_WriteFile
87
        dd      0;xfs_Write
26
        dd      0;xfs_SetFileEnd
-
 
27
        dd      xfs_GetFileInfo
-
 
28
        dd      0;xfs_SetFileInfo
-
 
29
        dd      0
-
 
30
        dd      0;xfs_Delete
88
        dd      0;xfs_SetFileEnd
31
        dd      0;xfs_CreateFolder
89
        dd      xfs_GetFileInfo
Line -... Line 90...
-
 
90
xfs._.user_functions_end:
32
xfs_user_functions_end:
91
endg
33
endg
-
 
34
 
92
 
-
 
93
; test partition type (valid XFS one?)
35
include 'xfs.inc'
94
; alloc and fill XFS (see xfs.inc) structure
36
 
95
; this function is called for each partition
-
 
96
; return 0 (not XFS or invalid) / pointer to partition structure
37
; Mount if it's a valid XFS partition.
97
proc xfs_create_partition uses ebx esi edi
-
 
98
        ; check XFS signature
-
 
99
        cmp     [ebx+xfs_sb.sb_magicnum], XFS_SB_MAGIC
38
xfs_create_partition:
100
        jnz     .error_nofree
-
 
101
        ; test for supported feature flags and version in sb_versionnum
-
 
102
        movzx   eax, [ebx+xfs_sb.sb_versionnum]
-
 
103
        xchg    al, ah
-
 
104
        ; allow only known and supported features
-
 
105
        ; return error otherwise
-
 
106
        test    eax, NOT XFS_SB_VERSION_SUPPORTED
-
 
107
        jnz     .error_nofree
-
 
108
        ; version < 4 obsolete, not supported
39
;   in:
109
        ; version = 4,5 supported
40
; ebp -> PARTITION structure
110
        ; version > 5 unknown
-
 
111
        and     al, XFS_SB_VERSION_NUMBITS
41
; ebx -> boot sector
112
        cmp     al, 4
-
 
113
        jb      .error_nofree
42
;   out:
114
        cmp     al, 5
43
; eax -> XFS structure, 0 = not XFS
115
        ja      .error_nofree
44
        push    ebx ecx edx esi edi
116
        ; if MOREBITS bit is set, additional feature flags are in sb_features2
-
 
117
        test    eax, XFS_SB_VERSION_MOREBITSBIT
45
        cmp     dword [esi+DISK.MediaInfo.SectorSize], 512
118
        jz      @f
46
        jnz     .error
119
        movbe   eax, [ebx+xfs_sb.sb_features2]
-
 
120
        test    eax, NOT XFS_SB_VERSION2_SUPPORTED
47
        cmp     dword[ebx + xfs_sb.sb_magicnum], XFS_SB_MAGIC   ; signature
121
        jnz     .error_nofree
-
 
122
@@:
48
        jne     .error
123
        movbe   eax, [ebx+xfs_sb.sb_features_incompat]
49
 
-
 
50
        ; TODO: check XFS.versionnum and XFS.features2
124
        test    eax, NOT XFS_SB_FEAT_INCOMPAT_SUPPORTED
51
        ;       print superblock params for debugging (waiting for bug reports)
125
        jnz     .error_nofree
-
 
126
        ; all presented features are either supported or don't affect reading
52
 
127
        movi    eax, sizeof.XFS
53
        movi    eax, sizeof.XFS
128
        call    malloc
Line 54... Line 129...
54
        call    malloc
129
        mov     edi, eax
55
        test    eax, eax
-
 
56
        jz      .error
-
 
57
 
130
        test    eax, eax
58
        ; standard partition initialization, common for all file systems
131
        jz      .error
59
 
132
 
60
        mov     edi, eax
133
        ; standard partition initialization, common for all file systems
61
        mov     eax, dword[ebp + PARTITION.FirstSector]
134
        mov     eax, dword[ebp+PARTITION.FirstSector+DQ.lo]
62
        mov     dword[edi + XFS.FirstSector], eax
135
        mov     dword[edi+XFS.FirstSector+DQ.lo], eax
63
        mov     eax, dword[ebp + PARTITION.FirstSector + 4]
136
        mov     eax, dword[ebp+PARTITION.FirstSector+DQ.hi]
64
        mov     dword[edi + XFS.FirstSector + 4], eax
137
        mov     dword[edi+XFS.FirstSector+DQ.hi], eax
65
        mov     eax, dword[ebp + PARTITION.Length]
138
        mov     eax, dword[ebp+PARTITION.Length+DQ.lo]
66
        mov     dword[edi + XFS.Length], eax
139
        mov     dword[edi+XFS.Length+DQ.lo], eax
67
        mov     eax, dword[ebp + PARTITION.Length + 4]
140
        mov     eax, dword[ebp+PARTITION.Length+DQ.hi]
68
        mov     dword[edi + XFS.Length + 4], eax
-
 
69
        mov     eax, [ebp + PARTITION.Disk]
141
        mov     dword[edi+XFS.Length+DQ.hi], eax
70
        mov     [edi + XFS.Disk], eax
142
        mov     eax, [ebp+PARTITION.Disk]
71
        mov     [edi + XFS.FSUserFunctions], xfs_user_functions
-
 
72
 
143
        mov     [edi+XFS.Disk], eax
73
        ; here we initialize only one mutex so far (for the entire partition)
144
        mov     [edi+XFS.FSUserFunctions], xfs._.user_functions
Line -... Line 145...
-
 
145
        ; here we initialize only one mutex (for the entire partition)
-
 
146
        ; XFS potentially allows parallel r/w access to different AGs, keep it in mind
74
        ; XFS potentially allows parallel r/w access to several AGs, keep it in mind for SMP times
147
        lea     ecx, [edi+XFS.Lock]
-
 
148
        call    mutex_init
Line 75... Line 149...
75
 
149
 
76
        lea     ecx, [edi + XFS.Lock]
-
 
77
        call    mutex_init
150
;        movzx   eax, [ebx+xfs_sb.sb_sectsize]
78
 
-
 
79
        ; read superblock and fill just allocated XFS partition structure
-
 
80
 
-
 
-
 
151
;        xchg    al, ah
81
        mov     eax, [ebx + xfs_sb.sb_blocksize]
152
        mov     eax, [eax+DISK.MediaInfo.SectorSize]
82
        bswap   eax                                     ; XFS is big endian
153
        mov     [edi+XFS.sectsize], eax
83
        mov     [edi + XFS.blocksize], eax
154
 
-
 
155
        movbe   eax, [ebx+xfs_sb.sb_blocksize]
-
 
156
        mov     [edi+XFS.blocksize], eax
-
 
157
 
84
        movzx   eax, word[ebx + xfs_sb.sb_sectsize]
158
        movzx   eax, [ebx+xfs_sb.sb_versionnum]
-
 
159
        xchg    al, ah
-
 
160
        mov     [edi+XFS.versionnum], eax
-
 
161
        and     eax, XFS_SB_VERSION_NUMBITS
-
 
162
        mov     [edi+XFS.version], eax
-
 
163
 
-
 
164
        movbe   eax, [ebx+xfs_sb.sb_features2]
-
 
165
        mov     [edi+XFS.features2], eax
-
 
166
        cmp     [edi+XFS.version], 5
-
 
167
        jz      .v5
-
 
168
.v4:
-
 
169
        mov     [edi+XFS.inode_core_size], sizeof.xfs_dinode_core
-
 
170
        test    eax, XFS_SB_VERSION2_FTYPE
-
 
171
        setnz   al
-
 
172
        movzx   eax, al
-
 
173
        mov     [edi+XFS.ftype_size], eax
-
 
174
        mov     [edi+XFS.dir_block_magic], XFS_DIR2_BLOCK_MAGIC
-
 
175
        mov     [edi+XFS.dir_data_magic], XFS_DIR2_DATA_MAGIC
-
 
176
        mov     [edi+XFS.dir_leaf1_magic], XFS_DIR2_LEAF1_MAGIC
-
 
177
        mov     [edi+XFS.dir_leafn_magic], XFS_DIR2_LEAFN_MAGIC
-
 
178
        mov     [edi+XFS.da_node_magic], XFS_DA_NODE_MAGIC
-
 
179
        mov     [edi+XFS.bmap_magic], XFS_BMAP_MAGIC
-
 
180
        mov     [edi+XFS.dir_block_size], sizeof.xfs_dir2_data_hdr
-
 
181
        mov     [edi+XFS.bmbt_block_size], sizeof.xfs_bmbt_block
-
 
182
        mov     [edi+XFS.da_blkinfo_size], sizeof.xfs_da_blkinfo
85
        xchg    al, ah
183
        jmp     .vcommon
-
 
184
.v5:
86
        mov     [edi + XFS.sectsize], eax
185
        mov     [edi+XFS.inode_core_size], sizeof.xfs_dinode3_core
-
 
186
        movbe   eax, [ebx+xfs_sb.sb_features_incompat]
-
 
187
        mov     [edi+XFS.features_incompat], eax
-
 
188
        test    eax, XFS_SB_FEAT_INCOMPAT_FTYPE
-
 
189
        setnz   al
-
 
190
        movzx   eax, al
-
 
191
        mov     [edi+XFS.ftype_size], eax
-
 
192
        mov     [edi+XFS.dir_block_magic], XFS_DIR3_BLOCK_MAGIC
-
 
193
        mov     [edi+XFS.dir_data_magic], XFS_DIR3_DATA_MAGIC
-
 
194
        mov     [edi+XFS.dir_leaf1_magic], XFS_DIR3_LEAF1_MAGIC
-
 
195
        mov     [edi+XFS.dir_leafn_magic], XFS_DIR3_LEAFN_MAGIC
-
 
196
        mov     [edi+XFS.da_node_magic], XFS_DA3_NODE_MAGIC
87
        movzx   eax, word[ebx + xfs_sb.sb_versionnum]
197
        mov     [edi+XFS.bmap_magic], XFS_BMAP3_MAGIC
88
        xchg    al, ah
198
        mov     [edi+XFS.dir_block_size], sizeof.xfs_dir3_data_hdr
89
        mov     [edi + XFS.versionnum], eax
199
        mov     [edi+XFS.bmbt_block_size], sizeof.xfs_bmbt3_block
-
 
200
        mov     [edi+XFS.da_blkinfo_size], sizeof.xfs_da3_blkinfo
90
        mov     eax, [ebx + xfs_sb.sb_features2]
201
.vcommon:
91
        bswap   eax
202
 
92
        mov     [edi + XFS.features2], eax
203
        movzx   eax, [ebx+xfs_sb.sb_inodesize]
-
 
204
        xchg    al, ah
93
        movzx   eax, word[ebx + xfs_sb.sb_inodesize]
205
        mov     [edi+XFS.inodesize], eax
94
        xchg    al, ah
206
 
-
 
207
        movzx   eax, [ebx+xfs_sb.sb_inopblock]
95
        mov     [edi + XFS.inodesize], eax
208
        xchg    al, ah
96
        movzx   eax, word[ebx + xfs_sb.sb_inopblock]    ; inodes per block
209
        mov     [edi+XFS.inopblock], eax
97
        xchg    al, ah
210
 
98
        mov     [edi + XFS.inopblock], eax
211
        movzx   eax, [ebx+xfs_sb.sb_blocklog]
-
 
212
        mov     [edi+XFS.blocklog], eax
99
        movzx   eax, byte[ebx + xfs_sb.sb_blocklog]     ; log2 of block size, in bytes
213
 
100
        mov     [edi + XFS.blocklog], eax
214
;        movzx   eax, [ebx+xfs_sb.sb_sectlog]
-
 
215
        mov     eax, [edi+XFS.sectsize]
101
        movzx   eax, byte[ebx + xfs_sb.sb_sectlog]
216
        bsf     eax, eax
102
        mov     [edi + XFS.sectlog], eax
217
        mov     [edi+XFS.sectlog], eax
103
        movzx   eax, byte[ebx + xfs_sb.sb_inodelog]
-
 
104
        mov     [edi + XFS.inodelog], eax
-
 
105
        movzx   eax, byte[ebx + xfs_sb.sb_inopblog]
-
 
106
        mov     [edi + XFS.inopblog], eax
-
 
107
        movzx   eax, byte[ebx + xfs_sb.sb_dirblklog]
-
 
108
        mov     [edi + XFS.dirblklog], eax
-
 
Line 109... Line 218...
109
        mov     eax, dword[ebx + xfs_sb.sb_rootino + 4] ;
218
 
110
        bswap   eax                                     ; big
219
        movzx   eax, [ebx+xfs_sb.sb_inodelog]
-
 
220
        mov     [edi+XFS.inodelog], eax
111
        mov     dword[edi + XFS.rootino + 0], eax       ; endian
221
 
-
 
222
        movzx   eax, [ebx+xfs_sb.sb_inopblog]
-
 
223
        mov     [edi+XFS.inopblog], eax
-
 
224
 
-
 
225
        movzx   ecx, [ebx+xfs_sb.sb_dirblklog]
-
 
226
        mov     [edi+XFS.dirblklog], ecx
-
 
227
        movi    eax, 1
-
 
228
        shl     eax, cl
-
 
229
        mov     [edi+XFS.blkpdirblk], eax
-
 
230
 
-
 
231
        movbe   eax, [ebx+xfs_sb.sb_rootino.hi]
112
        mov     eax, dword[ebx + xfs_sb.sb_rootino + 0] ; 64bit
232
        mov     [edi+XFS.rootino.lo], eax
Line 113... Line 233...
113
        bswap   eax                                     ; number
233
        movbe   eax, [ebx+xfs_sb.sb_rootino.lo]
114
        mov     dword[edi + XFS.rootino + 4], eax       ;
234
        mov     [edi+XFS.rootino.hi], eax
115
 
-
 
116
        mov     eax, [edi + XFS.blocksize]
235
 
117
        mov     ecx, [edi + XFS.dirblklog]
236
        mov     eax, [edi+XFS.blocksize]
118
        shl     eax, cl
237
        mov     ecx, [edi+XFS.dirblklog]
Line 119... Line 238...
119
        mov     [edi + XFS.dirblocksize], eax           ; blocks for files, dirblocks for directories
238
        shl     eax, cl
120
 
239
        mov     [edi+XFS.dirblocksize], eax           ; blocks are for files, dirblocks are for directories
121
        ; sector is always smaller than block
240
 
Line -... Line 241...
-
 
241
        ; sector is always smaller than block
122
        ; so precalculate shift order to allow faster sector_num->block_num conversion
242
        ; so precalculate shift order to allow faster sector_num->block_num conversion
Line 123... Line -...
123
 
-
 
124
        mov     ecx, [edi + XFS.blocklog]
-
 
125
        sub     ecx, [edi + XFS.sectlog]
-
 
126
        mov     [edi + XFS.blockmsectlog], ecx
-
 
127
 
-
 
128
        mov     eax, 1
-
 
129
        shl     eax, cl
-
 
130
        mov     [edi + XFS.sectpblock], eax
243
        mov     ecx, [edi+XFS.blocklog]
131
 
244
        sub     ecx, [edi+XFS.sectlog]
Line 132... Line 245...
132
        ; shift order for inode_num->block_num conversion
245
        mov     [edi+XFS.sectpblog], ecx
133
 
246
 
134
        mov     eax, [edi + XFS.blocklog]
247
        mov     eax, 1
135
        sub     eax, [edi + XFS.inodelog]
-
 
136
        mov     [edi + XFS.inodetoblocklog], eax
-
 
137
 
-
 
138
        mov     eax, [ebx + xfs_sb.sb_agblocks]
-
 
139
        bswap   eax
-
 
140
        mov     [edi + XFS.agblocks], eax
248
        shl     eax, cl
141
        movzx   ecx, byte[ebx + xfs_sb.sb_agblklog]
249
        mov     [edi+XFS.sectpblock], eax
142
        mov     [edi + XFS.agblklog], ecx
250
 
143
 
251
        movbe   eax, [ebx+xfs_sb.sb_agblocks]
144
        ; get the mask for block numbers
252
        mov     [edi+XFS.agblocks], eax
145
        ; block numbers are AG relative!
253
 
146
        ; bitfield length may vary between partitions
254
        movzx   ecx, [ebx+xfs_sb.sb_agblklog]
-
 
255
        mov     [edi+XFS.agblklog], ecx
Line 147... Line 256...
147
 
256
 
148
        mov     eax, 1
-
 
149
        shl     eax, cl
257
        ; get the mask for block numbers
150
        dec     eax
258
        ; block numbers are AG relative!
151
        mov     dword[edi + XFS.agblockmask + 0], eax
259
        ; bitfield length may vary between partitions
152
        mov     eax, 1
260
        mov     eax, 1
-
 
261
        xor     edx, edx
153
        sub     ecx, 32
262
        shld    edx, eax, cl
-
 
263
        shl     eax, cl
Line 154... Line 264...
154
        jc      @f
264
        sub     eax, 1
155
        shl     eax, cl
265
        sbb     edx, 0
156
    @@:
266
        mov     [edi+XFS.agblockmask.lo], eax
157
        dec     eax
267
        mov     [edi+XFS.agblockmask.hi], edx
-
 
268
 
158
        mov     dword[edi + XFS.agblockmask + 4], eax
269
        ; calculate magic offsets for directories
-
 
270
        mov     ecx, [edi+XFS.blocklog]
Line 159... Line -...
159
 
-
 
160
        ; calculate magic offsets for directories
-
 
161
 
-
 
162
        mov     ecx, [edi + XFS.blocklog]
-
 
Line -... Line 271...
-
 
271
        mov     eax, XFS_DIR2_LEAF_OFFSET AND 0xffffffff        ; lo
163
        mov     eax, XFS_DIR2_LEAF_OFFSET AND 0xffffffff        ; lo
272
        mov     edx, XFS_DIR2_LEAF_OFFSET SHR 32                ; hi
164
        mov     edx, XFS_DIR2_LEAF_OFFSET SHR 32                ; hi
273
        shrd    eax, edx, cl
-
 
274
        shr     edx, cl
-
 
275
        mov     [edi+XFS.dir2_leaf_offset_blocks.lo], eax
-
 
276
        mov     [edi+XFS.dir2_leaf_offset_blocks.hi], edx
-
 
277
 
-
 
278
        mov     ecx, [edi+XFS.blocklog]
-
 
279
        mov     eax, XFS_DIR2_FREE_OFFSET AND 0xffffffff        ; lo
-
 
280
        mov     edx, XFS_DIR2_FREE_OFFSET SHR 32                ; hi
165
        shrd    eax, edx, cl
281
        shrd    eax, edx, cl
166
        mov     [edi + XFS.dir2_leaf_offset_blocks], eax
282
        shr     edx, cl
167
 
-
 
Line 168... Line 283...
168
        mov     ecx, [edi + XFS.blocklog]
283
        mov     [edi+XFS.dir2_free_offset_blocks.lo], eax
169
        mov     eax, XFS_DIR2_FREE_OFFSET AND 0xffffffff        ; lo
284
        mov     [edi+XFS.dir2_free_offset_blocks.hi], edx
170
        mov     edx, XFS_DIR2_FREE_OFFSET SHR 32                ; hi
285
 
171
        shrd    eax, edx, cl
286
 
172
        mov     [edi + XFS.dir2_free_offset_blocks], eax
287
        ; allocate memory for temp block, dirblock, inode, etc
-
 
288
        mov     eax, [edi+XFS.blocksize]
173
 
289
        call    malloc
174
;        mov     ecx, [edi + XFS.dirblklog]
290
        mov     [edi+XFS.cur_block], eax
175
;        mov     eax, [edi + XFS.blocksize]
-
 
176
;        shl     eax, cl
-
 
177
;        mov     [edi + XFS.dirblocksize], eax
-
 
178
 
-
 
Line 179... Line 291...
179
        mov     eax, [edi + XFS.blocksize]
291
        test    eax, eax
180
        call    malloc
292
        jz      .error
181
        test    eax, eax
293
 
182
        jz      .error
294
        mov     eax, [edi+XFS.blocksize]
183
        mov     [edi + XFS.cur_block], eax
295
        call    malloc
Line 184... Line 296...
184
 
296
        mov     [edi+XFS.cur_block_data], eax
185
        ; we do need XFS.blocksize bytes for single inode
297
        test    eax, eax
186
        ; minimal file system structure is block, inodes are packed in blocks
298
        jz      .error
187
 
-
 
-
 
299
 
188
        mov     eax, [edi + XFS.blocksize]
300
        ; we do need XFS.blocksize bytes for single inode
189
        call    malloc
301
        ; minimal file system structure is block, inodes are packed in blocks
-
 
302
        ; FIXME
190
        test    eax, eax
303
        mov     eax, [edi+XFS.blocksize]
191
        jz      .error
304
        call    malloc
192
        mov     [edi + XFS.cur_inode], eax
-
 
Line 193... Line -...
193
 
-
 
194
        ; temporary inode
-
 
195
        ; used for browsing directories
305
        mov     [edi+XFS.cur_inode], eax
196
 
306
        test    eax, eax
-
 
307
        jz      .error
197
        mov     eax, [edi + XFS.blocksize]
308
 
198
        call    malloc
309
        mov     eax, [edi+XFS.blocksize]
199
        test    eax, eax
-
 
Line 200... Line 310...
200
        jz      .error
310
        call    malloc
201
        mov     [edi + XFS.tmp_inode], eax
311
        test    eax, eax
202
 
312
        jz      .error
203
        ; current sector
313
        mov     [edi+XFS.tmp_inode], eax
204
        ; only for sector size structures like AGI
314
 
-
 
315
        ; current sector
-
 
316
        ; only for sector sized structures like AGF
-
 
317
        ; inodes usually fit this size, but not always!
205
        ; inodes has usually the same size, but never store them here
318
        ; therefore never store inode here
206
 
-
 
207
        mov     eax, [edi + XFS.sectsize]
319
        mov     eax, [edi+XFS.sectsize]
-
 
320
        call    malloc
Line 208... Line 321...
208
        call    malloc
321
        mov     [edi+XFS.cur_sect], eax
209
        test    eax, eax
322
        test    eax, eax
210
        jz      .error
-
 
211
        mov     [edi + XFS.cur_sect], eax
323
        jz      .error
212
 
324
 
213
        ; current directory block
-
 
Line 214... Line 325...
214
 
325
        mov     eax, [edi+XFS.dirblocksize]
215
        mov     eax, [edi + XFS.dirblocksize]
326
        call    malloc
216
        call    malloc
-
 
217
        test    eax, eax
327
        mov     [edi+XFS.cur_dirblock], eax
218
        jz      .error
328
        test    eax, eax
219
        mov     [edi + XFS.cur_dirblock], eax
-
 
Line 220... Line 329...
220
 
329
        jz      .error
221
  .quit:
330
 
-
 
331
.quit:
222
        mov     eax, edi                ; return pointer to allocated XFS partition structure
332
        ; return pointer to allocated XFS partition structure
-
 
333
        mov     eax, edi
-
 
334
        ret
223
        pop     edi esi edx ecx ebx
335
.error:
224
        ret
336
        mov     eax, edi
-
 
337
        call    xfs._.free
-
 
338
.error_nofree:
-
 
339
        xor     eax, eax
-
 
340
        ret
225
  .error:
341
endp
-
 
342
 
-
 
343
 
-
 
344
; lock partition access mutex
-
 
345
xfs._.lock:
-
 
346
        lea     ecx, [ebp+XFS.Lock]
-
 
347
        jmp     mutex_lock
-
 
348
 
-
 
349
 
-
 
350
; unlock partition access mutex
226
        xor     eax, eax
351
xfs._.unlock:
-
 
352
        lea     ecx, [ebp+XFS.Lock]
-
 
353
        jmp     mutex_unlock
-
 
354
 
-
 
355
 
227
        pop     edi esi edx ecx ebx
356
; free all the allocated memory
-
 
357
; called on partition destroy
-
 
358
; or during failed initialization from xfs_create_partition
-
 
359
xfs._.free:
-
 
360
        test    eax, eax
228
        ret
361
        jz      .done
-
 
362
        push    ebx
-
 
363
        mov     ebx, eax
-
 
364
 
-
 
365
 
229
 
366
        ; freeing order must correspond the order of
230
 
367
        ; allocation in xfs_create_partition
-
 
368
        mov     eax, [ebx+XFS.cur_block]
-
 
369
        test    eax, eax
-
 
370
        jz      .done
-
 
371
        call    free
-
 
372
 
231
; lock partition access mutex
373
        mov     eax, [ebx+XFS.cur_block_data]
232
proc xfs_lock
374
        test    eax, eax
-
 
375
        jz      .done
233
;DEBUGF 1,"xfs_lock\n"
376
        call    free
234
        lea     ecx, [ebp + XFS.Lock]
-
 
Line 235... Line 377...
235
        jmp     mutex_lock
377
 
236
endp
378
        mov     eax, [ebx+XFS.cur_inode]
237
 
379
        test    eax, eax
238
 
380
        jz      .done
239
; unlock partition access mutex
381
        call    free
240
proc xfs_unlock
382
 
241
;DEBUGF 1,"xfs_unlock\n"
383
        mov     eax, [ebx+XFS.tmp_inode]
242
        lea     ecx, [ebp + XFS.Lock]
384
        test    eax, eax
-
 
385
        jz      .done
-
 
386
        call    free
-
 
387
 
Line -... Line 388...
-
 
388
        mov     eax, [ebx+XFS.cur_sect]
243
        jmp     mutex_unlock
389
        test    eax, eax
244
endp
390
        jz      .done
Line 245... Line 391...
245
 
391
        call    free
246
 
392
 
247
; free all the allocated memory
393
        mov     eax, [ebx+XFS.cur_dirblock]
248
; called on partition destroy
-
 
249
proc xfs_free
394
        test    eax, eax
250
        push    ebp
395
        jz      .done
Line 251... Line 396...
251
        xchg    ebp, eax
396
        call    free
252
        stdcall kernel_free, [ebp + XFS.cur_block]
397
 
253
        stdcall kernel_free, [ebp + XFS.cur_inode]
398
 
254
        stdcall kernel_free, [ebp + XFS.cur_sect]
399
        mov     eax, ebx
-
 
400
        call    free
255
        stdcall kernel_free, [ebp + XFS.cur_dirblock]
401
        pop     ebx
256
        stdcall kernel_free, [ebp + XFS.tmp_inode]
-
 
257
        xchg    ebp, eax
402
.done:
258
        call    free
-
 
259
        pop     ebp
403
        ret
260
        ret
404
 
261
endp
-
 
262
 
405
 
263
 
406
;---------------------------------------------------------------
Line 264... Line -...
264
;---------------------------------------------------------------
-
 
265
; block number (AG relative)
-
 
266
; eax -- inode_lo
-
 
267
; edx -- inode_hi
-
 
268
; ebx -- buffer
-
 
269
;---------------------------------------------------------------
-
 
270
xfs_read_block:
407
; block number
271
        push    ebx esi
408
; eax -- inode_lo
272
 
409
; edx -- inode_hi
273
        push    edx
-
 
274
        push    eax
-
 
275
 
-
 
276
        ; XFS block numbers are AG relative
-
 
277
        ; they come in bitfield form of concatenated AG and block numbers
-
 
278
        ; to get absolute block number for fs_read32_sys we should
-
 
279
        ; 1. extract AG number (using precalculated mask)
-
 
280
        ; 2. multiply it by the AG size in blocks
-
 
281
        ; 3. add AG relative block number
-
 
282
 
-
 
283
        ; 1.
-
 
284
        mov     ecx, [ebp + XFS.agblklog]
-
 
285
        shrd    eax, edx, cl
-
 
286
        shr     edx, cl
-
 
287
        ; 2.
-
 
288
        mul     dword[ebp + XFS.agblocks]
-
 
289
        pop     ecx
-
 
290
        pop     esi
-
 
291
        and     ecx, dword[ebp + XFS.agblockmask + 0]
-
 
292
        and     esi, dword[ebp + XFS.agblockmask + 4]
-
 
293
        ; 3.
-
 
294
        add     eax, ecx
-
 
295
        adc     edx, esi
-
 
296
 
410
; ebx -- buffer
-
 
411
;---------------------------------------------------------------
Line 297... Line 412...
297
;DEBUGF 1,"read block: 0x%x%x\n",edx,eax
412
proc xfs._.read_block
298
        ; there is no way to read file system block at once, therefore we
-
 
299
        ; 1. calculate the number of sectors first
413
        movi    ecx, 1
300
        ; 2. and then read them in series
414
        call    xfs._.read_blocks
301
 
415
        ret
302
        ; 1.
416
endp
303
        mov     ecx, [ebp + XFS.blockmsectlog]
417
 
304
        shld    edx, eax, cl
418
 
305
        shl     eax, cl
-
 
306
        mov     esi, [ebp + XFS.sectpblock]
419
proc xfs._.blkrel2sectabs uses esi
307
 
420
        push    edx eax
308
        ; 2.
-
 
309
  .next_sector:
421
 
310
        push    eax edx
-
 
311
        call    fs_read32_sys
-
 
312
        mov     ecx, eax
422
        ; XFS block numbers are AG relative
313
        pop     edx eax
423
        ; they come in bitfield form of concatenated AG and block numbers
314
        test    ecx, ecx
-
 
315
        jnz     .error
424
        ; to get absolute block number for fs_read64_sys we should
316
        add     eax, 1                          ; be ready to fs_read64_sys
425
        ; 1. get AG number and multiply it by the AG size in blocks
-
 
426
        ; 2. extract and add AG relative block number
Line 317... Line -...
317
        adc     edx, 0
-
 
318
        add     ebx, [ebp + XFS.sectsize]       ; update buffer offset
-
 
319
        dec     esi
-
 
320
        jnz     .next_sector
-
 
321
 
-
 
322
  .quit:
-
 
323
        xor     eax, eax
-
 
324
        pop     esi ebx
-
 
325
        ret
-
 
326
  .error:
-
 
327
        mov     eax, ecx
-
 
328
        pop     esi ebx
-
 
329
        ret
-
 
330
 
-
 
331
 
-
 
Line 332... Line 427...
332
;---------------------------------------------------------------
427
 
333
; push buffer
428
        ; 1.
334
; push startblock_hi
429
        mov     ecx, [ebp+XFS.agblklog]
335
; push startblock_lo
430
        shrd    eax, edx, cl
336
; call xfs_read_dirblock
-
 
337
; test eax, eax
431
        shr     edx, cl
338
;---------------------------------------------------------------
432
        mul     [ebp+XFS.agblocks]
339
xfs_read_dirblock:
433
        ; 2.
-
 
434
        pop     ecx esi
Line 340... Line 435...
340
;mov eax, [esp + 4]
435
        and     ecx, [ebp+XFS.agblockmask.lo]
341
;mov edx, [esp + 8]
-
 
342
;DEBUGF 1,"read dirblock at: %d %d\n",edx,eax
-
 
343
;DEBUGF 1,"dirblklog: %d\n",[ebp + XFS.dirblklog]
-
 
344
        push    ebx esi
-
 
345
 
436
        and     esi, [ebp+XFS.agblockmask.hi]
346
        mov     eax, [esp + 12]         ; startblock_lo
437
        add     eax, ecx
347
        mov     edx, [esp + 16]         ; startblock_hi
-
 
348
        mov     ebx, [esp + 20]         ; buffer
438
        adc     edx, esi
349
 
-
 
350
        ; dirblock >= block
439
 
351
        ; read dirblocks by blocks
440
        mov     ecx, [ebp+XFS.sectpblog]
352
 
441
        shld    edx, eax, cl
353
        mov     ecx, [ebp + XFS.dirblklog]
-
 
354
        mov     esi, 1
442
        shl     eax, cl
355
        shl     esi, cl
443
        ret
356
  .next_block:
444
endp
357
        push    eax edx
445
 
358
        call    xfs_read_block
-
 
359
        mov     ecx, eax
446
 
360
        pop     edx eax
447
;---------------------------------------------------------------
361
        test    ecx, ecx
448
; start block number
362
        jnz     .error
449
; edx:eax -- block
363
        add     eax, 1          ; be ready to fs_read64_sys
450
; ebx -- buffer
364
        adc     edx, 0
451
; ecx -- count
365
        add     ebx, [ebp + XFS.blocksize]
-
 
366
        dec     esi
452
;---------------------------------------------------------------
-
 
453
proc xfs._.read_blocks
Line 367... Line -...
367
        jnz     .next_block
-
 
368
 
-
 
369
  .quit:
454
        push    ecx
370
        xor     eax, eax
455
        call    xfs._.blkrel2sectabs
371
        pop     esi ebx
456
        pop     ecx
372
        ret     12
457
        imul    ecx, [ebp+XFS.sectpblock]
373
  .error:
458
        call    fs_read64_sys
374
        mov     eax, ecx
459
        test    eax, eax
375
        pop     esi ebx
460
        ret
376
        ret     12
461
endp
377
 
462
 
378
 
-
 
379
;---------------------------------------------------------------
-
 
380
; push buffer
-
 
381
; push inode_hi
-
 
382
; push inode_lo
463
 
383
; call xfs_read_inode
-
 
384
; test eax, eax
-
 
385
;---------------------------------------------------------------
-
 
386
xfs_read_inode:
-
 
387
;DEBUGF 1,"reading inode: 0x%x%x\n",[esp+8],[esp+4]
-
 
388
        push    ebx
-
 
389
        mov     eax, [esp + 8]  ; inode_lo
-
 
390
        mov     edx, [esp + 12] ; inode_hi
-
 
391
        mov     ebx, [esp + 16] ; buffer
-
 
Line 392... Line -...
392
 
-
 
393
        ; inodes are packed into blocks
-
 
394
        ; 1. calculate block number
-
 
395
        ; 2. read the block
-
 
396
        ; 3. add inode offset to block base address
-
 
397
 
-
 
398
        ; 1.
-
 
399
        mov     ecx, [ebp + XFS.inodetoblocklog]
-
 
400
        shrd    eax, edx, cl
-
 
401
        shr     edx, cl
-
 
402
        ; 2.
-
 
403
        call    xfs_read_block
-
 
404
        test    eax, eax
-
 
405
        jnz     .error
-
 
406
 
-
 
407
        ; note that inode numbers should be first extracted from bitfields using mask
-
 
408
 
-
 
409
        mov     eax, [esp + 8]
-
 
410
        mov     edx, 1
464
proc xfs._.read_dirblock uses ebx, _startblock:qword, _buffer
411
        mov     ecx, [ebp + XFS.inopblog]
-
 
412
        shl     edx, cl
-
 
413
        dec     edx             ; get inode number mask
-
 
414
        and     eax, edx        ; apply mask
-
 
415
        mov     ecx, [ebp + XFS.inodelog]
-
 
416
        shl     eax, cl
-
 
417
        add     ebx, eax
-
 
418
 
-
 
419
        cmp     word[ebx], XFS_DINODE_MAGIC     ; test signature
-
 
420
        jne     .error
-
 
421
  .quit:
-
 
422
        xor     eax, eax
-
 
423
        mov     edx, ebx
-
 
424
        pop     ebx
-
 
425
        ret     12
-
 
426
  .error:
-
 
427
        movi    eax, ERROR_FS_FAIL
-
 
428
        mov     edx, ebx
-
 
429
        pop     ebx
-
 
430
        ret     12
-
 
431
 
-
 
432
 
465
        mov     eax, dword[_startblock+DQ.lo]
433
;----------------------------------------------------------------
-
 
434
; push encoding         ; ASCII / UNICODE
-
 
435
; push src              ; inode
-
 
436
; push dst              ; bdfe
-
 
437
; push entries_to_read
-
 
438
; push start_number     ; from 0
466
        mov     edx, dword[_startblock+DQ.hi]
439
;----------------------------------------------------------------
-
 
440
xfs_dir_get_bdfes:
-
 
441
DEBUGF 1,"xfs_dir_get_bdfes: %d entries from %d\n",[esp+8],[esp+4]
-
 
442
        sub     esp, 4     ; local vars
467
        mov     ebx, [_buffer]
443
        push    ecx edx esi edi
468
        mov     ecx, [ebp+XFS.blkpdirblk]
444
 
-
 
445
        mov     ebx, [esp + 36]         ; src
-
 
446
        mov     edx, [esp + 32]         ; dst
-
 
447
        mov     ecx, [esp + 24]         ; start_number
-
 
448
 
469
        call    xfs._.read_blocks
449
        ; define directory ondisk format and jump to corresponding label
-
 
450
 
-
 
451
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_LOCAL
-
 
452
        jne     .not_shortdir
-
 
453
        jmp     .shortdir
-
 
454
  .not_shortdir:
470
        ret
455
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
-
 
456
        jne     .not_blockdir
471
endp
457
        mov     eax, [ebx + xfs_inode.di_core.di_nextents]
-
 
458
        bswap   eax
-
 
459
        cmp     eax, 1
-
 
Line 460... Line -...
460
        jne     .not_blockdir
-
 
461
        jmp     .blockdir
-
 
Line 462... Line 472...
462
  .not_blockdir:
472
 
463
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
473
 
464
        jne     .not_leafdir
474
;---------------------------------------------------------------
465
        mov     eax, [ebx + xfs_inode.di_core.di_nextents]
-
 
466
        bswap   eax
475
; test eax, eax
467
        cmp     eax, 4
-
 
468
        ja      .not_leafdir
-
 
469
        jmp     .leafdir
-
 
470
  .not_leafdir:
-
 
471
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
-
 
472
        jne     .not_nodedir
-
 
473
        jmp     .nodedir
-
 
474
  .not_nodedir:
476
;---------------------------------------------------------------
-
 
477
proc xfs_read_inode uses ebx, _inode_lo, _inode_hi, _buffer
-
 
478
        mov     eax, [_inode_lo]
475
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
479
        mov     edx, [_inode_hi]
-
 
480
        mov     ebx, [_buffer]
-
 
481
        ; inodes are packed into blocks
-
 
482
        ; 1. calculate block number
-
 
483
        ; 2. read the block
-
 
484
        ; 3. add inode offset to block base address
-
 
485
        ; 1.
-
 
486
        mov     ecx, [ebp+XFS.inopblog]
-
 
487
        shrd    eax, edx, cl
-
 
488
        shr     edx, cl
-
 
489
        ; 2.
-
 
490
        call    xfs._.read_block
-
 
491
        jnz     .error
-
 
492
        ; inode numbers should be first extracted from bitfields by mask
-
 
493
 
-
 
494
        mov     eax, [_inode_lo]
-
 
495
        mov     edx, 1
-
 
496
        mov     ecx, [ebp+XFS.inopblog]
-
 
497
        shl     edx, cl
Line 476... Line -...
476
        jne     .not_btreedir
-
 
Line 477... Line 498...
477
        jmp     .btreedir
498
        dec     edx             ; get inode number mask
-
 
499
        and     eax, edx        ; apply mask
478
  .not_btreedir:
500
        mov     ecx, [ebp+XFS.inodelog]
-
 
501
        shl     eax, cl
-
 
502
        add     ebx, eax
479
        movi    eax, ERROR_FS_FAIL
503
        xor     eax, eax
480
        jmp     .error
504
 
481
 
505
        cmp     [ebx+xfs_inode.di_core.di_magic], XFS_DINODE_MAGIC
482
        ; short form directory (all the data fits into inode)
506
        jz      .quit
483
  .shortdir:
507
        movi    eax, ERROR_FS_FAIL
-
 
508
.quit:
484
;DEBUGF 1,"shortdir\n",
509
        mov     edx, ebx
485
        movzx   eax, word[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.count]
510
.error:
486
        test    al, al                  ; is count zero?
511
        ret
487
        jnz     @f                      ; if not, use it (i8count must be zero then)
512
endp
488
        shr     eax, 8                  ; use i8count
513
 
489
    @@:
514
 
-
 
515
; skip ecx first entries
490
        add     eax, 1                  ; '..' and '.' are implicit
516
proc xfs._.dir_sf_skip _count
491
        mov     dword[edx + 0], 1       ; version
517
        mov     ecx, [_count]
492
        mov     [edx + 8], eax          ; total entries
-
 
493
        sub     eax, [esp + 24]         ; start number
518
.next:
494
        cmp     eax, [esp + 28]         ; entries to read
-
 
495
        jbe     @f
519
        dec     ecx
496
        mov     eax, [esp + 28]
520
        js      .quit
497
    @@:
521
        dec     [ebp+XFS.entries_left_in_dir]
498
        mov     [esp + 28], eax
-
 
499
        mov     [edx + 4], eax          ; number of actually read entries
-
 
500
        mov     [ebp + XFS.entries_read], eax
-
 
501
 
522
        js      .quit
502
        ; inode numbers are often saved as 4 bytes (iff they fit)
523
.self:
503
        ; compute the length of inode numbers
524
        bts     [ebp+XFS.dir_sf_self_done], 0
504
 
-
 
505
        mov     eax, 4          ; 4 by default
525
        jc      .parent
506
        cmp     byte[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.i8count], 0
-
 
507
        je      @f
-
 
508
        add     eax, eax        ; 4+4=8, iff i8count != 0
-
 
509
    @@:
-
 
510
        mov     dword[edx + 12], 0      ; reserved
-
 
511
        mov     dword[edx + 16], 0      ;
-
 
512
        mov     dword[edx + 20], 0      ;
-
 
513
        mov     dword[edx + 24], 0      ;
-
 
514
        mov     dword[edx + 28], 0      ;
-
 
515
        add     edx, 32
-
 
516
        lea     esi, [ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.parent + eax]
-
 
517
        dec     ecx
-
 
518
        js      .shortdir.fill
-
 
519
 
526
        jmp     .next
520
        ; skip some entries if the first entry to read is not 0
-
 
521
 
-
 
522
  .shortdir.skip:
527
.parent:
523
        test    ecx, ecx
-
 
524
        jz      .shortdir.skipped
-
 
525
        movzx   edi, byte[esi + xfs_dir2_sf_entry.namelen]
-
 
526
        lea     esi, [esi + xfs_dir2_sf_entry.name + edi]
-
 
527
        add     esi, eax
-
 
528
        dec     ecx
-
 
529
        jnz     .shortdir.skip
-
 
530
        mov     ecx, [esp + 28]         ; entries to read
-
 
531
        jmp     .shortdir.skipped
-
 
532
  .shortdir.fill:
-
 
533
        mov     ecx, [esp + 28]         ; total number
528
        bts     [ebp+XFS.dir_sf_parent_done], 0
534
        test    ecx, ecx
-
 
535
        jz      .quit
-
 
536
        push    ecx
529
        jc      .common
537
;DEBUGF 1,"ecx: %d\n",ecx
530
        jmp     .next
538
        lea     edi, [edx + 40]         ; get file name offset
531
.common:
539
;DEBUGF 1,"filename: ..\n"
-
 
540
        mov     dword[edi], '..'
-
 
541
        mov     edi, edx
-
 
542
        push    eax ebx edx esi
-
 
543
        stdcall xfs_get_inode_number_sf, dword[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.count], dword[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.parent + 4], dword[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.parent]
532
        movzx   eax, [esi+xfs_dir2_sf_entry.namelen]
544
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.tmp_inode]
533
        add     esi, xfs_dir2_sf_entry.name
545
;        test    eax, eax
534
        add     esi, eax
546
;        jnz     .error
-
 
547
        stdcall xfs_get_inode_info, edx, edi
-
 
548
        test    eax, eax
535
        add     esi, [ebp+XFS.ftype_size]
549
        pop     esi edx ebx eax
536
        add     esi, [ebp+XFS.shortform_inodelen]
550
        jnz     .error
537
        jmp     .next
551
        mov     ecx, [esp + 44]         ; file name encding
538
.quit:
552
        mov     [edx + 4], ecx
-
 
553
        add     edx, 304                ; ASCII only for now
539
        ret
-
 
540
endp
-
 
541
 
-
 
542
 
-
 
543
proc xfs._.dir_sf_read uses edi, _count
554
        pop     ecx
544
locals
-
 
545
        _dst dd ?
-
 
546
endl
-
 
547
.next:
-
 
548
        dec     [_count]
-
 
549
        js      .quit
555
        dec     ecx
550
        dec     [ebp+XFS.entries_left_in_dir]
-
 
551
        js      .quit
-
 
552
        mov     [_dst], edx
-
 
553
.self:
Line 556... Line -...
556
        jz      .quit
-
 
557
 
-
 
558
;        push    ecx
-
 
559
;        lea     edi, [edx + 40]
-
 
560
;DEBUGF 1,"filename: .\n"
-
 
561
;        mov     dword[edi], '.'
-
 
Line 562... Line -...
562
;        mov     edi, edx
-
 
563
;        push    eax edx
-
 
564
;        stdcall xfs_get_inode_info, [ebp + XFS.cur_inode], edi
-
 
565
;        test    eax, eax
-
 
566
;        pop     edx eax
554
        bts     [ebp+XFS.dir_sf_self_done], 0
567
;        jnz     .error
-
 
568
;        mov     ecx, [esp + 44]
-
 
569
;        mov     [edx + 4], ecx
-
 
570
;        add     edx, 304                ; ASCII only for now
-
 
571
;        pop     ecx
-
 
572
;        dec     ecx
555
        jc      .parent
573
;        jz      .quit
556
        lea     edi, [edx+bdfe.name]
574
 
-
 
575
        ; we skipped some entries
-
 
576
        ; now we fill min(required, present) number of bdfe's
557
        mov     dword[edi], '.'
577
 
558
        stdcall xfs_get_inode_info, [ebp+XFS.cur_inode], edx
578
  .shortdir.skipped:
559
        jmp     .common
579
;DEBUGF 1,"ecx: %d\n",ecx
-
 
580
        push    ecx
560
.parent:
581
        movzx   ecx, byte[esi + xfs_dir2_sf_entry.namelen]
561
        bts     [ebp+XFS.dir_sf_parent_done], 0
582
        add     esi, xfs_dir2_sf_entry.name
562
        jc      .not_special
583
        lea     edi, [edx + 40]         ; bdfe offset of file name
563
        lea     edi, [edx+bdfe.name]         ; get file name offset
584
;DEBUGF 1,"filename: |%s|\n",esi
564
        mov     dword[edi], '..'        ; terminator included
-
 
565
        mov     edi, edx
585
        rep movsb
566
        lea     edx, [ebx+xfs_dir2_sf.hdr.parent]
586
        mov     word[edi], 0            ; terminator (ASCIIZ)
567
        call    xfs._.get_inode_number_sf
587
 
568
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
588
        push    eax ebx ecx edx esi
569
        test    eax, eax
589
;        push    edx     ; for xfs_get_inode_info
570
        jnz     .error
590
        mov     edi, edx
-
 
591
        stdcall xfs_get_inode_number_sf, dword[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.count], [esi + 4], [esi]
-
 
592
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.tmp_inode]
-
 
593
;        test    eax, eax
571
        stdcall xfs_get_inode_info, edx, edi
594
;        jnz     .error
-
 
595
        stdcall xfs_get_inode_info, edx, edi
-
 
596
        test    eax, eax
572
        jmp     .common
597
        pop     esi edx ecx ebx eax
573
.not_special:
598
        jnz     .error
574
        movzx   ecx, [esi+xfs_dir2_sf_entry.namelen]
599
        mov     ecx, [esp + 44]         ; file name encoding
575
        add     esi, xfs_dir2_sf_entry.name
600
        mov     [edx + 4], ecx
576
        lea     edi, [edx+bdfe.name]
-
 
577
        stdcall xfs._.copy_filename
Line 601... Line -...
601
 
-
 
602
        add     edx, 304                ; ASCII only for now
-
 
603
        add     esi, eax
-
 
604
        pop     ecx
-
 
605
        dec     ecx
-
 
606
        jnz     .shortdir.skipped
-
 
607
        jmp     .quit
-
 
608
 
-
 
609
  .blockdir:
-
 
610
;DEBUGF 1,"blockdir\n"
-
 
611
        push    edx
-
 
612
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
578
        add     esi, [ebp+XFS.ftype_size]
613
        stdcall xfs_extent_unpack, eax
579
        mov     edi, edx
614
;DEBUGF 1,"extent.br_startoff  : 0x%x%x\n",[ebp+XFS.extent.br_startoff+4],[ebp+XFS.extent.br_startoff+0]
-
 
615
;DEBUGF 1,"extent.br_startblock: 0x%x%x\n",[ebp+XFS.extent.br_startblock+4],[ebp+XFS.extent.br_startblock+0]
-
 
616
;DEBUGF 1,"extent.br_blockcount: %d\n",[ebp+XFS.extent.br_blockcount]
580
        mov     edx, esi
617
;DEBUGF 1,"extent.br_state     : %d\n",[ebp+XFS.extent.br_state]
-
 
618
        stdcall xfs_read_dirblock, dword[ebp + XFS.extent.br_startblock + 0], dword[ebp + XFS.extent.br_startblock + 4], [ebp + XFS.cur_dirblock]
581
        call    xfs._.get_inode_number_sf
619
        test    eax, eax
-
 
620
        pop     edx
-
 
621
        jnz     .error
-
 
622
;DEBUGF 1,"dirblock signature: %s\n",[ebp+XFS.cur_dirblock]
-
 
623
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
624
        mov     dword[edx + 0], 1       ; version
-
 
625
        mov     eax, [ebp + XFS.dirblocksize]
-
 
626
        mov     ecx, [ebx + eax - sizeof.xfs_dir2_block_tail + xfs_dir2_block_tail.stale]
-
 
627
        mov     eax, [ebx + eax - sizeof.xfs_dir2_block_tail + xfs_dir2_block_tail.count]
-
 
628
        bswap   ecx
-
 
629
        bswap   eax
582
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
630
        sub     eax, ecx                ; actual number of entries = count - stale
-
 
631
        mov     [edx + 8], eax          ; total entries
-
 
632
;DEBUGF 1,"total entries: %d\n",eax
-
 
633
        sub     eax, [esp + 24]         ; start number
583
        test    eax, eax
634
        cmp     eax, [esp + 28]         ; entries to read
584
        jnz     .error
635
        jbe     @f
-
 
636
        mov     eax, [esp + 28]
-
 
637
    @@:
-
 
638
        mov     [esp + 28], eax
-
 
639
        mov     [edx + 4], eax          ; number of actually read entries
585
        stdcall xfs_get_inode_info, edx, edi
640
        mov     [ebp + XFS.entries_read], eax
-
 
641
;DEBUGF 1,"actually read entries: %d\n",eax
586
        add     esi, [ebp+XFS.shortform_inodelen]
642
        mov     dword[edx + 12], 0      ; reserved
-
 
643
        mov     dword[edx + 16], 0      ;
587
.common:
-
 
588
        mov     edx, [_dst]
-
 
589
        mov     eax, [ebp+XFS.bdfe_nameenc]
644
        mov     dword[edx + 20], 0      ;
590
        mov     [edx+bdfe.nameenc], eax
645
        mov     dword[edx + 24], 0      ;
591
        add     edx, [ebp+XFS.bdfe_len]
646
        mov     dword[edx + 28], 0      ;
592
        inc     [ebp+XFS.entries_read]
647
        add     ebx, xfs_dir2_block.u
593
        jmp     .next
648
 
594
.quit:
649
        mov     ecx, [esp + 24]         ; start entry number
595
        xor     eax, eax
650
                                        ; also means how many to skip
596
.error:
651
        test    ecx, ecx
597
        ret
-
 
598
endp
652
        jz      .blockdir.skipped
599
 
653
  .blockdir.skip:
600
 
654
        cmp     word[ebx + xfs_dir2_data_union.unused.freetag], XFS_DIR2_DATA_FREE_TAG
601
proc xfs._.readdir_sf uses esi, _src, _dst
655
        jne     @f
602
        mov     ebx, [_src]
-
 
603
        mov     edx, [_dst]
656
        movzx   eax, word[ebx + xfs_dir2_data_union.unused.length]
604
        mov     [ebp+XFS.dir_sf_self_done], 0
-
 
605
        mov     [ebp+XFS.dir_sf_parent_done], 0
657
        xchg    al, ah
606
        mov     [ebp+XFS.entries_read], 0
-
 
607
        movzx   eax, [ebx+xfs_dir2_sf.hdr.count]
658
        add     ebx, eax
608
        ; '..' and '.' are implicit
659
        jmp     .blockdir.skip
609
        add     eax, 2
660
    @@:
610
        mov     [ebp+XFS.entries_left_in_dir], eax
-
 
611
        mov     [edx+bdfe_hdr.total_cnt], eax
-
 
612
        ; inode numbers are often saved as 4 bytes (iff they fit)
-
 
613
        ; compute the length of inode numbers
-
 
614
        ; 8 iff i8count != 0, 4 otherwise
Line 661... Line -...
661
        movzx   eax, [ebx + xfs_dir2_data_union.xentry.namelen]
-
 
662
        lea     ebx, [ebx + xfs_dir2_data_union.xentry.name + eax + 2]       ; 2 bytes for 'tag'
-
 
663
        add     ebx, 7                  ; align on 8 bytes
-
 
664
        and     ebx, not 7
-
 
665
        dec     ecx
-
 
666
        jnz     .blockdir.skip
-
 
667
  .blockdir.skipped:
-
 
668
        mov     ecx, [edx + 4]          ; actually read entries
-
 
669
        test    ecx, ecx
-
 
670
        jz      .quit
-
 
671
        add     edx, 32                 ; set edx to the first bdfe
-
 
672
  .blockdir.next_entry:
-
 
673
        cmp     word[ebx + xfs_dir2_data_union.unused.freetag], XFS_NULL
-
 
Line -... Line 615...
-
 
615
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
-
 
616
        setnz   al
-
 
617
        lea     eax, [eax*4+4]
-
 
618
        mov     [ebp+XFS.shortform_inodelen], eax
-
 
619
        add     edx, sizeof.bdfe_hdr
-
 
620
        lea     esi, [ebx+xfs_dir2_sf.hdr.parent+eax]
674
        jne     @f
621
        stdcall xfs._.dir_sf_skip, [ebp+XFS.entries_to_skip]
-
 
622
        stdcall xfs._.dir_sf_read, [ebp+XFS.requested_cnt]
675
        movzx   eax, word[ebx + xfs_dir2_data_union.unused.length]
623
        ret
-
 
624
endp
676
        xchg    al, ah
625
 
-
 
626
 
-
 
627
proc xfs._.readdir_block _literal_area, _out_buf
-
 
628
        mov     ebx, [_literal_area]
-
 
629
        mov     [ebp+XFS.entries_read], 0
-
 
630
        mov     eax, ebx
-
 
631
        mov     ebx, [ebp+XFS.cur_dirblock]
677
        add     ebx, eax
632
        stdcall xfs._.extent_unpack, eax
-
 
633
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], ebx
-
 
634
        mov     edx, [_out_buf]
-
 
635
        jnz     .error
-
 
636
        mov     eax, [ebp+XFS.dir_block_magic]
-
 
637
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
-
 
638
        movi    eax, ERROR_FS_FAIL
-
 
639
        jnz     .error
678
        jmp     .blockdir.next_entry
640
        mov     eax, [ebp+XFS.dirblocksize]
-
 
641
        movbe   ecx, [ebx+eax-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.stale]
-
 
642
        movbe   eax, [ebx+eax-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.count]
679
    @@:
643
        sub     eax, ecx        ; actual number of entries = count - stale
-
 
644
        mov     [ebp+XFS.entries_left_in_dir], eax
-
 
645
        mov     [edx+bdfe_hdr.total_cnt], eax
-
 
646
 
-
 
647
        add     ebx, [ebp+XFS.dir_block_size]
-
 
648
        add     edx, sizeof.bdfe_hdr
680
        push    ecx
649
        mov     [_out_buf], edx
-
 
650
        lea     edi, [_out_buf]
-
 
651
.next:
-
 
652
        movi    eax, ERROR_SUCCESS
-
 
653
        cmp     [ebp+XFS.requested_cnt], 0
-
 
654
        jz      .quit
-
 
655
        cmp     [ebp+XFS.entries_left_in_dir], 0
-
 
656
        jz      .quit
Line 681... Line -...
681
        push    eax ebx ecx edx esi
-
 
682
        mov     edi, edx
-
 
683
        mov     edx, dword[ebx + xfs_dir2_data_union.xentry.inumber + 0]
-
 
684
        mov     eax, dword[ebx + xfs_dir2_data_union.xentry.inumber + 4]
-
 
685
        bswap   edx
-
 
686
        bswap   eax
-
 
687
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.tmp_inode]
-
 
688
        stdcall xfs_get_inode_info, edx, edi
-
 
689
        test    eax, eax
-
 
690
        pop     esi edx ecx ebx eax
-
 
691
        jnz     .error
-
 
692
        mov     ecx, [esp + 44]
-
 
693
        mov     [edx + 4], ecx
-
 
694
        lea     edi, [edx + 40]
-
 
695
        movzx   ecx, byte[ebx + xfs_dir2_data_union.xentry.namelen]
-
 
696
        lea     esi, [ebx + xfs_dir2_data_union.xentry.name]
-
 
697
;DEBUGF 1,"filename: |%s|\n",esi
-
 
698
        rep movsb
-
 
699
;        call    utf8_to_cp866
-
 
700
        mov     word[edi], 0            ; terminator
-
 
701
        lea     ebx, [esi + 2]          ; skip 'tag'
-
 
Line 702... Line -...
702
        add     ebx, 7                  ; xfs_dir2_data_entries are aligned to 8 bytes
-
 
703
        and     ebx, not 7
-
 
704
        add     edx, 304
-
 
705
        pop     ecx
-
 
706
        dec     ecx
-
 
707
        jnz     .blockdir.next_entry
-
 
708
        jmp     .quit
-
 
709
 
-
 
710
  .leafdir:
-
 
711
;DEBUGF 1,"readdir: leaf\n"
-
 
712
        mov     [ebp + XFS.cur_inode_save], ebx
-
 
713
        push    ebx ecx edx
-
 
714
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
-
 
715
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
-
 
716
        bswap   edx
-
 
717
        stdcall xfs_extent_list_read_dirblock, eax, [ebp + XFS.dir2_leaf_offset_blocks], 0, edx, 0xffffffff, 0xffffffff
-
 
718
        mov     ecx, eax
-
 
719
        and     ecx, edx
-
 
720
        inc     ecx
-
 
721
        pop     edx ecx ebx
-
 
722
        jz      .error
-
 
723
 
-
 
724
        mov     eax, [ebp + XFS.cur_dirblock]
657
        stdcall xfs._.dir_entry_skip_read, edi
725
        movzx   ecx, word[eax + xfs_dir2_leaf.hdr.stale]
-
 
726
        movzx   eax, word[eax + xfs_dir2_leaf.hdr.count]
-
 
727
        xchg    cl, ch
658
        jz      .next
728
        xchg    al, ah
-
 
729
        sub     eax, ecx
-
 
730
;DEBUGF 1,"total count: %d\n",eax
-
 
731
 
-
 
732
        mov     dword[edx + 0], 1       ; version
-
 
733
        mov     [edx + 8], eax          ; total entries
-
 
734
        sub     eax, [esp + 24]         ; start number
-
 
735
        cmp     eax, [esp + 28]         ; entries to read
-
 
736
        jbe     @f
-
 
737
        mov     eax, [esp + 28]
-
 
738
    @@:
-
 
739
        mov     [esp + 28], eax
-
 
740
        mov     [edx + 4], eax          ; number of actually read entries
-
 
741
 
-
 
742
        mov     dword[edx + 12], 0      ; reserved
-
 
743
        mov     dword[edx + 16], 0      ;
-
 
744
        mov     dword[edx + 20], 0      ;
-
 
745
        mov     dword[edx + 24], 0      ;
-
 
746
        mov     dword[edx + 28], 0      ;
-
 
747
 
-
 
748
        mov     eax, [ebp + XFS.cur_dirblock]
-
 
749
        add     eax, [ebp + XFS.dirblocksize]
-
 
750
        mov     [ebp + XFS.max_dirblockaddr], eax
-
 
751
        mov     dword[ebp + XFS.next_block_num + 0], 0
-
 
752
        mov     dword[ebp + XFS.next_block_num + 4], 0
-
 
753
 
-
 
754
        mov     ebx, [ebp + XFS.max_dirblockaddr]       ; to read dirblock immediately
-
 
755
        mov     ecx, [esp + 24]         ; start number
-
 
756
        test    ecx, ecx
-
 
757
        jz      .leafdir.skipped
-
 
758
  .leafdir.skip:
-
 
759
        cmp     ebx, [ebp + XFS.max_dirblockaddr]
-
 
760
        jne     @f
659
.error:
761
        push    ecx edx
-
 
762
        mov     ebx, [ebp + XFS.cur_inode_save]
-
 
763
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
-
 
764
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
-
 
765
        bswap   edx
-
 
766
        stdcall xfs_extent_list_read_dirblock, eax, dword[ebp + XFS.next_block_num + 0], dword[ebp + XFS.next_block_num + 4], edx, [ebp + XFS.dir2_leaf_offset_blocks], 0
-
 
767
        mov     ecx, eax
-
 
768
        and     ecx, edx
-
 
769
        inc     ecx
-
 
770
        jz      .error
-
 
771
        add     eax, 1
-
 
772
        adc     edx, 0
-
 
773
        mov     dword[ebp + XFS.next_block_num + 0], eax
-
 
774
        mov     dword[ebp + XFS.next_block_num + 4], edx
660
.quit:
775
        mov     ebx, [ebp + XFS.cur_dirblock]
661
        ret
776
        add     ebx, sizeof.xfs_dir2_data_hdr
662
endp
777
        pop     edx ecx
663
 
778
    @@:
664
 
779
        cmp     word[ebx + xfs_dir2_data_union.unused.freetag], XFS_DIR2_DATA_FREE_TAG
665
proc xfs._.readdir_leaf_node uses esi, _inode_data, _out_buf
780
        jne     @f
666
        mov     ebx, [_inode_data]
-
 
667
        mov     edx, [_out_buf]
-
 
668
        mov     [ebp+XFS.cur_inode_save], ebx
781
        movzx   eax, word[ebx + xfs_dir2_data_union.unused.length]
669
        mov     [ebp+XFS.entries_read], 0
782
        xchg    al, ah
670
        mov     eax, ebx
-
 
671
        add     eax, [ebp+XFS.inode_core_size]
783
        add     ebx, eax
672
        movbe   edx, [ebx+xfs_inode.di_core.di_nextents]
-
 
673
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
-
 
674
        mov     [ebp+XFS.offset_begin.lo], ecx
-
 
675
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
784
        jmp     .leafdir.skip
676
        mov     [ebp+XFS.offset_begin.hi], ecx
-
 
677
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.lo]
-
 
678
        mov     [ebp+XFS.offset_end.lo], ecx
-
 
679
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.hi]
785
    @@:
680
        mov     [ebp+XFS.offset_end.hi], ecx
786
        movzx   eax, [ebx + xfs_dir2_data_union.xentry.namelen]
681
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.leafn_calc_entries, 0
787
        lea     ebx, [ebx + xfs_dir2_data_union.xentry.name + eax + 2]       ; 2 for 'tag'
-
 
788
        add     ebx, 7
-
 
789
        and     ebx, not 7
682
        jnz     .error
790
        dec     ecx
683
        mov     eax, [ebp+XFS.entries_read]
791
        jnz     .leafdir.skip
684
        mov     edx, [_out_buf]
-
 
685
        mov     [edx+bdfe_hdr.total_cnt], eax
792
  .leafdir.skipped:
686
        mov     [ebp+XFS.entries_left_in_dir], eax
793
        mov     [ebp + XFS.entries_read], 0
687
        add     [_out_buf], sizeof.bdfe_hdr
794
        mov     ecx, [edx + 4]          ; actually read entries
688
        mov     [ebp+XFS.entries_read], 0
795
        test    ecx, ecx
689
        movbe   edx, [ebx+xfs_inode.di_core.di_nextents]
796
        jz      .quit
690
        mov     eax, ebx
-
 
691
        add     eax, [ebp+XFS.inode_core_size]
-
 
692
        lea     ecx, [_out_buf]
797
        add     edx, 32                 ; first bdfe entry
693
        push    ecx
798
  .leafdir.next_entry:
694
        mov     [ebp+XFS.offset_begin.lo], 0
-
 
695
        mov     [ebp+XFS.offset_begin.hi], 0
799
;DEBUGF 1,"next_extry\n"
696
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
-
 
697
        mov     [ebp+XFS.offset_end.lo], ecx
800
        cmp     ebx, [ebp + XFS.max_dirblockaddr]
698
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
801
        jne     .leafdir.process_current_block
699
        mov     [ebp+XFS.offset_end.hi], ecx
802
        push    ecx edx
700
        pop     ecx
803
        mov     ebx, [ebp + XFS.cur_inode_save]
701
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.dir_btree_skip_read, ecx
804
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
702
;        jnz     .error
-
 
703
.error:
805
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
704
.quit:
806
        bswap   edx
705
        ret
-
 
706
endp
807
        stdcall xfs_extent_list_read_dirblock, eax, dword[ebp + XFS.next_block_num + 0], dword[ebp + XFS.next_block_num + 4], edx, [ebp + XFS.dir2_leaf_offset_blocks], 0
707
 
-
 
708
 
Line 808... Line 709...
808
;DEBUGF 1,"RETVALUE: %d %d\n",edx,eax
709
proc xfs._.dir_entry_skip_read uses esi edi, _arg
809
        mov     ecx, eax
-
 
810
        and     ecx, edx
-
 
811
        inc     ecx
710
        cmp     [ebx+xfs_dir2_data_union.unused.freetag], XFS_NULL
812
        jnz     @f
711
        jnz     @f
813
        pop     edx ecx
712
        movzx   eax, [ebx+xfs_dir2_data_union.unused.length]
814
        jmp     .quit
713
        xchg    al, ah
815
    @@:
-
 
816
        add     eax, 1
-
 
817
        adc     edx, 0
-
 
818
        mov     dword[ebp + XFS.next_block_num + 0], eax
714
        add     ebx, eax
819
        mov     dword[ebp + XFS.next_block_num + 4], edx
715
        jmp     .quit
820
        mov     ebx, [ebp + XFS.cur_dirblock]
716
@@:
821
        add     ebx, sizeof.xfs_dir2_data_hdr
717
        cmp     [ebp+XFS.entries_to_skip], 0
822
        pop     edx ecx
-
 
823
  .leafdir.process_current_block:
-
 
824
        cmp     word[ebx + xfs_dir2_data_union.unused.freetag], XFS_DIR2_DATA_FREE_TAG
718
        jz      .read
825
        jne     @f
719
.skip:
826
        movzx   eax, word[ebx + xfs_dir2_data_union.unused.length]
-
 
827
        xchg    al, ah
-
 
828
        add     ebx, eax
720
        dec     [ebp+XFS.entries_to_skip]
829
        jmp     .leafdir.next_entry
721
        movzx   ecx, [ebx+xfs_dir2_data_union.xentry.namelen]
830
    @@:
722
        lea     ebx, [ebx+xfs_dir2_data_union.xentry.name+ecx+2]
831
        push    eax ebx ecx edx esi
-
 
832
        mov     edi, edx
-
 
833
        mov     edx, dword[ebx + xfs_dir2_data_union.xentry.inumber + 0]
-
 
834
        mov     eax, dword[ebx + xfs_dir2_data_union.xentry.inumber + 4]
723
        add     ebx, [ebp+XFS.ftype_size]
835
        bswap   edx
724
        jmp     .common
836
        bswap   eax
725
.read:
837
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.tmp_inode]
726
        dec     [ebp+XFS.requested_cnt]
838
        stdcall xfs_get_inode_info, edx, edi
-
 
839
        test    eax, eax
727
        inc     [ebp+XFS.entries_read]
840
        pop     esi edx ecx ebx eax
728
        mov     edi, [_arg]
841
        jnz     .error
729
        mov     edi, [edi]
842
        push    ecx
730
        movbe   edx, [ebx+xfs_dir2_data_union.xentry.inumber.lo]
-
 
731
        movbe   eax, [ebx+xfs_dir2_data_union.xentry.inumber.hi]
-
 
732
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.tmp_inode]
843
        mov     ecx, [esp + 44]
733
        stdcall xfs_get_inode_info, edx, edi
-
 
734
        jnz     .error
Line 844... Line -...
844
        mov     [edx + 4], ecx
-
 
845
        lea     edi, [edx + 40]
-
 
846
        movzx   ecx, byte[ebx + xfs_dir2_data_union.xentry.namelen]
-
 
847
        lea     esi, [ebx + xfs_dir2_data_union.xentry.name]
-
 
848
;DEBUGF 1,"filename: |%s|\n",esi
-
 
Line 849... Line -...
849
        rep movsb
-
 
850
        pop     ecx
735
        mov     edx, [_arg]
851
        mov     word[edi], 0
736
        mov     edx, [edx]
852
        lea     ebx, [esi + 2]  ; skip 'tag'
-
 
853
        add     ebx, 7          ; xfs_dir2_data_entries are aligned to 8 bytes
-
 
854
        and     ebx, not 7
-
 
855
        add     edx, 304        ; ASCII only for now
737
        mov     ecx, [ebp+XFS.bdfe_nameenc]
856
        inc     [ebp + XFS.entries_read]
738
        mov     [edx+bdfe.nameenc], ecx
857
        dec     ecx
739
        lea     edi, [edx+bdfe.name]
858
        jnz     .leafdir.next_entry
740
        movzx   ecx, [ebx+xfs_dir2_data_union.xentry.namelen]
-
 
741
        lea     esi, [ebx+xfs_dir2_data_union.xentry.name]
859
        jmp     .quit
742
        stdcall xfs._.copy_filename
860
 
743
        lea     ebx, [esi+2]  ; skip 'tag'
-
 
744
        add     ebx, [ebp+XFS.ftype_size]
-
 
745
        mov     eax, [_arg]
-
 
746
        mov     edx, [eax]
-
 
747
        add     edx, [ebp+XFS.bdfe_len]
-
 
748
        mov     [eax], edx
-
 
749
.common:
-
 
750
        sub     ebx, [ebp+XFS.cur_dirblock]
-
 
751
        add     ebx, 7          ; xfs_dir2_data_entries are aligned to 8 bytes
-
 
752
        and     ebx, not 7
-
 
753
        add     ebx, [ebp+XFS.cur_dirblock]
861
  .nodedir:
754
        dec     [ebp+XFS.entries_left_in_dir]
-
 
755
.quit:
-
 
756
        movi    eax, ERROR_SUCCESS
-
 
757
        cmp     esp, esp
-
 
758
.error:
-
 
759
        ret
-
 
760
endp
-
 
761
 
-
 
762
 
862
;DEBUGF 1,"readdir: node\n"
763
proc xfs._.dir_btree_skip_read uses ebx ecx edx esi edi, _cur_dirblock, _offset_lo, _offset_hi, _arg
863
        push    edx
764
        mov     ebx, [_cur_dirblock]
864
        mov     [ebp + XFS.cur_inode_save], ebx
765
        mov     eax, [ebp+XFS.dir_data_magic]
-
 
766
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
-
 
767
        movi    eax, ERROR_FS_FAIL
-
 
768
        jnz     .error
-
 
769
        mov     eax, ebx
-
 
770
        add     eax, [ebp+XFS.dirblocksize]
-
 
771
        mov     [ebp+XFS.max_dirblockaddr], eax
-
 
772
;        add     ebx, xfs_dir2_block.u
865
        mov     [ebp + XFS.entries_read], 0
773
        add     ebx, [ebp+XFS.dir_block_size]
866
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
774
.next:
867
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
775
        movi    eax, ERROR_SUCCESS
868
        bswap   edx
776
        cmp     [ebp+XFS.requested_cnt], 0
869
        stdcall xfs_dir2_node_get_numfiles, eax, edx, [ebp + XFS.dir2_leaf_offset_blocks]
777
        jz      .quit
-
 
778
        cmp     [ebp+XFS.entries_left_in_dir], 0
870
        pop     edx
779
        jz      .quit
-
 
780
        cmp     ebx, [ebp+XFS.max_dirblockaddr]
-
 
781
        jz      .quit
871
        test    eax, eax
782
        stdcall xfs._.dir_entry_skip_read, [_arg]
-
 
783
        jz      .next
Line 872... Line -...
872
        jnz     .error
-
 
873
        mov     eax, [ebp + XFS.entries_read]
-
 
874
        mov     [ebp + XFS.entries_read], 0
-
 
875
;DEBUGF 1,"numfiles: %d\n",eax
-
 
876
        mov     dword[edx + 0], 1       ; version
-
 
877
        mov     [edx + 8], eax          ; total entries
-
 
878
        sub     eax, [esp + 24]         ; start number
-
 
879
        cmp     eax, [esp + 28]         ; entries to read
-
 
880
        jbe     @f
-
 
881
        mov     eax, [esp + 28]
-
 
882
    @@:
-
 
883
        mov     [esp + 28], eax
-
 
884
        mov     [edx + 4], eax          ; number of actually read entries
-
 
885
 
-
 
886
        mov     dword[edx + 12], 0      ; reserved
-
 
887
        mov     dword[edx + 16], 0      ;
-
 
888
        mov     dword[edx + 20], 0      ;
-
 
889
        mov     dword[edx + 24], 0      ;
-
 
890
        mov     dword[edx + 28], 0      ;
-
 
891
 
-
 
892
        mov     eax, [ebp + XFS.cur_dirblock]
-
 
893
        add     eax, [ebp + XFS.dirblocksize]
-
 
894
        mov     [ebp + XFS.max_dirblockaddr], eax
-
 
895
        mov     dword[ebp + XFS.next_block_num + 0], 0
-
 
896
        mov     dword[ebp + XFS.next_block_num + 4], 0
-
 
897
 
-
 
898
        mov     ebx, [ebp + XFS.max_dirblockaddr]       ; to read dirblock immediately
-
 
899
        mov     ecx, [esp + 24]         ; start number
-
 
900
        test    ecx, ecx
-
 
901
        jz      .leafdir.skipped
-
 
902
        jmp     .leafdir.skip
-
 
903
 
-
 
904
  .btreedir:
-
 
905
;DEBUGF 1,"readdir: btree\n"
-
 
Line -... Line 784...
-
 
784
.error:
906
        mov     [ebp + XFS.cur_inode_save], ebx
785
.quit:
-
 
786
        ret
-
 
787
endp
-
 
788
 
-
 
789
 
-
 
790
proc xfs._.readdir_btree uses esi, _inode_data, _out_buf
-
 
791
        mov     [ebp+XFS.cur_inode_save], ebx
907
        push    ebx edx
792
        mov     [ebp+XFS.entries_read], 0
-
 
793
        mov     eax, [ebp+XFS.inodesize]
908
        mov     eax, [ebx + xfs_inode.di_core.di_nextents]
794
        sub     eax, xfs_inode.di_u
909
        bswap   eax
795
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
910
        mov     [ebp + XFS.ro_nextents], eax
796
        jecxz   @f
911
        mov     eax, [ebp + XFS.inodesize]
-
 
912
        sub     eax, xfs_inode.di_u
-
 
913
        sub     eax, sizeof.xfs_bmdr_block
797
        shl     ecx, 3
914
        shr     eax, 4
798
        mov     eax, ecx
915
;DEBUGF 1,"maxnumresc: %d\n",eax
-
 
916
        mov     edx, dword[ebx + xfs_inode.di_u + sizeof.xfs_bmdr_block + sizeof.xfs_bmbt_key*eax + 0]
-
 
917
        mov     eax, dword[ebx + xfs_inode.di_u + sizeof.xfs_bmdr_block + sizeof.xfs_bmbt_key*eax + 4]
-
 
918
        bswap   eax
-
 
919
        bswap   edx
-
 
920
        mov     ebx, [ebp + XFS.cur_block]
799
@@:
921
;DEBUGF 1,"read_block: %x %x ",edx,eax
800
        lea     edx, [ebx+xfs_inode.di_u]
922
        stdcall xfs_read_block
801
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
923
        pop     edx ebx
-
 
924
        test    eax, eax
802
        mov     [ebp+XFS.offset_begin.lo], ecx
925
        jnz     .error
-
 
926
;DEBUGF 1,"ok\n"
-
 
927
 
-
 
928
        mov     ebx, [ebp + XFS.cur_block]
-
 
929
        push    edx
-
 
930
        mov     [ebp + XFS.entries_read], 0
-
 
931
        lea     eax, [ebx + sizeof.xfs_bmbt_block]
-
 
932
        mov     edx, [ebp + XFS.ro_nextents]
-
 
933
        stdcall xfs_dir2_node_get_numfiles, eax, edx, [ebp + XFS.dir2_leaf_offset_blocks]
803
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
934
        pop     edx
-
 
935
        test    eax, eax
804
        mov     [ebp+XFS.offset_begin.hi], ecx
936
        jnz     .error
-
 
937
        mov     eax, [ebp + XFS.entries_read]
-
 
938
        mov     [ebp + XFS.entries_read], 0
805
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.lo]
939
;DEBUGF 1,"numfiles: %d\n",eax
-
 
940
 
-
 
941
        mov     dword[edx + 0], 1       ; version
-
 
942
        mov     [edx + 8], eax          ; total entries
-
 
943
        sub     eax, [esp + 24]         ; start number
-
 
944
        cmp     eax, [esp + 28]         ; entries to read
-
 
945
        jbe     @f
-
 
946
        mov     eax, [esp + 28]
-
 
947
    @@:
-
 
948
        mov     [esp + 28], eax
806
        mov     [ebp+XFS.offset_end.lo], ecx
949
        mov     [edx + 4], eax          ; number of actually read entries
-
 
950
 
-
 
951
        mov     dword[edx + 12], 0
-
 
952
        mov     dword[edx + 16], 0
-
 
953
        mov     dword[edx + 20], 0
-
 
954
        mov     dword[edx + 24], 0
-
 
955
        mov     dword[edx + 28], 0
-
 
956
 
-
 
957
        mov     eax, [ebp + XFS.cur_dirblock]   ; fsblock?
-
 
958
        add     eax, [ebp + XFS.dirblocksize]
-
 
959
        mov     [ebp + XFS.max_dirblockaddr], eax
-
 
960
        mov     dword[ebp + XFS.next_block_num + 0], 0
-
 
961
        mov     dword[ebp + XFS.next_block_num + 4], 0
-
 
962
 
-
 
963
        mov     ebx, [ebp + XFS.max_dirblockaddr]       ; to read dirblock immediately
-
 
964
        mov     ecx, [esp + 24]         ; start number
-
 
965
        test    ecx, ecx
-
 
966
        jz      .btreedir.skipped
-
 
967
;        jmp     .btreedir.skip
-
 
968
  .btreedir.skip:
-
 
969
        cmp     ebx, [ebp + XFS.max_dirblockaddr]
-
 
970
        jne     @f
-
 
971
        push    ecx edx
-
 
972
        mov     ebx, [ebp + XFS.cur_block]
-
 
973
        lea     eax, [ebx + sizeof.xfs_bmbt_block]
-
 
974
        mov     edx, [ebp + XFS.ro_nextents]
-
 
975
        stdcall xfs_extent_list_read_dirblock, eax, dword[ebp + XFS.next_block_num + 0], dword[ebp + XFS.next_block_num + 4], edx, [ebp + XFS.dir2_leaf_offset_blocks], 0
-
 
976
;DEBUGF 1,"RETVALUE: %d %d\n",edx,eax
-
 
977
        mov     ecx, eax
-
 
978
        and     ecx, edx
-
 
979
        inc     ecx
-
 
980
        jz      .error
-
 
981
        add     eax, 1
-
 
982
        adc     edx, 0
-
 
983
        mov     dword[ebp + XFS.next_block_num + 0], eax
-
 
984
        mov     dword[ebp + XFS.next_block_num + 4], edx
-
 
985
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
986
        add     ebx, sizeof.xfs_dir2_data_hdr
-
 
987
        pop     edx ecx
-
 
988
    @@:
-
 
989
        cmp     word[ebx + xfs_dir2_data_union.unused.freetag], XFS_DIR2_DATA_FREE_TAG
-
 
990
        jne     @f
-
 
991
        movzx   eax, word[ebx + xfs_dir2_data_union.unused.length]
-
 
992
        xchg    al, ah
-
 
993
        add     ebx, eax
-
 
994
        jmp     .btreedir.skip
807
        mov     ecx, [ebp+XFS.dir2_free_offset_blocks.hi]
995
    @@:
-
 
996
        movzx   eax, [ebx + xfs_dir2_data_union.xentry.namelen]
-
 
997
        lea     ebx, [ebx + xfs_dir2_data_union.xentry.name + eax + 2]       ; 2 for 'tag'
-
 
998
        add     ebx, 7
-
 
999
        and     ebx, not 7
-
 
1000
        dec     ecx
-
 
1001
        jnz     .btreedir.skip
-
 
1002
  .btreedir.skipped:
-
 
1003
        mov     [ebp + XFS.entries_read], 0
-
 
1004
        mov     ecx, [edx + 4]          ; actually read entries
808
        mov     [ebp+XFS.offset_end.hi], ecx
1005
        test    ecx, ecx
-
 
1006
        jz      .quit
-
 
1007
        add     edx, 32
-
 
1008
  .btreedir.next_entry:
-
 
1009
;mov eax, [ebp + XFS.entries_read]
-
 
1010
;DEBUGF 1,"next_extry: %d\n",eax
-
 
1011
        cmp     ebx, [ebp + XFS.max_dirblockaddr]
-
 
1012
        jne     .btreedir.process_current_block
809
        stdcall xfs._.walk_btree, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.leafn_calc_entries, 0, 1
1013
        push    ecx edx
-
 
1014
        mov     ebx, [ebp + XFS.cur_block]
-
 
1015
        lea     eax, [ebx + sizeof.xfs_bmbt_block]
810
        mov     eax, [ebp+XFS.entries_read]
1016
        mov     edx, [ebp + XFS.ro_nextents]
-
 
1017
        stdcall xfs_extent_list_read_dirblock, eax, dword[ebp + XFS.next_block_num + 0], dword[ebp + XFS.next_block_num + 4], edx, [ebp + XFS.dir2_leaf_offset_blocks], 0
-
 
1018
;DEBUGF 1,"RETVALUE: %d %d\n",edx,eax
811
        mov     edx, [_out_buf]
1019
        mov     ecx, eax
812
        mov     [edx+bdfe_hdr.total_cnt], eax
1020
        and     ecx, edx
-
 
1021
        inc     ecx
-
 
1022
        jnz     @f
-
 
1023
        pop     edx ecx
813
        mov     [ebp+XFS.entries_left_in_dir], eax
1024
        jmp     .quit
-
 
1025
    @@:
-
 
1026
        add     eax, 1
-
 
1027
        adc     edx, 0
-
 
1028
        mov     dword[ebp + XFS.next_block_num + 0], eax
814
        mov     [ebp+XFS.entries_read], 0
1029
        mov     dword[ebp + XFS.next_block_num + 4], edx
815
        add     [_out_buf], sizeof.bdfe_hdr
Line 1030... Line 816...
1030
        mov     ebx, [ebp + XFS.cur_dirblock]
816
        mov     eax, [ebp+XFS.inodesize]
1031
        add     ebx, sizeof.xfs_dir2_data_hdr
817
        sub     eax, xfs_inode.di_u
1032
        pop     edx ecx
818
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1033
  .btreedir.process_current_block:
819
        jecxz   @f
1034
        cmp     word[ebx + xfs_dir2_data_union.unused.freetag], XFS_DIR2_DATA_FREE_TAG
820
        shl     ecx, 3
-
 
821
        mov     eax, ecx
1035
        jne     @f
822
@@:
1036
        movzx   eax, word[ebx + xfs_dir2_data_union.unused.length]
823
        lea     edx, [ebx+xfs_inode.di_u]
1037
        xchg    al, ah
824
        mov     [ebp+XFS.offset_begin.lo], 0
1038
        add     ebx, eax
-
 
1039
        jmp     .btreedir.next_entry
825
        mov     [ebp+XFS.offset_begin.hi], 0
1040
    @@:
826
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.lo]
-
 
827
        mov     [ebp+XFS.offset_end.lo], ecx
1041
        push    eax ebx ecx edx esi
828
        mov     ecx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
1042
        mov     edi, edx
829
        mov     [ebp+XFS.offset_end.hi], ecx
1043
        mov     edx, dword[ebx + xfs_dir2_data_union.xentry.inumber + 0]
830
        mov     ecx, [_out_buf]
-
 
831
        push    ecx
-
 
832
        mov     ecx, esp
1044
        mov     eax, dword[ebx + xfs_dir2_data_union.xentry.inumber + 4]
833
        stdcall xfs._.walk_btree, edx, eax, xfs._.extent_iterate_dirblocks, xfs._.dir_btree_skip_read, ecx, 1
1045
        bswap   edx
834
        pop     ecx
-
 
835
.error:
-
 
836
.quit:
-
 
837
        ret
1046
        bswap   eax
838
endp
1047
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.tmp_inode]
839
 
-
 
840
 
-
 
841
proc xfs._.copy_filename uses eax
-
 
842
        mov     eax, [ebp+XFS.bdfe_nameenc]
-
 
843
        cmp     eax, 3
-
 
844
        jz      .utf8
1048
        stdcall xfs_get_inode_info, edx, edi
845
        cmp     eax, 2
-
 
846
        jz      .utf16
-
 
847
.cp866:
1049
        test    eax, eax
848
        call    unicode.utf8.decode
-
 
849
        call    unicode.cp866.encode
1050
        pop     esi edx ecx ebx eax
850
        stosb
1051
        jnz     .error
851
        test    ecx, ecx
1052
        push    ecx
852
        jnz     .cp866
-
 
853
        mov     byte[edi], 0
-
 
854
        jmp     .done
-
 
855
.utf16:
-
 
856
        call    unicode.utf8.decode
-
 
857
        call    unicode.utf16.encode
-
 
858
        stosw
-
 
859
        shr     eax, 16
-
 
860
        jz      @f
-
 
861
        stosw
1053
        mov     ecx, [esp + 44]
862
@@:
1054
        mov     [edx + 4], ecx
863
        test    ecx, ecx
1055
        lea     edi, [edx + 40]
-
 
1056
        movzx   ecx, byte[ebx + xfs_dir2_data_union.xentry.namelen]
-
 
1057
        lea     esi, [ebx + xfs_dir2_data_union.xentry.name]
-
 
1058
;DEBUGF 1,"filename: |%s|\n",esi
-
 
1059
        rep movsb
-
 
1060
        pop     ecx
-
 
1061
        mov     word[edi], 0
-
 
1062
        lea     ebx, [esi + 2]  ; skip 'tag'
-
 
1063
        add     ebx, 7          ; xfs_dir2_data_entries are aligned to 8 bytes
-
 
1064
        and     ebx, not 7
-
 
1065
        add     edx, 304
-
 
1066
        inc     [ebp + XFS.entries_read]
-
 
1067
        dec     ecx
-
 
1068
        jnz     .btreedir.next_entry
-
 
1069
        jmp     .quit
-
 
1070
 
-
 
1071
 
-
 
1072
  .quit:
-
 
1073
        pop     edi esi edx ecx
-
 
1074
        add     esp, 4  ; pop vars
-
 
1075
        xor     eax, eax
-
 
1076
;        mov     ebx, [esp + 8]
-
 
1077
        mov     ebx, [ebp + XFS.entries_read]
-
 
1078
DEBUGF 1,"xfs_dir_get_bdfes done: %d\n",ebx
-
 
1079
        ret     20
864
        jnz     .utf16
1080
  .error:
-
 
1081
        pop     edi esi edx ecx
-
 
1082
        add     esp, 4  ; pop vars
-
 
1083
        mov     eax, ERROR_FS_FAIL
-
 
1084
        movi    ebx, -1
-
 
1085
        ret     20
-
 
1086
 
-
 
1087
 
-
 
1088
;----------------------------------------------------------------
-
 
1089
; push inode_hi
-
 
1090
; push inode_lo
-
 
1091
; push name
-
 
1092
;----------------------------------------------------------------
-
 
1093
xfs_get_inode_short:
-
 
1094
        ; this function searches for the file in _current_ dir
-
 
1095
        ; it is called recursively for all the subdirs /path/to/my/file
-
 
1096
 
865
        mov     word[edi], 0
1097
;DEBUGF 1,"xfs_get_inode_short: %s\n",[esp+4]
-
 
1098
        mov     esi, [esp + 4]  ; name
-
 
1099
        movzx   eax, word[esi]
-
 
1100
        cmp     eax, '.'        ; current dir; it is already read, just return
-
 
1101
        je      .quit
-
 
1102
        cmp     eax, './'       ; same thing
-
 
1103
        je      .quit
-
 
1104
 
866
        jmp     .done
1105
        ; read inode
-
 
1106
 
-
 
1107
        mov     eax, [esp + 8]  ; inode_lo
867
.utf8:
1108
        mov     edx, [esp + 12] ; inode_hi
-
 
1109
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.cur_inode]
868
        rep movsb
1110
        test    eax, eax
869
        mov     byte[edi], 0
-
 
870
.done:
-
 
871
        ret
-
 
872
endp
-
 
873
 
-
 
874
;----------------------------------------------------------------
-
 
875
; src              ; inode
-
 
876
; dst              ; bdfe
-
 
877
; start_number     ; from 0
-
 
878
;----------------------------------------------------------------
-
 
879
proc xfs._.readdir uses ebx esi edi, _start_number, _entries_to_read, _dst, _src, _encoding
-
 
880
        mov     ecx, [_start_number]
Line 1111... Line -...
1111
        movi    eax, ERROR_FS_FAIL
-
 
1112
        jnz     .error
-
 
1113
 
-
 
1114
        ; find file name in directory
-
 
1115
        ; switch directory ondisk format
-
 
1116
 
-
 
1117
        mov     ebx, edx
-
 
1118
        mov     [ebp + XFS.cur_inode_save], ebx
-
 
1119
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_LOCAL
-
 
1120
        jne     .not_shortdir
-
 
1121
;DEBUGF 1,"dir: shortdir\n"
-
 
1122
        jmp     .shortdir
-
 
Line 1123... Line 881...
1123
  .not_shortdir:
881
        mov     [ebp+XFS.entries_to_skip], ecx
-
 
882
        mov     eax, [_entries_to_read]
1124
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
883
        mov     [ebp+XFS.requested_cnt], eax
1125
        jne     .not_blockdir
884
        mov     eax, [_encoding]
1126
        mov     eax, [ebx + xfs_inode.di_core.di_nextents]
885
        mov     [ebp+XFS.bdfe_nameenc], eax
1127
        bswap   eax
886
        mov     ecx, 304
1128
        cmp     eax, 1
887
        cmp     eax, 1  ; CP866
1129
        jne     .not_blockdir
888
        jbe     @f
-
 
889
        mov     ecx, 560
-
 
890
@@:
1130
        jmp     .blockdir
891
        mov     [ebp+XFS.bdfe_len], ecx
-
 
892
        mov     edx, [_dst]
1131
  .not_blockdir:
893
        mov     [ebp+XFS.bdfe_buf], edx
1132
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
894
        mov     ebx, [_src]
-
 
895
        mov     [ebp+XFS.cur_inode_save], ebx
1133
        jne     .not_leafdir
896
 
1134
        mov     eax, [ebx + xfs_inode.di_core.di_nextents]
897
        mov     [edx+bdfe_hdr.version], 1
-
 
898
        mov     [edx+bdfe_hdr.zeroed+0x00], 0
-
 
899
        mov     [edx+bdfe_hdr.zeroed+0x04], 0
-
 
900
        mov     [edx+bdfe_hdr.zeroed+0x08], 0
1135
        bswap   eax
901
        mov     [edx+bdfe_hdr.zeroed+0x0c], 0
-
 
902
        mov     [edx+bdfe_hdr.zeroed+0x10], 0
1136
        cmp     eax, 4
903
 
-
 
904
        movzx   eax, [ebx+xfs_inode.di_core.di_format]
-
 
905
        ; switch directory ondisk format and jump to corresponding label
1137
        ja      .not_leafdir
906
        cmp     eax, XFS_DINODE_FMT_LOCAL
-
 
907
        jnz     @f
-
 
908
        add     ebx, [ebp+XFS.inode_core_size]
1138
        jmp     .leafdir
909
        stdcall xfs._.readdir_sf, ebx, [_dst]
1139
  .not_leafdir:
910
        test    eax, eax
1140
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
911
        jnz     .error
1141
        jne     .not_nodedir
912
        jmp     .quit
-
 
913
@@:
1142
        jmp     .nodedir
914
        cmp     eax, XFS_DINODE_FMT_BTREE
1143
  .not_nodedir:
915
        jnz     @f
-
 
916
        stdcall xfs._.readdir_btree, ebx, [_dst]
-
 
917
        jmp     .quit
1144
        cmp     byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
918
@@:
-
 
919
        cmp     eax, XFS_DINODE_FMT_EXTENTS
-
 
920
        movi    eax, ERROR_FS_FAIL
-
 
921
        jnz     .error
-
 
922
        call    xfs._.get_last_dirblock
-
 
923
        test    eax, eax
-
 
924
        jnz     @f
-
 
925
        add     ebx, [ebp+XFS.inode_core_size]
1145
        jne     .not_btreedir
926
        stdcall xfs._.readdir_block, ebx, [_dst]
1146
        jmp     .btreedir
927
        jmp     .quit
-
 
928
@@:
1147
  .not_btreedir:
929
        stdcall xfs._.readdir_leaf_node, ebx, [_dst]
-
 
930
        jmp     .quit
1148
DEBUGF 1,"NOT IMPLEMENTED: DIR FORMAT\n"
931
.quit:
-
 
932
        mov     edx, [_dst]
-
 
933
        mov     ebx, [ebp+XFS.entries_read]
-
 
934
        mov     [edx+bdfe_hdr.read_cnt], ebx
Line 1149... Line -...
1149
        jmp     .error
-
 
1150
 
-
 
1151
  .shortdir:
-
 
1152
  .shortdir.check_parent:
-
 
1153
        ; parent inode number in shortform directories is always implicit, check this case
-
 
1154
        mov     eax, [esi]
-
 
1155
        and     eax, 0x00ffffff
-
 
1156
        cmp     eax, '..'
-
 
1157
        je      .shortdir.parent2
-
 
1158
        cmp     eax, '../'
-
 
1159
        je      .shortdir.parent3
-
 
1160
        jmp     .shortdir.common
-
 
1161
  .shortdir.parent3:
-
 
1162
        inc     esi
-
 
1163
  .shortdir.parent2:
-
 
1164
        add     esi, 2
-
 
1165
        add     ebx, xfs_inode.di_u
-
 
1166
        stdcall xfs_get_inode_number_sf, dword[ebx + xfs_dir2_sf_hdr.count], dword[ebx + xfs_dir2_sf_hdr.parent + 4], dword[ebx + xfs_dir2_sf_hdr.parent]
-
 
1167
;DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
-
 
1168
        jmp     .quit
-
 
1169
 
-
 
Line -... Line 935...
-
 
935
        xor     eax, eax
1170
        ; not a parent inode?
936
.error:
1171
        ; search in the list, all the other files are stored uniformly
937
        ret
1172
 
938
endp
-
 
939
 
-
 
940
 
1173
  .shortdir.common:
941
; returns edx:eax inode or 0
-
 
942
proc xfs._.lookup_sf _name, _len
-
 
943
        add     ebx, [ebp+XFS.inode_core_size]
1174
        mov     eax, 4
944
        mov     esi, [_name]
1175
        movzx   edx, word[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.count] ; read count (byte) and i8count (byte) at once
945
        mov     ecx, [_len]
1176
        test    dl, dl          ; is count zero?
946
        cmp     ecx, 2
1177
        jnz     @f
947
        ja      .common
-
 
948
        jz      .check_parent
1178
        shr     edx, 8          ; use i8count
949
.check_self:
1179
        add     eax, eax        ; inode_num size
950
        cmp     byte[esi], '.'
1180
    @@:
951
        jnz     .common
1181
        lea     edi, [ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.parent + eax]
952
        mov     eax, [ebp+XFS.inode_self.lo]
1182
 
953
        mov     edx, [ebp+XFS.inode_self.hi]
1183
  .next_name:
954
        jmp     .quit
1184
        movzx   ecx, byte[edi + xfs_dir2_sf_entry.namelen]
955
.check_parent:
-
 
956
        cmp     word[esi], '..'
1185
        add     edi, xfs_dir2_sf_entry.name
957
        jnz     .common
1186
        mov     esi, [esp + 4]
958
        lea     edx, [ebx+xfs_dir2_sf.hdr.parent]
1187
;DEBUGF 1,"esi: %s\n",esi
959
        call    xfs._.get_inode_number_sf
-
 
960
        jmp     .quit
-
 
961
.common:
-
 
962
        movzx   edx, [ebx+xfs_dir2_sf.hdr.count]
1188
;DEBUGF 1,"edi: %s\n",edi
963
        movi    eax, 0
1189
        repe cmpsb
964
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
1190
        jne     @f
965
        setnz   al
1191
        cmp     byte[esi], 0            ; HINT: use adc here?
966
        lea     eax, [eax*4+4]
1192
        je      .found
967
        lea     edi, [ebx+xfs_dir2_sf.hdr.parent+eax]
1193
        cmp     byte[esi], '/'
968
.next_name:
1194
        je      .found_inc
969
        dec     edx
1195
    @@:
970
        jns     @f
1196
        add     edi, ecx
-
 
1197
        add     edi, eax
971
        movi    eax, ERROR_FILE_NOT_FOUND
1198
        dec     edx
972
        jmp     .error
1199
        jnz     .next_name
973
@@:
1200
        movi    eax, ERROR_FILE_NOT_FOUND
974
        movzx   ecx, [edi+xfs_dir2_sf_entry.namelen]
1201
        jmp     .error
975
        add     edi, xfs_dir2_sf_entry.name
1202
  .found_inc:           ; increment esi to skip '/' symbol
976
        mov     esi, [_name]
-
 
977
        cmp     ecx, [_len]
1203
                        ; this means esi always points to valid file name or zero terminator byte
978
        jnz     @f
1204
        inc     esi
979
        repz cmpsb
1205
  .found:
980
        jz      .found
1206
        stdcall xfs_get_inode_number_sf, dword[ebx + xfs_inode.di_u + xfs_dir2_sf_hdr.count], [edi + 4], [edi]
981
@@:
-
 
982
        add     edi, [ebp+XFS.ftype_size]
-
 
983
        add     edi, ecx
-
 
984
        add     edi, eax
-
 
985
        jmp     .next_name
-
 
986
.found:
-
 
987
        add     edi, [ebp+XFS.ftype_size]
-
 
988
        mov     edx, edi
-
 
989
        call    xfs._.get_inode_number_sf
-
 
990
.quit:
1207
;DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
991
        cmp     esp, esp
-
 
992
.error:
1208
        jmp     .quit
993
        ret
-
 
994
endp
-
 
995
 
1209
 
996
 
-
 
997
proc xfs._.lookup_block uses esi, _name, _len
-
 
998
        add     ebx, [ebp+XFS.inode_core_size]
1210
  .blockdir:
999
        mov     eax, ebx
-
 
1000
        mov     ebx, [ebp+XFS.cur_dirblock]
-
 
1001
        stdcall xfs._.extent_unpack, eax
1211
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
1002
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], ebx
1212
        stdcall xfs_extent_unpack, eax
1003
        jnz     .error
-
 
1004
        mov     eax, [ebp+XFS.dir_block_magic]
1213
        stdcall xfs_read_dirblock, dword[ebp + XFS.extent.br_startblock + 0], dword[ebp + XFS.extent.br_startblock + 4], [ebp + XFS.cur_dirblock]
1005
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
1214
        test    eax, eax
1006
        movi    eax, ERROR_FS_FAIL
1215
        jnz     .error
1007
        jnz     .error
-
 
1008
        stdcall xfs_hashname, [_name+4], [_len]
-
 
1009
        add     ebx, [ebp+XFS.dirblocksize]
-
 
1010
        movbe   ecx, [ebx-sizeof.xfs_dir2_block_tail+xfs_dir2_block_tail.count]
1216
;DEBUGF 1,"dirblock signature: %s\n",[ebp+XFS.cur_dirblock]
1011
        lea     edx, [ecx*sizeof.xfs_dir2_leaf_entry+sizeof.xfs_dir2_block_tail]
-
 
1012
        sub     ebx, edx
Line 1217... Line -...
1217
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
1218
        mov     eax, [ebp + XFS.dirblocksize]
-
 
1219
        mov     eax, [ebx + eax - sizeof.xfs_dir2_block_tail + xfs_dir2_block_tail.count]
-
 
1220
        ; note that we don't subtract xfs_dir2_block_tail.stale here,
-
 
1221
        ; since we need the number of leaf entries rather than file number
-
 
1222
        bswap   eax
-
 
1223
        add     ebx, [ebp + XFS.dirblocksize]
-
 
1224
;        mov     ecx, sizeof.xfs_dir2_leaf_entry
-
 
1225
        imul    ecx, eax, sizeof.xfs_dir2_leaf_entry
-
 
1226
        sub     ebx, sizeof.xfs_dir2_block_tail
-
 
1227
        sub     ebx, ecx
-
 
Line -... Line 1013...
-
 
1013
        stdcall xfs._.get_addr_by_hash, ebx, ecx
-
 
1014
        jnz     .error
-
 
1015
        mov     ebx, [ebp+XFS.cur_dirblock]
-
 
1016
        movbe   edx, [ebx+eax*XFS_DIR2_DATA_ALIGN+xfs_dir2_data_entry.inumber.lo]
-
 
1017
        movbe   eax, [ebx+eax*XFS_DIR2_DATA_ALIGN+xfs_dir2_data_entry.inumber.hi]
-
 
1018
.quit:
-
 
1019
.error:
-
 
1020
        ret
-
 
1021
endp
-
 
1022
 
1228
        shr     ecx, 3
1023
 
1229
        push    ecx     ; for xfs_get_inode_by_hash
1024
proc xfs._.get_inode_by_addr uses ebx esi edi, _inode_buf
1230
        push    ebx     ; for xfs_get_inode_by_hash
1025
        xor     edx, edx
-
 
1026
        shld    edx, eax, XFS_DIR2_DATA_ALIGN_LOG
-
 
1027
        shl     eax, XFS_DIR2_DATA_ALIGN_LOG
1231
 
1028
        mov     esi, [ebp+XFS.dirblocksize]
-
 
1029
        dec     esi
-
 
1030
        and     esi, eax
-
 
1031
        mov     ecx, [ebp+XFS.blocklog]
-
 
1032
        add     ecx, [ebp+XFS.dirblklog]
1232
        mov     edi, esi
1033
        shrd    eax, edx, cl
1233
        xor     eax, eax
1034
        shr     edx, cl
-
 
1035
        mov     ecx, [ebp+XFS.dirblklog]
-
 
1036
        shld    edx, eax, cl
1234
        mov     ecx, 4096       ; MAX_PATH_LEN
1037
        shl     eax, cl
1235
        repne scasb
1038
        mov     ebx, [_inode_buf]
1236
        movi    eax, ERROR_FS_FAIL
1039
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
-
 
1040
        jz      .extents
1237
        jne     .error
1041
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
-
 
1042
        jz      .btree
-
 
1043
        jmp     .error
-
 
1044
.extents:
-
 
1045
        movbe   ecx, [ebx+xfs_inode.di_core.di_nextents]
-
 
1046
        add     ebx, [ebp+XFS.inode_core_size]
-
 
1047
        mov     [ebp+XFS.offset_begin.lo], eax
Line -... Line 1048...
-
 
1048
        mov     [ebp+XFS.offset_begin.hi], edx
-
 
1049
        stdcall xfs._.extent_list.seek, ecx
-
 
1050
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
-
 
1051
        jnz     .error
-
 
1052
        jmp     .common
-
 
1053
.btree:
-
 
1054
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
-
 
1055
        shl     ecx, 3
1238
        neg     ecx
1056
        test    ecx, ecx
-
 
1057
        jnz     @f
-
 
1058
        mov     ecx, [ebp+XFS.inodesize]
-
 
1059
        sub     ecx, [ebp+XFS.inode_core_size]
-
 
1060
@@:
-
 
1061
        add     ebx, [ebp+XFS.inode_core_size]
-
 
1062
        stdcall xfs._.btree_read_block, ebx, ecx, eax, edx, [ebp+XFS.cur_dirblock]
-
 
1063
.common:
-
 
1064
        mov     ebx, [ebp+XFS.cur_dirblock]
1239
        add     ecx, 4096       ; MAX_PATH_LEN
1065
        mov     eax, [ebp+XFS.dir_data_magic]
-
 
1066
        cmp     [ebx+xfs_dir2_block.hdr.magic], eax
-
 
1067
        movi    eax, ERROR_FS_FAIL
-
 
1068
        jnz     .error
-
 
1069
        movbe   edx, [ebx+esi+xfs_dir2_data_entry.inumber.lo]
-
 
1070
        movbe   eax, [ebx+esi+xfs_dir2_data_entry.inumber.hi]
1240
        dec     ecx
1071
.error:
-
 
1072
.quit:
-
 
1073
        ret
-
 
1074
endp
-
 
1075
 
-
 
1076
 
1241
        mov     edx, ecx
1077
proc xfs._.lookup_leaf uses ebx esi edi, _name, _len
1242
;DEBUGF 1,"strlen total  : %d\n",edx
1078
        movbe   ecx, [ebx+xfs_inode.di_core.di_nextents]
1243
        mov     edi, esi
-
 
1244
        mov     eax, '/'
-
 
1245
        mov     ecx, edx
-
 
1246
        repne scasb
-
 
1247
        jne     @f
-
 
1248
        inc     ecx
-
 
1249
    @@:
-
 
1250
        neg     ecx
-
 
1251
        add     ecx, edx
-
 
1252
;DEBUGF 1,"strlen current: %d\n",ecx
-
 
1253
        stdcall xfs_hashname, esi, ecx
-
 
1254
        add     esi, ecx
-
 
1255
        cmp     byte[esi], '/'
-
 
1256
        jne     @f
-
 
1257
        inc     esi
-
 
1258
    @@:
-
 
1259
;DEBUGF 1,"hashed: 0x%x\n",eax
-
 
1260
;        bswap   eax
-
 
1261
        stdcall xfs_get_addr_by_hash
-
 
1262
        bswap   eax
-
 
1263
;DEBUGF 1,"got address: 0x%x\n",eax
-
 
1264
        cmp     eax, -1
-
 
1265
        jne     @f
-
 
1266
        movi    eax, ERROR_FILE_NOT_FOUND
-
 
1267
        mov     ebx, -1
-
 
1268
        jmp     .error
-
 
1269
    @@:
-
 
1270
        shl     eax, 3
-
 
1271
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
1272
        add     ebx, eax
-
 
1273
        mov     edx, [ebx + 0]
1079
        add     ebx, [ebp+XFS.inode_core_size]
1274
        mov     eax, [ebx + 4]
1080
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.lo]
-
 
1081
        mov     [ebp+XFS.offset_begin.lo], ecx
-
 
1082
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.hi]
1275
        bswap   edx
1083
        mov     [ebp+XFS.offset_begin.hi], ecx
1276
        bswap   eax
1084
        stdcall xfs._.extent_list.seek, ecx
-
 
1085
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
-
 
1086
        jnz     .error
-
 
1087
        mov     ebx, [ebp+XFS.cur_dirblock]
-
 
1088
        movzx   eax, [ebp+XFS.dir_leaf1_magic]
-
 
1089
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], ax
-
 
1090
        movi    eax, ERROR_FS_FAIL
1277
;DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
1091
        jnz     .error
-
 
1092
        stdcall xfs_hashname, [_name+4], [_len]
1278
        jmp     .quit
1093
        cmp     [ebp+XFS.version], 5
1279
 
1094
        jz      .v5
1280
  .leafdir:
-
 
1281
;DEBUGF 1,"dirblock signature: %s\n",[ebp+XFS.cur_dirblock]
-
 
1282
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
1095
.v4:
1283
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
1096
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1284
        bswap   edx
1097
        xchg    cl, ch
1285
        stdcall xfs_extent_list_read_dirblock, eax, [ebp + XFS.dir2_leaf_offset_blocks], 0, edx, -1, -1
1098
        add     ebx, xfs_dir2_leaf.ents
1286
;DEBUGF 1,"RETVALUE: %d %d\n",edx,eax
1099
        jmp     .vcommon
1287
        mov     ecx, eax
-
 
1288
        and     ecx, edx
1100
.v5:
1289
        inc     ecx
1101
        movzx   ecx, [ebx+xfs_dir3_leaf.hdr.count]
1290
        jz      .error
1102
        xchg    cl, ch
1291
 
1103
        add     ebx, xfs_dir3_leaf.ents
1292
        mov     ebx, [ebp + XFS.cur_dirblock]
1104
.vcommon:
1293
        movzx   eax, [ebx + xfs_dir2_leaf.hdr.count]
1105
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1294
        ; note that we don't subtract xfs_dir2_leaf.hdr.stale here,
1106
        jnz     .error
1295
        ; since we need the number of leaf entries rather than file number
-
 
1296
        xchg    al, ah
1107
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1297
        add     ebx, xfs_dir2_leaf.ents
1108
.quit:
1298
;        imul    ecx, eax, sizeof.xfs_dir2_leaf_entry
-
 
1299
;        shr     ecx, 3
1109
.error:
1300
        push    eax     ; for xfs_get_addr_by_hash: len
1110
        ret
1301
        push    ebx     ; for xfs_get_addr_by_hash: base
-
 
1302
 
1111
endp
1303
        mov     edi, esi
-
 
1304
        xor     eax, eax
1112
 
-
 
1113
 
1305
        mov     ecx, 4096       ; MAX_PATH_LEN
1114
proc xfs._.lookup_node uses ebx esi edi, _name, _len
1306
        repne scasb
1115
locals
1307
        movi    eax, ERROR_FS_FAIL
1116
        .hash dd ?
1308
        jne     .error
1117
endl
1309
        neg     ecx
1118
        mov     [ebp+XFS.cur_inode_save], ebx
1310
        add     ecx, 4096
-
 
1311
        dec     ecx
1119
        stdcall xfs_hashname, [_name+4], [_len]
Line 1312... Line -...
1312
        mov     edx, ecx
-
 
1313
;DEBUGF 1,"strlen total  : %d\n",edx
-
 
1314
        mov     edi, esi
-
 
Line 1315... Line 1120...
1315
        mov     eax, '/'
1120
        mov     [.hash], eax
1316
        mov     ecx, edx
1121
        mov     eax, ebx
1317
        repne scasb
-
 
1318
        jne     @f
1122
        add     eax, [ebp+XFS.inode_core_size]
-
 
1123
        movbe   edx, [ebx+xfs_inode.di_core.di_nextents]
1319
        inc     ecx
1124
        mov     esi, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1320
    @@:
1125
.begin:
1321
        neg     ecx
1126
        mov     ebx, [ebp+XFS.cur_inode_save]
1322
        add     ecx, edx
1127
        mov     eax, ebx
1323
;DEBUGF 1,"strlen current: %d\n",ecx
1128
        add     eax, [ebp+XFS.inode_core_size]
1324
        stdcall xfs_hashname, esi, ecx
1129
        movbe   edx, [ebx+xfs_inode.di_core.di_nextents]
1325
        add     esi, ecx
1130
        mov     ebx, eax
1326
        cmp     byte[esi], '/'
1131
        mov     [ebp+XFS.offset_begin.lo], esi
1327
        jne     @f
1132
        mov     [ebp+XFS.offset_begin.hi], 0
1328
        inc     esi
1133
        stdcall xfs._.extent_list.seek, edx
1329
    @@:
1134
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [ebp+XFS.cur_dirblock]
1330
;DEBUGF 1,"hashed: 0x%x\n",eax
1135
        jnz     .error
1331
        stdcall xfs_get_addr_by_hash
1136
        mov     ebx, [ebp+XFS.cur_dirblock]
1332
        bswap   eax
-
 
1333
;DEBUGF 1,"got address: 0x%x\n",eax
1137
        movzx   eax, [ebp+XFS.da_node_magic]
1334
        cmp     eax, -1
1138
        cmp     [ebx+xfs_da_intnode.hdr.info.magic], ax
1335
        jne     @f
-
 
1336
        movi    eax, ERROR_FILE_NOT_FOUND
1139
        jz      .node
1337
        mov     ebx, -1
1140
        movzx   eax, [ebp+XFS.dir_leafn_magic]
1338
        jmp     .error
1141
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], ax
1339
    @@:
1142
        jz      .leaf
-
 
1143
        movi    eax, ERROR_FS_FAIL
1340
 
1144
        jmp     .error
1341
        mov     ebx, [ebp + XFS.cur_inode_save]
1145
.node:
1342
        push    esi edi
-
 
1343
        xor     edi, edi
-
 
1344
        mov     esi, eax
1146
        cmp     [ebp+XFS.version], 5
1345
        shld    edi, esi, 3     ; get offset
1147
        jz      .node.v5
1346
        shl     esi, 3          ; 2^3 = 8 byte align
1148
.node.v4:
1347
        mov     edx, esi
1149
        lea     eax, [ebx+sizeof.xfs_da_intnode]
1348
        mov     ecx, [ebp + XFS.dirblklog]
1150
        movzx   edx, [ebx+xfs_da_intnode.hdr.count]
1349
        add     ecx, [ebp + XFS.blocklog]
1151
        jmp     .node.vcommon
1350
        mov     eax, 1
1152
.node.v5:
1351
        shl     eax, cl
1153
        lea     eax, [ebx+sizeof.xfs_da3_intnode]
1352
        dec     eax
1154
        movzx   edx, [ebx+xfs_da3_intnode.hdr.count]
1353
        and     edx, eax
1155
.node.vcommon:
1354
        push    edx
-
 
1355
        shrd    esi, edi, cl
-
 
1356
        shr     edi, cl
1156
        xchg    dl, dh
1357
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
-
 
1358
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
-
 
1359
        bswap   edx
1157
        stdcall xfs._.get_before_by_hashval, eax, edx, [.hash]
1360
        stdcall xfs_extent_list_read_dirblock, eax, esi, edi, edx, [ebp + XFS.dir2_leaf_offset_blocks], 0
1158
        jnz     .error
1361
;DEBUGF 1,"RETVALUE: %d %d\n",edx,eax
1159
        mov     esi, eax
1362
        pop     edx
1160
        jmp     .begin
1363
        pop     edi esi
1161
.leaf:
1364
        mov     ecx, eax
1162
        cmp     [ebp+XFS.version], 5
1365
        and     ecx, edx
1163
        jz      .leaf.v5
1366
        inc     ecx
1164
.leaf.v4:
1367
        jz      .error
1165
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1368
 
1166
        xchg    cl, ch
1369
        mov     ebx, [ebp + XFS.cur_dirblock]
1167
        add     ebx, xfs_dir2_leaf.ents
1370
        add     ebx, edx
1168
        jmp     .leaf.vcommon
1371
        mov     edx, [ebx + 0]
1169
.leaf.v5:
1372
        mov     eax, [ebx + 4]
-
 
1373
        bswap   edx
1170
        movzx   ecx, [ebx+xfs_dir3_leaf.hdr.count]
1374
        bswap   eax
1171
        xchg    cl, ch
1375
;DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
1172
        add     ebx, xfs_dir3_leaf.ents
1376
        jmp     .quit
-
 
1377
 
1173
.leaf.vcommon:
1378
  .nodedir:
1174
        mov     eax, [.hash]
1379
;DEBUGF 1,"lookupdir: node\n"
1175
        stdcall xfs._.get_addr_by_hash, ebx, ecx
-
 
1176
        jnz     .error
1380
        mov     [ebp + XFS.cur_inode_save], ebx
1177
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
1381
 
1178
.quit:
1382
        mov     edi, esi
1179
        cmp     esp, esp
Line 1383... Line -...
1383
        xor     eax, eax
-
 
1384
        mov     ecx, 4096       ; MAX_PATH_LEN
-
 
1385
        repne scasb
-
 
1386
        movi    eax, ERROR_FS_FAIL
-
 
1387
        jne     .error
-
 
1388
        neg     ecx
-
 
1389
        add     ecx, 4096       ; MAX_PATH_LEN
-
 
1390
        dec     ecx
-
 
Line 1391... Line -...
1391
        mov     edx, ecx
-
 
1392
;DEBUGF 1,"strlen total  : %d\n",edx
1180
        ret
1393
        mov     edi, esi
1181
.error:
1394
        mov     eax, '/'
1182
        test    esp, esp
1395
        mov     ecx, edx
1183
        ret
1396
        repne scasb
1184
endp
1397
        jne     @f
-
 
1398
        inc     ecx
1185
 
1399
    @@:
1186
 
1400
        neg     ecx
1187
proc xfs._.lookup_btree uses ebx esi edi, _name, _len
1401
        add     ecx, edx
-
 
1402
;DEBUGF 1,"strlen current: %d\n",ecx
1188
locals
1403
        stdcall xfs_hashname, esi, ecx
-
 
1404
        add     esi, ecx
-
 
1405
        cmp     byte[esi], '/'
-
 
1406
        jne     @f
-
 
1407
        inc     esi
-
 
1408
    @@:
1189
        .hash dd ?
1409
;DEBUGF 1,"hashed: 0x%x\n",eax
-
 
1410
        push    edi edx
-
 
1411
        mov     edi, eax
-
 
1412
        mov     [ebp + XFS.entries_read], 0
1190
endl
1413
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
-
 
1414
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
-
 
1415
        bswap   edx
-
 
1416
        stdcall xfs_dir2_lookupdir_node, eax, edx, [ebp + XFS.dir2_leaf_offset_blocks], edi
-
 
1417
        pop     edx edi
-
 
1418
        test    eax, eax
-
 
1419
        jnz     .error
-
 
1420
        bswap   ecx
-
 
1421
;DEBUGF 1,"got address: 0x%x\n",ecx
1191
        mov     [ebp+XFS.cur_inode_save], ebx
1422
 
1192
        stdcall xfs_hashname, [_name+4], [_len]
1423
        mov     ebx, [ebp + XFS.cur_inode_save]
-
 
1424
        push    esi edi
-
 
1425
        xor     edi, edi
-
 
1426
        mov     esi, ecx
-
 
1427
        shld    edi, esi, 3     ; get offset
-
 
1428
        shl     esi, 3          ; 8 byte align
1193
        mov     [.hash], eax
1429
        mov     edx, esi
-
 
1430
        mov     ecx, [ebp + XFS.dirblklog]
1194
        mov     edx, [ebp+XFS.dir2_leaf_offset_blocks.hi]
1431
        add     ecx, [ebp + XFS.blocklog]
-
 
1432
        mov     eax, 1
-
 
1433
        shl     eax, cl
-
 
1434
        dec     eax
-
 
1435
        and     edx, eax
-
 
1436
        push    edx
-
 
1437
        shrd    esi, edi, cl
-
 
1438
        shr     edi, cl
-
 
1439
        lea     eax, [ebx + xfs_inode.di_u + xfs_bmbt_rec.l0]
-
 
1440
        mov     edx, [ebx + xfs_inode.di_core.di_nextents]
-
 
1441
        bswap   edx
-
 
1442
        stdcall xfs_extent_list_read_dirblock, eax, esi, edi, edx, [ebp + XFS.dir2_leaf_offset_blocks], 0
-
 
1443
;DEBUGF 1,"RETVALUE: %d %d\n",edx,eax
-
 
1444
        pop     edx
-
 
1445
        pop     edi esi
-
 
1446
        mov     ecx, eax
-
 
1447
        and     ecx, edx
1195
        mov     eax, [ebp+XFS.dir2_leaf_offset_blocks.lo]
1448
        inc     ecx
1196
        jmp     .next_level.first
1449
        jz      .error
1197
.next_level:
1450
 
-
 
1451
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
1452
        add     ebx, edx
-
 
1453
        mov     edx, [ebx + 0]
-
 
1454
        mov     eax, [ebx + 4]
-
 
1455
        bswap   edx
1198
        lea     eax, [ebx+sizeof.xfs_da_intnode]
1456
        bswap   eax
-
 
1457
;DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
1199
        movzx   edx, [ebx+xfs_da_intnode.hdr.count]
1458
        jmp     .quit
-
 
1459
 
-
 
1460
  .btreedir:
-
 
1461
DEBUGF 1,"lookupdir: btree\n"
1200
        xchg    dl, dh
1462
        mov     [ebp + XFS.cur_inode_save], ebx
-
 
1463
 
1201
        stdcall xfs._.get_before_by_hashval, eax, edx, [.hash]
1464
        push    ebx edx
1202
        jnz     .error
1465
        mov     eax, [ebx + xfs_inode.di_core.di_nextents]
1203
        xor     edx, edx
1466
        bswap   eax
1204
.next_level.first:
1467
        mov     [ebp + XFS.ro_nextents], eax
-
 
1468
        mov     eax, [ebp + XFS.inodesize]
1205
        mov     ebx, [ebp+XFS.cur_inode_save]
1469
        sub     eax, xfs_inode.di_u
-
 
1470
        sub     eax, sizeof.xfs_bmdr_block
-
 
1471
        shr     eax, 4  ; FIXME forkoff
-
 
1472
;DEBUGF 1,"maxnumresc: %d\n",eax
-
 
1473
        mov     edx, dword[ebx + xfs_inode.di_u + sizeof.xfs_bmdr_block + sizeof.xfs_bmbt_key*eax + 0]
1206
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
1474
        mov     eax, dword[ebx + xfs_inode.di_u + sizeof.xfs_bmdr_block + sizeof.xfs_bmbt_key*eax + 4]
-
 
1475
        bswap   eax
1207
        shl     ecx, 3
1476
        bswap   edx
1208
        test    ecx, ecx
1477
        mov     ebx, [ebp + XFS.cur_block]
1209
        jnz     @f
1478
;DEBUGF 1,"read_block: %x %x ",edx,eax
1210
        mov     ecx, [ebp+XFS.inodesize]
1479
        stdcall xfs_read_block
-
 
1480
        pop     edx ebx
-
 
1481
        test    eax, eax
-
 
1482
        jnz     .error
-
 
1483
;DEBUGF 1,"ok\n"
-
 
1484
        mov     ebx, [ebp + XFS.cur_block]
-
 
1485
 
-
 
1486
        mov     edi, esi
1211
        sub     ecx, xfs_inode.di_u
1487
        xor     eax, eax
-
 
1488
        mov     ecx, 4096       ; MAX_PATH_LEN
1212
@@:
1489
        repne scasb
1213
        add     ebx, xfs_inode.di_u
1490
        movi    eax, ERROR_FS_FAIL
1214
        stdcall xfs._.btree_read_block, ebx, ecx, eax, edx, [ebp+XFS.cur_dirblock]
1491
        jne     .error
-
 
1492
        neg     ecx
-
 
1493
        add     ecx, 4096
-
 
1494
        dec     ecx
-
 
1495
        mov     edx, ecx
-
 
1496
DEBUGF 1,"strlen total  : %d\n",edx
-
 
1497
        mov     edi, esi
1215
        mov     ebx, [ebp+XFS.cur_dirblock]
1498
        mov     eax, '/'
1216
        cmp     [ebx+xfs_da_intnode.hdr.info.magic], XFS_DA_NODE_MAGIC
1499
        mov     ecx, edx
1217
        jz      .next_level
1500
        repne scasb
-
 
1501
        jne     @f
-
 
1502
        inc     ecx
1218
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], XFS_DIR2_LEAFN_MAGIC
1503
    @@:
-
 
1504
        neg     ecx
-
 
1505
        add     ecx, edx
-
 
1506
DEBUGF 1,"strlen current: %d\n",ecx
-
 
1507
        stdcall xfs_hashname, esi, ecx
-
 
1508
        add     esi, ecx
-
 
1509
        cmp     byte[esi], '/'
-
 
1510
        jne     @f
1219
        jz      .leafn
1511
        inc     esi
-
 
Line 1512... Line -...
1512
    @@:
-
 
1513
DEBUGF 1,"hashed: 0x%x\n",eax
-
 
Line -... Line 1220...
-
 
1220
        cmp     [ebx+xfs_dir2_leaf.hdr.info.magic], XFS_DIR2_LEAF1_MAGIC
-
 
1221
        jnz     .error
-
 
1222
        mov     eax, [.hash]
-
 
1223
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1514
        push    edi edx
1224
        xchg    cl, ch
1515
        mov     edi, eax
-
 
1516
        mov     [ebp + XFS.entries_read], 0
1225
        add     ebx, xfs_dir2_leaf.ents
1517
        lea     eax, [ebx + sizeof.xfs_bmbt_block]
1226
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1518
        mov     edx, [ebp + XFS.ro_nextents]
1227
        jnz     .error
1519
;push eax
-
 
1520
;mov eax, [ebp + XFS.dir2_leaf_offset_blocks]
1228
        mov     ebx, [ebp+XFS.cur_dirblock]
1521
;DEBUGF 1,": 0x%x %d\n",eax,eax
-
 
1522
;pop eax
-
 
1523
        stdcall xfs_dir2_lookupdir_node, eax, edx, [ebp + XFS.dir2_leaf_offset_blocks], edi
1229
        jmp     .got_addr
1524
        pop     edx edi
-
 
1525
        test    eax, eax
-
 
1526
        jnz     .error
1230
.leafn:
1527
        bswap   ecx
1231
        movzx   ecx, [ebx+xfs_dir2_leaf.hdr.count]
1528
DEBUGF 1,"got address: 0x%x\n",ecx
1232
        xchg    cl, ch
1529
 
1233
        add     ebx, xfs_dir2_leaf.ents
1530
        mov     ebx, [ebp + XFS.cur_block]
1234
        mov     eax, [.hash]
1531
        push    esi edi
1235
        stdcall xfs._.get_addr_by_hash, ebx, ecx
1532
        xor     edi, edi
-
 
1533
        mov     esi, ecx
1236
        jnz     .error
-
 
1237
        mov     ebx, [ebp+XFS.cur_block]
-
 
1238
.got_addr:
1534
        shld    edi, esi, 3  ; get offset
1239
        stdcall xfs._.get_inode_by_addr, [ebp+XFS.cur_inode_save]
-
 
1240
.quit:
1535
        shl     esi, 3
1241
        cmp     esp, esp
1536
        mov     edx, esi
1242
        ret
-
 
1243
.error:
-
 
1244
        test    esp, esp
1537
        mov     ecx, [ebp + XFS.dirblklog]
1245
        ret
1538
        add     ecx, [ebp + XFS.blocklog]
1246
endp
1539
        mov     eax, 1
1247
 
1540
        shl     eax, cl
1248
 
-
 
1249
; search for the _name in _inode dir
-
 
1250
; called for each /path/component/to/my/file
-
 
1251
; out:
1541
        dec     eax
1252
; ZF/zf   = ok/fail
-
 
1253
; edx:eax = inode/garbage:error
-
 
1254
proc xfs._.get_inode_short uses esi, _inode:qword, _len, _name
1542
        and     edx, eax
1255
        mov     esi, [_name]
-
 
1256
        mov     eax, dword[_inode+DQ.lo]
Line 1543... Line -...
1543
        push    edx
-
 
1544
        shrd    esi, edi, cl
-
 
1545
        shr     edi, cl
1257
        mov     edx, dword[_inode+DQ.hi]
1546
        lea     eax, [ebx + sizeof.xfs_bmbt_block]
1258
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1547
        mov     edx, [ebp + XFS.ro_nextents]
1259
        test    eax, eax
1548
        stdcall xfs_extent_list_read_dirblock, eax, esi, edi, edx, [ebp + XFS.dir2_leaf_offset_blocks], 0
1260
        movi    eax, ERROR_FS_FAIL
1549
;DEBUGF 1,"RETVALUE: %d %d\n",edx,eax
-
 
1550
        pop     edx
-
 
1551
        pop     edi esi
-
 
1552
        mov     ecx, eax
-
 
1553
        and     ecx, edx
-
 
1554
        inc     ecx
1261
        jnz     .error
1555
        jz      .error
1262
        ; switch directory ondisk format
1556
 
-
 
1557
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
1558
        add     ebx, edx
-
 
1559
        mov     edx, [ebx + 0]
-
 
1560
        mov     eax, [ebx + 4]
1263
        mov     ebx, edx
1561
        bswap   edx
-
 
1562
        bswap   eax
-
 
1563
DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
-
 
1564
        jmp     .quit
-
 
1565
 
-
 
1566
  .quit:
-
 
1567
        ret     12
1264
        mov     [ebp+XFS.cur_inode_save], ebx
1568
  .error:
-
 
1569
        xor     eax, eax
-
 
1570
        mov     edx, eax
-
 
1571
        ret     12
1265
        movzx   eax, [ebx+xfs_inode.di_core.di_format]
1572
 
-
 
1573
 
-
 
1574
;----------------------------------------------------------------
-
 
1575
; push name
-
 
1576
; call xfs_get_inode
1266
        cmp     eax, XFS_DINODE_FMT_LOCAL
1577
; test eax, eax
1267
        mov     edi, xfs._.lookup_sf
1578
;----------------------------------------------------------------
-
 
1579
xfs_get_inode:
1268
        jz      .lookup
1580
        ; call xfs_get_inode_short until file is found / error returned
-
 
1581
 
-
 
1582
;DEBUGF 1,"getting inode of: %s\n",[esp+4]
-
 
1583
        push    ebx esi edi
-
 
1584
 
1269
        cmp     eax, XFS_DINODE_FMT_BTREE
1585
        ; start from the root inode
1270
        mov     edi, xfs._.lookup_btree
1586
 
1271
        jz      .lookup
-
 
1272
        cmp     eax, XFS_DINODE_FMT_EXTENTS
-
 
1273
        jnz     .error
-
 
1274
        call    xfs._.get_last_dirblock
-
 
1275
        test    eax, eax
-
 
1276
        mov     edi, xfs._.lookup_block
-
 
1277
        jz      .lookup
-
 
1278
        cmp     edx, [ebp+XFS.dir2_free_offset_blocks.hi]
Line 1587... Line -...
1587
        mov     edx, dword[ebp + XFS.rootino + 4]       ; hi
-
 
1588
        mov     eax, dword[ebp + XFS.rootino + 0]       ; lo
-
 
1589
        mov     esi, [esp + 16] ; name
-
 
1590
 
-
 
1591
  .next_dir:
-
 
1592
        cmp     byte[esi], 0
-
 
1593
        je      .found
-
 
1594
 
1279
        mov     edi, xfs._.lookup_node
1595
;DEBUGF 1,"next_level: |%s|\n",esi
-
 
1596
        stdcall xfs_get_inode_short, esi, eax, edx
-
 
1597
        test    edx, edx
1280
        ja      .lookup
1598
        jnz     @f
1281
        cmp     eax, [ebp+XFS.dir2_free_offset_blocks.lo]
1599
        test    eax, eax
1282
        jae     .lookup
1600
        jz      .error
1283
        mov     edi, xfs._.lookup_leaf
-
 
1284
.lookup:
Line 1601... Line -...
1601
    @@:
-
 
1602
        jmp     .next_dir       ; file name found, go to next directory level
1285
        stdcall edi, [_name+4], [_len]
1603
 
-
 
1604
  .found:
-
 
1605
 
1286
.error:
1606
  .quit:
-
 
1607
        pop     edi esi ebx
1287
        ret
1608
        ret     4
-
 
1609
  .error:
-
 
1610
        pop     edi esi ebx
-
 
1611
        xor     eax, eax
-
 
1612
        mov     edx, eax
1288
endp
1613
        ret     4
1289
 
1614
 
1290
 
1615
 
1291
; ZF/zf   = ok/fail
1616
;----------------------------------------------------------------
1292
; edx:eax = inode/garbage:error
1617
; xfs_ReadFolder - XFS implementation of reading a folder
-
 
1618
; in:  ebp = pointer to XFS structure
-
 
1619
; in:  esi+[esp+4] = name
1293
proc xfs_get_inode uses ebx esi edi, _name
1620
; in:  ebx = pointer to parameters from sysfunc 70
1294
        ; call *._.get_inode_short until file is found / error returned
1621
; out: eax, ebx = return values for sysfunc 70
1295
        ; start from the root inode
1622
;----------------------------------------------------------------
1296
        mov     eax, [ebp+XFS.rootino.lo]
1623
xfs_ReadFolder:
-
 
1624
 
1297
        mov     edx, [ebp+XFS.rootino.hi]
1625
        ; to read folder
1298
        mov     esi, [_name]
Line 1626... Line -...
1626
        ; 1. lock partition
-
 
1627
        ; 2. find inode number
-
 
1628
        ; 3. read this inode
-
 
1629
        ; 4. get bdfe's
-
 
1630
        ; 5. unlock partition
-
 
1631
 
-
 
Line -... Line 1299...
-
 
1299
.next_dir:
1632
        ; 1.
1300
@@:
1633
        call    xfs_lock
1301
        cmp     byte[esi], '/'
1634
        push    ecx edx esi edi
1302
        jnz     @f
1635
 
-
 
1636
        ; 2.
-
 
1637
        push    ebx esi edi
1303
        inc     esi
1638
        add     esi, [esp + 32]         ; directory name
1304
        jmp     @b
1639
;DEBUGF 1,"xfs_ReadFolder: |%s|\n",esi
1305
@@:
1640
        stdcall xfs_get_inode, esi
1306
        cmp     byte[esi], 0
1641
        pop     edi esi ebx
-
 
1642
        mov     ecx, edx
1307
        jz      .found
1643
        or      ecx, eax
1308
        push    esi
1644
        jnz     @f
1309
        inc     esi
1645
        movi    eax, ERROR_FILE_NOT_FOUND
1310
@@:
1646
    @@:
-
 
1647
 
1311
        cmp     byte[esi], 0
1648
        ; 3.
1312
        jz      @f
1649
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.cur_inode]
1313
        cmp     byte[esi], '/'
1650
        test    eax, eax
-
 
1651
        movi    eax, ERROR_FS_FAIL
1314
        jz      @f
1652
        jnz     .error
-
 
1653
 
1315
        inc     esi
1654
        ; 4.
-
 
1655
        mov     eax, [ebx + 8]          ; encoding
1316
        jmp     @b
1656
        and     eax, 1
-
 
Line 1657... Line 1317...
1657
        stdcall xfs_dir_get_bdfes, [ebx + 4], [ebx + 12], [ebx + 16], edx, eax
1317
@@:
1658
        test    eax, eax
1318
        mov     ecx, esi
1659
        jnz     .error
-
 
1660
 
1319
        sub     ecx, [esp]
1661
  .quit:
1320
        mov     [ebp+XFS.inode_self.lo], eax
1662
;DEBUGF 1,"\n\n"
1321
        mov     [ebp+XFS.inode_self.hi], edx
1663
        pop     edi esi edx ecx
1322
        stdcall xfs._.get_inode_short, eax, edx, ecx      ; esi pushed above
Line 1664... Line 1323...
1664
        ; 5.
1323
        jz      .next_dir
1665
        call    xfs_unlock
-
 
1666
        xor     eax, eax
1324
.error:
1667
        ret
1325
.found:
1668
  .error:
1326
        ret
1669
;DEBUGF 1,"\n\n"
1327
endp
Line 1670... Line 1328...
1670
        pop     edi esi edx ecx
1328
 
1671
        push    eax
-
 
1672
        call    xfs_unlock
1329
 
1673
        pop     eax
1330
; in:  ebp = pointer to XFS structure
1674
        ret
1331
; in:  esi
1675
 
1332
; in:  ebx = pointer to parameters from sysfunc 70
Line 1676... Line -...
1676
 
-
 
1677
;----------------------------------------------------------------
1333
; out: eax, ebx = return values for sysfunc 70
1678
; push inode_num_hi
1334
; out: [edx] -- f70.1 out structure
1679
; push inode_num_lo
-
 
1680
; push [count]
-
 
1681
; call xfs_get_inode_number_sf
1335
proc xfs_ReadFolder uses esi edi
1682
;----------------------------------------------------------------
1336
        call    xfs._.lock
Line 1683... Line -...
1683
xfs_get_inode_number_sf:
-
 
1684
 
-
 
1685
        ; inode numbers in short form directories may be 4 or 8 bytes long
-
 
1686
        ; determine the length in run time and read inode number at given address
-
 
1687
 
-
 
Line -... Line 1337...
-
 
1337
        stdcall xfs_get_inode, esi
1688
        cmp     byte[esp + 4 + xfs_dir2_sf_hdr.i8count], 0      ; i8count == 0 means 4 byte per inode number
1338
        jnz     .error
1689
        je      .i4bytes
1339
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
1690
  .i8bytes:
1340
        test    eax, eax
1691
        mov     edx, [esp + 12] ; hi
-
 
1692
        mov     eax, [esp + 8]  ; lo
-
 
1693
        bswap   edx             ; big endian
1341
        jnz     .error
Line 1694... Line 1342...
1694
        bswap   eax
1342
        stdcall xfs._.readdir, [ebx+f70s1arg.start_idx], [ebx+f70s1arg.count], [ebx+f70s1arg.buf], edx, [ebx+f70s1arg.encoding]
1695
        ret     12
1343
        test    eax, eax
1696
  .i4bytes:
-
 
1697
        xor     edx, edx        ; no hi
1344
        jnz     .error
1698
        mov     eax, [esp + 12] ; hi = lo
1345
        mov     edx, [ebx+f70s1arg.buf]
1699
        bswap   eax             ; big endian
1346
        mov     ecx, [ebx+f70s1arg.count]
Line 1700... Line 1347...
1700
        ret     12
1347
        cmp     [edx+bdfe_hdr.read_cnt], ecx
1701
 
1348
        jz      .quit
1702
 
-
 
1703
;----------------------------------------------------------------
1349
        movi    eax, ERROR_END_OF_FILE
1704
; push dest
1350
.quit:
1705
; push src
1351
        mov     ebx, [edx+bdfe_hdr.read_cnt]
1706
; call xfs_get_inode_info
1352
 
Line 1707... Line 1353...
1707
;----------------------------------------------------------------
1353
.error:
1708
xfs_get_inode_info:
1354
        push    eax
1709
 
1355
        call    xfs._.unlock
1710
        ; get access time and other file properties
-
 
1711
        ; useful for browsing directories
-
 
1712
        ; called for each dir entry
-
 
1713
 
1356
        pop     eax
1714
;DEBUGF 1,"get_inode_info\n"
1357
        ret
1715
        xor     eax, eax
1358
endp
1716
        mov     edx, [esp + 4]
1359
 
1717
        movzx   ecx, word[edx + xfs_inode.di_core.di_mode]
1360
 
Line 1718... Line 1361...
1718
        xchg    cl, ch
1361
; edx -- pointer to inode number in big endian
1719
;DEBUGF 1,"di_mode: %x\n",ecx
-
 
1720
        test    ecx, S_IFDIR    ; directory?
1362
; ZF -- must be set at exit
1721
        jz      @f
1363
proc xfs._.get_inode_number_sf
1722
        mov     eax, 0x10       ; set directory flag
-
 
1723
    @@:
-
 
1724
 
-
 
1725
        mov     edi, [esp + 8]
-
 
1726
        mov     [edi + 0], eax
-
 
1727
        mov     eax, dword[edx + xfs_inode.di_core.di_size + 0] ; hi
-
 
1728
        bswap   eax
1364
        cmp     [ebx+xfs_dir2_sf.hdr.i8count], 0
1729
        mov     dword[edi + 36], eax    ; file size hi
-
 
1730
;DEBUGF 1,"file_size hi: %d\n",eax
1365
        jz      .i4bytes
1731
        mov     eax, dword[edx + xfs_inode.di_core.di_size + 4] ; lo
-
 
1732
        bswap   eax
-
 
1733
        mov     dword[edi + 32], eax    ; file size lo
-
 
1734
;DEBUGF 1,"file_size lo: %d\n",eax
-
 
1735
 
-
 
1736
        add     edi, 8
-
 
Line 1737... Line -...
1737
        mov     eax, [edx + xfs_inode.di_core.di_ctime.t_sec]
-
 
1738
        bswap   eax
-
 
Line 1739... Line 1366...
1739
        push    edx
1366
.i8bytes:
1740
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1367
        movbe   eax, [edx+DQ.hi]
1741
        call    fsTime2bdfe
1368
        movbe   edx, [edx+DQ.lo]
1742
        pop     edx
1369
        ret
1743
 
-
 
1744
        mov     eax, [edx + xfs_inode.di_core.di_atime.t_sec]
-
 
1745
        bswap   eax
-
 
1746
        push    edx
-
 
1747
        sub     eax, 978307200
1370
.i4bytes:
1748
        call    fsTime2bdfe
1371
        movbe   eax, [edx+DQ.lo]
1749
        pop     edx
1372
        xor     edx, edx
1750
 
1373
        ret
1751
        mov     eax, [edx + xfs_inode.di_core.di_mtime.t_sec]
1374
endp
1752
        bswap   eax
-
 
1753
        push    edx
1375
 
1754
        sub     eax, 978307200
1376
 
-
 
1377
proc xfs_get_inode_info uses ebx, _src, _dst
Line 1755... Line -...
1755
        call    fsTime2bdfe
-
 
1756
        pop     edx
-
 
1757
 
-
 
1758
  .quit:
1378
        ; get access time and other file properties
1759
        xor     eax, eax
1379
        ; useful for browsing directories
1760
        ret     8
-
 
1761
  .error:
-
 
1762
        movi    eax, ERROR_FS_FAIL
-
 
1763
        ret     8
1380
        ; called for each dir entry
1764
 
1381
        xor     eax, eax
1765
 
1382
        mov     edx, [_src]
1766
;----------------------------------------------------------------
-
 
1767
; push extent_data
-
 
1768
; call xfs_extent_unpack
1383
        movzx   ecx, [edx+xfs_inode.di_core.di_mode]
1769
;----------------------------------------------------------------
-
 
1770
xfs_extent_unpack:
1384
        xchg    cl, ch
1771
 
1385
        test    ecx, S_IFDIR
1772
        ; extents come as packet 128bit bitfields
1386
        jz      @f
1773
        ; lets unpack them to access internal fields
1387
        movi    eax, 0x10       ; set directory flag
1774
        ; write result to the XFS.extent structure
1388
@@:
1775
 
1389
        mov     edi, [_dst]
1776
        push    eax ebx ecx edx
1390
        mov     [edi+bdfe.attr], eax
1777
        mov     ebx, [esp + 20]
1391
        movbe   eax, [edx+xfs_inode.di_core.di_size.lo]
1778
 
-
 
1779
        xor     eax, eax
-
 
1780
        mov     edx, [ebx + 0]
1392
        mov     [edi+bdfe.size.hi], eax
1781
        bswap   edx
1393
        movbe   eax, [edx+xfs_inode.di_core.di_size.hi]
1782
        test    edx, 0x80000000         ; mask, see documentation
1394
        mov     [edi+bdfe.size.lo], eax
1783
        setnz   al
1395
 
1784
        mov     [ebp + XFS.extent.br_state], eax
-
 
1785
 
1396
        add     edi, 8
1786
        and     edx, 0x7fffffff         ; mask
1397
        movbe   eax, [edx+xfs_inode.di_core.di_ctime.t_sec]
1787
        mov     eax, [ebx + 4]
-
 
1788
        bswap   eax
1398
        push    edx
1789
        shrd    eax, edx, 9
1399
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1790
        shr     edx, 9
1400
        call    fsTime2bdfe
1791
        mov     dword[ebp + XFS.extent.br_startoff + 0], eax
-
 
1792
        mov     dword[ebp + XFS.extent.br_startoff + 4], edx
1401
        pop     edx
1793
 
1402
 
1794
        mov     edx, [ebx + 4]
1403
        movbe   eax, [edx+xfs_inode.di_core.di_atime.t_sec]
1795
        mov     eax, [ebx + 8]
1404
        push    edx
1796
        mov     ecx, [ebx + 12]
1405
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1797
        bswap   edx
1406
        call    fsTime2bdfe
1798
        bswap   eax
1407
        pop     edx
1799
        bswap   ecx
1408
 
-
 
1409
        movbe   eax, [edx+xfs_inode.di_core.di_mtime.t_sec]
Line 1800... Line 1410...
1800
        and     edx, 0x000001ff         ; mask
1410
        push    edx
1801
        shrd    ecx, eax, 21
1411
        sub     eax, 978307200  ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60
1802
        shrd    eax, edx, 21
1412
        call    fsTime2bdfe
1803
        mov     dword[ebp + XFS.extent.br_startblock + 0], ecx
1413
        pop     edx
1804
        mov     dword[ebp + XFS.extent.br_startblock + 4], eax
1414
 
1805
 
1415
        movi    eax, ERROR_SUCCESS
1806
        mov     eax, [ebx + 12]
1416
        cmp     esp, esp
1807
        bswap   eax
-
 
1808
        and     eax, 0x001fffff         ; mask
-
 
1809
        mov     [ebp + XFS.extent.br_blockcount], eax
-
 
1810
 
-
 
1811
        pop     edx ecx ebx eax
-
 
1812
;DEBUGF 1,"extent.br_startoff  : %d %d\n",[ebp+XFS.extent.br_startoff+4],[ebp+XFS.extent.br_startoff+0]
-
 
1813
;DEBUGF 1,"extent.br_startblock: %d %d\n",[ebp+XFS.extent.br_startblock+4],[ebp+XFS.extent.br_startblock+0]
-
 
1814
;DEBUGF 1,"extent.br_blockcount: %d\n",[ebp+XFS.extent.br_blockcount]
-
 
1815
;DEBUGF 1,"extent.br_state     : %d\n",[ebp+XFS.extent.br_state]
1417
        ret
1816
        ret     4
1418
endp
1817
 
-
 
1818
 
-
 
1819
;----------------------------------------------------------------
-
 
1820
; push namelen
1419
 
1821
; push name
-
 
1822
; call xfs_hashname
-
 
1823
;----------------------------------------------------------------
-
 
1824
xfs_hashname:   ; xfs_da_hashname
-
 
1825
 
1420
 
1826
        ; simple hash function
-
 
1827
        ; never fails)
1421
proc xfs._.extent_unpack uses eax ebx ecx edx, _extent_data
1828
 
1422
        ; extents come as packet 128bit bitfields
1829
        push    ecx esi
1423
        ; unpack them to access internal fields
1830
        xor     eax, eax
1424
        ; write result to the XFS.extent structure
1831
        mov     esi, [esp + 12] ; name
-
 
1832
        mov     ecx, [esp + 16] ; namelen
1425
        mov     ebx, [_extent_data]
1833
;mov esi, '.'
-
 
1834
;mov ecx, 1
1426
 
1835
;DEBUGF 1,"hashname: %d %s\n",ecx,esi
1427
        xor     eax, eax
1836
 
-
 
1837
    @@:
1428
        movbe   edx, [ebx+0]
1838
        rol     eax, 7
-
 
1839
        xor     al, [esi]
1429
        test    edx, 0x80000000         ; mask, see documentation
1840
        add     esi, 1
1430
        setnz   al
1841
        loop    @b
1431
        mov     [ebp+XFS.extent.br_state], eax
1842
 
1432
 
1843
        pop     esi ecx
1433
        and     edx, 0x7fffffff         ; mask
1844
        ret     8
1434
        movbe   eax, [ebx+4]
-
 
1435
        shrd    eax, edx, 9
-
 
1436
        shr     edx, 9
-
 
1437
        mov     [ebp+XFS.extent.br_startoff.lo], eax
-
 
1438
        mov     [ebp+XFS.extent.br_startoff.hi], edx
-
 
1439
 
-
 
1440
        movbe   edx, [ebx+4]
-
 
1441
        movbe   eax, [ebx+8]
-
 
1442
        movbe   ecx, [ebx+12]
-
 
1443
        and     edx, 0x000001ff         ; mask
-
 
1444
        shrd    ecx, eax, 21
-
 
1445
        shrd    eax, edx, 21
-
 
1446
        mov     [ebp+XFS.extent.br_startblock.lo], ecx
-
 
1447
        mov     [ebp+XFS.extent.br_startblock.hi], eax
-
 
1448
 
-
 
1449
        movbe   eax, [ebx+12]
-
 
1450
        and     eax, 0x001fffff         ; mask
-
 
1451
        mov     [ebp+XFS.extent.br_blockcount], eax
-
 
1452
        ret
-
 
1453
endp
-
 
1454
 
-
 
1455
 
-
 
1456
proc xfs_hashname uses ecx esi, _name, _len
-
 
1457
        xor     eax, eax
-
 
1458
        mov     esi, [_name]
-
 
1459
        mov     ecx, [_len]
-
 
1460
@@:
-
 
1461
        rol     eax, 7
-
 
1462
        xor     al, [esi]
-
 
1463
        add     esi, 1
-
 
1464
        dec     ecx
-
 
1465
        jnz     @b
-
 
1466
        ret
-
 
1467
endp
-
 
1468
 
-
 
1469
 
-
 
1470
; eax -- hash value
-
 
1471
proc xfs._.get_addr_by_hash uses ebx esi, _base, _len
-
 
1472
        ; look for the directory entry offset by its file name hash
-
 
1473
        ; allows fast file search for block, leaf and node directories
-
 
1474
        ; binary (ternary) search
-
 
1475
        mov     ebx, [_base]
-
 
1476
        mov     edx, [_len]
-
 
1477
.next:
-
 
1478
        mov     ecx, edx
-
 
1479
;        jecxz   .error
-
 
1480
        test    ecx, ecx
-
 
1481
        jz      .not_found
-
 
1482
        shr     ecx, 1
-
 
1483
        movbe   esi, [ebx+ecx*sizeof.xfs_dir2_leaf_entry+xfs_dir2_leaf_entry.hashval]
-
 
1484
        cmp     eax, esi
-
 
1485
        jb      .below
-
 
1486
        ja      .above
-
 
1487
        movbe   eax, [ebx+ecx*sizeof.xfs_dir2_leaf_entry+xfs_dir2_leaf_entry.address]
-
 
1488
        ret
-
 
1489
.below:
-
 
1490
        mov     edx, ecx
-
 
1491
        jmp     .next
-
 
1492
.above:
-
 
1493
        lea     ebx, [ebx+(ecx+1)*sizeof.xfs_dir2_leaf_entry]
-
 
1494
        sub     edx, ecx
-
 
1495
        dec     edx
-
 
1496
        jmp     .next
-
 
1497
.not_found:
-
 
1498
        movi    eax, ERROR_FILE_NOT_FOUND
-
 
1499
        test    esp, esp
-
 
1500
        ret
-
 
1501
endp
-
 
1502
 
-
 
1503
 
-
 
1504
;----------------------------------------------------------------
-
 
1505
; xfs_GetFileInfo: XFS implementation of getting file info
-
 
1506
; in:  ebp = pointer to XFS structure
-
 
1507
; in:  esi = name
-
 
1508
; in:  ebx = pointer to parameters from sysfunc 70
-
 
1509
; out: eax, ebx = return values for sysfunc 70
-
 
1510
;----------------------------------------------------------------
-
 
1511
proc xfs_GetFileInfo uses ecx edx esi edi
-
 
1512
        call    xfs._.lock
-
 
1513
        stdcall xfs_get_inode, esi
-
 
1514
        jnz     .error
-
 
1515
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
-
 
1516
        test    eax, eax
-
 
1517
        movi    eax, ERROR_FS_FAIL
-
 
1518
        jnz     .error
-
 
1519
        stdcall xfs_get_inode_info, edx, [ebx+f70s5arg.buf]
-
 
1520
.quit:
-
 
1521
        call    xfs._.unlock
-
 
1522
        xor     eax, eax
-
 
1523
        ret
-
 
1524
.error:
-
 
1525
        push    eax
-
 
1526
        call    xfs._.unlock
-
 
1527
        pop     eax
-
 
1528
        ret
-
 
1529
endp
-
 
1530
 
-
 
1531
 
-
 
1532
proc xfs._.file.read_extent uses ebx ecx edx, _callback, _callback_data
-
 
1533
        mov     eax, [ebp+XFS.file_offset.lo]
-
 
1534
        mov     edx, [ebp+XFS.file_offset.hi]
-
 
1535
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
-
 
1536
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
-
 
1537
        mov     ecx, [ebp+XFS.blocklog]
-
 
1538
        shld    edi, esi, cl
-
 
1539
        shl     esi, cl
-
 
1540
        cmp     edx, edi
-
 
1541
        jb      .hole
-
 
1542
        ja      .try_head
-
 
1543
        cmp     eax, esi
-
 
1544
        ja      .try_head
-
 
1545
        jz      .try_match
-
 
1546
.hole:
-
 
1547
        sub     esi, eax
-
 
1548
        sbb     edi, edx
-
 
1549
        movi    ecx, -1
-
 
1550
        test    edi, edi
-
 
1551
        jnz     @f
-
 
1552
        mov     ecx, esi
-
 
1553
@@:
-
 
1554
        cmp     ecx, [ebp+XFS.bytes_to_read]
-
 
1555
        jbe     @f
-
 
1556
        mov     ecx, [ebp+XFS.bytes_to_read]
-
 
1557
@@:
-
 
1558
        mov     edi, [ebp+XFS.file_buffer]
-
 
1559
        xor     eax, eax
-
 
1560
        sub     [ebp+XFS.bytes_to_read], ecx
-
 
1561
        sub     [ebp+XFS.bytes_left_in_file.lo], ecx
-
 
1562
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
-
 
1563
        add     [ebp+XFS.bytes_read], ecx
-
 
1564
        add     [ebp+XFS.file_buffer], ecx
-
 
1565
        add     [ebp+XFS.file_offset.lo], ecx
-
 
1566
        adc     [ebp+XFS.file_offset.hi], 0
-
 
1567
        rep stosb
-
 
1568
        cmp     [ebp+XFS.bytes_to_read], 0
-
 
1569
        jz      .quit
-
 
1570
        jmp     .try_match
-
 
1571
.try_head:
-
 
1572
        mov     eax, [ebp+XFS.file_offset.lo]
-
 
1573
        mov     ecx, [ebp+XFS.blocksize]
-
 
1574
        dec     ecx
-
 
1575
        test    eax, ecx
-
 
1576
        jz      .try_match
-
 
1577
.head:
-
 
1578
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
-
 
1579
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
-
 
1580
        mov     ebx, [ebp+XFS.cur_block_data]
-
 
1581
        stdcall xfs._.read_block
-
 
1582
        mov     esi, [ebp+XFS.cur_block_data]
-
 
1583
        mov     edi, [ebp+XFS.file_buffer]
-
 
1584
        mov     eax, [ebp+XFS.file_offset.lo]
-
 
1585
        mov     ecx, [ebp+XFS.blocksize]
Line 1845... Line 1586...
1845
 
1586
        dec     ecx
1846
 
-
 
1847
;----------------------------------------------------------------
1587
        and     eax, ecx
1848
; push  len
1588
        add     esi, eax
1849
; push  base
1589
        inc     ecx
1850
; eax -- hash value
1590
        sub     ecx, eax
1851
; call xfs_get_addr_by_hash
1591
        cmp     ecx, [ebp+XFS.bytes_to_read]
1852
;----------------------------------------------------------------
1592
        jbe     @f
-
 
1593
        mov     ecx, [ebp+XFS.bytes_to_read]
-
 
1594
@@:
1853
xfs_get_addr_by_hash:
1595
        sub     [ebp+XFS.bytes_to_read], ecx
-
 
1596
        sub     [ebp+XFS.bytes_left_in_file.lo], ecx
1854
 
1597
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
-
 
1598
        add     [ebp+XFS.bytes_read], ecx
-
 
1599
        add     [ebp+XFS.file_buffer], ecx
-
 
1600
        add     [ebp+XFS.file_offset.lo], ecx
1855
        ; look for the directory entry offset by its file name hash
1601
        adc     [ebp+XFS.file_offset.hi], 0
-
 
1602
        rep movsb
-
 
1603
        add     [ebp+XFS.extent.br_startoff.lo], 1
-
 
1604
        adc     [ebp+XFS.extent.br_startoff.hi], 0
-
 
1605
        add     [ebp+XFS.extent.br_startblock.lo], 1
-
 
1606
        adc     [ebp+XFS.extent.br_startblock.hi], 0
-
 
1607
        dec     [ebp+XFS.extent.br_blockcount]
-
 
1608
;        cmp     [ebp+XFS.bytes_to_read], 0
-
 
1609
        jz      .quit
1856
        ; allows fast file search for block, leaf and node directories
1610
.try_match:
1857
        ; binary (ternary) search
-
 
1858
 
-
 
1859
;DEBUGF 1,"get_addr_by_hash\n"
-
 
1860
        push    ebx esi
-
 
1861
        mov     ebx, [esp + 12] ; left
1611
        mov     eax, [ebp+XFS.bytes_to_read]
1862
        mov     edx, [esp + 16] ; len
-
 
1863
  .next:
1612
        test    eax, eax
1864
        mov     ecx, edx
1613
        jz      .quit
1865
;        jecxz   .error
1614
        cmp     eax, [ebp+XFS.blocksize]
1866
        test    ecx, ecx
1615
        jb      .tail
1867
        jz      .error
1616
        mov     ecx, [ebp+XFS.blocklog]
-
 
1617
        shr     eax, cl
-
 
1618
        cmp     eax, [ebp+XFS.extent.br_blockcount]
-
 
1619
        jbe     @f
-
 
1620
        mov     eax, [ebp+XFS.extent.br_blockcount]
-
 
1621
@@:
-
 
1622
        mov     ecx, eax
-
 
1623
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
-
 
1624
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
-
 
1625
        mov     ebx, [ebp+XFS.file_buffer]
-
 
1626
        push    ecx
-
 
1627
        stdcall xfs._.read_blocks
-
 
1628
        pop     eax
-
 
1629
        add     [ebp+XFS.extent.br_startoff.lo], eax
-
 
1630
        adc     [ebp+XFS.extent.br_startoff.hi], 0
-
 
1631
        add     [ebp+XFS.extent.br_startblock.lo], eax
-
 
1632
        adc     [ebp+XFS.extent.br_startblock.hi], 0
-
 
1633
        sub     [ebp+XFS.extent.br_blockcount], eax
-
 
1634
        imul    eax, [ebp+XFS.blocksize]
-
 
1635
        sub     [ebp+XFS.bytes_to_read], eax
-
 
1636
        sub     [ebp+XFS.bytes_left_in_file.lo], eax
-
 
1637
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
-
 
1638
        add     [ebp+XFS.bytes_read], eax
-
 
1639
        add     [ebp+XFS.file_buffer], eax
Line 1868... Line -...
1868
        shr     ecx, 1
-
 
1869
        mov     esi, [ebx + ecx*8 + xfs_dir2_leaf_entry.hashval]
-
 
1870
        bswap   esi
-
 
1871
;DEBUGF 1,"cmp 0x%x",esi
-
 
1872
        cmp     eax, esi
-
 
1873
        jb      .below
-
 
1874
        ja      .above
-
 
1875
        mov     eax, [ebx + ecx*8 + xfs_dir2_leaf_entry.address]
-
 
1876
        pop     esi ebx
-
 
1877
        ret     8
-
 
1878
  .below:
-
 
1879
;DEBUGF 1,"b\n"
-
 
1880
        mov     edx, ecx
-
 
1881
        jmp     .next
-
 
1882
  .above:
-
 
1883
;DEBUGF 1,"a\n"
-
 
1884
        lea     ebx, [ebx + ecx*8 + 8]
-
 
1885
        sub     edx, ecx
1640
        add     [ebp+XFS.file_offset.lo], eax
1886
        dec     edx
-
 
1887
        jmp     .next
-
 
1888
  .error:
1641
        adc     [ebp+XFS.file_offset.hi], 0
1889
        mov     eax, -1
-
 
1890
        pop     esi ebx
1642
;        cmp     [ebp+XFS.bytes_to_read], 0
1891
        ret     8
-
 
1892
 
-
 
1893
 
-
 
1894
;----------------------------------------------------------------
1643
        cmp     [ebp+XFS.extent.br_blockcount], 0
1895
; xfs_GetFileInfo - XFS implementation of getting file info
-
 
1896
; in:  ebp = pointer to XFS structure
-
 
1897
; in:  esi+[esp+4] = name
1644
        jz      .quit
1898
; in:  ebx = pointer to parameters from sysfunc 70
1645
.tail:
1899
; out: eax, ebx = return values for sysfunc 70
-
 
1900
;----------------------------------------------------------------
-
 
1901
xfs_GetFileInfo:
-
 
1902
 
-
 
1903
        ; lock partition
-
 
1904
        ; get inode number by file name
1646
        mov     eax, [ebp+XFS.extent.br_startblock.lo]
1905
        ; read inode
-
 
1906
        ; get info
-
 
1907
        ; unlock partition
-
 
1908
 
1647
        mov     edx, [ebp+XFS.extent.br_startblock.hi]
1909
        push    ecx edx esi edi
1648
        mov     ebx, [ebp+XFS.cur_block_data]
1910
        call    xfs_lock
-
 
1911
 
-
 
1912
        add     esi, [esp + 20]         ; name
-
 
1913
;DEBUGF 1,"xfs_GetFileInfo: |%s|\n",esi
-
 
1914
        stdcall xfs_get_inode, esi
-
 
1915
        mov     ecx, edx
-
 
1916
        or      ecx, eax
-
 
1917
        jnz     @f
-
 
1918
        movi    eax, ERROR_FILE_NOT_FOUND
1649
        stdcall xfs._.read_block
1919
        jmp     .error
-
 
1920
    @@:
1650
        mov     ecx, [ebp+XFS.bytes_to_read]
1921
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.cur_inode]
-
 
1922
        test    eax, eax
-
 
1923
        movi    eax, ERROR_FS_FAIL
1651
        cmp     [ebp+XFS.bytes_left_in_file.hi], 0
1924
        jnz     .error
-
 
1925
 
-
 
1926
        stdcall xfs_get_inode_info, edx, [ebx + 16]
-
 
1927
 
-
 
1928
  .quit:
-
 
1929
        call    xfs_unlock
1652
        jnz     @f
1930
        pop     edi esi edx ecx
-
 
1931
        xor     eax, eax
-
 
1932
;DEBUGF 1,"quit\n\n"
-
 
1933
        ret
-
 
1934
  .error:
-
 
1935
        call    xfs_unlock
-
 
1936
        pop     edi esi edx ecx
-
 
1937
;DEBUGF 1,"error\n\n"
-
 
1938
        ret
-
 
1939
 
-
 
1940
 
-
 
1941
;----------------------------------------------------------------
-
 
1942
; xfs_ReadFile - XFS implementation of reading a file
-
 
1943
; in:  ebp = pointer to XFS structure
-
 
1944
; in:  esi+[esp+4] = name
-
 
1945
; in:  ebx = pointer to parameters from sysfunc 70
-
 
1946
; out: eax, ebx = return values for sysfunc 70
-
 
1947
;----------------------------------------------------------------
-
 
1948
xfs_ReadFile:
-
 
1949
        push    ebx ecx edx esi edi
-
 
1950
        call    xfs_lock
-
 
1951
        add     esi, [esp + 24]
-
 
1952
        stdcall xfs_get_inode, esi
-
 
1953
        mov     ecx, edx
-
 
1954
        or      ecx, eax
-
 
1955
        jnz     @f
-
 
1956
        movi    eax, ERROR_FILE_NOT_FOUND
-
 
1957
        jmp     .error
-
 
1958
    @@:
-
 
1959
        stdcall xfs_read_inode, eax, edx, [ebp + XFS.cur_inode]
-
 
1960
        test    eax, eax
-
 
1961
        movi    eax, ERROR_FS_FAIL
-
 
1962
        jnz     .error
-
 
1963
        mov     [ebp + XFS.cur_inode_save], edx
-
 
1964
 
1653
        cmp     ecx, [ebp+XFS.bytes_left_in_file.lo]
1965
        cmp     byte[edx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
-
 
1966
        jne     .not_extent_list
-
 
1967
        jmp     .extent_list
-
 
1968
  .not_extent_list:
1654
        jbe     @f
1969
        cmp     byte[edx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
1655
        mov     ecx, [ebp+XFS.bytes_left_in_file.lo]
1970
        jne     .not_btree
-
 
1971
        jmp     .btree
1656
@@:
1972
  .not_btree:
-
 
1973
DEBUGF 1,"XFS: NOT IMPLEMENTED: FILE FORMAT\n"
-
 
1974
        movi    eax, ERROR_FS_FAIL
1657
        mov     esi, [ebp+XFS.cur_block_data]
1975
        jmp     .error
1658
        mov     edi, [ebp+XFS.file_buffer]
1976
  .extent_list:
-
 
1977
        mov     ecx, [ebx + 12]         ; bytes to read
1659
        mov     eax, ecx
1978
        mov     edi, [ebx + 16]         ; buffer for data
-
 
1979
        mov     esi, [ebx + 8]          ; offset_hi
-
 
1980
        mov     ebx, [ebx + 4]          ; offset_lo
1660
        rep movsb
1981
 
-
 
1982
        mov     eax, dword[edx + xfs_inode.di_core.di_size + 4] ; lo
-
 
1983
        bswap   eax
1661
        add     [ebp+XFS.bytes_read], eax
1984
        mov     dword[ebp + XFS.bytes_left_in_file + 0], eax    ; lo
-
 
1985
        mov     eax, dword[edx + xfs_inode.di_core.di_size + 0] ; hi
1662
        sub     [ebp+XFS.bytes_to_read], eax
1986
        bswap   eax
-
 
1987
        mov     dword[ebp + XFS.bytes_left_in_file + 4], eax    ; hi
-
 
1988
 
1663
        sub     [ebp+XFS.bytes_left_in_file.lo], eax
1989
        mov     eax, [edx + xfs_inode.di_core.di_nextents]
1664
        sbb     [ebp+XFS.bytes_left_in_file.hi], 0
1990
        bswap   eax
1665
        add     [ebp+XFS.file_buffer], eax
1991
        mov     [ebp + XFS.left_extents], eax
1666
        add     [ebp+XFS.file_offset.lo], eax
1992
 
1667
        adc     [ebp+XFS.file_offset.hi], 0
1993
        mov     dword[ebp + XFS.bytes_read], 0          ; actually read bytes
-
 
1994
 
-
 
1995
        xor     eax, eax                ; extent offset in list
-
 
1996
  .extent_list.next_extent:
-
 
1997
;DEBUGF 1,"extent_list.next_extent, eax: 0x%x\n",eax
1668
        add     [ebp+XFS.extent.br_startoff.lo], 1
1998
;DEBUGF 1,"bytes_to_read: %d\n",ecx
-
 
1999
;DEBUGF 1,"cur file offset: %d %d\n",esi,ebx
-
 
2000
;DEBUGF 1,"esp: 0x%x\n",esp
1669
        adc     [ebp+XFS.extent.br_startoff.hi], 0
2001
        cmp     [ebp + XFS.left_extents], 0
1670
        add     [ebp+XFS.extent.br_startblock.lo], 1
2002
        jne     @f
-
 
2003
        test    ecx, ecx
1671
        adc     [ebp+XFS.extent.br_startblock.hi], 0
2004
        jz      .quit
-
 
2005
        movi    eax, ERROR_END_OF_FILE
1672
        dec     [ebp+XFS.extent.br_blockcount]
2006
        jmp     .error
-
 
2007
    @@:
-
 
2008
        push    eax
1673
.quit:
2009
        lea     eax, [edx + xfs_inode.di_u + eax + xfs_bmbt_rec.l0]
-
 
2010
        stdcall xfs_extent_unpack, eax
-
 
2011
        pop     eax
1674
        mov     esi, [ebp+XFS.extent.br_startoff.lo]
2012
        dec     [ebp + XFS.left_extents]
1675
        mov     edi, [ebp+XFS.extent.br_startoff.hi]
2013
        add     eax, sizeof.xfs_bmbt_rec
1676
        movi    eax, ERROR_SUCCESS
2014
        push    eax ebx ecx edx esi
-
 
2015
        mov     ecx, [ebp + XFS.blocklog]
-
 
2016
        shrd    ebx, esi, cl
1677
        cmp     esp, esp
2017
        shr     esi, cl
1678
        ret
2018
        cmp     esi, dword[ebp + XFS.extent.br_startoff + 4]
1679
endp
2019
        jb      .extent_list.to_hole          ; handle sparse files
1680
 
2020
        ja      @f
-
 
2021
        cmp     ebx, dword[ebp + XFS.extent.br_startoff + 0]
-
 
2022
        jb      .extent_list.to_hole          ; handle sparse files
1681
 
-
 
1682
;----------------------------------------------------------------
2023
        je      .extent_list.to_extent        ; read from the start of current extent
1683
; in:  ebp = pointer to XFS structure
2024
    @@:
1684
; in:  esi = name
2025
        xor     edx, edx
1685
; in:  ebx = pointer to parameters from sysfunc 70
2026
        mov     eax, [ebp + XFS.extent.br_blockcount]
-
 
2027
        add     eax, dword[ebp + XFS.extent.br_startoff + 0]
-
 
2028
        adc     edx, dword[ebp + XFS.extent.br_startoff + 4]
-
 
2029
;DEBUGF 1,"br_startoff: %d %d\n",edx,eax
-
 
2030
        cmp     esi, edx
-
 
2031
        ja      .extent_list.skip_extent
-
 
2032
        jb      .extent_list.to_extent
1686
; out: eax, ebx = return values for sysfunc 70
2033
        cmp     ebx, eax
1687
;----------------------------------------------------------------
2034
        jae     .extent_list.skip_extent
-
 
2035
        jmp     .extent_list.to_extent
1688
proc xfs_Read uses ecx edx esi edi
2036
  .extent_list.to_hole:
1689
locals
2037
;DEBUGF 1,"extent_list.to_hole\n"
1690
        .offset_begin DQ ?
2038
        pop     esi edx ecx ebx eax
1691
        .offset_end   DQ ?
2039
        jmp     .extent_list.read_hole
-
 
2040
  .extent_list.to_extent:
1692
endl
2041
;DEBUGF 1,"extent_list.to_extent\n"
1693
        call    xfs._.lock
2042
        pop     esi edx ecx ebx eax
-
 
2043
        jmp     .extent_list.read_extent
1694
        mov     [ebp+XFS.bytes_read], 0
2044
  .extent_list.skip_extent:
1695
        mov     eax, [ebx+f70s0arg.count]
2045
;DEBUGF 1,"extent_list.skip_extent\n"
-
 
2046
        pop     esi edx ecx ebx eax
-
 
2047
        jmp     .extent_list.next_extent
-
 
2048
 
1696
        mov     [ebp+XFS.bytes_to_read], eax
2049
  .extent_list.read_hole:
-
 
2050
;DEBUGF 1,"hole: offt: 0x%x%x ",esi,ebx
-
 
2051
        push    eax edx
1697
        test    eax, eax
2052
        mov     eax, dword[ebp + XFS.extent.br_startoff + 0]
-
 
2053
        mov     edx, dword[ebp + XFS.extent.br_startoff + 4]
-
 
2054
        push    esi ebx
-
 
2055
        mov     ebx, ecx
1698
        jz      .quit
2056
        sub     eax, ebx        ; get hole_size, it is 64 bit
1699
        mov     eax, [ebx+f70s0arg.buf]
2057
        sbb     edx, 0          ; now edx:eax contains the size of hole
-
 
2058
;DEBUGF 1,"size: 0x%x%x\n",edx,eax
-
 
2059
        jnz     @f              ; if hole size >= 2^32, write bytes_to_read zero bytes
1700
        mov     [ebp+XFS.file_buffer], eax
2060
        cmp     eax, ecx        ; if hole size >= bytes_to_read, write bytes_to_read zeros
-
 
2061
        jae     @f
-
 
2062
        mov     ecx, eax        ; if hole is < than bytes_to_read, write hole size zeros
-
 
2063
    @@:
-
 
2064
        sub     ebx, ecx        ; bytes_to_read - hole_size = left_to_read
-
 
2065
        add     dword[esp + 0], ecx     ; update pushed file offset
-
 
2066
        adc     dword[esp + 4], 0
-
 
2067
        xor     eax, eax        ; hole is made of zeros
-
 
2068
        rep stosb
1701
        mov     eax, [ebx+f70s0arg.offset.hi]
2069
        mov     ecx, ebx
1702
        mov     [ebp+XFS.file_offset.hi], eax
2070
        pop     ebx esi
1703
        mov     eax, [ebx+f70s0arg.offset.lo]
2071
 
-
 
2072
        test    ecx, ecx        ; all requested bytes are read?
-
 
2073
        pop     edx eax
-
 
2074
        jz      .quit
1704
        mov     [ebp+XFS.file_offset.lo], eax
2075
        jmp     .extent_list.read_extent        ; continue from the start of unpacked extent
-
 
2076
 
-
 
2077
  .extent_list.read_extent:
-
 
2078
;DEBUGF 1,"extent_list.read_extent\n"
-
 
2079
        push    eax ebx ecx edx esi
-
 
2080
        mov     eax, ebx
-
 
2081
        mov     edx, esi
-
 
2082
        mov     ecx, [ebp + XFS.blocklog]
1705
 
2083
        shrd    eax, edx, cl
1706
        stdcall xfs_get_inode, esi
2084
        shr     edx, cl
-
 
2085
        sub     eax, dword[ebp + XFS.extent.br_startoff + 0]    ; skip esi:ebx ?
1707
        jnz     .error
2086
        sbb     edx, dword[ebp + XFS.extent.br_startoff + 4]
-
 
2087
        sub     [ebp + XFS.extent.br_blockcount], eax
1708
        stdcall xfs_read_inode, eax, edx, [ebp+XFS.cur_inode]
2088
        add     dword[ebp + XFS.extent.br_startblock + 0], eax
-
 
2089
        adc     dword[ebp + XFS.extent.br_startblock + 4], 0
-
 
2090
  .extent_list.read_extent.next_block:
-
 
2091
;DEBUGF 1,"extent_list.read_extent.next_block\n"
1709
        test    eax, eax
2092
        cmp     [ebp + XFS.extent.br_blockcount], 0     ; out of blocks in current extent?
1710
        movi    eax, ERROR_FS_FAIL
2093
        jne     @f
1711
        jnz     .error
2094
        pop     esi edx ecx ebx eax
-
 
2095
        jmp     .extent_list.next_extent                ; go to next extent
1712
        mov     [ebp+XFS.cur_inode_save], edx
2096
    @@:
-
 
2097
        mov     eax, dword[ebp + XFS.extent.br_startblock + 0]
-
 
2098
        mov     edx, dword[ebp + XFS.extent.br_startblock + 4]
-
 
2099
        push    ebx
1713
        mov     ebx, edx
2100
        mov     ebx, [ebp + XFS.cur_block]
1714
        ; precompute .offset_begin
2101
;DEBUGF 1,"read block: 0x%x%x\n",edx,eax
-
 
2102
        stdcall xfs_read_block
1715
        mov     esi, [ebp+XFS.file_offset.lo]
2103
        test    eax, eax
1716
        mov     edi, [ebp+XFS.file_offset.hi]
2104
        pop     ebx
-
 
2105
        jz      @f
-
 
2106
        pop     esi edx ecx ebx eax
-
 
2107
        movi    eax, ERROR_FS_FAIL
1717
        mov     ecx, [ebp+XFS.blocklog]
2108
        jmp     .error
1718
        shrd    esi, edi, cl
2109
    @@:
1719
        shr     edi, cl
2110
        dec     [ebp + XFS.extent.br_blockcount]
1720
        mov     [.offset_begin.lo], esi
2111
        add     dword[ebp + XFS.extent.br_startblock + 0], 1
-
 
2112
        adc     dword[ebp + XFS.extent.br_startblock + 4], 0
1721
        mov     [.offset_begin.hi], edi
2113
        mov     esi, [ebp + XFS.cur_block]
1722
        ; precompute .offset_end
2114
        mov     ecx, [ebp + XFS.blocklog]
1723
        mov     esi, [ebp+XFS.file_offset.lo]
2115
        mov     eax, 1
1724
        mov     edi, [ebp+XFS.file_offset.hi]
2116
        shl     eax, cl
1725
        add     esi, [ebp+XFS.bytes_to_read]
2117
        dec     eax             ; get blocklog mask
1726
        adc     edi, 0
2118
        and     eax, ebx        ; offset in current block
1727
        mov     ecx, [ebp+XFS.blocksize]
2119
        add     esi, eax
1728
        dec     ecx
2120
        neg     eax
1729
        add     esi, ecx
-
 
1730
        adc     edi, 0
Line 2121... Line -...
2121
        add     eax, [ebp + XFS.blocksize]
-
 
2122
        mov     ecx, [esp + 8]  ; pushed ecx, bytes_to_read
-
 
2123
        cmp     ecx, eax        ; is current block enough?
-
 
2124
        jbe     @f              ; if so, read bytes_to_read bytes
-
 
2125
        mov     ecx, eax        ; otherwise read the block up to the end
-
 
2126
    @@:
-
 
2127
        sub     [esp + 8], ecx          ; left_to_read
-
 
2128
        add     [esp + 12], ecx         ; update current file offset, pushed ebx
-
 
2129
        sub     dword[ebp + XFS.bytes_left_in_file + 0], ecx
-
 
2130
        sbb     dword[ebp + XFS.bytes_left_in_file + 4], 0
1731
        mov     ecx, [ebp+XFS.blocklog]
2131
        jnc     @f
-
 
2132
        add     dword[ebp + XFS.bytes_left_in_file + 0], ecx
-
 
2133
        mov     ecx, dword[ebp + XFS.bytes_left_in_file + 0]
-
 
2134
        mov     dword[ebp + XFS.bytes_left_in_file + 0], 0
-
 
2135
        mov     dword[ebp + XFS.bytes_left_in_file + 4], 0
-
 
2136
    @@:
-
 
2137
        add     [ebp + XFS.bytes_read], ecx
-
 
2138
        adc     [esp + 0], dword 0      ; pushed esi
-
 
2139
;DEBUGF 1,"read data: %d\n",ecx
-
 
2140
        rep movsb
-
 
2141
        mov     ecx, [esp + 8]
-
 
2142
;DEBUGF 1,"left_to_read: %d\n",ecx
-
 
2143
        xor     ebx, ebx
1732
        shrd    esi, edi, cl
2144
        test    ecx, ecx
1733
        shr     edi, cl
2145
        jz      @f
-
 
2146
        cmp     dword[ebp + XFS.bytes_left_in_file + 4], 0
-
 
2147
        jne     .extent_list.read_extent.next_block
1734
        mov     [.offset_end.lo], esi
2148
        cmp     dword[ebp + XFS.bytes_left_in_file + 0], 0
1735
        mov     [.offset_end.hi], edi
2149
        jne     .extent_list.read_extent.next_block
-
 
2150
    @@:
-
 
2151
        pop     esi edx ecx ebx eax
-
 
2152
        jmp     .quit
-
 
2153
 
1736
 
2154
  .btree:
-
 
2155
        mov     ecx, [ebx + 12]         ; bytes to read
1737
        movbe   ecx, [ebx+xfs_inode.di_core.di_size.hi]
2156
        mov     [ebp + XFS.bytes_to_read], ecx
1738
        movbe   edx, [ebx+xfs_inode.di_core.di_size.lo]
2157
        mov     edi, [ebx + 16]         ; buffer for data
-
 
2158
        mov     esi, [ebx + 8]          ; offset_hi
1739
        mov     [ebp+XFS.bytes_left_in_file.lo], ecx
2159
        mov     ebx, [ebx + 4]          ; offset_lo
-
 
2160
        mov     dword[ebp + XFS.file_offset + 0], ebx
-
 
2161
        mov     dword[ebp + XFS.file_offset + 4], esi
-
 
2162
        mov     [ebp + XFS.buffer_pos], edi
-
 
2163
 
-
 
2164
        mov     eax, dword[edx + xfs_inode.di_core.di_size + 4] ; lo
-
 
2165
        bswap   eax
-
 
2166
        mov     dword[ebp + XFS.bytes_left_in_file + 0], eax    ; lo
-
 
2167
        mov     eax, dword[edx + xfs_inode.di_core.di_size + 0] ; hi
-
 
2168
        bswap   eax
-
 
2169
        mov     dword[ebp + XFS.bytes_left_in_file + 4], eax    ; hi
1740
        mov     [ebp+XFS.bytes_left_in_file.hi], edx
2170
 
-
 
2171
        mov     eax, [edx + xfs_inode.di_core.di_nextents]
-
 
2172
        bswap   eax
-
 
2173
        mov     [ebp + XFS.left_extents], eax
1741
 
2174
 
1742
        sub     ecx, [ebp+XFS.file_offset.lo]
2175
        mov     dword[ebp + XFS.bytes_read], 0          ; actually read bytes
1743
        sbb     edx, [ebp+XFS.file_offset.hi]
2176
 
-
 
2177
        push    ebx ecx edx esi edi
-
 
2178
        mov     [ebp + XFS.eof], 0
1744
        movi    eax, ERROR_END_OF_FILE
2179
        mov     eax, dword[ebp + XFS.file_offset + 0]
-
 
2180
        mov     edx, dword[ebp + XFS.file_offset + 4]
-
 
2181
        add     eax, [ebp + XFS.bytes_to_read]
-
 
2182
        adc     edx, 0
-
 
2183
        sub     eax, dword[ebp + XFS.bytes_left_in_file + 0]
-
 
2184
        sbb     edx, dword[ebp + XFS.bytes_left_in_file + 4]
-
 
2185
        jc      @f      ; file_offset + bytes_to_read < file_size
-
 
2186
        jz      @f      ; file_offset + bytes_to_read = file_size
1745
        jb      .error
2187
        mov     [ebp + XFS.eof], 1
-
 
2188
        cmp     edx, 0
-
 
2189
        jne     .error.eof
-
 
2190
        sub     dword[ebp + XFS.bytes_to_read], eax
1746
        mov     [ebp+XFS.eof], 0
2191
        jc      .error.eof
-
 
2192
        jz      .error.eof
-
 
2193
    @@:
-
 
2194
        stdcall xfs_btree_read, 0, 0, 1
-
 
2195
        pop     edi esi edx ecx ebx
-
 
2196
        test    eax, eax
1747
        test    edx, edx
2197
        jnz     .error
-
 
2198
        cmp     [ebp + XFS.eof], 1
1748
        jnz     @f
2199
        jne     .quit
-
 
2200
        jmp     .error.eof
1749
        cmp     ecx, [ebp+XFS.bytes_to_read]
2201
 
-
 
2202
 
-
 
2203
  .quit:
-
 
2204
        call    xfs_unlock
-
 
2205
        pop     edi esi edx ecx ebx
-
 
2206
        xor     eax, eax
-
 
2207
        mov     ebx, [ebp + XFS.bytes_read]
-
 
2208
;DEBUGF 1,"quit: %d\n\n",ebx
-
 
2209
        ret
1750
        jae     @f
2210
  .error.eof:
-
 
2211
        movi    eax, ERROR_END_OF_FILE
-
 
Line 2212... Line -...
2212
  .error:
-
 
2213
;DEBUGF 1,"error\n\n"
-
 
Line 2214... Line 1751...
2214
        call    xfs_unlock
1751
        mov     [ebp+XFS.eof], ERROR_END_OF_FILE
2215
        pop     edi esi edx ecx ebx
1752
        mov     [ebp+XFS.bytes_to_read], ecx
2216
        mov     ebx, [ebp + XFS.bytes_read]
1753
@@:
2217
        ret
-
 
2218
 
1754
 
2219
 
1755
        cmp     [ebx+xfs_inode.di_core.di_format], XFS_DINODE_FMT_BTREE
-
 
1756
        jz      .btree
2220
;----------------------------------------------------------------
1757
.extent_list:
2221
; push  max_offset_hi
1758
        mov     eax, ebx
2222
; push  max_offset_lo
1759
        add     eax, [ebp+XFS.inode_core_size]
2223
; push  nextents
-
 
2224
; push  block_number_hi
1760
        movbe   edx, [ebx+xfs_inode.di_core.di_nextents]
2225
; push  block_number_lo
1761
        mov     ecx, [.offset_begin.lo]
2226
; push  extent_list
1762
        mov     [ebp+XFS.offset_begin.lo], ecx
2227
; -1 / read block number
1763
        mov     ecx, [.offset_begin.hi]
2228
;----------------------------------------------------------------
1764
        mov     [ebp+XFS.offset_begin.hi], ecx
2229
xfs_extent_list_read_dirblock:  ; skips holes
1765
        mov     ecx, [.offset_end.lo]
2230
;DEBUGF 1,"xfs_extent_list_read_dirblock\n"
1766
        mov     [ebp+XFS.offset_end.lo], ecx
-
 
1767
        mov     ecx, [.offset_end.hi]
2231
        push    ebx esi edi
1768
        mov     [ebp+XFS.offset_end.hi], ecx
-
 
1769
        stdcall xfs._.walk_extent_list, edx, eax, xfs._.file.read_extent, 0, 0
-
 
1770
        jnz     .error
-
 
1771
        jmp     .hole_check
-
 
1772
.btree:
-
 
1773
        mov     eax, [ebp+XFS.inodesize]
-
 
1774
        sub     eax, [ebp+XFS.inode_core_size]
-
 
1775
        movzx   ecx, [ebx+xfs_inode.di_core.di_forkoff]
-
 
1776
        jecxz   @f
-
 
1777
        shl     ecx, 3
-
 
1778
        mov     eax, ecx
-
 
1779
@@:
-
 
1780
        mov     edx, ebx
-
 
1781
        add     edx, [ebp+XFS.inode_core_size]
-
 
1782
        mov     ecx, [.offset_begin.lo]
Line 2232... Line -...
2232
;mov eax, [esp+28]
-
 
2233
;DEBUGF 1,"nextents: %d\n",eax
-
 
2234
;mov eax, [esp+20]
-
 
2235
;mov edx, [esp+24]
-
 
2236
;DEBUGF 1,"block_number: 0x%x%x\n",edx,eax
-
 
2237
;mov eax, [esp+32]
-
 
2238
;mov edx, [esp+36]
-
 
2239
;DEBUGF 1,"max_addr    : 0x%x%x\n",edx,eax
-
 
2240
        mov     ebx, [esp + 16]
-
 
2241
        mov     esi, [esp + 20]
-
 
2242
        mov     edi, [esp + 24]
-
 
2243
;        mov     ecx, [esp + 28] ; nextents
-
 
Line -... Line 1783...
-
 
1783
        mov     [ebp+XFS.offset_begin.lo], ecx
-
 
1784
        mov     ecx, [.offset_begin.hi]
-
 
1785
        mov     [ebp+XFS.offset_begin.hi], ecx
-
 
1786
        mov     ecx, [.offset_end.lo]
2244
  .next_extent:
1787
        mov     [ebp+XFS.offset_end.lo], ecx
2245
;DEBUGF 1,"next_extent\n"
1788
        mov     ecx, [.offset_end.hi]
-
 
1789
        mov     [ebp+XFS.offset_end.hi], ecx
2246
        dec     dword[esp + 28]
1790
        stdcall xfs._.walk_btree, edx, eax, xfs._.file.read_extent, 0, 0, 1
2247
        js      .error
1791
.hole_check:
2248
        stdcall xfs_extent_unpack, ebx
-
 
2249
        add     ebx, sizeof.xfs_bmbt_rec        ; next extent
-
 
2250
        mov     edx, dword[ebp + XFS.extent.br_startoff + 4]
-
 
2251
        mov     eax, dword[ebp + XFS.extent.br_startoff + 0]
1792
        cmp     [ebp+XFS.bytes_left_in_file.hi], 0
2252
        cmp     edx, [esp + 36] ; max_offset_hi
-
 
2253
        ja      .error
-
 
2254
        jb      @f
1793
        jnz     @f
2255
        cmp     eax, [esp + 32] ; max_offset_lo
1794
        cmp     [ebp+XFS.bytes_left_in_file.lo], 0
-
 
1795
        jz      .hole_done
-
 
1796
@@:
-
 
1797
        cmp     [ebp+XFS.bytes_to_read], 0
-
 
1798
        jz      .hole_done
-
 
1799
        mov     ebx, [ebp+XFS.cur_inode_save]
-
 
1800
        movbe   edx, [ebx+xfs_inode.di_core.di_size.lo]
-
 
1801
        movbe   eax, [ebx+xfs_inode.di_core.di_size.hi]
-
 
1802
        sub     eax, [ebp+XFS.file_offset.lo]
2256
        jae     .error
1803
        sbb     edx, [ebp+XFS.file_offset.hi]
2257
    @@:
1804
        jc      .hole_done
2258
        cmp     edi, edx
1805
        mov     ecx, [ebp+XFS.bytes_to_read]
-
 
1806
        test    edx, edx
-
 
1807
        jnz     .hole_read
-
 
1808
        cmp     eax, [ebp+XFS.bytes_to_read]
-
 
1809
        jae     .hole_read
-
 
1810
        mov     ecx, eax
-
 
1811
        jmp     .hole_read
-
 
1812
.hole_read:
-
 
1813
        sub     [ebp+XFS.bytes_to_read], ecx
-
 
1814
        add     [ebp+XFS.bytes_read], ecx
-
 
1815
        mov     edi, [ebp+XFS.file_buffer]
-
 
1816
        xor     eax, eax
2259
        jb      .hole
1817
        rep stosb
-
 
1818
.hole_done:
2260
        ja      .check_count
1819
.quit:
-
 
1820
        mov     eax, [ebp+XFS.eof]
-
 
1821
.error:
2261
        cmp     esi, eax
1822
        push    eax
2262
        jb      .hole
1823
        call    xfs._.unlock
2263
        ja      .check_count
1824
        pop     eax
2264
        jmp     .read_block
1825
        mov     ebx, [ebp+XFS.bytes_read]
-
 
1826
        ret
-
 
1827
endp
-
 
1828
 
2265
  .hole:
1829
 
2266
;DEBUGF 1,"hole\n"
1830
proc xfs._.leafn_calc_entries uses ebx ecx edx esi edi, _cur_dirblock, _offset_lo, _offset_hi, _arg
2267
        mov     esi, eax
1831
        mov     edx, [_cur_dirblock]
2268
        mov     edi, edx
-
 
2269
        jmp     .read_block
-
 
2270
  .check_count:
-
 
2271
;DEBUGF 1,"check_count\n"
1832
        movzx   eax, [ebp+XFS.da_node_magic]
2272
        add     eax, [ebp + XFS.extent.br_blockcount]
1833
        cmp     [edx+xfs_dir2_leaf.hdr.info.magic], ax
2273
        adc     edx, 0
-
 
2274
        cmp     edi, edx
-
 
2275
        ja      .next_extent
-
 
2276
        jb      .read_block
-
 
Line 2277... Line -...
2277
        cmp     esi, eax
-
 
2278
        jae     .next_extent
-
 
2279
;        jmp     .read_block
-
 
2280
  .read_block:
-
 
2281
;DEBUGF 1,"read_block\n"
-
 
2282
        push    esi edi
1834
        jz      .quit
2283
        sub     esi, dword[ebp + XFS.extent.br_startoff + 0]
-
 
2284
        sbb     edi, dword[ebp + XFS.extent.br_startoff + 4]
1835
        cmp     [ebp+XFS.version], 5
2285
        add     esi, dword[ebp + XFS.extent.br_startblock + 0]
1836
        jnz     @f
2286
        adc     edi, dword[ebp + XFS.extent.br_startblock + 4]
1837
        add     edx, xfs_dir3_leaf.hdr.count-xfs_dir2_leaf.hdr.count
2287
        stdcall xfs_read_dirblock, esi, edi, [ebp + XFS.cur_dirblock]
1838
@@:
2288
        pop     edx eax
1839
        movzx   eax, [edx+xfs_dir2_leaf.hdr.count]
2289
  .quit:
-
 
2290
;DEBUGF 1,"xfs_extent_list_read_dirblock: quit\n"
-
 
2291
        pop     edi esi ebx
1840
        movzx   ecx, [edx+xfs_dir2_leaf.hdr.stale]
2292
        ret     24
-
 
2293
  .error:
-
 
2294
;DEBUGF 1,"xfs_extent_list_read_dirblock: error\n"
-
 
2295
        xor     eax, eax
-
 
2296
        dec     eax
-
 
2297
        mov     edx, eax
1841
        xchg    al, ah
2298
        pop     edi esi ebx
1842
        xchg    cl, ch
2299
        ret     24
-
 
2300
 
-
 
2301
 
-
 
2302
;----------------------------------------------------------------
-
 
2303
; push  dirblock_num
-
 
2304
; push  nextents
-
 
2305
; push  extent_list
-
 
2306
;----------------------------------------------------------------
-
 
2307
xfs_dir2_node_get_numfiles:
-
 
2308
 
-
 
2309
        ; unfortunately, we need to set 'total entries' field
-
 
2310
        ; this often requires additional effort, since there is no such a number in most directory ondisk formats
-
 
2311
 
-
 
2312
;DEBUGF 1,"xfs_dir2_node_get_numfiles\n"
-
 
2313
        push    ebx ecx edx esi edi
1843
        sub     eax, ecx
2314
 
1844
        add     [ebp+XFS.entries_read], eax
2315
        mov     eax, [esp + 24]
1845
.quit:
-
 
1846
        movi    eax, ERROR_SUCCESS
2316
        mov     edx, [esp + 28]
1847
        cmp     esp, esp
-
 
1848
        ret
-
 
1849
endp
-
 
1850
 
2317
        mov     esi, [esp + 32]
1851
 
2318
        stdcall xfs_extent_list_read_dirblock, eax, esi, 0, edx, -1, -1
1852
proc xfs._.get_before_by_hashval uses ebx edx esi edi, _base, _count, _hash
2319
        mov     ecx, eax
1853
        mov     edi, [_hash]
-
 
1854
        mov     edx, [_count]
-
 
1855
        xor     ecx, ecx
-
 
1856
.node.next:
2320
        and     ecx, edx
1857
        movbe   eax, [ebx+xfs_da_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.hashval]
2321
        inc     ecx
1858
        cmp     [ebp+XFS.version], 5
2322
        jnz     @f
1859
        jnz     @f
2323
        movi    eax, ERROR_FS_FAIL
-
 
2324
        jmp     .error
-
 
2325
    @@:
-
 
2326
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
2327
        cmp     word[ebx + xfs_da_intnode.hdr.info.magic], XFS_DA_NODE_MAGIC
-
 
2328
        je      .node
-
 
2329
        cmp     word[ebx + xfs_da_intnode.hdr.info.magic], XFS_DIR2_LEAFN_MAGIC
-
 
2330
        je      .leaf
-
 
2331
        mov     eax, ERROR_FS_FAIL
-
 
2332
        jmp     .error
-
 
2333
 
-
 
2334
  .node:
-
 
2335
;DEBUGF 1,".node\n"
1860
        movbe   eax, [ebx+xfs_da3_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.hashval]
2336
        mov     edi, [ebx + xfs_da_intnode.hdr.info.forw]
1861
@@:
-
 
1862
        cmp     eax, edi
2337
        bswap   edi
1863
        ja      .node.leaf_found
-
 
1864
        inc     ecx
-
 
1865
        cmp     ecx, edx
-
 
1866
        jnz     .node.next
-
 
1867
        movi    eax, ERROR_FILE_NOT_FOUND
-
 
1868
        test    esp, esp
Line -... Line 1869...
-
 
1869
        jmp     .error
-
 
1870
.node.leaf_found:
-
 
1871
        movbe   eax, [ebx+xfs_da_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.before]
-
 
1872
        cmp     [ebp+XFS.version], 5
-
 
1873
        jnz     @f
-
 
1874
        movbe   eax, [ebx+xfs_da3_intnode.btree+ecx*sizeof.xfs_da_node_entry+xfs_da_node_entry.before]
-
 
1875
@@:
2338
        mov     eax, [esp + 24]
1876
        jmp     .quit
-
 
1877
.error:
-
 
1878
        test    esp, esp
-
 
1879
        ret
2339
        mov     edx, [esp + 28]
1880
.quit:
2340
        mov     esi, [ebx + xfs_da_intnode.btree.before]
1881
        cmp     esp, esp
2341
        bswap   esi
1882
        ret
2342
        stdcall xfs_dir2_node_get_numfiles, eax, edx, esi
1883
endp
2343
        test    eax, eax
1884
 
2344
        jnz     .error
1885
 
2345
        jmp     .common
1886
proc xfs._.long_btree.seek uses ebx esi edi, _ptr, _size
2346
 
1887
        mov     ebx, [_ptr]
2347
  .leaf:
1888
        mov     esi, [_size]
-
 
1889
        sub     esi, sizeof.xfs_bmdr_block
-
 
1890
        shr     esi, 4
-
 
1891
        shl     esi, 3
2348
;DEBUGF 1,".leaf\n"
1892
        movzx   eax, [ebx+xfs_bmdr_block.bb_level]
-
 
1893
        movzx   ecx, [ebx+xfs_bmdr_block.bb_numrecs]
Line 2349... Line -...
2349
        movzx   ecx, word[ebx + xfs_dir2_leaf.hdr.count]
-
 
2350
        xchg    cl, ch
-
 
2351
        movzx   eax, word[ebx + xfs_dir2_leaf.hdr.stale]
-
 
2352
        xchg    al, ah
-
 
2353
        sub     ecx, eax
-
 
2354
        add     [ebp + XFS.entries_read], ecx
-
 
2355
        mov     edi, [ebx + xfs_dir2_leaf.hdr.info.forw]
-
 
2356
        bswap   edi
-
 
2357
        jmp     .common
-
 
Line -... Line 1894...
-
 
1894
        xchg    cl, ch
-
 
1895
        add     ebx, sizeof.xfs_bmdr_block
-
 
1896
        jmp     .common
-
 
1897
.not_root:
-
 
1898
        mov     esi, [ebp+XFS.blocksize]
-
 
1899
        sub     esi, sizeof.xfs_bmbt_block
-
 
1900
        shr     esi, 4
-
 
1901
        shl     esi, 3
-
 
1902
        movzx   eax, [ebx+xfs_bmbt_block.bb_level]
-
 
1903
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
-
 
1904
        xchg    cl, ch
-
 
1905
        add     ebx, sizeof.xfs_bmbt_block
-
 
1906
.common:
Line 2358... Line -...
2358
 
-
 
2359
  .common:
-
 
2360
        test    edi, edi
-
 
2361
        jz      .quit
-
 
2362
        mov     esi, edi
-
 
2363
        mov     eax, [esp + 24]
-
 
2364
        mov     edx, [esp + 28]
-
 
2365
        stdcall xfs_dir2_node_get_numfiles, eax, edx, esi
-
 
2366
        test    eax, eax
-
 
2367
        jnz     .error
-
 
2368
        jmp     .quit
1907
        test    eax, eax
2369
 
1908
        jz      .leaf
2370
  .quit:
-
 
2371
;DEBUGF 1,".quit\n"
1909
.node:
2372
        pop     edi esi edx ecx ebx
1910
.next_rec:
2373
        xor     eax, eax
-
 
2374
        ret     12
1911
        dec     ecx
2375
  .error:
-
 
2376
;DEBUGF 1,".error\n"
1912
        js      .error
2377
        pop     edi esi edx ecx ebx
1913
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_key+xfs_bmbt_key.br_startoff.lo]
2378
        movi    eax, ERROR_FS_FAIL
1914
        cmp     [ebp+XFS.offset_begin.hi], eax
2379
        ret     12
-
 
2380
 
-
 
2381
 
-
 
2382
;----------------------------------------------------------------
-
 
2383
; push  hash
-
 
2384
; push  dirblock_num
-
 
Line -... Line 1915...
-
 
1915
        ja      .node_found
2385
; push  nextents
1916
        jb      .next_rec
2386
; push  extent_list
1917
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_key+xfs_bmbt_key.br_startoff.hi]
2387
;----------------------------------------------------------------
1918
        cmp     [ebp+XFS.offset_begin.lo], eax
2388
xfs_dir2_lookupdir_node:
1919
        jae     .node_found
2389
DEBUGF 1,"xfs_dir2_lookupdir_node\n"
1920
        jmp     .next_rec
2390
        push    ebx edx esi edi
1921
.node_found:
2391
 
1922
        add     ebx, esi
2392
        mov     eax, [esp + 20]
1923
        movbe   edx, [ebx+ecx*sizeof.xfs_bmbt_ptr+xfs_bmbt_ptr.lo]
2393
        mov     edx, [esp + 24]
1924
        movbe   eax, [ebx+ecx*sizeof.xfs_bmbt_ptr+xfs_bmbt_ptr.hi]
2394
        mov     esi, [esp + 28]
1925
        mov     ebx, [ebp+XFS.cur_block]
2395
DEBUGF 1,"read dirblock: 0x%x %d\n",esi,esi
1926
        stdcall xfs._.read_block
-
 
1927
        test    eax, eax
2396
        stdcall xfs_extent_list_read_dirblock, eax, esi, 0, edx, -1, -1
1928
        jnz     .error
-
 
1929
        mov     ebx, [ebp+XFS.cur_block]
-
 
1930
        jmp     .not_root
Line 2397... Line -...
2397
DEBUGF 1,"dirblock read: 0x%x%x\n",edx,eax
-
 
2398
        mov     ecx, eax
-
 
2399
        and     ecx, edx
-
 
2400
        inc     ecx
-
 
2401
        jnz     @f
-
 
2402
        movi    eax, ERROR_FS_FAIL
-
 
2403
        jmp     .error
-
 
2404
    @@:
-
 
2405
DEBUGF 1,"checkpoint #1\n"
-
 
2406
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
2407
        cmp     word[ebx + xfs_da_intnode.hdr.info.magic], XFS_DA_NODE_MAGIC
-
 
Line -... Line 1931...
-
 
1931
.leaf:
2408
        je      .node
1932
        jmp     .quit
2409
        cmp     word[ebx + xfs_da_intnode.hdr.info.magic], XFS_DIR2_LEAFN_MAGIC
1933
.error:
2410
        je      .leaf
1934
.quit:
-
 
1935
        ret
-
 
1936
endp
2411
        mov     eax, ERROR_FS_FAIL
1937
 
-
 
1938
 
-
 
1939
proc xfs._.walk_btree uses ebx esi edi, _ptr, _size, _callback_extent, _callback_block, _callback_data, _is_root
2412
DEBUGF 1,"checkpoint #2\n"
1940
        stdcall xfs._.long_btree.seek, [_ptr+4], [_size]
2413
        jmp     .error
1941
        mov     [_is_root], 0
2414
 
1942
.begin:
2415
  .node:
1943
        mov     ebx, [ebp+XFS.cur_block]
2416
DEBUGF 1,".node\n"
1944
        mov     eax, [ebp+XFS.bmap_magic]
2417
        mov     edi, [esp + 32] ; hash
1945
        cmp     [ebx+xfs_bmbt_block.bb_magic], eax
2418
        movzx   ecx, word[ebx + xfs_da_intnode.hdr.count]
-
 
2419
        xchg    cl, ch
1946
        movi    eax, ERROR_FS_FAIL
2420
        mov     [ebp + XFS.left_leaves], ecx
1947
        jnz     .error
2421
        xor     ecx, ecx
1948
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
-
 
1949
        xchg    cl, ch
2422
  .node.next_leaf:
1950
        add     ebx, [ebp+XFS.bmbt_block_size]
2423
        mov     esi, [ebx + xfs_da_intnode.btree + ecx*sizeof.xfs_da_node_entry + xfs_da_node_entry.hashval]
1951
        stdcall xfs._.walk_extent_list, ecx, ebx, [_callback_extent+8], [_callback_block+4], [_callback_data]
2424
        bswap   esi
1952
        jnz     .error
2425
        cmp     edi, esi
1953
        mov     esi, [ebp+XFS.offset_begin.lo]
2426
        jbe     .node.leaf_found
-
 
2427
        inc     ecx
-
 
2428
        cmp     ecx, [ebp + XFS.left_leaves]
1954
        mov     edi, [ebp+XFS.offset_begin.hi]
-
 
1955
        cmp     edi, [ebp+XFS.offset_end.hi]
Line 2429... Line -...
2429
        jne     .node.next_leaf
-
 
2430
        mov     eax, ERROR_FILE_NOT_FOUND
-
 
2431
        jmp     .error
-
 
2432
    @@:
-
 
2433
  .node.leaf_found:
-
 
2434
        mov     eax, [esp + 20]
-
 
2435
        mov     edx, [esp + 24]
-
 
2436
        mov     esi, [ebx + xfs_da_intnode.btree + ecx*sizeof.xfs_da_node_entry + xfs_da_node_entry.before]
-
 
2437
        bswap   esi
-
 
2438
        stdcall xfs_dir2_lookupdir_node, eax, edx, esi, edi
-
 
2439
        test    eax, eax
-
 
2440
        jz      .quit
-
 
2441
        movi    eax, ERROR_FILE_NOT_FOUND
-
 
2442
        jmp     .error
-
 
2443
 
1956
        ja      .quit
2444
  .leaf:
-
 
2445
DEBUGF 1,".leaf\n"
1957
        cmp     esi, [ebp+XFS.offset_end.lo]
2446
        movzx   ecx, [ebx + xfs_dir2_leaf.hdr.count]
1958
        jae     .quit
2447
        xchg    cl, ch
1959
        sub     ebx, [ebp+XFS.bmbt_block_size]
2448
        lea     esi, [ebx + xfs_dir2_leaf.ents]
1960
        movbe   edx, [ebx+xfs_bmbt_block.bb_rightsib.lo]
2449
        mov     eax, [esp + 32]
-
 
2450
        stdcall xfs_get_addr_by_hash, esi, ecx
-
 
2451
        cmp     eax, -1
-
 
2452
        je      .error
1961
        movbe   eax, [ebx+xfs_bmbt_block.bb_rightsib.hi]
2453
        mov     ecx, eax
-
 
2454
        jmp     .quit
-
 
2455
 
-
 
2456
  .quit:
-
 
2457
DEBUGF 1,".quit\n"
-
 
2458
        pop     edi esi edx ebx
-
 
2459
        xor     eax, eax
-
 
2460
        ret     16
-
 
2461
  .error:
-
 
2462
DEBUGF 1,".error\n"
-
 
2463
        pop     edi esi edx ebx
-
 
2464
        ret     16
-
 
2465
 
-
 
2466
 
-
 
2467
;----------------------------------------------------------------
-
 
2468
; push  dirblock_num
-
 
2469
; push  nextents
-
 
2470
; push  extent_list
-
 
2471
;----------------------------------------------------------------
-
 
2472
xfs_dir2_btree_get_numfiles:
-
 
2473
;DEBUGF 1,"xfs_dir2_node_get_numfiles\n"
-
 
2474
        push    ebx ecx edx esi edi
-
 
2475
 
1962
        mov     ecx, eax
2476
        mov     eax, [esp + 24]
1963
        and     ecx, edx
2477
        mov     edx, [esp + 28]
-
 
2478
        mov     esi, [esp + 32]
-
 
2479
        stdcall xfs_extent_list_read_dirblock, eax, esi, 0, edx, -1, -1
-
 
2480
        mov     ecx, eax
-
 
2481
        and     ecx, edx
-
 
2482
        inc     ecx
-
 
2483
        jnz     @f
-
 
2484
        movi    eax, ERROR_FS_FAIL
-
 
2485
        jmp     .error
-
 
2486
    @@:
-
 
2487
        mov     ebx, [ebp + XFS.cur_dirblock]
-
 
2488
        cmp     word[ebx + xfs_da_intnode.hdr.info.magic], XFS_DA_NODE_MAGIC
-
 
2489
        je      .node
-
 
2490
        cmp     word[ebx + xfs_da_intnode.hdr.info.magic], XFS_DIR2_LEAFN_MAGIC
-
 
2491
        je      .leaf
-
 
2492
        mov     eax, ERROR_FS_FAIL
-
 
2493
        jmp     .error
1964
        inc     ecx
2494
 
-
 
2495
  .node:
-
 
2496
;DEBUGF 1,".node\n"
-
 
2497
        mov     edi, [ebx + xfs_da_intnode.hdr.info.forw]
-
 
2498
        bswap   edi
-
 
2499
        mov     eax, [esp + 24]
-
 
2500
        mov     edx, [esp + 28]
-
 
2501
        mov     esi, [ebx + xfs_da_intnode.btree.before]
-
 
2502
        bswap   esi
-
 
2503
        stdcall xfs_dir2_node_get_numfiles, eax, edx, esi
-
 
2504
        test    eax, eax
-
 
2505
        jnz     .error
-
 
2506
        jmp     .common
-
 
2507
 
-
 
2508
  .leaf:
-
 
2509
;DEBUGF 1,".leaf\n"
-
 
2510
        movzx   ecx, word[ebx + xfs_dir2_leaf.hdr.count]
1965
        jz      .quit
2511
        xchg    cl, ch
-
 
2512
        movzx   eax, word[ebx + xfs_dir2_leaf.hdr.stale]
-
 
2513
        xchg    al, ah
-
 
2514
        sub     ecx, eax
-
 
2515
        add     [ebp + XFS.entries_read], ecx
-
 
2516
        mov     edi, [ebx + xfs_dir2_leaf.hdr.info.forw]
-
 
2517
        bswap   edi
1966
        mov     ebx, [ebp+XFS.cur_block]
2518
        jmp     .common
-
 
2519
 
-
 
2520
  .common:
-
 
2521
        test    edi, edi
-
 
2522
        jz      .quit
-
 
2523
        mov     esi, edi
-
 
2524
        mov     eax, [esp + 24]
-
 
2525
        mov     edx, [esp + 28]
1967
        stdcall xfs._.read_block
2526
        stdcall xfs_dir2_node_get_numfiles, eax, edx, esi
-
 
2527
        test    eax, eax
-
 
2528
        jnz     .error
-
 
2529
        jmp     .quit
1968
        jnz     .error
2530
 
-
 
2531
  .quit:
-
 
2532
;DEBUGF 1,".quit\n"
-
 
2533
        pop     edi esi edx ecx ebx
-
 
2534
        xor     eax, eax
-
 
2535
        ret     12
-
 
2536
  .error:
-
 
2537
;DEBUGF 1,".error\n"
-
 
2538
        pop     edi esi edx ecx ebx
-
 
2539
        movi    eax, ERROR_FS_FAIL
1969
        jmp     .begin
2540
        ret     12
-
 
2541
 
1970
.error:
2542
 
1971
.quit:
2543
;----------------------------------------------------------------
1972
        ret
2544
; push  is_root
-
 
2545
; push  block_hi
-
 
2546
; push  block_lo
-
 
2547
;----------------------------------------------------------------
-
 
2548
xfs_btree_read:
-
 
2549
        push    ebx ecx edx esi edi
-
 
2550
        cmp     dword[esp + 32], 1      ; is root?
-
 
2551
        je      .root
-
 
2552
        jmp     .not_root
-
 
2553
  .root:
-
 
2554
DEBUGF 1,".root\n"
-
 
2555
        mov     ebx, [ebp + XFS.cur_inode_save]
-
 
2556
        add     ebx, xfs_inode.di_u
1973
endp
2557
        movzx   edx, [ebx + xfs_bmdr_block.bb_numrecs]
-
 
2558
        xchg    dl, dh
-
 
2559
        dec     edx
-
 
2560
        add     ebx, sizeof.xfs_bmdr_block
1974
 
2561
        xor     eax, eax
1975
 
2562
        dec     eax
1976
proc xfs._.btree_read_block uses ebx esi edi, _tree, _size, _block_lo, _block_hi, _buf
2563
 .root.next_key:
-
 
2564
DEBUGF 1,".root.next_key\n"
-
 
2565
        cmp     [ebp + XFS.bytes_to_read], 0
-
 
2566
        je      .quit
-
 
2567
        inc     eax
-
 
2568
        cmp     eax, edx        ; out of keys?
-
 
2569
        ja      .root.key_found ; there is no length field, so try the last key
-
 
2570
        lea     edi, [ebx + sizeof.xfs_bmbt_key*eax + 0]
-
 
2571
        lea     esi, [ebx + sizeof.xfs_bmbt_key*eax + 4]
-
 
2572
        bswap   edi
-
 
2573
        bswap   esi
-
 
2574
        mov     ecx, [ebp + XFS.blocklog]
-
 
2575
        shld    edi, esi, cl
1977
        mov     eax, [_block_lo]
2576
        shl     esi, cl
-
 
2577
        cmp     edi, dword[ebp + XFS.file_offset + 4]
-
 
2578
        ja      .root.prev_or_hole
-
 
2579
        jb      .root.next_key
-
 
2580
        cmp     esi, dword[ebp + XFS.file_offset + 0]
-
 
2581
        ja      .root.prev_or_hole
-
 
2582
        jb      .root.next_key
-
 
2583
        jmp     .root.key_found
-
 
2584
  .root.prev_or_hole:
-
 
2585
DEBUGF 1,".root.prev_or_hole\n"
-
 
2586
        test    eax, eax
-
 
2587
        jz      .root.hole
-
 
2588
        dec     eax
-
 
2589
        jmp     .root.key_found
-
 
2590
  .root.hole:
-
 
2591
DEBUGF 1,".root.hole\n"
-
 
2592
        push    eax edx esi edi
-
 
2593
        mov     ecx, [ebp + XFS.blocklog]
-
 
2594
        shld    edi, esi, cl
-
 
2595
        shl     esi, cl
1978
        mov     [ebp+XFS.offset_begin.lo], eax
2596
        sub     esi, dword[ebp + XFS.file_offset + 0]
-
 
2597
        sbb     edi, dword[ebp + XFS.file_offset + 4]
1979
        mov     eax, [_block_hi]
2598
        mov     ecx, [ebp + XFS.bytes_to_read]
-
 
2599
        cmp     edi, 0  ; hole size >= 2^32
-
 
2600
        jne     @f
-
 
2601
        cmp     ecx, esi
1980
        mov     [ebp+XFS.offset_begin.hi], eax
2602
        jbe     @f
-
 
2603
        mov     ecx, esi
1981
        stdcall xfs._.long_btree.seek, [_tree+4], [_size]
2604
    @@:
-
 
2605
        add     dword[ebp + XFS.file_offset + 0], ecx
-
 
2606
        adc     dword[ebp + XFS.file_offset + 4], 0
1982
        jnz     .error
2607
        sub     [ebp + XFS.bytes_to_read], ecx
1983
        mov     ebx, [ebp+XFS.cur_block]
2608
        xor     eax, eax
-
 
2609
        mov     edi, [ebp + XFS.buffer_pos]
-
 
2610
        rep stosb
1984
        mov     eax, [ebp+XFS.bmap_magic]
2611
        mov     [ebp + XFS.buffer_pos], edi
-
 
2612
        pop     edi esi edx eax
-
 
2613
        jmp     .root.next_key
-
 
2614
  .root.key_found:
-
 
2615
DEBUGF 1,".root.key_found\n"
1985
        cmp     [ebx+xfs_bmbt_block.bb_magic], eax
2616
        mov     edx, [ebp + XFS.cur_inode_save]
-
 
2617
        mov     eax, [ebp + XFS.inodesize]
-
 
2618
        sub     eax, xfs_inode.di_u
-
 
2619
        cmp     [edx + xfs_inode.di_core.di_forkoff], 0
-
 
2620
        je      @f
-
 
2621
        movzx   eax, [edx + xfs_inode.di_core.di_forkoff]
-
 
2622
        shl     eax, XFS_DIR2_DATA_ALIGN_LOG    ; 3
-
 
2623
    @@:
1986
        jnz     .error
2624
        sub     eax, sizeof.xfs_bmdr_block
-
 
2625
        shr     eax, 4  ;log2(sizeof.xfs_bmbt_key + sizeof.xfs_bmdr_ptr)
-
 
2626
        mov     edx, [ebx + sizeof.xfs_bmbt_key*eax + 0]        ; hi
1987
        movzx   ecx, [ebx+xfs_bmbt_block.bb_numrecs]
2627
        mov     eax, [ebx + sizeof.xfs_bmbt_key*eax + 4]        ; hi
-
 
2628
        bswap   edx
1988
        xchg    cl, ch
Line 2629... Line -...
2629
        bswap   eax
-
 
Line 2630... Line 1989...
2630
        stdcall xfs_btree_read, eax, edx, 0
1989
        add     ebx, [ebp+XFS.bmbt_block_size]
-
 
1990
        mov     eax, [_block_lo]
-
 
1991
        mov     [ebp+XFS.offset_begin.lo], eax
2631
        test    eax, eax
1992
        mov     eax, [_block_hi]
2632
        jnz     .error
1993
        mov     [ebp+XFS.offset_begin.hi], eax
-
 
1994
        stdcall xfs._.extent_list.seek, ecx
-
 
1995
        stdcall xfs._.read_dirblock, [ebp+XFS.extent.br_startblock.lo], [ebp+XFS.extent.br_startblock.hi], [_buf]
2633
        jmp     .root.next_key
1996
.error:
2634
 
1997
.quit:
2635
  .not_root:
1998
        ret
2636
DEBUGF 1,".root.not_root\n"
1999
endp
2637
        mov     eax, [esp + 24] ; block_lo
2000
 
-
 
2001
 
-
 
2002
proc xfs._.extent_list.seek uses esi, _count
-
 
2003
        sub     ebx, sizeof.xfs_bmbt_rec
-
 
2004
        inc     [_count]
Line 2638... Line -...
2638
        mov     edx, [esp + 28] ; block_hi
-
 
2639
        mov     ebx, [ebp + XFS.cur_block]
-
 
2640
        stdcall xfs_read_block
-
 
2641
        test    eax, eax
-
 
2642
        jnz     .error
-
 
2643
        mov     ebx, [ebp + XFS.cur_block]
-
 
2644
 
-
 
2645
        cmp     [ebx + xfs_bmbt_block.bb_magic], XFS_BMAP_MAGIC
-
 
2646
        jne     .error
-
 
2647
        cmp     [ebx + xfs_bmbt_block.bb_level], 0      ; leaf?
-
 
2648
        je      .leaf
2005
.find_low:
2649
        jmp     .node
-
 
2650
 
-
 
2651
  .node:
2006
        add     ebx, sizeof.xfs_bmbt_rec
2652
;        mov     eax, [ebp + XFS.blocksize]
-
 
2653
;        sub     eax, sizeof.xfs_bmbt_block
-