Subversion Repositories Kolibri OS

Rev

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

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