Subversion Repositories Kolibri OS

Rev

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

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