Subversion Repositories Kolibri OS

Rev

Rev 6462 | Rev 9888 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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