Subversion Repositories Kolibri OS

Rev

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

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